18 KiB
AI Agent 功能迁移计划
项目背景
将 AIExamPlatform 中的 AI agent 问答功能迁移到 AgentAPI 微服务架构中。
源项目:/Users/mac/Projects/AIExamPlatform/AIExamPlatform/app
目标项目:/Users/mac/Projects/AIExamPlatform/AgentAPI
核心需求优先级
P0 - 最高优先级(本计划重点)
集成 questionagent 的答案增强功能:
- 传入题目信息(题干、选项、正确答案)
- 传入 AI 生成的答案和参考答案
- 调用
questionagent进行增强知识问答 - 返回增强后的答案(包含教材知识点、解题策略、可视化建议等)
P1 - 较低优先级(后续实现)
- 异步题目导入功能
- 导入过程中自动调用 AI agents 生成答案
一、迁移范围分析
1.1 核心功能模块
✅ 已存在于 AgentAPI
- questionagent 子模块:
/Users/mac/Projects/AIExamPlatform/AgentAPI/agentapi/external/questionagentTeachingVisualAgent:教学可视化 agentAnswerEnhancer:答案增强器(核心功能)MinerUDocumentExplorerSkill:教材知识点查询ProblemAnalyzer:题目分析器SolverRegistry:解题器注册表
🔄 需要适配的功能
从源项目迁移以下 agent 功能(作为参考,但核心使用 questionagent):
- ConversationAgent:对话式学习(多轮对话、记忆管理)
- QuestionChatAgent:题目对话(技能系统、意图识别)
- ExplanationAgent:题目解析生成
- SimilarityAgent:相似题目查找(基于标签的规则匹配)
1.2 依赖分析
当前 AgentAPI 依赖
fastapi>=0.135.3
sqlalchemy>=2.0.49
pydantic>=2.12.5
uvicorn[standard]>=0.44.0
需要新增的依赖
# LangChain 生态
langchain>=0.3.25
langchain-openai>=0.3.16
langchain-mcp-adapters>=0.1.7
# OpenAI / Anthropic
openai>=1.76.0
anthropic>=0.94.0 # 可选,如果需要 Claude
# MCP 协议
mcp>=1.18.0
# 其他工具
pillow>=11.2.0 # 图像处理
pyyaml>=6.0.2 # 配置文件
二、架构设计
2.1 目录结构
AgentAPI/agentapi/
├── external/
│ └── questionagent/ # 已存在的 git submodule
│ ├── src/agent/ # Agent 运行时
│ └── src/teaching_visual_mcp/ # MCP 工具
├── services/
│ ├── chat_service.py # 已存在
│ ├── agent_service.py # 新增:Agent 服务层
│ └── answer_enhancement_service.py # 新增:答案增强服务
├── repositories/
│ ├── chat_repository.py # 已存在
│ └── agent_session_repository.py # 新增:Agent 会话持久化
├── models/
│ ├── chat.py # 已存在
│ ├── question.py # 已存在
│ └── agent_session.py # 新增:Agent 会话模型
├── http/routers/
│ ├── chat.py # 已存在
│ └── agents.py # 新增:Agent API 路由
└── schemas/
└── agent_schemas.py # 新增:Agent 请求/响应模型
2.2 数据模型设计
AgentSession(新增)
class AgentSession(Base):
__tablename__ = "agent_sessions"
id: Mapped[int]
user_id: Mapped[str]
question_id: Mapped[int | None]
agent_type: Mapped[str] # "answer_enhancement", "conversation", "question_chat"
status: Mapped[str] # "active", "completed", "failed"
metadata: Mapped[dict] # JSON 字段存储 agent 特定数据
created_at: Mapped[datetime]
updated_at: Mapped[datetime]
AgentMessage(新增)
class AgentMessage(Base):
__tablename__ = "agent_messages"
id: Mapped[int]
session_id: Mapped[int]
role: Mapped[str] # "user", "assistant", "system"
content: Mapped[str]
metadata: Mapped[dict | None] # 存储技能使用、工具调用等信息
created_at: Mapped[datetime]
QuestionAnswer 扩展(已存在,需要利用)
# 已有字段:
# - answer_source: "official", "ai_generated", "ai_enhanced"
# - content_markdown: 答案内容
# - version_no: 版本号
三、详细实施步骤
步骤 1:环境准备与依赖安装
目标:安装必要的依赖,确保 questionagent 子模块可用
操作:
cd /Users/mac/Projects/AIExamPlatform/AgentAPI
# 添加 LangChain 和 AI 相关依赖
uv add "langchain>=0.3.25"
uv add "langchain-openai>=0.3.16"
uv add "langchain-mcp-adapters>=0.1.7"
uv add "openai>=1.76.0"
uv add "mcp>=1.18.0"
uv add "pillow>=11.2.0"
uv add "pyyaml>=6.0.2"
# 可选:如果需要 Claude
uv add "anthropic>=0.94.0"
# 同步环境
uv sync
验收标准:
- ✅
uv.lock更新成功 - ✅ 所有依赖安装无冲突
- ✅ 可以成功
from agent.runtime import TeachingVisualAgent
步骤 2:创建 Agent 服务层
目标:封装 questionagent 的答案增强功能为 AgentAPI 的服务层
文件:agentapi/services/answer_enhancement_service.py
核心功能:
class AnswerEnhancementService:
"""答案增强服务
封装 questionagent 的 AnswerEnhancer,提供:
1. 题目分析
2. 教材知识点查询
3. 答案策略生成
4. 可视化建议
"""
def __init__(self):
# 初始化 questionagent 组件
self.agent_settings = AgentSettings()
self.mineru_skill = MinerUDocumentExplorerSkill(...)
self.answer_enhancer = AnswerEnhancer(
mineru_skill=self.mineru_skill,
analyzer=ProblemAnalyzer(),
solver_registry=build_default_solver_registry(),
)
def enhance_answer(
self,
question_id: int,
question_text: str,
ai_answer: str | None,
reference_answer: str | None,
subject_hint: str | None = None,
topic_hint: str | None = None,
) -> AnswerEnhancementResult:
"""增强答案
Args:
question_id: 题目 ID
question_text: 题目文本(题干 + 选项)
ai_answer: AI 生成的答案
reference_answer: 参考答案
subject_hint: 科目提示
topic_hint: 主题提示
Returns:
增强后的答案结果
"""
request = AnswerEnhancementRequest(
question=question_text,
subject_hint=subject_hint,
topic_hint=topic_hint,
include_visual_plan=True,
)
result = self.answer_enhancer.enhance_answer(request)
return result
验收标准:
- ✅ 服务类可以成功初始化
- ✅
enhance_answer方法可以调用 questionagent - ✅ 返回结构化的增强结果
步骤 3:创建数据库模型和 Repository
目标:持久化 Agent 会话和消息
文件:
agentapi/models/agent_session.pyagentapi/repositories/agent_session_repository.py
核心功能:
# Repository
class AgentSessionRepository:
def create_session(
self,
user_id: str,
question_id: int | None,
agent_type: str,
) -> AgentSession:
"""创建 Agent 会话"""
def add_message(
self,
session_id: int,
role: str,
content: str,
metadata: dict | None = None,
) -> AgentMessage:
"""添加消息到会话"""
def get_session_history(
self,
session_id: int,
) -> list[AgentMessage]:
"""获取会话历史"""
验收标准:
- ✅ 数据库迁移脚本生成成功
- ✅ 可以创建和查询 Agent 会话
- ✅ 消息历史正确存储和检索
步骤 4:创建 API 路由
目标:暴露答案增强功能为 RESTful API
文件:agentapi/http/routers/agents.py
核心端点:
4.1 答案增强 API
@router.post("/answer-enhancement")
async def enhance_answer(
request: AnswerEnhancementRequest,
db: Session = Depends(get_db),
) -> AnswerEnhancementResponse:
"""增强答案
请求示例:
{
"question_id": 123,
"subject_hint": "信号与系统",
"topic_hint": "卷积",
"include_visual_plan": true
}
响应示例:
{
"question_id": 123,
"subject": "信号与系统",
"topic": "卷积运算",
"knowledge_points": [...],
"key_points": ["理解卷积定义", "掌握图解法"],
"answer_strategy": [
{"title": "步骤1", "detail": "..."},
{"title": "步骤2", "detail": "..."}
],
"answer_draft": "完整答案文本...",
"visual_plan": {...},
"study_advice": [...]
}
"""
4.2 Agent 会话 API(可选,用于多轮对话)
@router.post("/sessions")
async def create_agent_session(
request: CreateSessionRequest,
db: Session = Depends(get_db),
) -> SessionResponse:
"""创建 Agent 会话"""
@router.post("/sessions/{session_id}/messages")
async def send_message(
session_id: int,
request: SendMessageRequest,
db: Session = Depends(get_db),
) -> MessageResponse:
"""发送消息到 Agent 会话"""
验收标准:
- ✅ API 端点可以正常访问
- ✅ 请求验证正确(Pydantic)
- ✅ 返回结构化的增强结果
- ✅ 错误处理完善(404, 500 等)
步骤 5:集成到现有 Question 流程
目标:将答案增强功能集成到题目答案生成流程
文件:agentapi/services/question_service.py(扩展现有服务)
核心功能:
class QuestionService:
@staticmethod
def generate_enhanced_answer(
db: Session,
question_id: int,
user_id: str,
) -> QuestionAnswer:
"""为题目生成增强答案
流程:
1. 查询题目信息(题干、选项、正确答案)
2. 调用 AnswerEnhancementService
3. 将增强结果保存为 QuestionAnswer(answer_source="ai_enhanced")
4. 返回答案记录
"""
# 1. 查询题目
question_repo = QuestionRepository(db)
question = question_repo.get_question_with_details(question_id)
# 2. 构建题目文本
question_text = _build_question_text(question)
# 3. 调用答案增强服务
enhancement_service = AnswerEnhancementService()
result = enhancement_service.enhance_answer(
question_id=question_id,
question_text=question_text,
ai_answer=None, # 可选:如果已有 AI 答案
reference_answer=_get_official_answer(question),
subject_hint=_infer_subject(question),
topic_hint=None,
)
# 4. 保存增强答案
answer = question_repo.create_answer(
question_id=question_id,
answer_source="ai_enhanced",
content_markdown=result.answer_draft,
metadata={
"subject": result.subject,
"topic": result.topic,
"key_points": result.key_points,
"answer_strategy": [s.model_dump() for s in result.answer_strategy],
"visual_plan": result.visual_plan,
"study_advice": result.study_advice,
}
)
db.commit()
return answer
验收标准:
- ✅ 可以为题目生成增强答案
- ✅ 答案正确保存到数据库
- ✅ metadata 字段包含完整的增强信息
- ✅ 可以查询和展示增强答案
步骤 6:配置和环境变量
目标:配置 OpenAI API、MinerU 等外部服务
文件:agentapi/config.py(扩展现有配置)
新增配置:
class Settings(BaseSettings):
# ... 现有配置 ...
# OpenAI 配置
openai_api_key: str | None = None
openai_base_url: str | None = None
openai_agent_model: str = "gpt-4.1-mini"
# Agent 配置
agent_temperature: float = 0.0
agent_max_iterations: int = 8
# MinerU 配置
mineru_qmd_command: str = "qmd"
mineru_default_collection: str = "textbooks"
mineru_lookup_mode: Literal["search", "query"] = "query"
# 教学可视化配置
teaching_visual_artifact_root: Path = Path(".artifacts/teaching-visuals")
环境变量示例(.env):
# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_AGENT_MODEL=gpt-4.1-mini
# MinerU(可选,如果需要教材查询)
TVAGENT_MINERU_DEFAULT_COLLECTION=textbooks
TVAGENT_MINERU_LOOKUP_MODE=query
验收标准:
- ✅ 配置可以从环境变量加载
- ✅ OpenAI API 密钥正确配置
- ✅ Agent 可以成功调用 OpenAI
四、测试计划
4.1 单元测试
文件:tests/services/test_answer_enhancement_service.py
def test_enhance_answer_basic():
"""测试基本答案增强功能"""
service = AnswerEnhancementService()
result = service.enhance_answer(
question_id=1,
question_text="求信号 x(t) 和 h(t) 的卷积...",
ai_answer=None,
reference_answer="y(t) = ...",
subject_hint="信号与系统",
)
assert result.subject == "信号与系统"
assert len(result.key_points) > 0
assert len(result.answer_strategy) > 0
assert result.answer_draft is not None
4.2 集成测试
文件:tests/http/test_agents_router.py
def test_answer_enhancement_api(client: TestClient, db: Session):
"""测试答案增强 API"""
# 1. 创建测试题目
question = create_test_question(db)
# 2. 调用答案增强 API
response = client.post(
"/api/v1/agents/answer-enhancement",
json={
"question_id": question.id,
"subject_hint": "信号与系统",
"include_visual_plan": True,
}
)
assert response.status_code == 200
data = response.json()
assert data["question_id"] == question.id
assert "key_points" in data
assert "answer_strategy" in data
4.3 端到端测试
手动测试流程:
- 启动 AgentAPI 服务
- 使用 Postman/curl 调用答案增强 API
- 验证返回的增强答案质量
- 检查数据库中的答案记录
五、迁移优先级和时间估算
| 步骤 | 优先级 | 预估时间 | 依赖 |
|---|---|---|---|
| 步骤 1:依赖安装 | P0 | 0.5h | 无 |
| 步骤 2:服务层 | P0 | 2h | 步骤 1 |
| 步骤 3:数据模型 | P0 | 1.5h | 步骤 1 |
| 步骤 4:API 路由 | P0 | 2h | 步骤 2, 3 |
| 步骤 5:集成到 Question | P0 | 1.5h | 步骤 2, 3, 4 |
| 步骤 6:配置 | P0 | 0.5h | 步骤 1 |
| 测试 | P0 | 2h | 所有步骤 |
总计:约 10 小时(1-2 个工作日)
六、风险和注意事项
6.1 技术风险
-
OpenAI API 调用失败
- 风险:API 密钥无效、配额不足、网络问题
- 缓解:实现降级策略(本地 fallback)、错误重试、详细日志
-
MinerU 教材查询依赖
- 风险:
qmd命令不可用、教材集合未配置 - 缓解:使 MinerU 功能可选,提供 mock 数据用于测试
- 风险:
-
性能问题
- 风险:LLM 调用耗时长(5-30秒)
- 缓解:实现异步处理、添加超时控制、考虑缓存策略
6.2 数据一致性
-
答案版本管理
- 问题:同一题目可能有多个 AI 生成的答案版本
- 方案:利用
QuestionAnswer.version_no和is_latest字段
-
元数据存储
- 问题:增强结果包含复杂的嵌套结构
- 方案:使用 JSON 字段存储 metadata,或考虑单独的表
6.3 兼容性
-
questionagent 子模块更新
- 问题:外部子模块更新可能破坏兼容性
- 方案:锁定子模块版本、编写适配层、充分测试
-
Python 版本要求
- 问题:questionagent 要求 Python >=3.11,AgentAPI 要求 >=3.12
- 方案:已兼容,无问题
七、后续扩展(P1 优先级)
7.1 异步题目导入
功能:
- 批量导入题目时,自动调用 AI agents 生成答案
- 使用 Celery 或 FastAPI BackgroundTasks 实现异步处理
架构:
# 任务队列
@celery_app.task
def generate_answer_for_question(question_id: int):
"""异步生成题目答案"""
db = SessionLocal()
try:
QuestionService.generate_enhanced_answer(db, question_id, "system")
finally:
db.close()
# 导入流程
def import_questions_batch(questions: list[dict]):
"""批量导入题目"""
for q_data in questions:
# 1. 创建题目记录
question = create_question(q_data)
# 2. 异步生成答案
generate_answer_for_question.delay(question.id)
7.2 其他 Agent 功能
- ConversationAgent:对话式学习(多轮对话)
- SimilarityAgent:相似题目推荐
- QuestionChatAgent:题目对话(技能系统)
八、成功标准
核心功能验收
- ✅ 可以通过 API 调用答案增强功能
- ✅ 增强答案包含教材知识点、解题策略、可视化建议
- ✅ 答案正确保存到数据库
- ✅ 性能可接受(单次调用 < 30秒)
代码质量
- ✅ 代码符合 AgentAPI 架构规范(services/repositories/models/routers)
- ✅ 类型注解完整(Python 3.12+ typing)
- ✅ 错误处理完善
- ✅ 日志记录清晰
文档和测试
- ✅ API 文档完整(FastAPI 自动生成)
- ✅ 单元测试覆盖核心逻辑
- ✅ 集成测试验证端到端流程
- ✅ README 包含使用说明和配置指南
九、开放问题
以下问题需要在实施过程中明确:
-
教材集合配置
- 是否已有 MinerU 教材集合?
- 教材数据存储在哪里?
- 如何配置
qmd命令?
-
OpenAI API 配置
- 使用哪个 OpenAI 模型?(gpt-4.1-mini, gpt-4o, etc.)
- API 密钥如何管理?(环境变量、密钥管理服务)
- 是否需要支持其他 LLM 提供商(Claude, 本地模型)?
-
答案展示
- 前端如何展示增强答案?
- 是否需要支持 Markdown 渲染?
- 可视化建议如何展示?
-
性能优化
- 是否需要缓存增强结果?
- 是否需要异步处理?
- 是否需要限流?
-
用户权限
- 哪些用户可以调用答案增强功能?
- 是否需要计费或配额限制?
十、参考资料
- questionagent README:
/Users/mac/Projects/AIExamPlatform/AgentAPI/agentapi/external/questionagent/README.md - AgentAPI 架构:
/Users/mac/Projects/AIExamPlatform/AgentAPI/docs/README.md - LangChain 文档:https://python.langchain.com/
- MCP 协议:https://modelcontextprotocol.io/