# edu_agent **Repository Path**: itheim/edu_agent ## Basic Information - **Project Name**: edu_agent - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-08 - **Last Updated**: 2026-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 智能教学助手系统 基于多智能体架构的教学助手系统,集成 LangGraph + FastAPI + Vue3 + SSE,提供智能出题、作业批改、课程设计等教学辅助功能。 ## 技术栈 | 层级 | 技术 | |------|------| | LLM编排 | LangGraph 1.2 + LangChain 1.3 | | LLM | 通义千问 (qwen-plus) via OpenAI兼容接口 | | 向量库 | ChromaDB 1.5 (MMR检索) | | 后端 | FastAPI 0.136 + Uvicorn | | 前端 | Vue3 + Element Plus + Pinia | | 流式通信 | SSE (Server-Sent Events) | | 认证 | JWT (python-jose) | | 部署 | Docker Compose | ## 项目结构 ``` project/ ├── backend/ # 后端服务 │ ├── agents/ # Agent模块 │ │ ├── supervisor.py # 意图识别Agent(路由调度) │ │ ├── question_gen.py # 出题Agent │ │ ├── answer_gen.py # 生成答案Agent │ │ ├── course_design.py # 课程设计Agent │ │ ├── grader.py # 批改Agent(作业+试卷) │ │ ├── review.py # 审核Agent(interrupt续跑) │ │ └── __init__.py # Agent注册表 │ ├── api/ # API层 │ │ ├── routes/ # 路由模块 │ │ │ ├── auth.py # 认证(JWT注册/登录) │ │ │ ├── chat.py # 对话(SSE流式 + 非流式) │ │ │ ├── question.py # 出题(SSE流式 + 非流式) │ │ │ ├── homework.py # 批改(作业/试卷/审核) │ │ │ └── course.py # 课程设计(SSE流式 + 非流式) │ │ ├── deps.py # 依赖注入(JWT解析/图实例) │ │ └── middleware.py # 中间件(限流/日志) │ ├── core/ # 核心配置 │ │ ├── config.py # pydantic-settings配置 │ │ ├── llm_factory.py # LLM/Embedding工厂 │ │ └── exceptions.py # 异常处理 │ ├── graph/ # LangGraph图定义 │ │ ├── builder.py # 多Agent图构建 │ │ └── state.py # 共享状态定义 │ ├── models/ # 数据模型 │ │ ├── request.py # 请求模型 │ │ ├── response.py # 响应模型 │ │ └── schemas.py # 结构化输出Schema │ ├── rag/ # RAG检索模块 │ │ ├── setup.py # 向量库初始化(12条教学知识) │ │ └── retriever.py # MMR知识检索 │ ├── data/ # 数据目录 │ ├── main.py # FastAPI应用入口 │ ├── Dockerfile │ └── requirements.txt ├── frontend/ # 前端服务 │ ├── src/ │ │ ├── api/ # API调用层 │ │ ├── components/ # Vue组件 │ │ ├── router/ # 路由配置 │ │ ├── stores/ # Pinia状态管理 │ │ ├── utils/ # 工具函数 │ │ ├── views/ # 页面视图 │ │ ├── App.vue │ │ └── main.js │ ├── nginx.conf # Nginx配置(含SSE代理) │ ├── Dockerfile │ ├── index.html │ ├── package.json │ └── vite.config.js ├── tests/ # 测试套件 │ ├── conftest.py # pytest共享fixture │ ├── test_intent.py # 意图识别测试(52条参数化) │ ├── test_grading.py # 批改一致性测试 │ ├── test_rag.py # RAG评估测试 │ ├── test_api.py # API集成测试 │ └── locustfile.py # 压测脚本 ├── docker-compose.yml # Docker编排 ├── .env.example # 环境变量模板 ├── .gitignore └── README.md ``` ## 快速开始 ### 环境准备 - Python 3.11+ - Node.js 20+ - 通义千问 API Key ### 后端启动 ```bash # 1. 进入后端目录 cd backend # 2. 创建虚拟环境 python -m venv .venv # Windows .venv\Scripts\activate # macOS/Linux source .venv/bin/activate # 3. 安装依赖 pip install -r requirements.txt # 4. 配置环境变量 cp .env.example .env # 编辑 .env,填入你的 OPENAI_API_KEY # 5. 启动服务 python main.py # 或 uvicorn main:app --host 0.0.0.0 --port 8000 --reload ``` 后端启动后访问: - API服务:http://localhost:8000 - API文档:http://localhost:8000/docs - 健康检查:http://localhost:8000/api/health ### 前端启动 ```bash # 1. 进入前端目录 cd frontend # 2. 安装依赖 npm install # 3. 启动开发服务器 npm run dev ``` 前端启动后访问:http://localhost:3000 > Vite开发服务器已配置代理,自动将 `/api` 请求转发到后端 `http://localhost:8000` ## Docker部署 ```bash # 1. 配置环境变量 cp .env.example backend/.env # 编辑 backend/.env,填入你的 OPENAI_API_KEY # 2. 构建并启动 docker-compose up --build # 3. 后台运行 docker-compose up -d ``` 服务启动后: - 前端:http://localhost (端口80) - 后端API:http://localhost/api(通过Nginx代理) - 健康检查:http://localhost/api/health > 前端Nginx已内置SSE代理配置(`proxy_buffering off`),无需额外配置。 ## API文档 启动后端后,访问 Swagger UI 查看完整API文档: - Swagger UI:http://localhost:8000/docs - ReDoc:http://localhost:8000/redoc ### 主要API端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/health | 健康检查 | | POST | /api/auth/register | 用户注册 | | POST | /api/auth/login | 用户登录 | | POST | /api/chat | 非流式对话 | | POST | /api/chat/stream | SSE流式对话 | | POST | /api/question/generate | 非流式出题 | | POST | /api/question/generate/stream | SSE流式出题 | | POST | /api/homework/grade | 批改作业 | | POST | /api/homework/grade/stream | SSE流式批改作业 | | POST | /api/homework/exam | 批改试卷 | | POST | /api/homework/exam/stream | SSE流式批改试卷 | | POST | /api/homework/review | 人工审核(interrupt续跑) | | POST | /api/course/design | 非流式课程设计 | | POST | /api/course/design/stream | SSE流式课程设计 | ## 测试 ### pytest 单元测试 ```bash # 在项目根目录运行 cd project # 运行全部测试 pytest tests/ -v # 运行指定测试文件 pytest tests/test_intent.py -v pytest tests/test_api.py -v # 运行并生成覆盖率报告 pytest tests/ --cov=backend --cov-report=html ``` ### Locust 压力测试 ```bash # 确保后端已启动 # 启动Locust Web UI locust -f tests/locustfile.py --host=http://localhost:8000 # 访问 http://localhost:8089 配置并发用户数 # 或命令行直接运行 locust -f tests/locustfile.py --host=http://localhost:8000 \ --users 10 --spawn-rate 2 --run-time 60s --headless ``` ### 测试说明 | 测试文件 | 说明 | 用例数 | |----------|------|--------| | test_intent.py | 意图识别参数化测试 | 52条(6种意图) | | test_grading.py | 批改一致性测试(标准差<15, 极差<30) | 5条 | | test_rag.py | RAG召回率(Recall@3>0.6) + 忠实度评估 | 14条 | | test_api.py | API集成测试(含SSE格式验证) | 11条 | | locustfile.py | Locust压测(对话3:出题2:批改1) | 3任务 | ## 架构说明 ### 分层架构 ``` ┌─────────────────────────────────────────┐ │ Vue3 + Element Plus │ 前端 │ fetch + ReadableStream │ SSE接收 ├─────────────────────────────────────────┤ │ Nginx (反向代理) │ SSE: proxy_buffering off ├─────────────────────────────────────────┤ │ FastAPI 路由层 │ REST + SSE流式 │ auth / chat / question / homework / course │ ├─────────────────────────────────────────┤ │ LangGraph 多Agent图 │ 状态机编排 │ supervisor → question_gen / grader / ...│ ├─────────────────────────────────────────┤ │ RAG 检索层 │ ChromaDB + MMR │ 12条教学知识 + Embedding │ └─────────────────────────────────────────┘ ``` ### Agent注册表 新增Agent只需两步: 1. 在 `agents/` 目录创建Agent类(继承 `BaseAgent`) 2. 在 `agents/__init__.py` 的 `AGENT_REGISTRY` 中注册 ```python # agents/__init__.py AGENT_REGISTRY = { "supervisor": SupervisorAgent(), "question_gen": QuestionGenAgent(), "answer_gen": AnswerGenAgent(), "course_design": CourseDesignAgent(), "grader": GraderAgent(), "review": ReviewAgent(), } ``` ### SSE流式通信 后端使用 FastAPI 的 `StreamingResponse` 实现SSE,前端通过 `fetch + ReadableStream` 接收事件流: **后端(SSE事件生成器):** ```python async def event_generator(): async for event in graph.astream_events(...): if event["event"] == "on_chat_model_stream": yield f"data: {json.dumps({'type': 'token', 'content': chunk.content})}\n\n" yield f"data: {json.dumps({'type': 'done', 'thread_id': thread_id})}\n\n" return StreamingResponse(event_generator(), media_type="text/event-stream") ``` **前端(SSE事件接收):** ```javascript const response = await fetch('/api/chat/stream', { method: 'POST', body, headers }) const reader = response.body.getReader() const decoder = new TextDecoder() while (true) { const { done, value } = await reader.read() if (done) break const text = decoder.decode(value) // 解析 "data: {...}\n\n" 格式 } ``` **SSE数据格式:** - Token事件:`data: {"type": "token", "content": "..."}\n\n` - 完成事件:`data: {"type": "done", "thread_id": "..."}\n\n` - 错误事件:`data: {"type": "error", "message": "..."}\n\n`