一个知识库“能回答”并不等于“回答得可信”。同一个错误结果,可能来自文档没有解析完整、文本块切得不合适、召回结果偏离问题,也可能是模型忽略证据后自行补全。只有把链路拆开评测,优化才不会变成反复调整参数。

本文承接 RAGFlow 知识库搭建实战,重点讨论上线前后怎样建立一套轻量、可复现、能够定位原因的评测体系。

文档经过检索、重排和证据验证后形成可信回答的示意图
评测的目标不是得到一个孤立分数,而是看清证据怎样抵达回答。

1. 先把“效果好”拆成四个问题

一次完整问答至少包含四个可以独立检查的环节:

对应的四个问题是:

  1. 检索是否找到了证据:正确文本块有没有进入候选集合;
  2. 重排是否把证据放在前面:真正相关的内容是否获得更高优先级;
  3. 回答是否忠于证据:结论能否从引用片段中推出;
  4. 证据不足时是否克制:系统是否会明确拒答,而不是补出一个听起来合理的答案。

如果只看最后一句回答,就无法区分“没找到”与“找到了但没使用”。

2. 建立一份小而有代表性的测试集

起步时不必追求几千条问题。先从业务中选择 40~80 条高价值问题,并覆盖不同难度:

问题类型 示例特征 主要检查点
直接事实 答案集中在一个段落 基础召回与引用
条件流程 包含前置条件和操作顺序 分块是否保留上下文
跨段组合 需要合并两处以上证据 多路召回与生成约束
时间敏感 新旧制度存在冲突 版本、日期与优先级
边界问题 文档中没有明确答案 拒答准确率
表格问题 答案来自行列交叉位置 表格解析与结构保留

每条测试数据至少保留五项信息:问题、标准答案要点、证据文档、证据位置、问题类型。标准答案不必写成长文,明确“必须包含什么”和“不能声称什么”更有用。

3. 检索层看什么指标

检索层的指标应围绕“正确证据排在哪里”设计。

指标 它回答的问题 适合发现
Recall@K 前 K 个结果是否包含正确证据 召回缺失
MRR 第一条正确证据排得是否足够靠前 排序质量
nDCG@K 多条相关证据的整体顺序是否合理 多证据问题
命中文档率 是否至少命中正确来源文档 路由和过滤问题
冗余率 前 K 个文本块是否高度重复 重复切块与去重问题

例如 Recall@5 很高而 MRR 较低,说明证据通常能找回来,但总被相似却不关键的片段压在后面。这时优先调整重排、字段权重或去重,而不是继续增大召回数量。

4. 回答层不仅看“像不像标准答案”

最终回答至少需要三类判断:

  • 完整性:是否覆盖标准答案中的关键要点;
  • 忠实度:每个事实能否由检索证据支持;
  • 可追溯性:引用能否定位到具体文档和片段。

可以把一条回答拆成若干事实声明,再逐条检查证据覆盖,而不是直接给整段文字打一个模糊总分。

5. 用诊断矩阵定位参数

不要从“效果差”直接跳到“换模型”。先根据现象定位环节:

现象 优先排查 常见动作
正确文档完全没有出现 文档解析、过滤条件、查询表达 检查解析结果,补充关键词召回
正确片段在后几位 重排、相似片段竞争 调整重排权重并去重
片段正确但缺少上下文 分块策略 增大重叠或按标题层级切分
引用正确但结论扩大 生成提示与事实约束 要求逐条引用并限制推断
无答案时仍强行回答 拒答阈值 加入边界问题和置信度门槛
新旧制度混在一起 元数据过滤 增加版本、生效日期与状态字段

这张表的价值在于让每次调整都有假设:改动前说明想解决什么,改动后只用固定测试集验证这一点。

6. 把评测变成持续回路

离线测试集只能覆盖已知问题。上线后还要从真实查询中持续补充三类样本:用户重复追问、低置信度回答、人工纠正结果。

建议为每次配置变更保存版本号,并记录分块规则、嵌入模型、检索权重、重排方式和回答模板。这样一次提升才是可复现的工程结果,而不是“今天似乎更好”。

7. 一套够用的最小落地方案

如果团队刚开始做评测,可以先完成以下闭环:

  1. 选出 50 条真实问题,其中至少 10 条是应当拒答的问题;
  2. 为每条问题标注证据文档和证据片段;
  3. 保存前 5 条检索结果,计算 Recall@5 与 MRR;
  4. 检查回答要点、证据支持和引用位置;
  5. 每次只调整一类参数,并保留前后对比;
  6. 把线上失败查询持续补入测试集。

真正可靠的知识库,不是永远给出答案,而是知道证据在哪里、证据够不够,以及什么时候应该停下来。