企业知识库系列(00):在写第一行代码之前,先把评测数据集做好

为什么要先建测试集

这个系列要做一件事:横向对比六个开源 RAG 方案(LightRAG、GraphRAG、HippoRAG、HyperGraphRAG、RAG-Anything、gbrain),给出选型建议。

但"横向对比"有一个前提:同一套问题,同一套评分标准。如果每篇文章都用自己的文档、自己出的题,结果没有可比性------你测 LightRAG 用的是 API 文档,测 GraphRAG 用的是论文,这不叫对比,叫各显神通。

所以在跑第一个方案之前,先把测试集建好。这篇文章记录这件事的完整过程。


为什么不直接用 BEIR

第一个直觉是去找现成的标准数据集。RAG 评测领域最常引用的是 BEIR------一个包含 18 个子集的检索基准,覆盖问答、事实核查、医疗文献等。

但 BEIR 有一个根本性问题:它是学术检索任务,和企业知识库的实际使用场景有明显的分布差距。

维度 BEIR 企业知识库
文档类型 学术论文、维基百科 API 文档、操作手册、技术规范
问题类型 事实核查、论文检索 "怎么配置"、"为什么报错"、"哪个方案更合适"
拒答能力 无(假设答案一定存在) 必须:文档没有的内容不能瞎编
语言 全英文 中英混合

用 BEIR 测企业 RAG,就像用高考题去测岗位面试能力------题型对不上,分数没有参考价值。

正确的做法:用与目标场景同分布的文档,合成专属测试集


文档来源的选择

测试集要能代表"企业技术文档"这个类别。选了两套开源项目的官方文档:

LightRAG 官方文档(13 个 Markdown):

  • API 服务配置、Docker 部署、多站点部署
  • 文件处理流程、分块策略、解析器开发
  • Milvus 配置、离线部署、角色 LLM 配置

graphrag 官方文档(17 个 Markdown):

  • 架构设计、默认数据流、输入输出格式
  • 索引配置、查询方式、提示词调优
  • CLI 使用、可视化工具

这两套文档的特点恰好是企业技术文档的典型形态:有操作步骤、有配置示例、有跨文档的依赖关系。而且 LightRAG 和 graphrag 本身就是后续要测的方案,用它们的文档做测试集,既自洽又有实战代表性。

共 30 个有效文档(过滤了内容少于 200 字符的占位文件)。


三类问题的设计逻辑

测试集需要覆盖三种典型的失败模式:

类型一:单跳事实查询(50%,50题)

答案直接在某一个文档里,不需要跨文档推理。

测的是:检索的基础召回能力------给定问题,能不能找到包含答案的文档片段?

真实样例:

vbnet 复制代码
Q: What are the two main categories of configuration settings
   in the LightRAG Docker Deployment?
A: Server Configuration and LLM Configuration
src: [DockerDeployment.md]

Q: What is the condition under which query/document asymmetric
   embedding is enabled in LightRAG?
A: query/document asymmetric embedding is enabled only when
   EMBEDDING_ASYMMETRIC=true is explicitly set
src: [AsymmetricEmbedding.md]

类型二:多跳推理(30%,20题)

答案需要组合来自多个文档的信息。典型场景:跨文档比较、系统集成理解、端到端流程追踪。

测的是:图 RAG 和混合检索相对于纯向量检索的增量价值------单文档找到了,但没有拼出完整答案。

真实样例:

vbnet 复制代码
Q: How does the configuration of Milvus index parameters through
   vector_db_storage_cls_kwargs facilitate a multi-site deployment
   of LightRAG?
A: The configuration allows dynamic configuration for different
   LightRAG instances in a multi-site setup...
src: [MilvusConfigurationGuide.md, MultiSiteDeployment.md]

Q: Compare the authentication flow in LightRAG API Server with
   the role-specific LLM configuration approach...
src: [LightRAG-API-Server.md, RoleSpecificLLMConfiguration.md]

类型三:边界拒答(20%,19题)

问题与文档主题相关,但答案在文档中不存在。这是企业知识库最容易出问题的地方------很多方案会"幻觉"出一个听起来合理但完全错误的答案。

测的是:方案的拒答能力。正确答案是"文档中没有此信息",而不是编造一个答案。

真实样例:

kotlin 复制代码
Q: What is the cost of a premium support plan for RAG system deployments?
A: The provided documents do not contain information about this topic.

Q: How does the RAG system handle data privacy for users
   in the EU under GDPR regulations?
A: The provided documents do not contain information about this topic.

Q: What are the security protocols implemented in the DockerDeployment?
A: The provided documents do not contain information about this topic.

用 LLM 合成题目

手工出 89 道题不现实,让 LLM 来做这件事。

核心策略:给 LLM 原始文档,让它按类型生成问题和参考答案,并在 Prompt 里约束输出格式。

单跳题 Prompt 结构:

css 复制代码
你是技术文档专家,正在为 RAG 系统构建评测集。

给定以下技术文档,生成 {n} 道单跳事实查询题。
要求:
- 问题必须能从本文档单独回答
- 覆盖关键概念、配置项、操作步骤
- 输出严格 JSON 格式

文档标题:{title}
文档内容:{content}

输出格式:
[{"question": "...", "ground_truth": "...", "question_type": "single_hop"}]

多跳题 Prompt 结构:

erlang 复制代码
给定多个技术文档,生成需要跨文档推理的问题。
要求:问题必须用到至少 2 个文档的信息才能完整回答。

文档 1:{title_1}\n{content_1}
文档 2:{title_2}\n{content_2}
...

边界题 Prompt 结构:

复制代码
给定以下文档覆盖的主题,生成该领域中文档 没有 覆盖的问题。
这类问题测试系统的拒答能力。
已覆盖主题:{covered_topics}

生成过程中遇到的问题

问题一:ragas TestsetGenerator 在 transforms 阶段超时

最初尝试用 ragas 官方的 TestsetGenerator,它会先对所有文档跑 HeadlinesExtractorSummaryExtractor 等 transforms,然后才生成问题。在国内网络环境下,这个过程调用 LLM API 时频繁超时,30 个文档跑了 22 分钟后卡死。

最终放弃 ragas TestsetGenerator,改用直接 LLM 调用。ragas 保留用于后续的评测阶段(计算 Faithfulness / Answer Relevancy 等指标),不用于生成阶段。

问题二:部分文档组合 JSON 解析失败

GLM-4-flash 在某些文档上返回的 JSON 格式不完整(多了解释文字或缺少括号),json.loads 失败,这些题被过滤掉。

受影响的文档:MultiSiteDeployment.mdParserDebugCLI.mdReproduce.mdgraphrag_get_started.mdgraphrag_manual_prompt_tuning.md------这几个文档本身内容以配置示例和命令行操作为主,LLM 倾向于输出代码块而不是 JSON。

实际生成结果:89 题(目标 100 题,差距约 10% 属于可接受范围)。


最终数据集结构

bash 复制代码
kb-00-testset/
├── generate_testset.py          # 生成脚本
├── .env.example                 # 环境变量模板
├── data/
│   ├── raw_docs/                # 30 个源文档
│   │   ├── AsymmetricEmbedding.md
│   │   ├── DockerDeployment.md
│   │   ├── ... (LightRAG docs)
│   │   ├── graphrag_architecture.md
│   │   └── ... (graphrag docs)
│   └── output/
│       ├── testset.jsonl        # 89 题评测集
│       └── testset_stats.json   # 统计摘要

每条记录格式:

json 复制代码
{
  "question": "What are the two main categories of configuration...",
  "ground_truth": "Server Configuration and LLM Configuration",
  "source_docs": ["DockerDeployment.md"],
  "question_type": "single_hop"
}

数据集统计:

json 复制代码
{
  "total": 89,
  "single_hop": 50,
  "multi_hop": 20,
  "boundary": 19,
  "source_docs_count": 30,
  "llm_model": "glm-4-flash"
}

这个测试集能测什么

后续每篇方案实测文章(LightRAG、GraphRAG、HippoRAG 等),都会用这 89 题打分,统一报告:

指标 含义 工具
Context Recall 检索的相关文档是否都被召回 RAGAS
Context Precision 召回的文档中有多少是真正相关的 RAGAS
Answer Faithfulness 生成答案是否忠实于检索到的内容 RAGAS
Answer Relevancy 答案是否回答了问题 RAGAS
边界拒答率 19道边界题中,正确拒答的比例 自定义
P90 检索延迟 第90百分位的检索响应时间 计时

前四个指标来自 RAGAS 框架,第五个是本系列的自定义指标(测的是各方案在"不知道"时有没有诚实地说"不知道"),第六个用于评估生产可用性。

这六个维度组合在一起,才能回答一个完整的选型问题:这个方案在我的场景下够不够用?


运行方式

bash 复制代码
cd llm-in-action

# 复制环境变量
cp kb-00-testset/.env.example kb-00-testset/.env
# 填入 LLM_API_KEY 等配置

# 生成测试集(从任意目录运行)
python kb-00-testset/generate_testset.py

# 自定义题目数量
python kb-00-testset/generate_testset.py --size 50

依赖安装:

bash 复制代码
conda activate dev_base
pip install openai python-dotenv

下一篇,正式开始第一个方案的实测:LightRAG vs QAnything------经典向量 RAG 横评。同一套 89 题,看两个方案在单跳、多跳、边界三个维度的真实表现。


欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页

相关推荐
水上冰石6 小时前
【MHS协议】第四章:ESP32 接入 MHS 协议实战:从零构建一个 MHS 兼容设备
人工智能·架构·机器人
知了一笑7 小时前
个体看衰AI,企业加速转型
人工智能·ai
飞哥数智坊8 小时前
一只虾到多只虾:先聊聊我为什么要“拆虾”
人工智能
飞哥数智坊8 小时前
架构图 SKILL 封装好了,顺便做了虾的适配
人工智能
冬奇Lab8 小时前
Code Agent 解剖(16):AgentTeams——为什么一个 agent 不够用?
人工智能
东风破_8 小时前
聊天记录越来越长怎么办?从消息数量截断到 Token 截断
人工智能
冬奇Lab8 小时前
开源项目第204期:LoopX — 长周期 Agent 控制平面,跑在 Codex/Claude Code 之上的状态管理层
人工智能·开源
ZGIAI9 小时前
旧模型下线前,客服 Agent 怎么迁移
人工智能·架构
东风破_9 小时前
程序重启后,AI 为什么把你忘了?从 InMemory 到持久化 Memory
人工智能
ZGIAI9 小时前
客服知识库更新后,怎么批量验收
人工智能·架构