note/app_prd/知识增强服务.md

7.7 KiB
Raw Blame History

产品需求文档:知识增强服务 (KES)

Knowledge Enrichment Service - Backend

文档版本 V1.0
依赖模块 UDC-M (模块一), QPES (模块二)
最后更新 2025-12-09
状态 待开发
涉及端 后端 API, 异步 Worker, 外部 API 交互

1. 项目背景与目标

1.1 背景

模块二QPES已经完成了“文档 -> 题目”的物理拆解,数据库中已经有了干净的题干、答案和图片。 但此时的题目是“孤立”的,无法支持“查找所有关于‘勾股定理’的题”或“生成一份‘三角函数’的试卷”等业务场景。我们需要为题目注入元数据Metadata

1.2 目标

构建一个异步的知识增强与人工审核服务

  • 自动打标:监控未处理的题目,调用外部 summary_api 自动提取知识点和方法。
  • 人工介入 (HITL):提供接口,允许教研人员对 AI 提取的标签进行审核、修改和确认。
  • 数据回填:将处理结果结构化地更新回主数据库。

2. 系统架构设计

系统设计为 “生产者-消费者” 模式,以解耦数据库读取与外部 API 调用(防止外部 API 阻塞系统)。

2.1 核心组件

  1. Enrichment Scheduler (调度器):
    • 定时任务 (Celery Beat) 或 事件触发。
    • 扫描 questions 表中 enrich_status = 'pending' 的记录。
    • 将任务推送到 Redis 队列。
  2. API Client Worker (执行器):
    • 消费队列。
    • 调用外部 summary_api
    • 关键特性: 实现流控 (Rate Limiting)、重试 (Retry) 和熔断机制。
  3. Review API (审核接口):
    • 提供给前端/教研后台,用于人工修改知识点。

2.2 外部接口定义 (Mock Summary API)

假设外部接口契约如下(开发时需对接真实接口):

  • Input: {"question_text": "...", "answer": "..."}
  • Output:
    {
      "summary": "一道关于利用勾股定理求解直角三角形斜边的应用题",
      "knowledges": ["勾股定理", "直角三角形性质"],
      "methods": ["数形结合", "方程思想"]
    }
    

3. 功能需求详细说明

3.1 自动打标流程

  1. 任务获取: 查询 questions 表,条件:enrich_status='pending'
  2. 构建 Payload: 拼接 ocr_text (含公式/图片链接) 和 answer_md
  3. 调用 API: 发送 HTTP POST 请求给 summary_api
  4. 结果处理:
    • 成功:
      • 将返回的 JSON 填入 knowledges, methods, problem_summary 字段。
      • 同时将这些值 Copy 一份给 updated_knowledges, updated_methods (作为人工审核的默认值)。
      • 更新状态 enrich_status = 'done'
    • 失败 (5xx/Timeout):
      • 触发重试(指数退避,最多 3 次)。
      • 若最终失败,更新状态 enrich_status = 'failed',并记录 error_msg

3.2 人工审核 (Human-in-the-Loop)

  • 审核逻辑: AI 的提取结果并不总是 100% 准确。系统信任链为:人工数据 > AI 数据
  • 数据流:
    1. 前端展示 updated_knowledges (初始值等于 AI 提取值)。
    2. 人工修改(增删改)。
    3. 调用 PUT /questions/{id}/review 接口保存。
    4. 系统更新 updated_atreviewer_id

3.3 知识库一致性 (Optional Advanced)

  • 需求: 虽然初期可以存自由文本的 Tag但为了检索准确建议引入“标准知识点树”。
  • 逻辑: 在保存 Tag 前,检查 Tag 是否在系统的 knowledge_tree 表中。如果不在,标记为“新词”,提示管理员审核。

4. 数据库设计 (PostgreSQL)

沿用模块二的 questions 表,本模块主要负责 UPDATE 操作。

4.1 Table: questions (字段补充)

字段名 类型 说明
... ... (模块二已有的基础字段)
problem_summary TEXT 题目一句话摘要 (AI生成)
knowledges JSONB AI提取: ["k1", "k2"]
methods JSONB AI提取: ["m1"]
updated_knowledges JSONB 人工审核版 (应用层展示以此为准)
updated_methods JSONB 人工审核版
enrich_status VARCHAR pending (待处理), processing, done, failed
enrich_error TEXT 调用外部API失败的错误日志
is_reviewed BOOLEAN 是否经过人工确认 (默认 False)
reviewer_id INT 审核人ID
reviewed_at TIMESTAMP 审核时间

5. API 接口定义 (RESTful)

Base URL: /api/v1/enrichments

5.1 触发/重试打标

  • POST /trigger
  • Description: 手动触发一次批量打标(通常由定时任务调用,也可以人工触发重试失败任务)。
  • Body: {"retry_failed": true}
  • Response: {"triggered_count": 50}

5.2 提交人工审核结果

  • PUT /questions/{question_id}/review
  • Description: 教研人员提交修正后的知识点。
  • Body:
    {
      "knowledges": ["修正后的知识点1", "修正后的知识点2"],
      "methods": ["方法1"],
      "confirm": true // 标记 is_reviewed = true
    }
    
  • Response: 200 OK

5.3 获取待审核题目列表

  • GET /questions/review-queue
  • Query:
    • status: done (已AI打标等待人工)
    • is_reviewed: false
  • Response: 题目列表 (含 AI 提取的 Tag)。

6. 技术选型 (Vibe Coding Stack)

6.1 核心技术

  • HTTP Client: httpx (异步) 或 aiohttp
    • 理由: 相比 requests,异步客户端在 Celery Worker 中能支持更高的并发Event Loop适合 I/O 密集型任务。
  • Resilience (弹性): tenacity
    • 理由: Python 最好的重试库。用装饰器 @retry 就能实现指数退避,代码极简。
  • Rate Limiting: Redis + Lua Script 或 Celery 自带的 rate limit。
    • 理由: 防止把外部 summary_api 打挂。

6.2 代码结构示例 (Service Layer)

# services/enrichment_service.py
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential

class SummaryAPIClient:
    def __init__(self, base_url: str, api_key: str):
        self.client = httpx.AsyncClient(base_url=base_url, headers={"Authorization": api_key})

    @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
    async def get_summary(self, text: str):
        response = await self.client.post("/summarize", json={"text": text})
        response.raise_for_status()
        return response.json()

7. 模块间联动总结

到此为止,三个模块已经形成了一个完美的闭环:

  1. UDC-M (文档与转换):

    • Input: 用户上传 PDF/Docx。
    • Output: 永久存储原始文件 + 标准 Markdown (含 MinIO 图片链)。
    • Data: documents 表。
  2. QPES (题目解析):

    • Input: 读取 documents 里的 Markdown。
    • Action: 调用 DeepSeek 切分题目。
    • Output: 结构化题目。
    • Data: questions 表 (基础字段)。
  3. KES (知识增强):

    • Input: 读取 questions (Pending 状态)。
    • Action: 调用 Summary API + 人工审核。
    • Output: 完整的、带标签的题库。
    • Data: questions 表 (Tag 字段)。

部署建议 这三个模块可以部署在同一个代码仓库 (Monorepo) 中,共享数据库 Model 定义,但通过Docker Compose 拆分为不同的服务容器运行以便根据负载独立扩容例如UDC 扩容 GPU 节点KES 扩容 IO 密集型节点)。