RAG 系统进化论(九):RAG 评测,怎样证明系统真的变好了?

RAG 系统进化论(九):RAG 评测,怎样证明系统真的变好了?

本文导读: RAG 增加了更多技术,并不代表效果一定更好。本文将从评测集开始,介绍 Recall@K、MRR、nDCG、答案正确性、忠实度、引用和拒答评测,再通过 Experiment(实验)、Trace(调用链)、Span(执行步骤)、用户反馈与 LangSmith,建立比较版本和定位问题的方法。

从 Naive RAG 到 Agentic RAG,系统不断增加新能力:

text 复制代码
向量检索
→ 查询改写与混合检索
→ 动态路由和多数据源
→ 证据检查与纠错
→ 图关系与多模态
→ 自主规划和多步工具调用

能力越多,一个问题就越难回答:

系统真的变好了吗?

假设我们为 RAG 增加了 Reranker(重排序模型)。

一次测试中,正确文档从第五名上升到第一名,看起来效果很好。

但它也可能:

  • 让其他问题的正确文档下降;
  • 增加 300 毫秒延迟;
  • 提高每次请求成本;
  • 对某类文档有效,对另一类文档变差;
  • 检索变准了,最终答案却没有改善。

如果没有固定测试集和指标,我们只能依赖几个演示问题判断效果。

当系统进入 Agentic RAG(智能体式 RAG)后,情况更复杂:

text 复制代码
最终答案错误
可能来自计划、路由、查询改写、工具参数、
检索、重排、证据判断或生成中的任何一步

因此,RAG 需要两套互相配合的能力:

text 复制代码
Evaluation(评测):
用固定数据和指标比较系统质量

Observability(可观测性):
记录一次请求经过了什么步骤,并定位失败位置

RAG 评测与可观测性的完整流程

评测不能只看最终答案

RAG 至少包含三个层次:

text 复制代码
检索层:有没有找到正确证据?
生成层:有没有正确使用证据?
系统层:延迟、费用、稳定性和安全性怎样?

只评最终答案,会把不同失败原因混在一起。

例如:

text 复制代码
问题:AX-2048-C 出现 E1007 应该怎么办?

情况一:
没有检索到故障说明
→ Retrieval Failure(检索失败)

情况二:
检索到了正确说明,模型却增加了错误步骤
→ Generation Failure(生成失败)

情况三:
答案正确,但调用了十几个无关工具
→ Workflow Failure(工作流失败)

不同失败需要完全不同的改进方式。

第一步:建立评测 Dataset

Dataset(评测数据集)是一组可重复使用的测试样本。

一条 RAG 样本通常包含:

text 复制代码
输入问题
期望答案或关键事实
相关文档 ID
相关证据片段
是否应该拒答
问题类型和业务标签
ts 复制代码
interface RAGEvaluationExample {
  // 保存用户会真实提出的问题
  question: string;

  // 保存答案必须包含的关键事实,而不强制逐字一致
  expectedFacts: string[];

  // 保存应该被检索到的文档或证据标识
  relevantEvidenceIds: string[];

  // 标记知识库没有答案时系统是否应该拒答
  shouldRefuse: boolean;

  // 使用标签区分型号、政策、多跳、表格等问题类型
  tags: string[];
}

数据集不能只收集简单成功案例,还要包含:

  • 普通事实问题;
  • 型号、错误码和专有名词;
  • 多轮对话中的指代;
  • 比较和多跳问题;
  • 过期或冲突资料;
  • 知识库没有答案的问题;
  • 权限不足的问题;
  • 容易触发错误工具的问题。

高质量数据集通常来自三部分:

text 复制代码
产品设计阶段人工编写的核心问题
线上真实问题经过脱敏和审核后沉淀
针对已知风险生成的边界与对抗样本

第二步:评测检索是否找到正确证据

检索评测需要提前标注"哪些证据与这个问题相关"。

常见指标包括 Recall@K、Precision@K、MRR 和 nDCG。

Recall@K:正确证据找全了多少?

Recall@K(前 K 条结果召回率)表示:

text 复制代码
前 K 条结果中找到的相关证据数
÷
这个问题全部相关证据数

假设一个问题需要三条证据,Top-5(前五条结果)找到了其中两条:

text 复制代码
Recall@5 = 2 / 3

Recall@K 关注不要漏掉正确证据,特别适合评估候选召回阶段。

Precision@K:返回结果中有多少是相关的?

Precision@K(前 K 条结果精确率)表示:

text 复制代码
前 K 条结果中的相关证据数
÷
K

如果 Top-5 中只有两条相关:

