一个基于 React + Node.js 的实验室科研协作应用,包含以下能力:
- AI 对话与流式回复
- 本地组会知识库上传与简易 RAG
- 实验参与者登记表单
- 组会日程日历与自定义 schedule 管理
- React 18
- Vite
- React Context API
- 自定义 CSS
react-markdown+remark-gfm+rehype-highlight
- Node.js 原生
http/https dotenv- 本地 JSON 文件持久化
- 讯飞星火 MaaS API
- 支持输入问题并流式展示模型回复
- 支持中断生成
- 支持历史对话切换与删除
- 首页提供预设科研问题卡片
- 可上传
.txt、.md、.markdown文本文件 - 上传后的文档保存到本地
lab_docs/ - 后端收到用户问题后,会先从
lab_docs/中做简易关键词检索 - 检索出的文本片段会拼接到 system prompt 中,再发送给讯飞模型
- 采用实验表单风格界面
- 当前包含字段:
NameStudent IDAgeGendertrainedChinese levelEnglish levelOther languages
- 前端只负责登记提交,不直接展示已登记列表
- 数据保存在后端
data/participants.json
- Sidebar 新增“组会日程”入口
- 提供简约月历视图
- 每周一晚
20:00 - 23:00固定标记为组会 2026-04-19标记为“史语所踏青活动”- 支持用户新增和删除自定义日程
- 数据保存在后端
data/schedules.json
CRUD/
├── data/
│ ├── participants.json # 实验参与者登记数据
│ └── schedules.json # 自定义日程数据
├── lab_docs/ # 本地知识库文档目录
├── public/
├── src/
│ ├── assets/ # 图标与静态资源
│ ├── components/
│ │ ├── Main/
│ │ │ ├── Main.jsx # 主工作区:聊天、登记、知识库、日历
│ │ │ └── Main.css
│ │ ├── MarkdownRenderer/
│ │ │ └── MarkdownRenderer.jsx
│ │ └── SideBar/
│ │ ├── SideBar.jsx # Sidebar 工作区导航
│ │ └── SideBar.css
│ ├── context/
│ │ └── Context.jsx # 全局状态与前端接口调用
│ ├── services/
│ │ └── streamParser.js # SSE 流式解析与节奏渲染
│ ├── App.jsx
│ ├── main.jsx
│ └── index.css
├── .env
├── index.html
├── package.json
├── server.js # 后端 API、RAG、数据持久化
└── vite.config.js
npm install在项目根目录创建 .env:
XUNFEI_API_KEY=your_xunfei_api_key_here
PORT=3001npm run server默认监听:
http://localhost:3001
另开一个终端:
npm run dev默认访问:
http://localhost:5173
npm run build用户输入
→ Context.jsx 调用 streamParser.fetchStream()
→ 前端请求 POST /api/chat
→ server.js 先从 lab_docs/ 检索相关文本
→ 后端将检索结果拼进 system prompt
→ 请求讯飞星火流式接口
→ 后端将 SSE 流返回前端
→ streamParser 解析并按节奏 flush
→ Main.jsx 渲染消息
用户填写表单
→ Context.jsx 提交 POST /api/participants
→ server.js 校验字段
→ 写入 data/participants.json
用户填写 schedule 表单
→ Context.jsx 提交 POST /api/schedules
→ server.js 写入 data/schedules.json
→ 前端重新拉取并更新日历
GET /healthPOST /api/chat
Content-Type: application/json请求体示例:
{
"messages": [
{
"role": "user",
"content": "请总结本周组会重点"
}
]
}GET /api/participants
POST /api/participants
PUT /api/participants/:id
DELETE /api/participants/:id请求体示例:
{
"name": "张三",
"studentId": "PB21000000",
"age": "23",
"gender": "Male",
"trained": "Yes",
"chineseLevel": "Native",
"englishLevel": "Proficient",
"otherLanguages": "Japanese"
}GET /api/schedules
POST /api/schedules
DELETE /api/schedules/:id请求体示例:
{
"title": "论文精读",
"date": "2026-04-22",
"startTime": "19:00",
"endTime": "21:00",
"note": "讨论新到文献"
}GET /api/documents
POST /api/documents当前上传方式不是 multipart,而是前端先读取文本内容,再以 JSON 发送:
{
"filename": "week-7.md",
"content": "# 第七周组会\n\n本周讨论了……"
}当前实现是“简易 RAG”,不是向量数据库方案。
处理逻辑如下:
- 前端上传文本到
lab_docs/ - 用户提问时,后端读取
lab_docs/所有文本 - 按段落切分文档
- 对问题做简单关键词切分
- 统计每个段落的关键词命中分数
- 取分数最高的若干段落作为上下文
- 将这些段落拼接进 system prompt 后调用模型
相关核心代码:
server.js中的retrieveRelevantContextserver.js中的buildPromptMessages
- 当前知识库上传仅适合文本类文件,不支持
.pdf、.docx - 前端接口地址目前写死为
http://localhost:3001 - 日历中的每周一组会与
2026-04-19踏青活动属于前端固定规则 - 若要让踏青活动每年循环,或支持编辑固定组会,需要进一步扩展规则层
- 支持 PDF / Word 文档解析
- 接入向量数据库,替代关键词检索
- 为参与者登记增加管理员后台
- 为日程增加编辑功能
- 为前端请求增加 Vite 代理或环境变量配置