A newer version of the Gradio SDK is available: 6.12.0
TeachAgent 新前端迁移开发清单
本文档记录从旧版 Flask 模板前端迁移到新版 React 前端的完整开发任务。 更新日期:2026-04-13
一、项目架构概览
| 层级 | 技术栈 | 端口 |
|---|---|---|
| 新前端 | React 19 + Vite + Ant Design + TailwindCSS + Redux | 3000 |
| 旧前端 | Flask Jinja2 + Bootstrap 5 + 原生JS | 7860(与后端同源) |
| 后端 API | Flask + Blueprint | 7860 |
| 数据库 | Elasticsearch 9.3.3 (向量+文档) + SQLite (用户) | 9200 |
| AI 服务 | SiliconFlow (Embedding/Rerank) + DeepSeek (Chat) | 外部API |
二、迁移状态总览
已完成模块
| 模块 | 新前端文件 | 状态 | 备注 |
|---|---|---|---|
| 登录 | LoginPage.jsx |
✅ 完成 | 邮箱/手机/密码三种方式 |
| 注册 | RegisterPage.jsx |
✅ 完成 | 用户名+密码 |
| 路由保护 | ProtectedRoute.jsx |
✅ 完成 | JWT + 角色校验 |
| 教师 Dashboard | teacher/Dashboard.jsx |
✅ 完成 | 统计卡片、快速入门 |
| Agent 列表 | teacher/AgentList.jsx |
✅ 完成 | CRUD、分发链接、详情查看 |
| Agent 创建 | teacher/CreateAgent.jsx |
✅ 完成 | 4步向导、AI工作流生成 |
| 工作流编辑器 | components/common/WorkflowEditor.jsx |
✅ 完成 | React Flow 可视化 |
| 知识库管理 | teacher/KnowledgeBase.jsx |
⚠️ 基本完成 | 缺批量上传、拖拽 |
| 学生管理 | teacher/StudentManagement.jsx |
✅ 完成 | CRUD、密码重置、进度 |
| 学生门户 | student/StudentPortal.jsx |
✅ 完成 | Agent列表、Token验证、活动记录 |
| Agent 对话 | student/AgentChat.jsx |
⚠️ 部分完成 | 流式对话可用,插件系统缺失 |
| 打字机 Hook | hooks/useTypewriter.js |
✅ 已实现 | 未接入使用 |
未实现模块
| 模块 | 旧版位置 | 优先级 |
|---|---|---|
| 代码执行插件(对话内嵌) | student.html 侧面板 |
P0 |
| 3D 可视化插件(对话内嵌) | student.html 侧面板 |
P1 |
| 思维导图插件(对话内嵌) | student.html 侧面板 |
P1 |
| 独立代码执行页 | code_execution.html |
P1 |
| Token 直接访问入口(登录页) | login.html |
P2 |
三、关键 BUG 与问题
3.1 流式输出 SSE 实现问题(P0)
当前实现: AgentChat.jsx 使用 fetch + ReadableStream reader 手动解析 SSE
后端发送格式:
data: {"type": "start", "plugins": [...], "references": [...]}
data: {"type": "content", "content": "文本片段"}
data: {"type": "metadata", "content": {...}}
data: {"type": "done"}
问题清单:
| # | 问题 | 严重度 | 说明 |
|---|---|---|---|
| 1 | metadata 事件未处理 |
中 | 前端只处理 start/content/done,metadata 被忽略 |
| 2 | 无 error 事件类型 |
高 | 后端出错时直接断流,前端会一直卡在"思考中" |
| 3 | [DONE] 哨兵检测无效 |
低 | 前端检查 [DONE] 但后端从不发送此标记 |
| 4 | 流结束时 buffer 未清空 | 中 | 如果流在 \n\n 结尾,最后一个事件可能丢失 |
| 5 | 断流时无 JSON 恢复 | 中 | 连接中断时 partial JSON 直接丢失 |
| 6 | 无超时/重连机制 | 中 | 网络波动时前端无法恢复 |
建议重构方向:
- 后端增加
type: "error"事件 - 前端增加 metadata 事件处理
- 添加流超时检测(如 30s 无数据则提示)
- 清理无用的
[DONE]检查
3.2 API 路径不一致(P0)
| 前端调用 | 后端实际路径 | 问题 |
|---|---|---|
axios.post('/api/verify_token') (AgentChat.jsx:84) |
/api/verify_token |
axios baseURL 是 /api,实际请求变成 /api/api/verify_token(双重前缀) |
getProgress(taskId) → /knowledge/progress/${taskId} |
/api/progress/${taskId}(在 app.py 主路由) |
路径不在 knowledge blueprint 下 |
getDistributions(agentId) → /agent/${agentId}/distributions |
后端未实现此端点 | 404 |
authService.refreshToken() → /auth/refresh |
后端未实现 | 404 |
authService.getCurrentUser() → /auth/me |
后端未实现 | 404 |
authService.changePassword() → /auth/change_password |
后端未实现 | 404 |
3.3 其他前端问题
| # | 问题 | 位置 | 说明 |
|---|---|---|---|
| 1 | Agent 编辑路由缺失 | CreateAgent.jsx |
编辑模式通过 localStorage 传参,无独立路由 |
| 2 | 知识库进度轮询路径错误 | knowledgeService.js |
应直接调 /api/progress/ 而非通过 knowledge 前缀 |
| 3 | 学生 Dashboard 是空壳 | StudentDashboard.jsx |
只是路由容器,无独立内容 |
四、完整 API 端点对照表
4.1 认证模块 /api/auth/*
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/auth/login |
POST | ✅ 旧版密码登录 | ❌ 未使用 | 可废弃 |
/api/auth/login-password |
POST | ✅ | ✅ | 正常 |
/api/auth/login-email |
POST | ✅ | ✅ | 正常 |
/api/auth/login-phone |
POST | ✅ | ✅ | 正常 |
/api/auth/send-email-code |
POST | ✅ | ✅ | 正常(邮件服务不可用) |
/api/auth/send-phone-code |
POST | ✅ | ✅ | 正常(开发模式模拟) |
/api/auth/register |
POST | ✅ | ✅ | 正常 |
/api/auth/verify |
GET | ✅ | ❌ 未使用 | - |
/api/auth/logout |
POST | ✅ | ✅ | 正常 |
/api/auth/refresh |
POST | ❌ 未实现 | ✅ 有调用 | 需实现 |
/api/auth/me |
GET | ❌ 未实现 | ✅ 有调用 | 需实现 |
/api/auth/change_password |
POST | ❌ 未实现 | ✅ 有调用 | 需实现 |
/api/auth/check |
GET | ✅ session检查 | ❌ 未使用 | 旧版遗留 |
4.2 知识库模块 /api/knowledge/*
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/knowledge/ |
GET | ✅ | ✅ | 正常 |
/api/knowledge/ |
POST | ✅ 文件上传创建 | ✅ | 正常 |
/api/knowledge/<id> |
DELETE | ✅ | ✅ | 正常 |
/api/knowledge/<id>/documents |
GET | ✅ | ✅ | 正常 |
/api/knowledge/<id>/documents |
POST | ✅ | ✅ | 正常 |
/api/knowledge/<id>/documents/<file> |
DELETE | ✅ | ✅ | 正常 |
/api/progress/<task_id> |
GET | ✅(app.py主路由) | ⚠️ 路径可能错 | 需核实 |
4.3 Agent 模块 /api/agent/*
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/agent/create |
POST | ✅ | ✅ | 正常 |
/api/agent/list |
GET | ✅ | ✅ | 正常 |
/api/agent/<id> |
GET | ✅ | ✅ | 正常 |
/api/agent/<id> |
PUT | ✅ | ✅ | 正常 |
/api/agent/<id> |
DELETE | ✅ | ✅ | 正常 |
/api/agent/<id>/distribute |
POST | ✅ | ✅ | 正常 |
/api/agent/<id>/distributions |
GET | ❌ 未实现 | ✅ 有调用 | 需实现 |
/api/agent/ai-assist |
POST | ✅ | ✅ | 正常 |
4.4 代码执行模块 /api/code/*
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/code/execute |
POST | ✅ | ❌ 未接入 | 需前端实现 |
/api/code/input |
POST | ✅ | ❌ 未接入 | 需前端实现 |
/api/code/stop |
POST | ✅ | ❌ 未接入 | 需前端实现 |
/api/code/generate |
POST | ✅ | ❌ 未接入 | 需前端实现 |
4.5 可视化模块 /api/visualization/*
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/visualization/mindmap |
POST | ✅ | ❌ 未接入 | 需前端实现 |
/api/visualization/3d-surface |
POST | ✅ | ❌ 未接入 | 需前端实现 |
4.6 学生模块
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/student/agents |
GET | ✅ | ✅ | 正常 |
/api/student/activities |
GET | ✅ | ✅ | 正常 |
/api/student/chat/<id> |
POST (SSE) | ✅ | ✅ | ⚠️ 有解析问题 |
/api/verify_token |
POST | ✅ (app.py) | ⚠️ 路径双重前缀 | 需修复 |
4.7 学生管理模块 /api/teacher/students/*
| 端点 | 方法 | 后端 | 前端调用 | 状态 |
|---|---|---|---|---|
/api/teacher/students |
GET | ✅ | ✅ | 正常 |
/api/teacher/students |
POST | ✅ | ✅ | 正常 |
/api/teacher/students/<id> |
PUT | ✅ | ✅ | 正常 |
/api/teacher/students/<id> |
DELETE | ✅ | ✅ | 正常 |
/api/teacher/students/<id>/reset-password |
POST | ✅ | ✅ | 正常 |
/api/teacher/students/<id>/progress |
GET | ✅ | ✅ | 正常 |
五、分阶段开发计划
第一阶段:基础修复(让现有功能跑通)
修复 API 路径双重前缀问题
AgentChat.jsx中axios.post('/api/verify_token')改为用 api 实例或去掉/api前缀- 排查所有直接使用
axios而非api实例的调用
修复知识库进度轮询路径
knowledgeService.js中getProgress()路径对齐后端/api/progress/<task_id>
修复 SSE 流式输出
- 前端增加
metadata事件处理(至少不报错) - 后端增加
type: "error"事件,出错时通知前端 - 移除前端无用的
[DONE]检查 - 添加流超时检测(30s 无数据提示用户)
- 修复流结束时 buffer 未清空问题
- 前端增加
实现缺失的后端端点
GET /api/agent/<id>/distributions— 获取 Agent 的分发链接列表GET /api/auth/me— 返回当前登录用户信息POST /api/auth/refresh— JWT token 刷新(或前端去掉此调用)POST /api/auth/change_password— 修改密码(或前端暂时隐藏入口)
第二阶段:插件系统迁移(核心差异)
AgentChat 插件框架设计
- 在对话界面右侧增加可展开的插件面板(Ant Design Drawer 或自定义侧栏)
- 根据后端 SSE
start事件返回的plugins字段决定显示哪些插件 Tab - 插件自动激活:后端检测到关键词后在
start事件中标记suggested_plugins - 插件面板状态:折叠/展开/全屏
- 布局:左侧对话区 + 右侧插件面板,移动端改为底部抽屉
代码执行插件
- 使用 CodeMirror 6 (
@uiw/react-codemirror+@codemirror/lang-python) - 上半区:代码编辑器(Python语法高亮、行号)
- 下半区:终端输出面板(深色背景、绿色提示符、支持 ANSI 颜色)
- 交互式输入:检测到
input()时显示输入框 - 控制按钮:运行 / 停止 / 清除
- 对接 API:
POST /api/code/execute→ 发送代码,轮询输出POST /api/code/input→ 发送用户输入POST /api/code/stop→ 终止执行
- AI 回复中的代码块可一键复制到编辑器
- AI 代码生成按钮 →
POST /api/code/generate
- 使用 CodeMirror 6 (
3D 可视化插件(保持旧版 Plotly iframe 方案)
- 从 AI 回复中提取 Python 代码(包含
create_3d_plot函数) POST /api/visualization/3d-surface发送代码- 返回
html_url后在插件面板中用<iframe>加载 - 支持全屏查看(Ant Design Modal 全屏模式)
- 加载中显示 Spin 组件
- Plotly 原生交互:旋转、缩放、平移、悬浮提示、导出
- 从 AI 回复中提取 Python 代码(包含
思维导图插件(markmap 前端渲染,替代旧版 PlantUML)
- 安装
markmap-lib+markmap-view - 从 AI 回复中提取 Markdown 层级结构
- 使用
Transformer.transform()解析为树结构 - 使用
Markmap.create()渲染到 SVG 容器 - 交互支持:缩放、平移、节点展开/折叠
- 支持全屏查看和导出为 SVG/PNG
- 后端修改:让 LLM prompt 输出 Markdown 标题格式而非 PlantUML 语法
- 安装
第三阶段:独立功能页面
独立代码执行页
/code- 完整的 Python IDE 界面(编辑器 + 终端)
- 语法高亮、行号、Tab 缩进
- 运行/停止/清除控制按钮
- 从旧版
code_execution.html迁移逻辑
Token 直接访问入口
- 登录页增加"使用 Token 直接访问"选项
- 输入 Token → 验证 → 跳转到对应 Agent 对话页
第四阶段:体验优化
打字机效果
- 将
useTypewriter.jshook 接入 AgentChat 的流式渲染 - 支持暂停/继续/加速控制
- 或直接在流式输出时模拟打字效果(当前逐 chunk 渲染已有类似效果,评估是否需要)
- 将
知识库批量上传
- 支持多文件选择和拖拽上传
- 批量进度追踪
Agent 编辑流程优化
- 为编辑模式添加独立路由
/teacher/agent/edit/:id - 替换 localStorage 传参方式为 URL 参数 + API 获取
- 为编辑模式添加独立路由
学生 Dashboard 充实内容
- 学习统计、最近活动、推荐 Agent 等
LaTeX 公式渲染
- 旧版使用 KaTeX,新版 AgentChat 的 Markdown 渲染中需集成
- 支持行内公式
$...$和块级公式$$...$$
消息中的引用源展示优化
- 旧版有可折叠的引用卡片,显示文件名+摘要
- 新版已有基础实现,但样式和交互可优化
第五阶段:后端优化
统一认证机制
- 旧版 app.py 中的硬编码用户和 session 装饰器与新版 JWT 并存,需要统一
- 决策:全部迁移到 JWT,废弃 session 方式
- 更新
@login_required、@teacher_required、@student_required装饰器为 JWT 验证
密码哈希升级
- 当前使用 SHA256 直接哈希,建议升级为 bcrypt 或 argon2
- 需要兼容迁移方案(登录时自动升级哈希)
插件检测逻辑优化
- 当前基于消息关键词匹配(如包含"代码"就触发代码插件),过于粗糙
- 考虑让 LLM 在回复中标记是否需要插件,或使用更精确的意图识别
六、旧版功能对照清单
教师端功能
| 功能 | 旧版 | 新版 | 差距 |
|---|---|---|---|
| 统计面板 | 知识库数/Agent数/分发数 | ✅ 相同 | - |
| 知识库创建 | 多文件上传+进度条 | ⚠️ 单文件 | 缺批量 |
| 知识库文件管理 | 添加/删除文件 | ✅ | - |
| Agent 创建 | 基本信息+插件+知识库+工作流 | ✅ 4步向导 | - |
| Agent 工作流 | jsPlumb 可视化 | ✅ React Flow | 升级 |
| Agent 管理 | 列表+详情+编辑+删除 | ✅ | 编辑入口可优化 |
| 分发链接 | 创建+复制+过期设置 | ✅ | - |
| 学生管理 | CRUD+密码重置+进度 | ✅ | - |
学生端功能
| 功能 | 旧版 | 新版 | 差距 |
|---|---|---|---|
| 学生门户 | Agent列表+Token验证+活动记录 | ✅ | - |
| Agent 对话 | SSE流式+Markdown+代码高亮 | ✅ 基本可用 | SSE有bug |
| 打字机效果 | 暂停/加速控制 | ❌ Hook已写未接入 | 需接入 |
| LaTeX 公式 | KaTeX 渲染 | ❌ | 需集成 |
| 代码执行插件 | 侧面板内嵌 IDE | ❌ | 核心缺失 |
| 3D 可视化插件 | Plotly 侧面板 | ❌ | 核心缺失 |
| 思维导图插件 | PlantUML 侧面板 | ❌ | 核心缺失 |
| 引用源展示 | 可折叠卡片 | ⚠️ 基础实现 | 可优化 |
| 独立代码页 | 完整Python IDE | ❌ | 需新建页面 |
七、技术选型
7.1 思维导图:markmap(推荐)
废弃旧方案:旧版使用 PlantUML 语法 → 发送到外部 HuggingFace Space API → 返回 PNG 图片。问题:依赖外部服务、不可交互、渲染慢。
新方案:使用 markmap 在前端直接从 Markdown 生成交互式 SVG 思维导图。
| 对比项 | 旧方案 (PlantUML) | 新方案 (markmap) |
|---|---|---|
| 渲染位置 | 后端调外部API | 前端本地渲染 |
| 输出格式 | 静态 PNG | 交互式 SVG |
| 交互能力 | 无 | 缩放/平移/展开折叠 |
| 外部依赖 | HuggingFace Space | 无 |
| 延迟 | 3-10秒 | 毫秒级 |
| 输入格式 | PlantUML 专有语法 | Markdown 标题层级 |
安装:
npm install markmap-lib markmap-view d3@7
核心用法:
import { Transformer } from 'markmap-lib';
import { Markmap } from 'markmap-view';
// Markdown → 思维导图数据
const transformer = new Transformer();
const { root } = transformer.transform(markdownText);
// 渲染到 SVG 元素
Markmap.create(svgElement, null, root);
后端改动:
- 让 LLM 在回复中直接输出 Markdown 层级结构(而非 PlantUML 语法)
- 或者保留后端端点,改为返回 Markdown 文本而非图片 URL
- 前端从 AI 回复中提取 Markdown 标题结构,直接渲染
备选库对比:
| 库 | Stars | 特点 | 适合场景 |
|---|---|---|---|
| markmap | 9k+ | Markdown原生、SVG交互、轻量 | ✅ 本项目(AI输出Markdown) |
| simple-mind-map | 11k+ | 功能最全、主题丰富、插件多 | 需要完整思维导图编辑器 |
| mind-elixir | 3k | 零依赖、有React组件 | 需要拖拽编辑节点 |
| React Flow | 24k+ | 项目已在用、高度可定制 | 已用于工作流,可复用 |
选择 markmap 的理由:
- AI 天然输出 Markdown,无需格式转换
- 纯前端渲染,不依赖外部服务
- 交互体验远超静态图片
- 包体积小,集成简单
7.2 3D 可视化:保持 Plotly iframe 方案
旧版方案已经很成熟,保持不变:
前端提取代码 → POST /api/visualization/3d-surface → 后端沙箱执行 Python
→ 生成 Plotly HTML(内嵌 plotly.js) → 返回 HTML 文件 URL → 前端 iframe 加载
交互能力(Plotly 原生支持):
- 3D 旋转(鼠标拖拽)
- 缩放(滚轮)
- 平移(Shift+拖拽)
- 悬浮提示(坐标值)
- 图例切换
- 导出 PNG
- 双击重置视角
React 迁移要点:
- 不需要安装
react-plotly.js(图表在 iframe 中独立运行) - 只需在 AgentChat 插件面板中嵌入
<iframe src={htmlUrl} /> - 添加全屏按钮和关闭按钮
后端数据流:
输入: { code: "def create_3d_plot():\n return {'x':[], 'y':[], 'z':[], 'type':'surface'}" }
输出: { success: true, html_url: "/static/3d_plot_1713012345.html" }
7.3 代码编辑器:CodeMirror 6(推荐)
| 对比项 | Monaco Editor | CodeMirror 6 |
|---|---|---|
| 包体积 | ~2.5MB (gzip) | ~150KB (gzip) |
| 加载速度 | 较慢 | 快 |
| 移动端 | 差 | 好 |
| Python 支持 | 完整 | 完整 |
| React 集成 | @monaco-editor/react | @uiw/react-codemirror |
| 适合场景 | 完整 IDE | 轻量代码片段编辑 |
选择 CodeMirror 的理由:
- 本项目只需要 Python 代码编辑,不需要完整 IDE 功能
- 包体积小 15 倍,对教育平台的加载速度至关重要
- 移动端适配更好(学生可能用手机访问)
安装:
npm install @uiw/react-codemirror @codemirror/lang-python
7.4 LaTeX 公式:rehype-katex(推荐)
当前 AgentChat 已使用 react-markdown + remark-gfm,集成 KaTeX 只需加两个插件:
npm install remark-math rehype-katex katex
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import 'katex/dist/katex.min.css';
<ReactMarkdown remarkPlugins={[remarkGfm, remarkMath]} rehypePlugins={[rehypeKatex]}>
{content}
</ReactMarkdown>
7.5 技术选型汇总
| 组件 | 选型 | npm 包 | 理由 |
|---|---|---|---|
| 思维导图 | markmap | markmap-lib + markmap-view |
Markdown原生、前端渲染、交互式 |
| 3D 可视化 | Plotly iframe | 无需前端安装 | 保持旧版成熟方案,后端生成HTML |
| 代码编辑器 | CodeMirror 6 | @uiw/react-codemirror |
轻量、移动端友好 |
| LaTeX 公式 | KaTeX | remark-math + rehype-katex |
与现有 react-markdown 无缝集成 |
| 代码高亮 | react-syntax-highlighter | 已安装 | 项目已在用 |
| 工作流编辑 | React Flow | 已安装 | 项目已在用 |
八、文件结构参考
frontend/src/
├── App.jsx # 路由配置
├── index.css # 全局样式
├── services/
│ ├── api.js # axios 实例 + 拦截器
│ ├── authService.js # 认证 API
│ ├── agentService.js # Agent API
│ └── knowledgeService.js # 知识库 API
├── store/
│ ├── store.js # Redux store
│ └── slices/
│ ├── authSlice.js # 认证状态
│ ├── agentSlice.js # Agent 状态
│ ├── chatSlice.js # 对话状态
│ ├── workflowSlice.js # 工作流状态
│ └── uiSlice.js # UI 状态
├── pages/
│ ├── LoginPage.jsx # 登录页
│ ├── RegisterPage.jsx # 注册页
│ ├── teacher/
│ │ ├── TeacherDashboard.jsx # 教师端框架
│ │ ├── Dashboard.jsx # 概览页
│ │ ├── AgentList.jsx # Agent 列表
│ │ ├── CreateAgent.jsx # Agent 创建向导
│ │ ├── KnowledgeBase.jsx # 知识库管理
│ │ └── StudentManagement.jsx # 学生管理
│ └── student/
│ ├── StudentDashboard.jsx # 学生端框架
│ ├── StudentPortal.jsx # 学生门户
│ └── AgentChat.jsx # Agent 对话
├── components/
│ └── common/
│ ├── ProtectedRoute.jsx # 路由保护
│ └── WorkflowEditor.jsx # 工作流编辑器
└── hooks/
└── useTypewriter.js # 打字机效果 hook
agent/ # 后端
├── app.py # Flask 主应用 + 路由
├── config.py # 配置
├── auth.db # SQLite 用户库
├── student_management.py # 学生管理路由
├── modules/
│ ├── auth/routes.py # 认证路由
│ ├── knowledge_base/
│ │ ├── routes.py # 知识库路由
│ │ ├── retriever.py # ES 检索器
│ │ ├── reranker.py # 重排序器
│ │ ├── generator.py # LLM 生成器
│ │ ├── processor.py # 文档处理器
│ │ └── vector_store.py # ES 向量存储
│ ├── agent_builder/routes.py # Agent 构建路由
│ ├── code_executor/routes.py # 代码执行路由
│ └── visualization/routes.py # 可视化路由
├── agents/ # Agent JSON 配置存储
├── uploads/ # 上传文件存储
└── templates/ # 旧版 HTML 模板(待废弃)