text 复制代码
Precision@5 = 2 / 5

Precision@K 关注候选结果中的噪声。

Recall 和 Precision 可能互相拉扯:

text 复制代码
返回更多结果
→ Recall 可能提高
→ Precision 可能下降
→ 上下文和 Token 成本增加
MRR:第一条正确证据排得多靠前?

MRR 的全称是 Mean Reciprocal Rank(平均倒数排名)。

对每个问题,只看第一条相关结果的位置:

text 复制代码
第一条正确证据排名第 1 → 1 / 1 = 1
第一条正确证据排名第 2 → 1 / 2 = 0.5
第一条正确证据排名第 5 → 1 / 5 = 0.2
完全没有找到             → 0

再对所有问题取平均。

MRR 适合"找到一条正确证据就够了"的场景,不适合衡量多个相关结果的整体排序。

nDCG:多条证据的排序质量怎样?

nDCG 的全称是 Normalized Discounted Cumulative Gain(归一化折损累计增益)。

它同时考虑:

  • 结果是否相关;
  • 相关程度是高、中还是低;
  • 高相关结果是否排在前面。

排名越靠后,贡献会被折损;再与理想排序比较,得到 0~1 之间的归一化结果。

nDCG 适合存在多条证据、而且相关程度不同的场景。

四个指标关注点不同:

指标 主要回答
Recall@K 应该找到的证据找全了吗?
Precision@K 返回结果中有多少是有用的?
MRR 第一条正确证据出现得够早吗?
nDCG 多条不同相关程度的证据顺序合理吗?

不要只选择一个指标代表全部检索质量。

第三步:评测生成答案

检索正确不代表答案一定正确。

生成评测常关注三个维度。

Correctness:答案是否正确?

Correctness(正确性)比较系统答案与参考事实是否一致。

它不应该只做字符串匹配,因为同一个答案可以有多种表达。

可以检查:

  • 必要事实是否完整;
  • 数值和单位是否正确;
  • 适用条件是否一致;
  • 是否包含与参考答案冲突的结论。
Faithfulness:答案是否忠于证据?

Faithfulness(忠实度,也常称 Groundedness,证据支持度)判断答案中的陈述能否由检索证据支持。

text 复制代码
证据:
质量问题可以在 30 天内申请售后。

答案:
质量问题保证在 30 天内全额退款。

判断:
不忠实,因为"保证全额退款"没有证据支持。

正确性和忠实度也不同:

text 复制代码
答案碰巧符合现实,但证据中没有
→ 可能正确,但不忠于当前证据

答案完整复述了一份旧政策
→ 忠于所给证据,但业务结论错误
Answer Relevance:是否真正回答了问题?

Answer Relevance(答案相关性)判断回答是否围绕用户问题,是否出现大量无关内容或回避核心问题。

一个答案可能事实都正确,却没有回答用户真正关心的部分。

第四步:评测引用和拒答

RAG 的价值之一是提供可检查证据,因此引用也需要评测。

Citation Accuracy

Citation Accuracy(引用准确率)检查:

  • 引用的来源是否真实存在;
  • 引用位置是否包含对应结论;
  • 页码和区域是否正确;
  • 答案中的关键事实是否引用了正确来源。
No-answer Accuracy

No-answer Accuracy(无答案识别准确率)检查系统在资料不足时能否正确拒答。

评测集需要同时包含:

text 复制代码
应该回答的问题
应该拒绝回答的问题
只有部分证据的问题
证据互相冲突的问题

只测试有答案的问题,会鼓励系统在任何情况下都给出结论。

第五步:评测 Agentic RAG 的过程

Agentic RAG 不能只比较最终文字,还要评测执行过程:

维度 示例
Plan Quality(计划质量) 是否拆出了完成目标所需步骤
Tool Selection(工具选择) 是否选择了正确工具
Tool Arguments(工具参数) 参数是否完整、合法、符合用户意图
Task Completion(任务完成度) 是否满足全部完成条件
Efficiency(执行效率) 是否存在重复和无效调用
Safety(安全性) 是否越权或跳过人工确认

例如,最终退款率计算正确,但系统读取了用户无权访问的数据,这次任务仍然应该判定失败。

第六步:用 Experiment 比较版本

Experiment(实验)是在同一数据集上运行某个系统版本,并保存每条样本的输出、指标、延迟和配置。

例如比较:

text 复制代码
实验 A:
纯向量检索,Top-5

实验 B:
BM25 + 向量检索 + RRF

实验 C:
混合检索 + Reranker

