跳转至

RAG 质量评估自动化 · 运维手册

适用场景:RAG 系统要进生产,但每次改切分策略、换 embedding、调提示词都不确定有没有变差——需要一套可回归、可进 CI 的质量评估,而不是靠人工抽查。


1. 为什么 RAG 必须做自动化质量评估

RAG 的坏是静默坏。检索错一段,生成就顺着错的编;chunk 切坏了,faithfulness 悄悄塌,用户可能两周后才投诉「答案不对」。这种劣化,靠人肉看几句话发现不了,更不可能在每次改配置时都看一遍。

自动化评估的本质:把「检索准不准、生成靠不靠谱」翻译成可回归的数字。任何改动(换 embedding、改 reranker、调 prompt)一跑评估,指标掉就报警。这是 RAG 上线后能不能睡安稳觉的分水岭。

2. 评估拆解:检索侧与生成侧各看什么

RAG 是两半拼起来的,评估也得拆开看:

  • 检索侧:该用的段落有没有被找回、有没有排到前面。指标是 recall@k、precision@k、MRR、nDCG。
  • 生成侧:答案有没有忠于上下文、有没有答对所问。指标是 faithfulness、answer relevancy、citation accuracy。

只测一半会漏。检索满分但生成瞎编,照样生产事故;生成很顺但检索错,答案是对的也不可信。我习惯两半都测,端到端再加拒绝/权限类检查。

3. 四大核心指标

不需要参考答案也能跑的三个(生产最常用):

  • faithfulness(忠实度):答案的每个断言是否都能在检索到的上下文里找到支撑。低说明在编。这是 RAG 的命门指标。
  • answer relevancy(答案相关性):有没有正面回答用户问题,而不是答非所问。
  • context precision / recall(上下文精准/召回):检索回来的段落里有多少是相关的(precision),该用的关键段落有没有被漏掉(recall)。

有标准答案时再加 answer correctness,直接比对。注意:faithfulness ≠ correctness——模型可以很忠实地复述一段错误文档,所以 correctness 必须配参考答案或专家复核。

4. 工具选型:别一上来全装

  • Ragas:RAG 专用指标最全(faithfulness / answer relevancy / context precision+recall),离线评测首选。
  • DeepEval:pytest 风格,把评估写成测试用例,最适合接 CI 做回归门禁。
  • TruLens:RAG triad + 链路追踪,看「为什么错」很顺手。
  • Phoenix:追踪 + 评估,可自托管、可完全离线,敏感语料友好。

我的搭配:离线诊断用 Ragas,回归门禁用 DeepEval,线上排错加 Phoenix。不是越多越好,三个够用。

5. 测试集怎么建:100–300 条真实问题

评估的质量上限等于测试集的质量。走过场的测试集 = 走过场的分数。

# 测试集最小结构:问题 + 预期答案 + 相关源文档
test_cases = [
    {
        "query": "退款多久到账?",
        "reference_answer": "一般 3–5 个工作日原路退回。",
        "retrieval_context": ["退款政策.pdf 第3条…", "客服手册.docx…"],
    },
    # ... 至少覆盖难例、答不出的边界 case
]

要点:① 用真实用户问题,不是编造的;② 必含答不出的难例(验证拒绝能力);③ 人肉抽检一批答案,把人判和自动分对齐,校准 judge 后再信任分数;④ 测试集版本化,跟着代码进仓库。

6. 本地 judge 与数据不出域

很多团队卡在「评估要不要把语料发给云端大模型」。答案是:可以不出域。

  • 检索指标(recall@k/MRR/nDCG)根本不需要模型。
  • judge 类指标:DeepEval 文档支持 Ollama 作评估模型;TruLens 列了 Ollama/LiteLLM/HF 作 judge provider;Ragas 有基于 Vectara HHEM 的 faithfulness 变体;Phoenix 声明可完全离线(air-gapped)。

涉及合规语料,我一律本地 judge。把 judge 模型和被测系统放在同一内网,评估流量不触外网。

7. 把评估接进 CI:回归门禁拦住劣化

这是让评估「有用」的关键一步——不进 CI,评估报告就只是个摆设。

# test_rag_eval.py —— 直接进 pytest / CI
from deepeval import assert_test
from deepeval.metrics import FaithfulnessMetric, AnswerRelevancyMetric
from deepeval.test_case import LLMTestCase

