dagent_eval/docs/LLM自动生成问题方案.md

19 KiB
Raw Permalink Blame History

LLM 自动生成问题 + 测试 + 审核方案

版本: v1.0
日期: 2026-04-21
目标: 基于知识库 MD 文件,自动生成测试问题,经过查重和质量审核后,直接送入单跳召回测试


一、整体流程

┌──────────────┐
│ 上传 MD 文件  │
└──────┬───────┘
       ↓
┌──────────────────────────┐
│ LLM 按章节生成 Q&A        │
│ - 每个 section 生成 N 个   │
│ - 同时生成参考答案         │
│ - 记录答案来源原文片段     │
└──────┬───────────────────┘
       ↓
┌─────────────────────────────────┐
│         审核流程                 │
│  ┌─────────────────────────┐   │
│  │ 1. 批次内查重            │   │
│  │    - 精确查重hash     │   │
│  │    - 语义查重embedding│   │
│  └─────────────────────────┘   │
│  ┌─────────────────────────┐   │
│  │ 2. 跨历史问题库查重       │   │
│  │    - 与已审核问题对比     │   │
│  └─────────────────────────┘   │
│  ┌─────────────────────────┐   │
│  │ 3. 问题质量自动评分       │   │
│  │    - 可回答性            │   │
│  │    - 问题清晰度          │   │
│  │    - 答案准确性          │   │
│  │    - 独特性              │   │
│  └─────────────────────────┘   │
│  ┌─────────────────────────┐   │
│  │ 4. 人工确认/编辑/删除     │   │
│  │    - 自动通过高质量问题   │   │
│  │    - 标记低质量/重复问题  │   │
│  └─────────────────────────┘   │
└─────────┬───────────────────────┘
          ↓
┌──────────────────────────┐
│ 导出为标准 MD 格式        │
│ (与现有单跳测试格式一致)  │
└──────┬───────────────────┘
       ↓
┌──────────────────────────┐
│ 直接送入单跳召回测试      │
└──────────────────────────┘

二、模块设计