一次修改是否值得上线,不能只看平均分,还要检查:

  • 哪些问题类型提升了;
  • 哪些样本发生回退;
  • P50(50% 请求不超过的延迟)、P95(95% 请求不超过的延迟)等延迟分位数;
  • Token 和模型调用成本;
  • 拒答率是否异常升高;
  • 是否触发新的安全问题。
ts 复制代码
async function runRAGExperiment(
  version: RAGVersion,
  dataset: RAGEvaluationExample[],
) {
  // 对同一数据集运行当前版本,保证版本之间可以公平比较
  const runs = await Promise.all(
    dataset.map((example) =>
      runRAGSystem(version, example.question),
    ),
  );

  // 分别计算检索、生成、引用、拒答和系统成本指标
  const metrics = evaluateRuns(runs, dataset, {
    retrieval: ["recall_at_k", "mrr", "ndcg"],
    generation: ["correctness", "faithfulness"],
    system: ["latency", "token_cost", "error_rate"],
  });

  // 按问题标签拆分结果,避免平均分掩盖局部回退
  return buildExperimentReport(
    version,
    runs,
    metrics,
    { groupBy: "tags" },
  );
}

第七步:Trace 与 Span 定位一次请求

离线评测告诉我们"某个版本整体怎样",线上可观测性帮助解释"这一次请求发生了什么"。

Trace(调用链)记录一次请求从开始到结束的完整过程。

Span(调用片段)记录其中某一个步骤。

text 复制代码
Trace:回答用户问题
  ├── Span:查询改写
  ├── Span:BM25 检索
  ├── Span:向量检索
  ├── Span:RRF 融合
  ├── Span:Reranker
  └── Span:大模型生成

每个 Span 可以记录:

text 复制代码
输入与输出
开始时间与耗时
模型和提示词版本
检索结果与分数
Token 与费用
错误信息
父子调用关系
用户反馈
ts 复制代码
async function tracedRAGRequest(
  question: string,
) {
  // 创建根调用链,关联一次用户请求及其版本信息
  return trace("rag_request", { question }, async () => {
    // 单独记录查询改写,便于判断问题是否在这里被改变
    const query = await span(
      "query_rewrite",
      () => rewriteQuery(question),
    );

    // 单独记录检索输入、候选结果、分数和耗时
    const evidence = await span(
      "retrieval",
      () => retrieveEvidence(query),
    );

    // 单独记录最终提示词、模型输出和 Token 消耗
    return await span(
      "generation",
      () => generateAnswer(question, evidence),
    );
  });
}

伪代码中的 tracespan 表达的是通用观测思想,不限定某个平台的具体 API。

LangSmith 应该在哪个阶段加入?

LangSmith 是面向大模型应用的追踪、评测和监测平台。

在这个系列里,它不需要从 Naive RAG 第一行代码就成为文章主角。

当系统开始出现多次模型调用、检索、重排、路由和智能体循环时,我们真正需要:

  • 用 Trace 查看完整调用链;
  • 用 Dataset 保存评测问题和参考结果;
  • 用 Evaluator(评估器)计算正确性、证据支持度和相关性;
  • 用 Experiment 比较不同系统版本;
  • 把自动评测和用户反馈记录到具体运行;
  • 过滤和分析线上失败、延迟与成本。

这正是引入 LangSmith 的合适位置。

根据当前平台能力,可以形成如下对应关系:

RAG 需求 LangSmith 中的作用
查看一次请求经过哪些步骤 Tracing(追踪)
保存固定评测样本 Datasets(数据集)
比较两个 RAG 版本 Experiments(实验)
计算自动或人工指标 Evaluators 与 Feedback(评估器与反馈)
分析线上质量、延迟和错误 Observability 与 Monitoring(可观测性与监测)

LangSmith 不会自动让 RAG 变准。

它提供的是记录、比较和定位问题的基础设施。指标怎样定义、测试集是否可信、失败怎样分类,仍然需要团队自己设计。

第八步:建立 Feedback 与失败分类

Feedback(反馈)可以来自:

text 复制代码
用户点赞或点踩
用户修改后的正确答案
客服标记的错误类型
自动评估器分数
人工审核结论
工具调用是否成功

只有一个"差评"还不够,系统需要 Failure Taxonomy(失败分类体系):

text 复制代码
query_understanding:问题理解错误
retrieval_missing:没有召回正确证据
retrieval_noise:无关证据过多
stale_data:使用过期资料
generation_unsupported:答案缺少证据支持
wrong_tool:选择了错误工具
permission_violation:发生权限问题
latency:延迟不可接受

线上失败应该经过审核后加入回归测试集:

RAG 评测与可观测性引入了哪些技术和方案?

这一阶段不再依靠"感觉回答不错",而是使用数据集、指标和调用链持续验证系统质量。

技术 主要作用 产生的结果
Dataset(评测数据集) 保存固定问题、期望答案和相关证据 可重复运行的测试样本
Retrieval Metrics(检索指标) 衡量正确证据是否被召回和排在前面 Recall@K、Precision@K、MRR、nDCG
Generation Evaluator(生成评估器) 检查答案正确性、相关性和证据支持度 Correctness、Faithfulness 等分数
Citation Evaluation(引用评测) 检查引用是否存在并支持相应结论 引用准确率
Experiment(实验) 在同一数据集上比较模型、索引和工作流版本 可对比的评测结果
Trace 与 Span(调用链与步骤) 记录一次请求经过的节点、耗时和输入输出 可定位的执行链路
Feedback(反馈) 收集用户、人工和自动评估结果 线上质量信号
Quality Gate(质量门禁) 根据指标决定版本能否发布 通过、拒绝或继续修改

常见落地方式可以分成三类。

方案一:离线回归评测

建立一组固定问题,在每次修改检索器、模型或提示词后重新运行,对比质量、延迟和费用。

它适合开发和发布前验证,是所有 RAG 系统都应该具备的基础能力。

方案二:线上可观测性

text 复制代码
一次用户请求
→ 查询改写 Span
→ 检索 Span
→ 重排 Span
→ 生成 Span
→ 最终回答与反馈

通过 Trace 找到失败发生在哪一步,适合已经进入真实用户环境的系统。

方案三:持续评测闭环

将经过人工确认和脱敏的线上失败加入评测数据集,修改系统后运行新实验,通过质量门禁再发布。

这样,线上问题会变成下一次迭代必须通过的回归测试。

这一阶段解决了什么?

RAG 评测与可观测性让团队能够:

  1. 区分检索错误、生成错误和工作流错误;
  2. 用固定数据集比较修改前后的质量;
  3. 观察延迟、Token、费用和失败节点;
  4. 将线上失败转化为可重复的回归测试;
  5. 用证据决定是否上线,而不是依赖主观感觉。

评测与观测还不等于可运营

即使我们已经发现:

text 复制代码
某个新 Embedding 模型让 Recall@5 提高了 6%
但 P95 延迟增加了 40%
某些旧文档没有被正确删除

团队仍然要决定:

  • 怎样迁移已有向量;
  • 如何给索引、提示词和模型做版本管理;
  • 怎样灰度发布;
  • 指标下降时如何回滚;
  • 如何控制权限、成本和数据更新;
  • 线上反馈由谁处理。

"看见问题"不等于"长期治理问题"。

下一篇:可运营 RAG

下一篇是这个系列的最后一篇:可运营 RAG。

我们会把前面分散的能力收束成闭环:

text 复制代码
数据进入
→ 解析与索引
→ 检索和生成
→ 评测与监测
→ 发布与回滚
→ 用户反馈
→ 重新改进数据和系统

RAG 评测与可观测性回答了"系统现在表现怎样、问题发生在哪里"。

可运营 RAG 要解决的是:

怎样让数据、权限、成本、版本、发布和反馈形成一套可以长期运行的工程体系?

相关推荐
IT小盘1 小时前
10-使用Reranker提升RAG回答准确率
人工智能·python
小黑技术栈1 小时前
DevEco Code Plan+Build模式:审方案再执行的技术实践
人工智能
Thom5801 小时前
【聚宽 JoinQuant】聚宽如何获取持仓和订单?get_orders()与get_open_orders()教程
人工智能·经验分享·量化交易·聚宽·量化编程
EasyDSS1 小时前
景区客流遇冷?用EasyDSS企业融媒体平台直播/点播解锁「云上文旅」新玩法
人工智能·媒体·直播·点播·easydss
刘一说1 小时前
AI科技热点日报 | 2026年08月04日
人工智能·科技
如此这般英俊1 小时前
手搓Claude Code-第十章 system_prompt
数据结构·人工智能·python·语言模型·自然语言处理·prompt
云端漫步19871 小时前
HarmonyOS NEXT AI 智能生活助手:AI 日程规划
人工智能·华为·生活·harmonyos
孙启超1 小时前
【AI应用开发】怎么降低 Agent 幻觉?有几种可行方案?
大数据·人工智能·llm·agent·rag·幻觉·ai应用开发
丘丘用户思思澪2 小时前
生产环境下优化 Agent Token 成本的系统化实战指南
人工智能