def test_rag_faithfulness():
    test_case = LLMTestCase(
        input="退款多久到账?",
        actual_output=answer,
        retrieval_context=context,
    )
    assert_test(test_case, [FaithfulnessMetric(threshold=0.85),
                            AnswerRelevancyMetric(threshold=0.80)])

给每个指标设阈值(如 faithfulness < 0.85 就 fail),改 chunk 策略、换 embedding、调 prompt 的 PR 一跑就知道劣没劣化。指标掉 = 构建红 = 拦住发布。

8. 一次真实事故复盘:chunk 切错导致 faithfulness 塌方

某次为了提召回,把 chunk_size 从 512 拉到 2048、overlap 归零。离线看 recall@k 涨了,就合了。上线三天后客服反馈「答案开始胡说」。一查评估:faithfulness 从 0.92 掉到 0.71。

根因:大 chunk 把无关内容塞进同一段,生成时模型被噪声带偏、开始编造。回滚 chunk 配置,改回 512/64,faithfulness 回升。教训:recall 涨不等于质量涨,faithfulness 才是 RAG 的兜底指标,任何检索侧改动都必须连带跑生成侧评估。

9. 上线后的评估纪律与巡检

我把 RAG 评估固化成日常纪律:

  1. 版本化测试集:随代码演进,新业务线补对应难例。
  2. 每次改动必跑评估:chunk / embedding / reranker / prompt 任一变更,CI 里跑全套,faithfulness 掉就拦。
  3. judge 校准:每季度抽一批答案做人机对齐,judge 漂移就重训或换本地模型。
  4. 线上采样回归:每周从真实流量采样 50 条,跑一遍评估,盯 faithfulness 长尾。
  5. 指标看板:faithfulness / answer relevancy / context recall 接监控,跌破阈值即 P1。

绝不靠「感觉这次改得不错」上线——RAG 的劣化是静默的,只有数字能拦住它。

10. 常见问题排查

问题 1:faithfulness 低但答案看着对

大概率是检索把无关段落塞进 context,模型被带偏。先查 context precision:相关段落有没有排到前面。降噪(更小 chunk、加 reranker)通常立竿见影。

问题 2:评估很慢跑不完 CI

用本地 judge + 抽样测试集(先跑 50 条做门禁,全量留夜间跑)。检索指标本就无需模型,先把它们前置。

问题 3:judge 分数和人判对不上

judge 没校准。抽 30–50 条人工打分,比对偏差,要么换更强的本地 judge,要么把评判标准写进 prompt 重新校准,别直接信原始分。

问题 4:测试集建一次就完,还是得一直维护

必须持续维护,把它当代码一样对待。业务线加了新功能、知识库换了文档,测试集不跟着补,评估就测不到新路径,劣化会漏检。我的做法:每个新栏目或新数据源至少补 10–20 条真实问题,难例和边界 case 优先;季度做一次整体复审,删掉过时问题、补进新场景。测试集的版本要和被测系统的版本对齐,否则「分数涨了」可能只是测试集变了。


FAQ

RAG 为什么要做自动化质量评估? RAG 的失败是静默的——检索错一段、生成就瞎编,肉眼很难在每次改 chunk/embedding/提示词后发现。自动化评估把「检索准不准、生成靠不靠谱」变成可回归的数字,任何改动一跑就知道有没有劣化。

四大核心指标分别看什么? faithfulness 看答案是否忠于检索到的上下文(有没有编造);answer relevancy 看有没有答对用户的问题;context precision/recall 看检索有没有把该用的段落排到前面、有没有漏掉关键段落;answer correctness 在有标准答案时直接比对。前三个无需参考答案也能跑。

评估一定要把数据发给云端大模型吗? 不必。recall@k、MRR、nDCG 这类检索指标根本不需要模型;judge 类指标可用本地模型(Ollama/DeepEval 文档支持)或 Vectara 的 HHEM 分类器,Phoenix 还能完全离线。涉及敏感语料时,优先本地 judge,数据不出域。

怎么把评估接进 CI 做回归门禁? 用 DeepEval 这类 pytest 风格框架,把评估写成测试用例,在流水线里跑。给每个指标设阈值,faithfulness 掉到 0.85 以下就让构建失败、拦住发布。测试集要版本化、带引用答案和源文档,跟着代码一起进仓库。

测试集应该怎么建才不走过场? 100–300 条真实问题 + 预期答案 + 相关源文档,必须包含答不出的难例和边界 case。别只用 happy path。建好后人肉抽检一批答案,把人判和自动分对齐,校准 judge 再信任它的分数。


相关文章