内容
<p align="center">
<img src="https://img.shields.io/badge/Python-3.10+-blue?logo=python&logoColor=white" alt="Python">
<img src="https://img.shields.io/badge/FastAPI-0.130+-009688?logo=fastapi&logoColor=white" alt="FastAPI">
<img src="https://img.shields.io/badge/LangGraph-1.0-purple?logo=langchain&logoColor=white" alt="LangGraph">
<img src="https://img.shields.io/badge/License-MIT-green" alt="License">
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen" alt="PRs Welcome">
</p>
<h1 align="center">Forewish Backend</h1>
<p align="center">
<strong>基于LangGraph + FastAPI的多Agent智能考试系统</strong>
<br />
<em>意图识别 · 多 Agent 协作 · RAG 知识库 · MCP 协议 · 流式输出</em>
</p>
<p align="center">
<a href="#-快速开始">快速开始</a> ·
<a href="#-核心特性">核心特性</a> ·
<a href="#-架构概览">架构</a> ·
<a href="#-api-参考">API 参考</a> ·
<a href="#-环境变量">配置</a>
</p>
---
## 🎯 核心特性
<table>
<tr>
<td width="50%">
<h3>🤖 MainAgent 架构</h3>
意图识别 + 工具调用循环,渐进式技能发现,按需执行。一次对话即可完成从意图理解到试卷生成的全流程。
</td>
<td width="50%">
<h3>🧩 多 Agent 协作</h3>
Analyzer、多题型生成(单选/填空/解答)、配图、汇总等 Agent 通过 LangGraph 状态图编排,各司其职。
</td>
</tr>
<tr>
<td>
<h3>📚 RAG 知识库</h3>
支持 PDF / DOCX / TXT / Web 多源文档导入,4 种切片策略,ChromaDB 语义检索,跨知识库搜索。
</td>
<td>
<h3>🔌 MCP 协议</h3>
内置 MCP Server(搜索工具)和 Client,支持 local / remote / WebSocket / HTTP 多种连接方式。
</td>
</tr>
<tr>
<td>
<h3>⚡ 流式响应</h3>
SSE(Server-Sent Events)实时推送生成进度,前端即时渲染,提升用户体验。
</td>
<td>
<h3>🛠️ 可扩展技能系统</h3>
自动扫描 <code>app/skills/</code> 目录,热插拔注册。已有:试卷生成、PDF 处理。
</td>
</tr>
</table>
## 🏗️ 技术栈
| 类别 | 技术 | 说明 |
|:-----|:-----|:-----|
| **Web** | FastAPI + Uvicorn | 异步高性能 ASGI 框架 |
| **LLM 编排** | LangGraph 1.0 + LangChain | 多 Agent 状态图编排 |
| **LLM 服务** | LangChain-OpenAI | 兼容任意 OpenAI API 格式的模型 |
| **关系数据库** | SQLAlchemy 2.0 (async) + MySQL | 异步 ORM,aiomysql 驱动 |
| **向量数据库** | ChromaDB | 文档嵌入向量持久化存储与检索 |
| **缓存** | Redis | Session 缓存与热数据管理 |
| **MCP** | mcp\[cli\] (FastMCP) | Model Context Protocol 工具协议 |
| **文档解析** | pdfplumber · python-docx · BeautifulSoup4 | 多格式文档解析 |
| **日志** | Loguru | 结构化日志 |
| **追踪** | LangSmith | LLM 调用链追踪与调试 |
## 🏛️ 架构概览
```
┌──────────────────────────────────────────────┐
│ FastAPI Application │
│ │
│ /chat /generate-exam /knowledge-bases ... │
└───────────────────┬──────────────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌────────────────────┐ ┌───────────────────┐
│ MainAgent │ │ Exam CRUD API │ │ RAG Pipeline │
│ (意图 + 调度) │ │ (试卷管理) │ │ (知识库) │
└────────┬────────┘ └────────────────────┘ └────────┬──────────┘
│ │
┌─────────────┼─────────────┐ ┌────────────┼────────────┐
▼ ▼ ▼ ▼ ▼ ▼
┌────────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐
│ Summary │ │ Analyzer │ │ Skill │ │ Parser │ │ Chunker │ │ Embedding │
│ Agent │ │ Agent │ │ System │ │ PDF/DOCX │ │ 4 种策略 │ │ Service │
└────────────┘ └──────────┘ └─────┬──────┘ │ Web/Text │ └──────────┘ └─────┬─────┘
│ └──────────┘ │
┌────────────┼────────────┐ ▼
▼ ▼ ▼ ┌───────────────┐
┌────────────┐┌──────────┐┌──────────┐ │ ChromaDB │
│ MCQ Agent ││Fill Blank││ Essay │ │ Vector Store │
└────────────┘│ Agent ││ Agent │ └───────────────┘
└──────────┘└──────────┘
│
┌────────┼────────┐
▼ ▼ ▼
┌──────────┐┌──────┐┌────────┐
│Illustrate││Aggre-││ MCP │
│ Agent ││gator ││ Client │
└──────────┘└──────┘└────────┘
```
### 试卷生成流程
```
用户输入 ──▶ MainAgent(意图识别)──▶ 技能调度
│
┌───────────────────────────┘
▼
SummaryAgent ──▶ AnalyzerAgent ──▶ 需求提取
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
MultipleChoice FillBlank Essay
Agent Agent Agent
│ │ │
└──────────────────┼──────────────────┘
▼
IllustrationAgent(可选)
▼
AggregatorAgent ──▶ 保存 & 返回试卷
```
### RAG 知识库流程
```
文档上传 / 网页导入
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Parser │────▶│ Chunker │────▶│ Embedding │────▶│ ChromaDB │
│ 文档解析 │ │ 文本切片 │ │ 向量化 │ │ 向量存储 │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
PDF/DOCX/Web/TXT Auto/Custom/ OpenAI API 持久化存储
FAQ/ParentChild 兼容接口
▲ 查询 │
│ ▼
用户检索请求 ◀──── RetrievalService ◀──── 语义相似度 Top-K ◀────────┘
```
**支持的切片策略:
| 策略 | 说明 |
|:-----|:-----|
| `auto` | RecursiveCharacterTextSplitter,智能递归切分 |
| `custom` | 可配置 `chunk_size` 与 `chunk_overlap` |
| `faq` | LLM 自动提取问答对,适用于 FAQ 场景 |
| `parent_child` | 子段用于检索,返回父段上下文,兼顾精度与完整性 |
## 📁 项目结构
```
forewish-backend/
├── app/
│ ├── main.py # FastAPI 入口,生命周期管理
│ ├── database.py # 数据库连接与初始化
│ ├── config/
│ │ └── settings.py # Pydantic Settings 配置
│ ├── agents/ # Agent 层
│ │ ├── base_agent.py # Agent 基类
│ │ ├── main_agent/ # MainAgent(意图识别 + 技能调度)
│ │ │ ├── agent.py # 核心逻辑:工具调用循环
│ │ │ └── tools/ # 内置工具定义
│ │ ├── sub_agent.py # 子任务 Agent
│ │ ├── summary_agent.py |历史对话汇总
│ │ ├── analyzer_agent.py |出题需求分析
│ │ ├── multiple_choice_agent.py |单选题生成
│ │ ├── fill_blank_agent.py |填空题生成
│ │ ├── essay_agent.py |解答题生成
│ │ ├── illustration_agent.py |题目配图
│ │ └── aggregator_agent.py |结果汇总 & 保存
│ ├── api/ # API 路由
│ │ ├── routes.py # 对话 & 生成接口
│ │ ├── file_routes.py |试卷文件操作
│ │ └── exam_routes.py |试卷 CRUD
│ ├── models/ # 数据模型
│ │ ├── schemas.py # 请求/响应 Pydantic 模型
│ │ ├── state.py | LangGraph State 定义
│ │ ├── exam.py # Exam ORM 模型
│ │ └── exam_schemas.py # 试卷 API 模型
│ ├── services/ # 业务服务
│ │ ├── agent_service.py # MainAgent 单例 & 统一入口
│ │ └── exam_service.py # 试卷 CRUD 业务逻辑
│ ├── skills/ # 技能模块(热插拔)
│ │ ├── base_skill.py # 技能基类
│ │ ├── exam_generation/ # 试卷生成技能
│ │ └── pdf/ # PDF 处理技能
│ ├── rag/ # RAG 知识库模块
│ │ ├── models/ # ORM & Pydantic 模型
│ │ │ ├── knowledge_base.py # 知识库表
│ │ │ ├── document.py # 文档 & 分段表
│ │ │ └── schemas.py # 请求/响应模型
│ │ ├── services/ # 业务逻辑
│ │ │ ├── knowledge_base_service.py
│ │ │ ├── document_service.py # 文档处理流水线
│ │ │ ├── embedding_service.py # 向量化服务
│ │ │ ├── retrieval_service.py # 语义检索
│ │ │ ├── parser/ # 文档解析器
│ │ │ │ ├── pdf_parser.py # PDF(含图片/表格)
│ │ │ │ ├── docx_parser.py # Word 文档
│ │ │ │ ├── web_parser.py # 网页抓取
│ │ │ │ └── text_parser.py # TXT / Markdown
│ │ │ └── chunker/ # 切片策略
│ │ │ ├── auto_chunker.py
│ │ │ ├── custom_chunker.py
│ │ │ ├── faq_chunker.py
│ │ │ └── parent_child_chunker.py
│ ├── mcp/ # MCP 协议
│ │ ├── mcp_client.py # MCP Client(多连接方式)
│ │ └── search_server.py # MCP Server(搜索工具)
│ ├── tools/
│ │ └── web_search.py # SerpAPI Google 搜索
│ └── utils/
│ └── file_utils.py # 试卷文件管理
├── tests/
│ └── test_api.py
├── mcp.json # MCP Server 配置
├── requirements.txt
├── env.example
├── Makefile
├── start_service.sh # 启动脚本
└── ARCHITECTURE.md # 架构设计文档
```
## 🚀 快速开始
### 前置依赖
- Python 3.10+
- MySQL 8.0+
- Redis 6.0+
- 兼容 OpenAI API 的 LLM 服务
### 1. 克隆 & 安装
```bash
git clone https://github.com/your-org/forewish-backend.git
cd forewish-backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
make install # 或 pip install -r requirements.txt
```
### 2. 配置环境变量
```bash
cp env.example .env
```
编辑 `.env`,填写必要配置:
```bash
# LLM(必填)
OPENAI_API_KEY=sk-your-key
OPENAI_API_BASE=https://api.openai.com/v1
OPENAI_MODEL=gpt-4.1
# MySQL(必填)
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=forewish
# RAG Embedding(可选,留空则复用 OpenAI 配置)
EMBEDDING_MODEL=text-embedding-ada-002
```
### 3. 启动
```bash
make run
```
或直接运行:
```bash
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
### 4. 验证
| 地址 | 说明 |
|:-----|:-----|
| http://localhost:8000 | 根路径 |
| http://localhost:8000/docs | Swagger UI 交互式文档 |
| http://localhost:8000/redoc | ReDoc 文档 |
## 📡 API 参考
### 对话与生成
| 方法 | 路径 | 说明 |
|:-----|:-----|:-----|
| `GET` | `/api/v1/health` | 健康检查 |
| `POST` | `/api/v1/chat` | 智能对话(意图识别 + 自动路由) |
| `POST` | `/api/v1/chat/stream` | 流式对话(SSE) |
| `POST` | `/api/v1/generate-exam` | 结构化生成试卷 |
| `POST` | `/api/v1/generate-exam/stream` | 流式生成试卷(SSE) |
| `POST` | `/api/v1/analyze-conversation` | 对话意图分析(仅分析不执行) |
### 试卷管理
| 方法 | 路径 | 说明 |
|:-----|:-----|:-----|
| `POST` | `/api/v1/exams` | 创建试卷记录 |
| `GET` | `/api/v1/exams` | 分页查询试卷 |
| `GET` | `/api/v1/exams/stats` | 试卷统计信息 |
| `GET` | `/api/v1/exams/{exam_id}` | 获取试卷详情 |
| `PUT` | `/api/v1/exams/{exam_id}` | 更新试卷 |
| `DELETE` | `/api/v1/exams/{exam_id}` | 删除试卷(软删除) |
| `POST` | `/api/v1/exams/{exam_id}/publish` | 发布试卷 |
| `POST` | `/api/v1/exams/{exam_id}/archive` | 归档试卷 |
### 知识库(RAG)
| 方法 | 路径 | 说明 |
|:-----|:-----|:-----|
| `POST` | `/api/v1/knowledge-bases` | 创建知识库 |
| `GET` | `/api/v1/knowledge-bases` | 知识库列表(分页/搜索) |
| `GET` | `/api/v1/knowledge-bases/{kb_id}` | 知识库详情 |
| `PUT` | `/api/v1/knowledge-bases/{kb_id}` | 更新知识库配置 |
| `DELETE` | `/api/v1/knowledge-bases/{kb_id}` | 删除知识库 |
| `POST` | `/api/v1/knowledge-bases/{kb_id}/documents/upload` | 上传文档(PDF/DOCX/TXT) |
| `POST` | `/api/v1/knowledge-bases/{kb_id}/documents/web` | 从网页导入 |
| `GET` | `/api/v1/knowledge-bases/{kb_id}/documents` | 获取文档列表 |
| `GET` | `/api/v1/knowledge-bases/{kb_id}/documents/{doc_id}` | 获取文档详情 |
| `GET` | `/api/v1/knowledge-bases/{kb_id}/documents/{doc_id}/chunks` | 获取文档分段 |
| `DELETE` | `/api/v1/knowledge-bases/{kb_id}/documents/{doc_id}` | 删除文档 |
| `POST` | `/api/v1/knowledge-bases/{kb_id}/documents/{doc_id}/reprocess` | 重新处理文档 |
| `POST` | `/api/v1/knowledge-bases/{kb_id}/search` | 单知识库语义检索 |
| `POST` | `/api/v1/knowledge-bases/search` | 跨知识库联合检索 |
### 文件操作
| 方法 | 路径 | 说明 |
|:-----|:-----|:-----|
| `GET` | `/api/v1/exams/list` | 已保存试卷文件列表 |
| `GET` | `/api/v1/exams/download/{filename}` | 下载试卷文件 |
| `GET` | `/api/v1/exams/read/{filename}` | 读取试卷内容 |
| `DELETE` | `/api/v1/exams/delete/{filename}` | 删除试卷文件 |
### 请求示例
<details>
<summary><strong>智能对话</strong></summary>
```bash
curl -X POST http://localhost:8000/api/v1/chat \
-H "Content-Type: application/json" \
-d '{
"message": "帮我生成5道Python单选题,3道填空题",
"session_id": "optional-session-id",
"history": [],
"context": {}
}'
```
</details>
<details>
<summary><strong>结构化生成试卷</strong></summary>
```bash
curl -X POST http://localhost:8000/api/v1/generate-exam \
-H "Content-Type: application/json" \
-d '{
"topic": "Python基础",
"multiple_choice_count": 5,
"fill_blank_count": 3,
"essay_count": 2,
"difficulty": "中等",
"additional_requirements": "重点考查函数和类的使用"
}'
```
</details>
<details>
<summary><strong>创建知识库 & 上传文档</strong></summary>
```bash
# 创建知识库
curl -X POST http://localhost:8000/api/v1/knowledge-bases \
-H "Content-Type: application/json" \
-d '{
"name": "Python 教材",
"description": "Python 编程基础教材知识库",
"chunk_strategy": "auto"
}'
# 上传文档到知识库
curl -X POST http://localhost:8000/api/v1/knowledge-bases/{kb_id}/documents/upload \
-F "file=@textbook.pdf"
# 语义检索
curl -X POST http://localhost:8000/api/v1/knowledge-bases/{kb_id}/search \
-H "Content-Type: application/json" \
-d '{
"query": "Python 装饰器的用法",
"top_k": 5
}'
```
</details>
## ⚙️ 环境变量
<details>
<summary>完整配置清单(点击展开)</summary>
| 分组 | 变量 | 默认值 | 说明 |
|:-----|:-----|:-------|:-----|
| **LLM** | `OPENAI_API_KEY` | — | LLM API 密钥(必填) |
| | `OPENAI_API_BASE` | — | API 地址(必填) |
| | `OPENAI_MODEL` | `gpt-4.1` | 模型名称 |
| **应用** | `APP_NAME` | `EasyExam` | 应用名称 |
| | `APP_VERSION` | `0.1.0` | 版本号 |
| | `DEBUG` | `true` | 调试模式 |
| | `HOST` | `0.0.0.0` | 监听地址 |
| | `PORT` | `8000` | 端口号 |
| **MySQL** | `MYSQL_HOST` | `localhost` | 数据库地址 |
| | `MYSQL_PORT` | `3306` | 端口 |
| | `MYSQL_USER` | `root` | 用户名 |
| | `MYSQL_PASSWORD` | — | 密码(必填) |
| | `MYSQL_DATABASE` | `forewish` | 数据库名 |
| **Redis** | `REDIS_HOST` | `localhost` | Redis 地址 |
| | `REDIS_PORT` | `6379` | 端口 |
| | `REDIS_DB` | `0` | 数据库编号 |
| | `REDIS_PASSWORD` | — | 密码 |
| **配图** | `ENABLE_ILLUSTRATION` | `true` | 是否启用 AI 配图 |
| | `IMAGE_API_BASE` | — | 图像 API 地址 |
| | `IMAGE_API_KEY` | — | 图像 API 密钥 |
| | `IMAGE_MODEL` | — | 图像模型 |
| **搜索** | `SERPAPI_KEY` | — | SerpAPI 密钥 |
| **MCP** | `USE_MCP` | `true` | 是否使用 MCP 协议 |
| **RAG** | `EMBEDDING_API_BASE` | — | Embedding API 地址(留空复用 OpenAI) |
| | `EMBEDDING_API_KEY` | — | Embedding API 密钥 |
| | `EMBEDDING_MODEL` | `text-embedding-ada-002` | Embedding 模型 |
| **ChromaDB** | `CHROMA_PERSIST_DIR` | `./chroma_data` | 向量数据持久化目录 |
| **RAG 文件** | `RAG_UPLOAD_DIR` | `./uploaded_docs` | 文档上传目录 |
| | `RAG_DEFAULT_CHUNK_SIZE` | `500` | 默认切片大小 |
| | `RAG_DEFAULT_CHUNK_OVERLAP` | `50` | 默认切片重叠 |
| **后台任务** | `ENABLE_BACKGROUND_TASK` | `false` | 启用后台异步任务 |
| | `BACKGROUND_TASK_TIMEOUT` | `300` | 超时时间(秒) |
| **日志** | `LOG_LEVEL` | `INFO` | 日志级别 |
| | `LOG_FILE` | `logs/app.log` | 日志文件路径 |
</details>
## 🔧 MainAgent 工具集
MainAgent 通过工具调用循环完成复杂任务,内置以下工具:
| 工具 | 说明 |
|:-----|:-----|
| `read_skill_doc` | 读取技能文档,判断是否匹配当前需求 |
| `execute_skill` | 执行指定技能(如试卷生成) |
| `sub_agent` | 派发子任务到 SubAgent 并行处理 |
| `google_search` | 联网搜索增强内容质量 |
| `task_manage` | 任务规划与状态管理 |
| `background_task` | 后台异步任务管理 |
## 📦 技能系统
系统自动扫描 `app/skills/` 目录,注册包含 `SKILL.md` + `scripts/` 的模块为可用技能:
| 技能 | 说明 |
|:-----|:-----|
| `exam_generation` | 多 Agent 协作生成试卷(单选/填空/解答/配图) |
| `pdf` | PDF 提取、创建、合并、表单处理 |
> 新增技能只需在 `app/skills/` 下创建目录,包含 `SKILL.md`(技能描述)和 `scripts/`(执行脚本)即可被自动发现注册。
## 🔗 MCP 配置
项目内置 MCP Server 与 Client:
- **Server** (`app/mcp/search_server.py`):提供 `google_search`、`wikipedia_search`、`fetch_webpage` 三个搜索工具
- **Client** (`app/mcp/mcp_client.py`):支持 local / remote / WebSocket / HTTP / SSE 多种连接方式
```json
// mcp.json
{
"mcpServers": {
"easyexam-tools": {
"command": "python",
"args": ["app/mcp/search_server.py"],
"type": "local"
}
}
}
```
通过 `USE_MCP=true` 启用 MCP 模式(推荐),`false` 则使用 `bind_tools` 直连。
## 🧑💻 开发
```bash
make install # 安装依赖
make run # 启动开发服务器(热重载)
make test # 运行测试
make format # 格式化代码(Black + isort)
make lint # 代码检查(Flake8 + mypy)
make clean # 清理缓存文件
make venv # 创建虚拟环境
```
## 🗺️ Roadmap
- [x] MainAgent 意图识别 + 技能调度
- [x] 多 Agent 协作试卷生成
- [x] SSE 流式响应
- [x] MCP 协议集成
- [x] RAG 知识库(多源文档 / 多策略切片 / 语义检索)
- [x] 试卷 CRUD 与文件管理
- [ ] 基于 RAG 的增强出题(知识库 + Agent 联动)
- [ ] 用户认证与权限系统
- [ ] Agent 并行执行优化
- [ ] 难度自适应 & 题目去重
- [ ] 自动评分系统
## 📄 License
[MIT](LICENSE)
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器