2.1 生成模块(/api/qa-gen

API 设计

POST   /api/qa-gen/task                    # 创建生成任务
GET    /api/qa-gen/task/list               # 任务列表
GET    /api/qa-gen/task/{id}               # 任务详情(含进度)
DELETE /api/qa-gen/task/{id}               # 删除任务
GET    /api/qa-gen/task/{id}/questions     # 获取生成的问题列表
POST   /api/qa-gen/question/{id}/approve   # 通过问题
POST   /api/qa-gen/question/{id}/reject    # 拒绝问题
PUT    /api/qa-gen/question/{id}           # 编辑问题
POST   /api/qa-gen/task/{id}/export-md     # 导出已通过问题为 MD

生成策略

输入:

  • MD 文件(与单跳测试相同格式)
  • 配置参数:
    • model: LLM 模型(默认 gpt-4o-mini
    • questions_per_section: 每章节生成问题数(默认 5
    • quality_threshold: 质量阈值(默认 0.6
    • judge_config_id: 评分模型配置

处理流程:

  1. ## section 切分文档
  2. 对每个 section
    • 提取章节标题和内容
    • 调用 LLM 生成 N 个问题
    • 每个问题包含:
      • 问题文本
      • 参考答案
      • 答案来源原文片段(用于质量审核)
  3. 后台异步执行,支持进度回调

Prompt 模板:

你是一个专业的技术文档测试问题生成专家。

任务:根据以下技术文档章节内容,生成 {N} 个测试问题。

章节标题:{section_path}
章节内容:
{content}

要求:
1. 问题必须能从该章节内容直接回答(不要生成需要跨文档才能回答的问题)
2. 问题应覆盖章节的关键知识点
3. 问题表述清晰,无歧义
4. 答案准确,与原文一致
5. 标注答案来源的原文片段(用于后续审核)

输出格式JSON
[
  {
    "question": "问题文本",
    "answer": "参考答案",
    "source_chunk": "答案来源的原文片段50-200字"
  },
  ...
]

2.2 查重模块

两层查重机制

层级 方法 阈值 说明
精确查重 问题文本 hash 完全相同 快速过滤完全重复
语义查重 embedding 余弦相似度 > 0.92 识别语义相似问题

查重范围

  1. 批次内查重:当前生成任务内的问题互相查重
  2. 跨历史查重:与 qa_approved_question 表中已审核通过的问题查重

实现细节

Embedding 计算:

  • 使用 text-embedding-3-small 或配置的 embedding 模型
  • 问题生成后立即计算 embedding 并存储
  • embedding 存储为 JSON 字符串1536 维向量)

查重流程:

# 1. 精确查重
question_hash = hashlib.md5(question.strip().lower().encode()).hexdigest()
if question_hash in existing_hashes:
    mark_as_duplicate()

# 2. 语义查重
question_embedding = get_embedding(question)
similarities = cosine_similarity(question_embedding, all_embeddings)
if max(similarities) > 0.92:
    mark_as_similar(most_similar_question_id)

2.3 质量审核模块

自动质量评分

每条生成的问题自动打分0-1综合以下维度

维度 权重 评分方法
可回答性 30% LLM 判断:答案是否能从 source_chunk 推导出
问题清晰度 25% LLM 判断:问题是否有歧义、表述是否清晰
答案准确性 30% LLM 判断:参考答案是否与 source_chunk 一致
独特性 15% 计算与最相似问题的语义距离1 - max_similarity

质量评分 Prompt

评估以下测试问题的质量,从 0-1 打分。

问题:{question}
参考答案:{answer}
答案来源原文:{source_chunk}

评估维度:
1. 可回答性0-1答案是否能从原文推导出
2. 问题清晰度0-1问题是否清晰无歧义
3. 答案准确性0-1参考答案是否与原文一致

输出格式JSON
{
  "answerable": 0.9,
  "clarity": 0.85,
  "accuracy": 0.95,
  "reasoning": "简短说明"
}

审核状态流转

pending待审核
    ↓
    ├─→ approved通过→ 进入 qa_approved_question 表
    ├─→ rejected拒绝→ 不进入测试
    └─→ edited编辑后→ 重新计算 embedding 和质量分

自动通过规则:

  • quality_score >= threshold(默认 0.6
  • dup_of IS NULL(非重复)
  • 自动标记为 approved

需人工审核:

  • quality_score < threshold
  • dup_of IS NOT NULL(疑似重复)

2.4 数据库设计

新增表

-- 生成任务表
CREATE TABLE qa_gen_task (
    id              TEXT PRIMARY KEY,
    name            TEXT,
    status          TEXT NOT NULL DEFAULT 'pending',  -- pending/running/done/failed
    model           TEXT NOT NULL,                    -- 使用的 LLM 模型
    judge_config_id TEXT,                             -- 评分模型配置
    questions_per_section INTEGER DEFAULT 5,
    quality_threshold     REAL DEFAULT 0.6,
    progress        INTEGER DEFAULT 0,
    total           INTEGER DEFAULT 0,
    error_message   TEXT,
    created_at      TEXT NOT NULL,
    finished_at     TEXT
);

-- 生成的问题表(待审核池)
CREATE TABLE qa_gen_question (
    id                TEXT PRIMARY KEY,
    task_id           TEXT NOT NULL,
    section_path      TEXT NOT NULL,
    question          TEXT NOT NULL,
    reference_answer  TEXT NOT NULL,
    source_chunk      TEXT,                -- 答案来源原文片段
    quality_score     REAL,                -- 自动质量评分0-1
    quality_detail    TEXT,                -- JSON: {answerable, clarity, accuracy, reasoning}
    dup_of            TEXT,                -- 重复问题的 id如果是重复的
    dup_similarity    REAL,                -- 与重复问题的相似度
    status            TEXT NOT NULL DEFAULT 'pending',  -- pending/approved/rejected/edited
    embedding         TEXT,                -- JSON 向量,用于查重
    created_at        TEXT NOT NULL,
    updated_at        TEXT
);

-- 已审核通过的问题库(用于查重基准 + 导出测试)
CREATE TABLE qa_approved_question (
    id                TEXT PRIMARY KEY,
    gen_question_id   TEXT NOT NULL,      -- 关联 qa_gen_question.id
    section_path      TEXT NOT NULL,
    question          TEXT NOT NULL,
    reference_answer  TEXT NOT NULL,
    embedding         TEXT NOT NULL,       -- 用于后续查重
    source_task_id    TEXT NOT NULL,
    quality_score     REAL,
    approved_at       TEXT NOT NULL,
    approved_by       TEXT DEFAULT 'auto' -- auto/manual
);

-- 索引
CREATE INDEX idx_qa_gen_question_task_id ON qa_gen_question(task_id);
CREATE INDEX idx_qa_gen_question_status ON qa_gen_question(status);
CREATE INDEX idx_qa_approved_question_section ON qa_approved_question(section_path);

三、前端设计

3.1 页面结构

新增"问题生成"一级菜单,包含两个子页面:

问题生成
  ├─ 生成任务
  └─ 问题审核

3.2 生成任务页

布局: 类似单跳测试的任务列表页

功能:

  • 上传 MD 文件
  • 配置生成参数:
    • 模型选择(下拉)
    • 每章节问题数(数字输入,默认 5
    • 质量阈值滑块0-1默认 0.6
    • 评分模型配置(下拉,复用 judge_config
  • 任务列表:
    • 任务名称、状态、进度、创建时间
    • 操作:查看问题、删除任务

任务状态展示:

┌────────────────────────────────────────────────────┐
│ 任务名称evb_linux_development                     │
│ 状态:运行中  进度45/107 章节                      │
│ 已生成225 个问题  自动通过180  待审核45        │
│ [查看问题] [停止任务]                               │
└────────────────────────────────────────────────────┘

3.3 问题审核页(核心交互)

布局: 左右分栏

┌─────────────────────────────────────────────────────────────┐
│  筛选:[全部] [待审核] [重复] [低质量] [已通过] [已拒绝]      │
│  任务:[下拉选择任务]                                         │
├──────────┬──────────────────────────────────────────────────┤
│          │  批量操作:[全部通过] [通过高质量(>0.6)] [导出MD]  │
│          ├──────────────────────────────────────────────────┤
│  章节列表 │  问题列表                                         │
│          │  ┌────────────────────────────────────────────┐  │
│  □ 全选   │  │ ✅ Q1: 如何配置 DDR 参数?  质量分: 0.85   │  │
│  □ ch1   │  │    A: 通过修改 xxx 配置文件...              │  │
│  (12/15) │  │    来源: linux_development/ddr/config       │  │
│          │  │    [通过] [拒绝] [编辑]                     │  │
│  □ ch2   │  └────────────────────────────────────────────┘  │
│  (8/10)  │  ┌────────────────────────────────────────────┐  │
│          │  │ ⚠️ Q2: DDR 配置文件在哪?  质量分: 0.45     │  │
│  □ ch3   │  │    A: 在 /etc/ddr.conf                     │  │
│  (5/8)   │  │    ⚠️ 与"Q1"相似度 0.94(疑似重复)         │  │
│          │  │    [通过] [拒绝] [编辑] [查看原问题]        │  │
│          │  └────────────────────────────────────────────┘  │
│          │  ┌────────────────────────────────────────────┐  │
│          │  │ ❌ Q3: xxx  质量分: 0.32                  │  │
│          │  │    A: xxx                                  │  │
│          │  │    ⚠️ 低质量:问题不清晰                    │  │
│          │  │    [通过] [拒绝] [编辑]                     │  │
│          │  └────────────────────────────────────────────┘  │
└──────────┴──────────────────────────────────────────────────┘

交互细节:

  1. 问题卡片状态标识:

    • 绿色已通过quality_score >= threshold 且非重复)
    • ⚠️ 黄色:待审核(低质量或疑似重复)
    • 红色:已拒绝
  2. 批量操作:

    • "全部通过":将当前筛选结果中所有 pending 问题标记为 approved
    • "通过高质量":仅通过 quality_score >= threshold 且非重复的问题
    • "导出 MD":导出已通过问题为标准 MD 格式
  3. 编辑问题:

    • 弹出对话框,可修改问题、答案
    • 保存后重新计算 embedding 和质量分
    • 状态变为 edited
  4. 查看原问题:

    • 点击"查看原问题"跳转到重复问题的卡片
    • 高亮显示相似部分

3.4 导出 MD 格式

导出的 MD 文件格式与单跳测试输入格式完全一致:

## section_path / doc_name

## Q1: 问题文本
**A1:** 参考答案

## Q2: 问题文本
**A2:** 参考答案

---

## section_path2 / doc_name2

## Q1: 问题文本
**A1:** 参考答案

导出后可直接上传到"单跳召回测试"模块进行测试。


四、实现优先级

P0核心功能1-2 周)

模块 功能 工作量
后端 生成任务 API上传 MD → LLM 生成 Q&A → 存库) 1-2 天
后端 问题列表 API + 通过/拒绝/编辑 API 0.5 天
后端 导出 MD API 0.5 天
前端 生成任务页(上传 + 配置 + 任务列表) 1 天
前端 问题审核页(列表 + 基础交互) 1-2 天
数据库 新增 3 张表 + schema 迁移 0.5 天

P1查重 + 质量评分1 周)

模块 功能 工作量
后端 批次内查重hash + embedding 1 天
后端 质量自动评分LLM 评分) 1 天
前端 问题卡片状态标识(质量分、重复标记) 0.5 天
前端 批量操作(全部通过、通过高质量) 0.5 天

P2跨历史查重 + 优化3-5 天)

