Files
agent_management/.omc/plans/agent-migration-plan.md
T

18 KiB
Raw Blame History

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/questionagent
    • TeachingVisualAgent:教学可视化 agent
    • AnswerEnhancer:答案增强器(核心功能)
    • 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.py
  • agentapi/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 端到端测试

手动测试流程:

  1. 启动 AgentAPI 服务
  2. 使用 Postman/curl 调用答案增强 API
  3. 验证返回的增强答案质量
  4. 检查数据库中的答案记录

五、迁移优先级和时间估算

步骤 优先级 预估时间 依赖
步骤 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 技术风险

  1. OpenAI API 调用失败

    • 风险:API 密钥无效、配额不足、网络问题
    • 缓解:实现降级策略(本地 fallback)、错误重试、详细日志
  2. MinerU 教材查询依赖

    • 风险:qmd 命令不可用、教材集合未配置
    • 缓解:使 MinerU 功能可选,提供 mock 数据用于测试
  3. 性能问题

    • 风险:LLM 调用耗时长(5-30秒)
    • 缓解:实现异步处理、添加超时控制、考虑缓存策略

6.2 数据一致性

  1. 答案版本管理

    • 问题:同一题目可能有多个 AI 生成的答案版本
    • 方案:利用 QuestionAnswer.version_no 和 is_latest 字段
  2. 元数据存储

    • 问题:增强结果包含复杂的嵌套结构
    • 方案:使用 JSON 字段存储 metadata,或考虑单独的表

6.3 兼容性

  1. questionagent 子模块更新

    • 问题:外部子模块更新可能破坏兼容性
    • 方案:锁定子模块版本、编写适配层、充分测试
  2. 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 包含使用说明和配置指南

九、开放问题

以下问题需要在实施过程中明确:

  1. 教材集合配置

    • 是否已有 MinerU 教材集合?
    • 教材数据存储在哪里?
    • 如何配置 qmd 命令?
  2. OpenAI API 配置

    • 使用哪个 OpenAI 模型?(gpt-4.1-mini, gpt-4o, etc.)
    • API 密钥如何管理?(环境变量、密钥管理服务)
    • 是否需要支持其他 LLM 提供商(Claude, 本地模型)?
  3. 答案展示

    • 前端如何展示增强答案?
    • 是否需要支持 Markdown 渲染?
    • 可视化建议如何展示?
  4. 性能优化

    • 是否需要缓存增强结果?
    • 是否需要异步处理?
    • 是否需要限流?
  5. 用户权限

    • 哪些用户可以调用答案增强功能?
    • 是否需要计费或配额限制?

十、参考资料