模块 功能 工作量
后端 跨历史问题库查重 0.5 天
前端 查看原问题跳转 0.5 天
前端 编辑问题对话框 0.5 天
优化 embedding 批量计算优化 0.5 天
优化 生成任务并发控制 0.5 天

五、技术选型

LLM 模型

用途 推荐模型 备选
问题生成 gpt-4o-mini gpt-4o, claude-3.5-sonnet
质量评分 gpt-4o-mini gpt-4o
Embedding text-embedding-3-small text-embedding-3-large

依赖库

  • 后端: 复用现有 judge_config 表的 OpenAI 配置
  • Embedding 使用 OpenAI SDK 或 sentence-transformers(如果需要本地部署)
  • 相似度计算: numpy.dot + numpy.linalg.norm(余弦相似度)

六、风险与注意事项

6.1 成本控制

  • 问题生成: 每个 section 约 500-2000 tokens 输入,生成 5 个问题约 500 tokens 输出
    • 估算12,000 条问题2,400 sections × 5≈ 3M tokens input + 1M tokens output
    • 成本gpt-4o-mini约 $0.6
  • 质量评分: 每个问题约 300 tokens 输入 + 100 tokens 输出
    • 估算12,000 条问题 ≈ 3.6M tokens input + 1.2M tokens output
    • 成本gpt-4o-mini约 $0.7
  • Embedding 每个问题约 20 tokens
    • 估算12,000 条问题 ≈ 240K tokens
    • 成本text-embedding-3-small约 $0.005

总成本: 约 $1.3 / 12,000 条问题

6.2 性能优化

  • 并发控制: 生成任务使用 asyncio.Semaphore 限制并发数(默认 5
  • 批量 embedding 每次最多 100 个问题批量计算 embedding
  • 查重优化: 使用 numpy 向量化计算,避免循环

6.3 数据一致性

  • 事务保护: 问题通过/拒绝操作使用数据库事务
  • 幂等性: 重复提交生成任务时检查是否已存在相同任务

七、后续扩展

7.1 高级功能

  • 问题难度分级: 自动标注问题难度(简单/中等/困难)
  • 知识点标签: 自动提取问题涉及的知识点标签
  • 多轮对话问题: 生成需要多轮交互的复杂问题
  • 负样本生成: 生成故意错误的答案,用于测试模型鲁棒性

7.2 集成优化

  • 与单跳测试联动: 审核通过后自动创建单跳测试任务
  • 测试结果反馈: 单跳测试失败的问题自动标记为"需优化"
  • 持续迭代: 根据测试结果自动调整生成策略

八、总结

本方案提供了一个完整的"生成 → 查重 → 审核 → 测试"闭环,核心优势:

  1. 自动化程度高: 90% 的高质量问题可自动通过,人工仅需审核 10%
  2. 质量可控: 多维度质量评分 + 查重机制保证问题质量
  3. 无缝集成: 导出格式与现有单跳测试完全兼容
  4. 可扩展性强: 模块化设计,易于后续扩展

预期效果: 将问题生成效率提升 10 倍,从人工编写 1 小时 10 条问题,提升到 LLM 生成 1 小时 1000+ 条问题(含审核)。