无论你是自己构建 RAG(DIY),还是使用 RAG 平台,都需要能够衡量用户在使用 RAG 应用时看到的响应质量。这被称为 RAG evaluation,即 RAG 评估。它衡量系统找到正确文档或 chunks 的准确程度(检索准确性),以及系统如何从这些文档或 chunks 中连贯、正确地组织响应(生成准确性)。
在深入细节之前,先区分两类 RAG 评估会很有帮助:
离线评估
在开发周期中执行。这类评估通常更深入,也更消耗资源,用于在部署前优化流水线设置。
在线评估
在真实流量上执行。它用于识别真实用户如何与系统交互,但为了保持低延迟用户体验,需要采用轻量级方法。
本章主要聚焦离线 RAG 评估,讨论它为什么重要、应该考虑哪些指标,以及如何解释每个指标。随后,在“在线 RAG 评估”中,我们会简要讨论在线评估,并提供一些最佳实践。
RAG 是如何失败的?
如果没有系统性方法衡量 RAG 应用质量,这不仅是一个技术疏忽;它还是一个业务风险,可能破坏你的整个 AI 战略。没有结构化、严谨的 RAG 评估框架,你就有可能部署会产生幻觉或不准确答案的应用,最终侵蚀用户对应用的信任,并削弱它对业务的价值。
在生产环境中,这些技术故障会表现为更低的客户满意度,例如客户满意度分数下降,更低的净推荐值(NPS),甚至是合规事件增加,而这些事件往往成本很高。
正如你在第 1 章中学到的,RAG 查询流程至少由两个不同但相互依赖的组件组成:检索器和生成器。查询流程中任何一个组件出现故障或退化,都可能导致低质量输出。
因此,一个健壮的评估策略必须能够独立诊断查询流程中所有组件的问题,同时也要评估它们协同工作时的表现。通过将这些技术组件与检索和生成评估指标,以及系统指标(我们将在“系统指标:延迟和正常运行时间”中讨论)连接起来,你可以确保 RAG 技术栈针对可衡量的业务结果进行优化。
检索失败
RAG 中最关键也最常见的一类失败发生在检索阶段;一旦检索过程有缺陷,整个系统都会受到影响。无论生成器 LLM 多么先进,它都无法基于错误或无关上下文生成正确且相关的答案。
注意
在生产中,我们建议先优化检索器,再优化生成式 LLM。通过从基础向量搜索切换到混合搜索(向量搜索 + BM25),或加入重排序器(见第 3 章),来提升检索指标,往往可以带来可衡量收益。如果你的检索召回率只有 40%,再多提示词工程也无法让你的 RAG 应用成功。
检索中有两种常见失败模式:
未能检索到信息(低召回率)
当你的数据集中包含回答用户查询所需的准确信息,但检索机制完全没有把它找出来时,就会发生这种失败。
这实际上会让 LLM “失明”,并主要表现为两种方式:
一种是完全失败,即检索器完全找不到相关信息,使 LLM 没有任何可用于支撑响应的信息。
另一种是部分失败,即系统检索到了一些相关 chunks,但漏掉了生成全面且准确答案所需的其他关键片段。
在这些场景中,LLM 会被逼入困境:它要么承认自己找不到信息(这通常没有帮助),要么更危险地回退到自己的预训练知识,生成一个听起来合理但其实是编造的或过时的响应。
无关检索(低精确率)
在这种场景中,检索器是“嘈杂的”——它成功找到了文档 chunks,但其中一部分或全部与用户查询无关,也不包含回答查询所需的具体事实。
例如,如果用户问:“新建 GitHub 仓库需要哪些安全协议?”检索器可能会拉取一些关于 GitHub 功能的一般信息。虽然这些 chunks 与 “GitHub” 有关,但对于回答关于安全协议的具体问题毫无用处。
再举一个例子,考虑查询:“项目发布前强制性的最终审批步骤是什么?提交风险评估表的具体截止时间是什么?” 在我们的例子中,系统有如下三个 chunks 可用:
Chunk A(相关):“所有项目在 Go-Live 日期之前,都必须完成 ‘Stakeholder Sign-off’,作为最终强制步骤。”
Chunk B(相关):“风险评估表必须在预定发布前至少 72 小时提交到 Compliance Portal。”
Chunk C(无关/噪声):“鼓励项目经理使用 ‘Team Celebration’ 预算,在成功发布活动后举办午餐。”
现在想象一下,检索器成功识别出 Chunk A 是相关的,但未能检索 Chunk B。相反,它仅仅因为 Chunk C 包含 “Project” 和 “launch” 这些词,就把 Chunk C 拉了进来,从而在提供给 LLM 的上下文中制造了“噪声”。
此时,LLM 被迫只使用 “Stakeholder Sign-off” 信息和 “Team Celebration” 信息来生成答案。最终响应可能看起来像这样:
项目发布的强制性最终步骤是 Stakeholder Sign-off。关于风险评估的截止时间,文档没有指定时间范围;不过,请确保在发布完成后安排团队庆祝午餐。
由于检索器漏掉了 Chunk B,LLM 无法提供 72 小时截止时间。即便它承认不知道截止时间(这比幻觉更好,但仍然是系统失败),它还加入了用户并未询问的庆祝午餐这种“噪声”干扰。用户可能会因为系统找不到截止时间而误以为不存在截止时间,最终错过合规窗口,导致项目发布延迟。
最终,健壮检索依赖同时优化精确率和召回率。通过利用 recall@k、precision@k、nDCG 或 UMBRELA 等指标(见“检索指标”),你可以识别并修复检索流水线中的问题,使生成式 LLM 能够依赖正确事实。
虽然许多检索失败可以通过调优流水线本身来解决,但有些失败根植于检索方法本身的架构限制。标准 RAG 通常难以处理复杂的多跳查询,例如“收购 Startup X 的那家公司总部在哪里?”,也难以处理宽泛的“sensemaking”查询,例如“工程团队如何看待新政策?” 这类查询需要的不只是简单语义匹配。要解决它们,我们必须转向 agentic RAG(第 7 章)或知识图谱(第 9 章)。
生成失败
即使检索工作得很好,或者至少相当不错,已经交付了回答查询所需的最佳 chunks,你的应用仍然可能因为生成步骤失败而产生糟糕结果。一个有效的 RAG 系统不仅需要一个优秀的“图书管理员”作为检索器,还需要一个称职且可信赖的“作者”作为生成器。
有几类重要的生成失败需要注意:忠实性失败、上下文利用失败,以及答案相关性失败。
忠实性失败
这通常被称为幻觉,可以说是最严重的一类生成错误。当 LLM 的答案直接与提供的 chunks 中的事实相矛盾,或不被这些事实支持时,就会发生这种错误。
例如,如果某个 chunk 明确写着:“项目截止日期是 7 月 31 日”,而 LLM 自信地回答:“项目截止日期在 8 月初”,那么它就没有完成其首要指令:基于提供给它的信息生成响应。
对于任何依赖 RAG 系统获取事实准确性的企业用户而言,这可能是最具破坏性的错误,因为它会彻底摧毁应用的可信度。
区分 faithful incorrectness(忠实但错误)和 unfaithful incorrectness(不忠实且错误)是有帮助的。前者指 LLM 是否只基于提供的 chunks 生成响应,但提供的信息本身是错的;后者指最终答案是否没有反映源数据。一个响应可以完全忠实于一份过时文档——例如准确说出一份陈旧 PDF 文档中的 2023 年截止日期——但对 2024 年的用户来说仍然是错误的。区分这两者对排障至关重要:如果响应不忠实,那么可能是 LLM 出了问题;如果响应忠实但错误,那么就是检索器取回了过时 chunks,你可能需要修复数据摄取流水线,或实现文档版本管理。
上下文利用失败
这类生成错误发生在检索器已经成功识别并提供多个相关信息 chunks,但 LLM 未能在最终答案中整合所有这些信息时。这可能源于 LLM 的挑战,例如排序偏差,也就是只关注第一个或最后一个 chunk,模型实际上忽略了所提供上下文中的关键部分。
例如,用户可能问:“Project Atlas 的财务风险和收益是什么?” 检索器正确提供了两个 chunks:一个详细说明项目的高收入潜力(收益),另一个来自风险评估文档,说明显著市场波动(风险)。如果 LLM 生成的答案只描述项目的收入收益,而完全忽略提供的风险上下文,就发生了上下文利用失败。
最终答案并不是幻觉,因为它基于部分上下文,但它危险地不完整且具有误导性,呈现了偏斜图景,可能导致糟糕决策。
后文“生成指标”中讨论的 AutoNuggetizer,是在评估 RAG 生成质量时识别上下文利用缺口的一种方法。
答案相关性失败
在这种场景中,LLM 的答案可能完全忠实于提供的上下文,并包含所有相关事实,但最终没有回答用户的核心问题或意图。
例如,如果用户问:“推送这次新更新安全吗?” 而上下文列出了该更新的功能,那么一个答案相关性失败的回答可能是:“这次新更新包含功能 A、B 和 C。” 虽然这在事实上符合上下文,但它把推理负担重新交给了用户,用户现在必须自己解释这些功能,以判断更新是否安全。系统没有交付用户请求的结论性洞察,因此没有完成一个有帮助助手的角色。
注意
我们会在“生成指标”中讨论 ROUGE-L 和 BERTScore 等答案相似度指标,它们会将生成答案与“ground truth”答案进行比较;不过,这些指标往往会漏掉这种失败,因此在这种情况下并不有效。使用 LLM-as-a-judge 的自定义评分准则(见“使用 LLM 进行评估:LLM-as-a-Judge”)通常表现更好。
由于 LLM 并不完美,RAG 中的生成步骤可能以多种方式失败,导致响应与事实不一致、没有体现所有事实,或者只是没有以令人满意的方式回答用户问题。
答案不相关的原因之一,可能是你的数据集中没有相关数据,而这通常可能源于数据摄取问题。
由于数据摄取不足导致的失败
“垃圾进,垃圾出”这一原则对 RAG 尤其适用。系统输出质量从根本上受限于从源头摄取的数据质量。
如果摄取流水线——也就是负责解析、清洗和索引源文档的过程——存在缺陷,那么你希望 RAG 所依据的数据本质上已经受损。无论检索器多么准确,生成器多么精确,它们都无法弥补一个不完整、结构不当、过时或直接错误的事实来源。
数据摄取中有两个常见挑战:结构解析错误和内容陈旧。
结构解析错误
摄取过程未能正确解释复杂文档格式,或未能从 PDF、DOCX 或 PPTX 文档内部的表格、图表或图片中正确抽取相关信息。文本可能被抽取出来了,但其表格或层级上下文丢失了,把结构化数据变成了一串没有意义的词。
这通常表现为检索相关性系统性偏低,尤其是在表格密集或高度视觉化的文档上。当你在摄取流水线中实现健壮日志记录时,这类失败可以被主动识别并修复。
内容陈旧
即使你的数据摄取流水线定期刷新数据以确保其最新,你仍然可能观察到过时或被替代的文档没有被正确移除或版本化。于是,你的 RAG 应用可能会“自信地”检索一年前政策文档中的信息,将其作为当前事实呈现,并导致用户基于危险的过时信息采取行动。
解决内容陈旧最直接的方式,是为每个文档使用唯一 entity ID,并配合版本管理。所有文档及其 chunks 都可以标记这个 entity ID 和一个版本号;当该文档的新版本被摄取时,所有旧版本的 chunks 都会被移除。
有了这一机制,你还可以主动运行陈旧数据测试。如果同一个文档(entity ID)的两个版本同时出现在 RAG 系统中,那么你就知道摄取流程出了问题。
RAG 失败总结
最终,摄取不足会间接触发前面讨论过的检索和生成失败。这些与摄取相关的问题尤其隐蔽,因为它们会制造一种虚假的可靠感;系统看起来可能运行得很好,但实际上运行在有缺陷的基础之上。
表 6-1 总结了我们讨论过的所有失败模式。
表 6-1 RAG 中的失败模式
| 流水线阶段 | 失败模式 | 描述 | 缓解策略 |
|---|---|---|---|
| 检索 | 未能检索到信息(低召回率) | 信息存在但没有浮现出来;导致 LLM “失明”。 | 使用混合搜索(向量 + BM25),或实现重排序器,以浮现更好的 chunks。 |
| 检索 | 无关检索(低精确率) | 检索器很“吵”,拉取了不包含答案的 chunks。 | 使用混合搜索(向量 + BM25),或实现重排序器,以浮现更好的 chunks。 |
| 检索 | 架构限制 | 难以处理多跳或宽泛的 “sensemaking” 查询。 | 转向 agentic RAG,或集成知识图谱。 |
| 生成 | 幻觉 | LLM 与上下文矛盾,或包含与上下文事实不一致的信息。 | 使用幻觉检测机制。 |
| 生成 | 上下文利用失败 | LLM 忽略某些 chunks,导致答案不完整。 | 优化提示词工程,确保所有 chunks 都被加权考虑。 |
| 生成 | 答案相关性失败 | 答案“安全”且忠实,但没有回答核心问题。 | 实现自定义 LLM-as-a-judge 评分准则。 |
| 摄取 | 结构解析错误 | 表格/图表没有被正确抽取,信息内容丢失。 | 在流水线中实现健壮日志记录;为 PDF、DOCX 和 PPTX 文件使用专门解析器。 |
| 摄取 | 内容陈旧 | 过时文档被当作“当前”检索,因为它们没有被清除。 | 使用唯一 entity ID 和版本管理。 |
现在你已经理解了 RAG 的失败模式,接下来我们会查看帮助识别这些失败的指标。但在深入指标之前,我们首先要理解许多 RAG 评估指标中使用的一种常见且关键技术:LLM-as-a-judge。
使用 LLM 进行评估:LLM-as-a-Judge
随着 LLM 变得更强大、更通用,使用 LLM 进行评估的想法随之出现。这种方法的常见名称是 “LLM-as-a-judge”:利用 LLM 来模拟给定指标上的“公正裁判”。
什么是 LLM-as-a-Judge?
在 LLM-as-a-judge 方法中,LLM 会接收用户查询、你的 RAG 应用生成的响应,以及一组明确评估标准,例如“请从 1 到 10 分评估这份摘要的准确性、简洁性和连贯性”。随后,根据提供给它的具体 LLM 提示词,裁判会给出数字分数、类别评级,或详细文本批评来说明其评估理由。
使用 LLM-as-a-judge 的主要好处是灵活性。不同于传统指标,你可以用自然语言提示词为 LLM 提供自定义的、详细的评分准则。你可以指示它根据几乎任何你定义的标准,为 RAG 系统输出打分,例如简洁性、是否遵循特定人设、因果推理或创造力。例如,可以告诉一个 LLM judge:“扮演一位怀疑型专家,验证答案是否完全由所提供上下文支持,且不包含任何外推信息。” 它随后可以执行这个复杂、多维的指令,并按要求提供反馈。
总体而言,LLM-as-a-judge 已经成为评估领域中的强大工具。研究表明,例如 Lianmin Zheng 等人和 Krisztian Balog 等人的研究,在最佳配置下,顶级模型给出的判断与人类偏好高度相关。然而,这种有效性并不是“开箱即用”的保证;它是模型选择和提示词设计之间的微妙平衡。
性能细微差别
LLM judge 与人类直觉之间的一致性通常很高,但仍然高度依赖任务。一个 LLM 可能能以专家水准评估创意摘要,但在面对复杂数学推理的严格逻辑时表现不佳。
为了弥合这一差距,评估方法和模型本身一样重要。虽然对单个响应进行评分(pointwise)很常见,但让 judge 比较两个响应(pairwise)通常会带来更高稳定性,并与人类标准更一致。
内在偏见
尽管 LLM judge 很灵活,但它容易受到细微且通常不可见的偏见影响。最突出的是自指偏见,即模型偏好特定风格或语气,而不是原始准确性。解决这一问题很困难,通常需要在 LLM-as-a-judge 提示词中手动创建一个用于比较的“ground truth”。
更令人担忧的是高估偏见:LLM judge 可能表现出一种“亲 AI”倾向,潜在地高估来自 LLM 系统的输入表现,同时低估经典的、确定性的输入。
运维障碍:成本与延迟
除了输出质量之外,还有成本和延迟这些冷冰冰的现实。调用前沿模型 API 可能又慢又贵,使基于 LLM-as-a-judge 的指标比传统 ML 指标更加昂贵,也更耗时。
虽然 AI 发展趋势表明成本会下降、速度会上升,但目前这些因素使 LLM-as-a-judge 对大规模、迭代式测试周期并不现实,因为额外成本和延迟过高。
随机稳定性的挑战
也许最持久的障碍是不稳定性。由于 LLM 本质上是随机的,一个 judge 可能真的会“改变主意”,在不同运行中对完全相同的输入给出不同分数。这种非确定性使得可靠追踪 RAG 系统中的增量改进变得困难。
虽然开发者可以尝试通过将 temperature 设置为 0 或固定随机种子来强制确定性,但这些方法并不万无一失。实用的变通方案通常包括:
多次运行 judge 并取平均结果;
从主观打分转向结构化成对比较,以锚定模型逻辑。
LLM-as-a-Judge 中的自指偏见
使用 LLM-as-a-judge 时,要警惕自指偏见——这是一种 LLM judge 偏好模仿其自身训练数据、风格怪癖或冗长表达的输出的现象。由于许多 LLM 共享常见微调数据集,judge 可能仅仅因为一个答案“听起来像 AI”,就给它更高分,而不管其事实准确性如何。这可能制造危险反馈循环:
风格压倒内容
模型通常偏好礼貌、结构良好,但最终错误的“AI 腔”,胜过直白、准确、确定性的输出。
冗长陷阱
Judge 往往把长度等同于质量,奖励“废话”,惩罚简洁但正确的答案。
系统性盲点
如果 judge 模型有某个特定逻辑盲点,它很可能也无法惩罚被评估模型中的同类错误。
为了缓解这一点,你可能需要用人类验证过的“golden test set”校准 LLM judge,以确保你衡量的是性能,而不是自我映射。
LLM-as-a-Judge 如何工作
为了演示 LLM-as-a-judge 如何工作,我们来看下面的示例代码。它也可以在 GitHub notebook 中找到,用于创建一个 LLM judge,为事实性和答案相关性打分。这个示例类似于 Retrieval-Augmented Generation Assessment(Ragas)方法:
import os
import json
import re
from openai import OpenAI
client = OpenAI()
def evaluate_with_llm_judge(query, context, generated_answer, model="gpt-4o"):
"""
Uses an LLM to evaluate the quality of a RAG-generated answer.
Args:
query (str): The user's original query.
context (str): The context retrieved by the RAG system.
generated_answer (str): The answer generated by the RAG system.
model (str): The OpenAI model to use as the judge.
Returns:
dict: A dictionary containing the judge's scores and reasoning.
Returns None if the API call fails.
"""
if not client:
return {
"error": "OpenAI client not initialized."
}
prompt = f"""
You are an impartial judge evaluating the quality of an answer generated by
a Retrieval-Augmented Generation (RAG) system.
Your task is to evaluate the generated answer based on two criteria:
1. **Factuality**: Is the generated answer factually grounded in the
provided context? A faithful answer only uses information present in the
context and does not contradict it.
2. **Answer Relevance**: Is the generated answer relevant and helpful for
the given query?
You must provide a score from 1 to 5 for each criterion (1=Poor,
5=Excellent) and a brief explanation for your scores.
**Query:**
{query}
**Retrieved Context:**
{context}
**Generated Answer:**
{generated_answer}
Please provide your evaluation *only* in a valid JSON format with the
following keys: "factuality_score", "factuality_reasoning",
"relevance_score", "relevance_reasoning". Your response MUST be a single
JSON object and nothing else.
"""
try:
response = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": """You are an expert evaluator of
AI-generated text that responds only in valid JSON."""},
{"role": "user", "content": prompt}
],
temperature=0,
)
response_text = response.choices[0].message.content
# Clean up the response to extract only the JSON part.
# This handles cases where the model might wrap the JSON in
```json ... ```
json_match = re.search(r'{.*}', response_text, re.DOTALL)
if json_match:
json_str = json_match.group(0)
evaluation = json.loads(json_str)
return evaluation
else:
print("""Error: Could not find a valid JSON object in the model's
response.""")
print(f"Full response: {response_text}")
return None
except Exception as e:
print(f"An error occurred during API call or JSON parsing: {e}")
return None
如你所见,这个函数定义了一个提示词,明确告诉 LLM 你希望它做什么,也就是在这个例子中,为输入数据评分并解释评分。
下面是运行它时得到的内容:
evaluation_data = {
"query": "What is the boiling point of water?",
"context": """At standard atmospheric pressure, water (H₂O) boils at
100° Celsius (212° Fahrenheit).""",
"generated_answer": "Water boils at 100 degrees."
}
evaluation_result = evaluate_with_llm_judge(
item['query'],
item['context'],
item['generated_answer']
)
print(f"Query: {item['query']}")
print(f"Generated Answer: {item['generated_answer']}")
print(f"Factuality Score: {evaluation_result.get('factuality_score')}")
print(f"Factuality Reasoning: {evaluation_result.get('factuality_reasoning')}")
print(f"Relevance Score: {evaluation_result.get('relevance_score')}")
print(f"Relevance Reasoning: {evaluation_result.get('relevance_reasoning')}")
结果是:
Query: What is the boiling point of water?
Generated Answer: Water boils at 100 degrees.
Factuality Score: 4
Factuality Reasoning: The generated answer is mostly factually correct as it
states that water boils at 100 degrees, which aligns with the context. However,
it lacks the specification of the unit (Celsius) and the condition of standard
atmospheric pressure.
Relevance Score: 4
Relevance Reasoning: The answer is relevant to the query as it directly
addresses the boiling point of water. However, it could be more helpful by
specifying the unit of measurement and the condition under which this boiling
point is accurate.
现在我们已经理解了 LLM-as-a-judge 如何工作,以及它的一些限制,就可以深入实际 RAG 评估指标了。
RAG 评估指标
RAG 评估指标主要分为两类:检索指标和生成指标。在你的生产 RAG 系统中,检索指标告诉你向量搜索、混合搜索或重排序效果如何;而生成指标则让你洞察最终生成式 LLM 的有效性。
正如我们将看到的,有些指标使用传统数学技术计算,因此可以很容易地使用传统 MLOps 技术在生产中运行;而另一些指标使用 LLM-as-a-judge,因此需要额外考虑事项,我们会在“在生产中集成 RAG 评估”中强调。
GitHub 仓库包含本节中各种指标的示例。
检索指标
评估检索是诊断任何 RAG 应用最关键的一步。它归结为一个问题:“你的检索流水线是否准确地从源数据集中识别并获取了最相关 chunks,以回答用户查询?”
要计算传统信息检索(IR)指标,例如 precision、recall 和 F1-score,或 rank-aware 指标,例如 mean reciprocal rank(MRR)、mean average precision(MAP)和 normalized discounted cumulative gain(nDCG),你需要指定“golden chunks”(由人工整理的、排序后的相关 chunks 列表)。为每个查询生成和维护这些 golden chunks——尤其是在动态生产环境中——出了名地困难,并且通常不可行;随着源数据演化,ground truth 很快就会过时。
尽管如此,在回顾检索指标时,我们仍会先解释这些基础检索指标,因为它们在较小规模上很有用,然后再探索 UMBRELA 这类更可扩展技术。
基础检索指标:Precision、Recall 和 F1-score
Precision、recall 和 F1-score 是三个搜索评估指标,构成了检索评估的基础。我们先定义 precision 和 recall:
Precision@k
这个指标回答的问题是:“在我的检索器识别为最相关的前 k 个 chunks 中,有多少实际上是相关的?” 它衡量被检索上下文的信噪比,表示有多少无关信息被传给生成器:
precision@k = |{top-k 中的相关 chunks}| / k
当处理上下文窗口有限的 LLM 时,高精确率尤其关键,因为它确保这个宝贵空间被相关 chunks 填满。
Recall@k
这个指标回答另一个问题,即:“在整个数据集中所有与查询相关的 chunks 中,我的检索器在前 k 个结果里找到了多少?”
recall@k = |{top-k 中的相关 chunks}| / |{数据集中所有相关 chunks}|
这个指标衡量检索过程的完整性或覆盖度,表示可能漏掉了多少相关信息。
如你所见,这两个指标都依赖 top-k 中相关 chunks 的数量,这就需要我们前面提到的该查询对应的 golden chunks。
哪个更重要——precision 还是 recall?现实是,precision 和 recall 只是从不同角度评估检索系统质量:precision 关注找到的内容质量,而 recall 关注找到的相关项数量,相对于“本应找到的内容”。
Precision 和 recall 之间存在天然张力。系统可以通过简单返回大量 chunks 来轻松获得高 recall,但由于包含许多无关结果,precision 可能会显著下降。反过来,系统也可以只返回少数自己极有把握的 chunks 来获得高 precision,但这会损害 recall,因为它可能漏掉许多其他相关 chunks。这被称为 precision–recall trade-off。
F1-score@k 旨在通过提供一个单一、平衡的分数来处理这种张力:
F1-score@k = 2 × precision@k × recall@k / (precision@k + recall@k)
这个分数就是 precision@k 和 recall@k 的调和平均值。当检索相关 chunks(recall)和避免无关 chunks(precision)同样重要时,它很有用。
排名感知指标:MRR、MAP 和 nDCG
虽然 precision、recall 和 F1-score 是基础检索指标,但它们有一个明显限制:它们把 top-k 结果中的所有位置视为相同。在实践中,排名第 1 的相关 chunk 对 RAG 应用而言,可能比排名第 10 的相关 chunk 更有价值,尤其是在长提示词中可能存在“lost in the middle”效应时。
排名感知指标通过给出现在检索列表更靠前位置的相关 chunks 更高权重,来解决这一点。
Mean Reciprocal Rank(MRR)
MRR 是最简单的排名感知指标。它只关注找到的第一个相关 chunk 的排名。
对于每个查询,我们计算“位置 i 的倒数排名”:
rr_i = 1 / rank_i
其中 rank_i 是该查询第一个正确项的位置。如果没有找到相关项,则分数为 0。
一组 N 个查询的 MRR,是评估集中所有查询倒数排名的平均值:
MRR = (1/N) × Σ rr_i
它高度可解释,适合理想目标是快速找到一个好答案的任务。
Mean Average Precision(MAP)
MAP 提供了一个更全面的单值排名质量总结。对于单个查询,average precision(AP)的计算方式是,对每个位置的 precision 分数取平均:
AP_K = (1/N) × Σ Precision(k) · rel(k)
其中 rel(k) 表示位置 k 的条目是否相关,相关为 1,否则为 0。
然后,MAP 被计算为 U 个查询数据集上这些 AP 分数的平均值:
MAP = (1/U) × Σ AP_i
MAP 同时考虑 precision 和 recall,因为它专门在找到相关项的位置上平均 precision;因此,它会严厉惩罚把相关项排在较低位置的检索流水线。当存在多个相关 chunks 时,这使它成为整体检索质量的稳健衡量指标。
Normalized Discounted Cumulative Gain(nDCG)
nDCG 是最复杂也最灵活的排名感知指标。和 MAP 一样,它考虑相关 chunks 的位置,但其关键优势在于能够处理分级相关性。这意味着 chunks 可以被分配一个尺度上的相关性分数,例如 0 = 无关,1 = 相关,2 = 高度相关,3 = 完全相关,而 MAP 或 MRR 无法做到这一点。
计算包含几个步骤。首先,我们定义位置 K 上的 DCG(discounted cumulative gain):
DCG@K = Σ(i=1 到 k) (2^rel_i - 1) / log2(i + 1)
其中 rel_i 是相关性分数尺度,例如 0–3。
现在假设我们有一个参考“理想排名”,称为 iDCG;那么,我们定义 nDCG 如下:
nDCG@K = DCG@K / iDCG@K
换句话说,nDCG 是位置 K 上实际 DCG 与理想 DCG 的比值。
MRR、MAP 和 nDCG 这类排名感知指标,是为了在检索指标中引入排名敏感性而开发的。MRR 是其中最简单的,只关注第一个相关结果的位置,因此适合目标是快速找到一个好答案的任务。MAP 提供更稳健的评估,它会在每个相关文档出现的位置平均 precision,从而奖励不仅找到多个相关项,而且将它们排得更高的系统。
最后,nDCG 是最强大的指标,因为它不仅奖励更高排名,还可以纳入不同程度的相关性,例如“完全相关”与“有些相关”,因此是评估复杂检索流程的黄金标准。不过,对于只从检索流水线中包含前三个或前五个 chunks 的小规模应用,nDCG 通常有些过度,MRR 或 MAP 这类更简单指标通常就足够了。
UMBRELA 分数
到目前为止,我们讨论的所有指标,如 precision、recall、MRR 或 MAP,都有一个显著实践挑战:很难为评估中的每个查询整理“相关 chunks”,也称为 golden chunks。
创建 golden chunks 是一项人工、耗时的任务,在大型、动态或生产规模的 RAG 应用中通常几乎不可行。这推动了无参考检索评估方法的发展,例如 Open RAG Eval 中实现的 UMBRELA。UMBRELA 不再把检索 chunks 与静态 golden set 比较,而是采用 LLM-as-a-judge 方法,由 judge 评估每个被检索 chunk 对回答查询的相关性。
使用专门提示词时,LLM judge 会评估给定 chunk,并根据以下标准分配分数:
0 = 无关,表示该 chunk 与查询无关;
1 = 有关联,表示该 chunk 触及主题,但不包含真正答案;
2 = 高度相关,表示该 chunk 包含某些答案,尽管答案可能不清楚,或隐藏在无关文本中;
3 = 完全相关,表示该 chunk 专门用于精准回答查询。
UMBRELA 成功的一个关键方面在于,正如前文引用的 UMBRELA 论文所示,这些由 LLM 生成的分数与人类评估者给出的分数高度相关,从而验证了它作为检索评估方法的稳健性。
请记住,某个 chunk 的原始 UMBRELA 分数(0–3)本身就是一个强大、直接的相关性指标,但它也可以作为输入,用于 precision 或 nDCG 等排名感知指标。不过,使用 UMBRELA 计算 recall 很有挑战,因为你需要为数据集中每一个 chunk 计算 UMBRELA,这对大型数据集而言可能在实践上不可行。
采用 UMBRELA 风格的方法,意味着你实际上是用更高计算成本和推理延迟,换取减少人工标注工作。这使 UMBRELA 最适合这样一种生产环境:chunks 太动态或太庞大,导致人工专家无法持续标注,但预算允许必要的 LLM API 调用。
让我们看看如何计算 UMBRELA 分数。UMBRELA 使用的精确提示词如下,参见示例 notebook:
UMBRELA_PROMPT = """
Given a query and a passage, you must provide a score on an integer scale of 0
to 3 with the following meanings:
0 = represents that the passage has nothing to do with the query,
1 = represents that the passage seems related to the query but does not
answer it,
2 = represents that the passage has some answer for the query, but the
answer may be a bit unclear, or hidden amongst extraneous information and
3 = represents that the passage is dedicated to the query and contains
the exact answer.
Important Instructions:
Assign category 1 if the passage is somewhat related to the topic but not
completely, category 2 if the passage presents something very important related
to the entire topic but also has some extra information, and category 3 if the
passage only and entirely refers to the topic.
If none of the above satisfies, give it category 0.
Query: {query}
Passage: {chunk}
Split this problem into steps:
Consider the underlying intent of the search.
Measure how well the content matches a likely intent of the query (M).
Measure how trustworthy the passage is (T).
Consider the aspects above and the relative importance of each, and decide on a
final score (O). The final score must be an integer value only.
Do not provide any code in the result. Provide each score in the format of a
single integer without any reasoning.
"""
作为例子,想象我们有如下查询和被检索 chunks:
query = "How does photosynthesis work in plants?"
chunks = [
"Photosynthesis is the process used by plants, algae, and certain bacteria
to convert light energy into chemical energy, through a process that
converts carbon dioxide and water into glucose and oxygen.",
"Chlorophyll, the pigment that gives plants their green color, is crucial
for absorbing sunlight in organelles called chloroplasts.",
"Mitochondria are known as the powerhouses of the cell, responsible for
generating most of the cell's supply of adenosine triphosphate (ATP)."
]
当我们计算 UMBRELA 分数时,得到:
- Score 3 for chunk: 'Photosynthesis is the process used by plants, algae, and
certain bacteria to convert light energy into chemical energy, through a process
that converts carbon dioxide and water into glucose and oxygen....'
- Score 2 for chunk: 'Chlorophyll, the pigment that gives plants their green
color, is crucial for absorbing sunlight in organelles called chloroplasts....'
- Score 0 for chunk: 'Mitochondria are known as the powerhouses of the cell,
responsible for generating most of the cell's supply of adenosine triphosphate
(ATP)....'
这符合我们的预期。第一个 chunk 为用户查询提供了精确答案,因此得到 UMBRELA 分数 3。第二个 chunk 包含与查询相关的信息,因此得到 2 分;第三个 chunk 与光合作用无关,因此得分 0。
UMBRELA 方法使评估从人工标注 ground truth 转向动态、AI 驱动的判断,并使检索评估变得可扩展、自动化,并几乎适应任何查询和文档集合。接下来在“生成指标”中,我们会看到类似方法 AutoNuggetizer,下一节会进一步介绍它。
生成指标
高质量检索器为好答案提供必要原料,但并不保证一定产生好答案。生成器 LLM 必须有效地将被检索上下文综合成一个响应,该响应需要在事实上保持一致,直接回答用户查询,并最终正确且有帮助。
因此,核心问题是:“生成式 LLM 是否有效且恰当地使用所提供 chunks,为用户查询生成高质量响应?”
虽然答案必须回答用户查询并且事实可靠,但全面评估还必须审查答案是如何构造出来的。这需要更深入地观察生成响应与其获得的检索 chunks 之间的关系,以及文本自身的内在质量。
评估生成时,有几个关键指标可使用。
上下文利用
上下文利用衡量生成器使用被检索上下文中可用信息的有效性和完整性。上下文利用高分表示生成器高效且彻底,能够使用所有必要事实综合响应,而不会被无关细节分散注意力。
当 LLM 响应包含行内引用时,可以通过观察哪些上下文项(从这些引用中可以看出)被用于形成 RAG 响应的具体部分,来部分观察上下文利用情况。一种更严格的方法是 AutoNuggetizer 指标(见 “Open RAG Eval”),其工作方式如下:
Nugget 生成和分类:系统生成 “nuggets”,即与给定查询相关的原子事实或信息片段。这是通过同时分析查询和相关 chunks 完成的。生成这些 nuggets 后,系统会按重要性对其分类:
“Vital” nuggets 是被认为对全面且正确答案至关重要的事实。一个好的响应必须包含这些 nuggets。
“OK” nuggets 是相关且有助于增加细节的信息,但它们并非答案被认为正确所严格必需的。
建立分类后的 nuggets 后,第二阶段会评估语言模型实际生成的答案。对于每个生成答案,AutoNuggetizer 会判断它覆盖 nuggets 的程度:
Supported:答案完整且准确地包含 nugget 中呈现的事实。
Partially supported:答案包含 nugget 中的一部分信息,但可能不完整或不完全准确。
Not supported:答案完全不包含 nugget 中的信息。
最后,这些支持判断会被打分并聚合,生成对模型响应的整体评估。
答案准确性
答案准确性通常包含两个主要指标:答案相似度和答案相关性。
答案相似度会比较 ground truth answer 和生成答案,例如使用 BERTScore 或 ROUGE-L,这两种是计算两个字符串之间语义相似度的公认方法;而答案相关性评估生成答案与原始问题的相关程度,会惩罚不完整或包含冗余信息的答案。
重要的是,答案相似度和答案相关性都需要“golden answer”才能工作,而上下文利用(通过 AutoNuggetizer)和忠实性则不需要。
忠实性
忠实性(或事实一致性)衡量生成响应在多大程度上基于所提供 chunks,是评估 RAG 幻觉的关键指标。RAG 幻觉指生成器编造了被检索 chunks 中不存在的信息。如果响应中的每一条陈述都可以直接从被检索 chunks 中验证,则该响应被认为是忠实的(或事实一致的);如果模型在响应中超出了被检索 chunks 所提供的信息进行外推,则被认为是幻觉。
事实一致性可以通过对 HHEM 这样的幻觉检测模型进行简单调用来衡量,也可以使用 LLM-as-a-judge。
引用准确性
许多 RAG 系统会在响应中提供行内引用,你的应用也可能如此。引用准确性衡量你的引用是否可靠,以及是否正确反映它们嵌入在响应中的对应部分。
最常见形式是引用精确率,它衡量针对某个具体陈述所引用的来源是否真的支持该陈述。当模型生成一个句子并附上引用时,用户应该能够点击该链接,并轻松找到支持证据。高精确率意味着系统正确地将生成陈述归因到正确源文档,或文档中的 chunks,从而防止错误归因,并让验证过程顺畅。
在生产 RAG 评估中,你总是希望拥有大多数甚至全部这些指标,以便理解提供给 LLM 的 chunks 是否被高效用于生成准确、有帮助、可靠的终端用户答案。
响应一致性
响应一致性衡量的正是这个名字所暗示的内容:如果你让同一个查询多次经过 RAG 查询流程,得到的是同一个答案,还是不同答案?
为什么你的 RAG 流水线每次运行同一个查询时,答案会不同?主要原因之一是 LLM 是非确定性的,即使你把 temperature 设置为 0,它也可能在相同提示词和检索流水线中相同 “top k chunks” 下返回不同答案。
系统性衡量响应一致性,是任何生产级 RAG 应用的基础要求,它提供关于响应可预测性的洞察。由于语言模型的概率性质,措辞上的轻微变化是可以接受的,但响应的事实内容应该保持稳定。
在金融、医疗或法律服务等受监管行业中,一致性是必要条件,因为这些领域要求高度信任、可审计性和合规性。如果 RAG 系统对同一查询提供不同的金融建议或医疗信息,它就会变成一个不可靠且可能不合规的工具。
偏见与安全
你可以扩展 RAG 评估,将安全护栏直接集成到评估过程中,从而提供一个关键安全检查点。这涉及主动筛查被检索数据 chunks 和最终生成答案中的特定不良特征,以及响应中的偏见或歧视。
一种常见方法是纳入专门安全模型,例如 ShieldGemma 或 Llama Guard,用来标记给定响应中的安全或偏见问题。
Llama Guard 主要被设计为基于文本的安全分类器,用于监控和过滤 LLM 驱动对话中的内容。它的角色是在用户提示词和模型输出被处理或显示之前,扫描其中是否存在安全政策违规。Llama Guard 可以识别并标记不安全类别,例如仇恨言论、性内容(可能涉及未成年人)、鼓励自伤、恐怖主义相关内容,以及明确煽动暴力。
ShieldGemma 被设计为多模态安全模型,能够根据可定制安全政策审核文本和图像。在文本模式下,它与 Llama Guard 类似,但它的多模态能力使其也可以用于输出混合图片和文本的 RAG 应用。
最终,这类模型让你可以调优检索和生成步骤,以排除有问题的源数据,或拒绝生成不适当响应,确保模型在真实世界应用中负责任地运行。
正如我们已经看到的,RAG 评估中可以使用许多指标,覆盖检索和生成。有些需要 golden answers,有些则不需要。事实一致性可以说是生成器评估中最关键的维度,因为 RAG 的主要承诺是让 LLM 响应基于可验证事实,从而降低幻觉风险。
除了把自动安全模型用于评估之外,红队测试也提供了一种关键的人在回路方法,用来压力测试 RAG 系统中隐藏的偏见。
这个过程涉及专门团队或个人扮演对抗者,有意构造提示词和场景,以诱发有偏或不公平响应。红队会以非常规方式探测漏洞,使用细腻语言、文化语境或复杂伦理困境,试图发现自动指标在评估检索和生成时可能遗漏的内容——例如,你的系统是否过度依赖反映单一视角的一组文档(以及因此产生的 chunks),或生成了微妙强化有害刻板印象的语言?
从红队测试中获得的洞察,对迭代改进非常宝贵。当红队成功诱发有偏响应时,可以用它创建更健壮的安全过滤器,修改 LLM 提示词以避免特定类型的有偏语言,甚至指导调整被摄取进 RAG 应用的底层数据,以确保其更加多样且具有代表性。
下一节,我们会查看一些现有 RAG 评估产品,看看它们各自提供哪些指标。
RAG 评估产品
你当然可以构建自己的 RAG 评估系统,但这样做可能需要大量工作。幸运的是,评估工具生态正在快速成熟,你可以从一系列强大的开源框架和商业工具中选择。
它们之间的选择通常归结为灵活性和控制(开源)与易用性和托管基础设施(商业)之间的取舍。在本节中,我们会探索每类中一些最突出的产品,帮助你决定哪种方法适合你的项目。
Open RAG Eval
Open RAG Eval 是 RAG 评估领域的一个新近成员,它最知名的特点是引入了无参考指标,不需要 golden chunks 或 golden answers。
Open RAG Eval 由 Vectara 与滑铁卢大学研究人员合作开发,旨在克服为大规模、真实企业级 RAG 应用创建和维护 ground-truth 数据集所带来的巨大困难与成本。
为了实现无参考目标,该框架集成了新颖且有研究支撑的指标,其中大多数我们已经在“RAG 评估指标”中讨论过:
UMBRELA
一种无参考指标,使用 LLM-as-a-judge 通过 0–3 分尺度评估上下文相关性,从而评估整体检索性能。
AutoNuggetizer
一种自动事实核查方法,会将被检索 chunks 分解成事实 “nuggets”,然后评估这些基本 nuggets 是否反映在生成响应中。这提供了对 groundedness 和上下文利用的细粒度衡量。
幻觉分数
利用 Vectara 的 HHEM 模型,量化生成答案中不被检索上下文支持的信息。
引用指标
量化响应中包含的引用是否确实被其引用的源文档和 chunks 支持。
一致性指标
量化其他四个指标中任意一个的一致性。通过让你的 RAG 系统运行 N 次,可以衡量任一指标结果的均值和标准差,并衡量其一致性。
要使用 Open RAG Eval 评估你的 RAG 系统,首先需要创建一个查询列表。重要的是,只需要查询,不需要 golden answers。
Open RAG Eval 提供灵活的 connector 架构。如果你的 RAG 应用尚不被支持,可以轻松创建一个 connector;也可以使用已有的 Vectara、LangChain 或 LlamaIndex connector。你还可以从 RAG 系统中手动收集数据,放入 JSON 文件,然后直接喂给 Open RAG Eval。
运行评估时,你需要创建一个 YAML 配置文件,定义 queries 文件的位置、要使用的 connector,以及希望包含的评估指标类型。
评估完成后,你可以查看生成的 JSON 文件来深入探索结果,也可以使用 Open Evaluation,如图 6-1 所示。
图 6-1 展示了 Open Evaluation 应用界面示例,该界面显示了与不同收入相关查询有关的、经过一致性调整的 relevance、groundedness、factuality 和 citation 指数分数。
图 6-1 Open Evaluation 的示例用户界面——一个用于可视化 Open RAG Eval 输出的应用,帮助更好理解 RAG 检索、生成、groundedness 或引用问题
Open RAG Eval 的主要优势在于其无参考 RAG 评估的新颖方法,以及简洁且完全开源的实现,它提供了完全透明性和可扩展性。
Retrieval-Augmented Generation Assessment
Ragas 是 Retrieval-Augmented Generation Assessment 的缩写,是另一个开源 RAG 评估框架。Ragas 主要使用 LLM-as-a-judge 方法,并包含一大组指标,既覆盖 RAG,最近也覆盖 agentic workflows。
使用 Ragas 的典型工作流包括创建一个评估数据集,通常结构化为 Hugging Face dataset。该数据集必须包含 question、generated answer 和 retrieved contexts 这些列,也可以包含带有正确答案的 ground_truth 列。
数据集准备好后,会被传给 ragas.evaluate() 函数,该函数管理必要的 LLM 调用,以计算并返回指定指标的分数。
Ragas 的一个主要优势,是它与 LangChain 和 LlamaIndex 等流行库集成。一个尤其强大的功能是,它可以从一组文档中合成生成测试集,当没有现成测试集时,这有助于启动评估过程。不过,合成数据集必须谨慎使用,因为它们可能无法准确代表你的用户查询或你想评估的具体文档。
尽管 Ragas 有优势,但 Ragas 及其指标的内部工作方式可能有些难以理解,这会使诊断低分的具体原因变得困难。此外,它不提供任何无参考指标,因此对人工生成 golden datasets 的要求较高。
DeepEval
DeepEval 是一个开源评估框架,其核心理念是像单元测试一样对待 LLM 评估。
DeepEval 中的典型工作流从根本上说是以代码为中心的,设计上让使用 pytest 这类测试框架的开发者感到熟悉。开发者不是一次性评估整个数据集,而是定义单独的 LLMTestCase 对象。随后,这些测试用例会在测试函数中使用 deepeval.assert_test() 进行评估,该函数检查输出是否满足预定义指标阈值。
通过这种方法,你可以为特定行为和边界情况编写显式测试,就像为传统代码编写单元测试一样。
DeepEval 的一个主要优势,是与 pytest 框架紧密集成,使其特别适合 CI/CD 流水线中的自动化回归测试。
与 Ragas 类似,DeepEval 提供一套全面指标,超过 14 种,包括 faithfulness、answer relevancy、contextual recall 等。
DeepEval 还提供 G-Eval 指标,允许基于自定义标准进行评估。G-Eval 的主要优势是灵活性;你不再受限于一组固定指标。如果你需要评估某些非常主观或特定于领域的内容,G-Eval 允许你为其创建自定义且可靠的指标。
Amazon Bedrock
Amazon Bedrock 提供完全托管服务形式的 RAG 评估,旨在 AWS 生态内直接提供可扩展的端到端解决方案。
其工作流围绕创建一个 “evaluation job” 展开,用户会选择一个强大的基础模型,例如 Anthropic 的 Claude,作为 LLM-as-a-judge。这个 job 可以配置为单独评估检索组件,也可以评估完整的 retrieve-and-generate 流水线。
与 Ragas 和 DeepEval 类似,在检索阶段,使用 AWS Bedrock 的框架可以评估 context relevance 和 context recall,以确保找到正确的信息。
在生成阶段,它通过 faithfulness(用于检测幻觉)和 correctness(当有 ground-truth answer 可用时)等指标衡量质量。
Bedrock 的一个重要能力是内置支持负责任 AI 评估。它会自动在 harmfulness、stereotyping 和 answer refusal 等维度上为响应打分。这种同时关注质量和安全的双重点,为 RAG 应用的真实世界表现提供了更整体的视角。
Bedrock 的主要优势在于,它提供托管服务的便利性和可扩展性,消除了团队构建和维护自己评估基础设施的需要。它与 AWS Guardrails 等其他 AWS 服务的深度集成,创造了一种连贯的开发和治理体验。
然而,作为商业平台,它会带来与 judge 模型使用相关的运营成本;并且相比开源框架,它对底层评估提示词的透明度较低。
总结来说,自动化 RAG 评估有不少开源和商业产品,每个都有自身优缺点。一个经常被忽视的东西是真实用户(人类)反馈;接下来我们讨论这一点。
人类反馈
尽管 RAG 自动评估取得了显著进步,人类判断仍然是有价值的输入,因为自动指标可能难以处理细微差别、复杂用户意图,以及与细腻人类价值观的一致性。
最显而易见的方法之一,是在 RAG 应用中集成点赞/点踩按钮,并从自己的终端用户收集这些反馈,以理解他们对响应的满意度。
你不是只依赖代理指标或自动指标,而是使用用户显式反馈来计算用户满意度分数或接受率。这会成为你的主要关键绩效指标。
基础公式很简单:
User Satisfaction Rate = 点赞数量 / (点赞数量 + 点踩数量)
要使用这种方法,首先需要设置 RAG 应用,使其记录每次交互,并捕获与之关联的反馈。例如,你可以记录包含以下字段的事件:
交互的唯一 ID;
用户提示词;
被检索上下文(文档或文本 chunks);
最终生成答案;
用户反馈,例如点赞、点踩;
时间戳和其他元数据,例如 user ID、session ID。
一旦开始收集这些数据,你就可以计算几个强大的指标:
整体满意率
也就是上面提到的高层 KPI。它为你提供性能的鸟瞰视角。
按主题/类别划分的满意率
这更有洞察力。你可以对 prompts 分类,例如使用关键词匹配、嵌入或简单分类器,来查看 RAG 系统在哪些主题上处理得好,哪些主题上处理得差。
例如,你可能发现产品功能问题的满意率为 95%,但账单问题只有 60%,这表明你的账单知识库文档存在问题。
相关性分析
将用户满意度分数与你的自动 RAG 评估指标进行比较,例如 faithfulness 或 answer relevance。
例如,低 faithfulness 分数是否与点踩评级强相关?如果是,你的自动指标就是用户满意度的良好代理。如果不是,你的自动指标可能具有误导性。
失败分析
分析收到最多点踩反馈的交互,以识别表现最差的输出,确定根因,例如检索不佳、幻觉、格式糟糕,并优先修复。
把点赞/点踩反馈作为直接评估来源,是生产 RAG 系统的最佳实践。关键是为你的 RAG 应用埋点以捕获反馈,然后建立一个流程,定期审查最有问题的查询或主题,分析糟糕响应的原因,并修复问题。
现在你已经了解了 RAG 评估中可使用的自动指标、人类反馈,以及该领域现有产品,就已经具备了部署所选 RAG 评估方案的能力。不过,当评估部署在真实生产环境中时,理解完整 RAG 评估生命周期很重要,接下来我们讨论这一点。
在生产中集成 RAG 评估
无论使用什么指标,一个成熟的 RAG 评估框架都必须支持两个基本任务:衡量和调优。
衡量
衡量是对 RAG 应用质量进行系统性监控。这是上线前的基线要求,并且必须在上线后定期执行。任何时候你升级组件、添加数据或更改配置,都必须衡量其对响应质量的影响。如果没有适当衡量机制,一旦性能退化,你就是盲目的,也无法在发现问题后知道该拉哪一个杠杆。
调优
调优是使用 RAG 评估主动改善性能的过程。RAG 技术栈有许多复杂且可配置的组件,例如切分策略、嵌入模型、检索算法、LLM 选择、提示词工程。运行实验、系统性改变这些配置,并使用评估框架识别哪种组合产生最高质量,是构建最先进 RAG 应用的关键。
将 RAG 评估框架集成进流水线,会把它从“黑盒”转变为可调系统。根据应用所处生命周期,你将通过两个不同周期使用衡量和调优:离线和在线。
离线评估是调优的主要引擎。你会根据固定 golden dataset,系统性衡量不同配置的影响,例如调整切分策略或更换嵌入模型。通过分析这些衡量结果,你可以调优 RAG 流水线中的每个组件,或按需添加组件,以实现更好性能。
上线后,在线评估开始发挥作用,成为早期预警系统,监控调优后的模型在真实世界用户意图不可预测性下的表现。
在生产中使用 LLM-as-a-Judge
由于 LLM-as-a-judge 对许多 RAG 评估指标都很重要,因此必须用与应用本身相同的运维严谨性对待你的 LLM judge。因为 LLM-as-a-judge 实际上是一次二级模型调用,它会以增加成本和延迟的形式,给你的开发周期引入一种“税”。
如果你在在线评估中实现 LLM-as-a-judge,实时评估每一次用户交互是很少见的。相反,你可以实现批处理策略,或只在有代表性的流量样本上运行评估。
除了成本,可观测性和可审计性对 LLM judge 本身也很重要。由于 LLM judge 可能不一致或有偏见,你必须记录每个输入(查询、上下文和答案),以及 judge 的完整推理、最终分数和输出。这些元数据允许你随时间审计 judge 的表现;如果利益相关者质疑为什么系统质量分数下降,你需要 judge 提供的文本说明来判断 RAG 系统是否真的退化,还是 judge 只是“状态不好”。将 judge 输出视为关键系统遥测,可以确保你的评估框架仍然是可靠事实来源。
最后,请记住,LLM judge 也是代码,因此应该相应地进行版本管理。随着产品演化,你的 LLM judge 提示词可能需要变得更严格,或关注新标准。如果不严格版本化提示词和用于评估的具体模型版本,你就会面临“evaluation drift”风险,也就是分数变化不是因为 RAG 系统变化,而是因为你的尺子变了。
离线 RAG 评估
任何成熟 RAG 评估框架都必须深度集成进 MLOps 生命周期,尤其是 CI/CD 流水线。在新组件——例如更新后的嵌入模型、新重排序器或改进后的提示词——部署到生产环境(或升级)之前,它必须通过一个“evaluation gate”。这个 gate 会把控质量,要求任何变更都必须针对基准数据集进行测试,以确保达到最低质量水平。
对于大多数生产系统,这意味着对关键指标执行“无回归”政策:例如要求 faithfulness 和 retrieval relevance 分数保持在某个阈值以上,或相对前一版本有所提升,同时确保 P95 延迟增加不超过 5%。
维护这个 evaluation gate 需要一个与应用共同演化的动态基准。随着产品范围扩大或新数据加入,你需要更新这个 benchmark set,以反映这些变化,通常会把困难的或失败的真实用户查询提升到测试套件中。这确保 evaluation gate 始终是具有代表性的门槛。
因此,建议像管理代码一样版本化这些 benchmark datasets,这样可以维护透明审计轨迹,并防止性能随时间漂移。
在线 RAG 评估
到目前为止,我们还没有大量介绍在线评估,因为本章主要聚焦离线评估。但现在,我们确实想分享一些相关想法。
正如本章前面提到的,在线评估——也就是在实时系统流量上执行评估——可以帮助你基于真实用户查询识别 RAG 系统问题,因此很好地补充离线评估策略。不过,正如你可能预期的,它也带来几个挑战:
缺少 golden datasets
一个主要障碍是缺少 golden dataset:不同于使用精心整理的问答对进行离线评估,真实世界用户查询是不可预测且多样化的。因此,为每个查询构造 golden answers 通常不可行,因为企业数据具有动态性——这使得为每次交互定义绝对 ground truth 变得困难。
成本和延迟
在每个查询上运行复杂的 LLM-as-a-judge(使用 Gemini 3 或 GPT-5 这类前沿模型)可能会让运营成本翻倍,并引入显著延迟。
为了让在线评估在不击穿预算、不拖慢 RAG 应用的情况下可行,我们建议远离“阻塞式”评估:不要让用户等待 judge 批准答案,而是实现一条异步评估流水线。在这种架构中,RAG 系统会立即交付响应,但后台 worker 会记录查询、上下文和答案,并在“带外”进行评估。这让你可以运行 UMBRELA 或 AutoNuggetizer 这类无参考检查,而不会给用户感知延迟增加一毫秒。
为了控制成本,你不需要评估 100% 的流量,而可以使用智能采样,只评估 5–10% 的交互,这通常足以提供统计上显著的系统健康视图。
对于高级在线评估,你还可以尝试 A/B 测试,这是持续改进的黄金标准。通过将一小部分用户路由到“challenger”流水线,例如包含新重排序模型或改进提示词的流水线,并将其表现与“champion”(当前)流水线比较,你可以直接回答这个问题:这个改变是否真的帮助了用户?通过把这些自动异步分数与实时人类反馈(例如“人类反馈”中讨论的点赞/点踩信号)结合起来,你可以创建一个强大的“evaluation flywheel”,在真实环境中捕捉回归,并把高价值失败案例提升回离线 golden dataset,用于进一步调优。
系统指标:延迟和正常运行时间
到目前为止,我们主要聚焦于衡量被检索 chunks 和生成响应的质量。除此之外,你也可以把标准 DevOps 和运维指标纳入 RAG 质量仪表盘。
这些指标至关重要,因为它们直接影响用户体验、可扩展性和 RAG 应用的经济可行性。一个能提供完美答案但速度很慢、经常不可用或成本过高的系统,最终仍然会失败。因此,延迟、吞吐量、正常运行时间和成本等指标,应在评估框架中被视为一等公民,确保系统不仅准确,而且在生产环境中健壮、高效、可靠。
与大多数生产中的任务关键型企业系统一样,需要考虑三个关键维度:延迟和吞吐量、可靠性和正常运行时间,以及成本和资源效率。
延迟和吞吐量
延迟衡量 RAG 系统处理用户查询并返回最终生成响应所需的时间。监控平均延迟以及尾部延迟(例如 P95 或 P99),有助于识别瓶颈,并确保持续响应良好的用户体验。
为了更精确地排障,你可以将端到端延迟分解成每个组件的指标,分别追踪检索器、重排序器和 LLM 的性能。通过监控每个阶段的值,你可以定位具体瓶颈,并在组件层面进行针对性优化。
与延迟密切相关的是吞吐量,通常以每秒查询数(QPS)衡量,它表示系统可以同时处理多少请求。这个指标对容量规划和理解系统在负载下表现至关重要。
可靠性和正常运行时间
正常运行时间是你的 RAG 应用可运行且用户可访问的时间百分比。高正常运行时间通常目标为 99.9% 或更高,是建立用户信任并确保服务可靠的基础。
与正常运行时间互补的是错误率,它追踪失败请求的频率,例如 HTTP 5xx 服务器错误或超时。错误率突然飙升可能表示 LLM API、向量数据库、重排序器、幻觉检测模型或其他基础设施组件存在底层问题。持续监控这些可靠性指标,对于维持健康稳定服务至关重要。
成本和资源效率
成本是任何 RAG 系统的关键运维指标,尤其是规模化运行的系统。它涉及监控每个组件相关费用,包括向量数据库、检索模型、重排序器、混合搜索,以及 LLM 提供商的 API 调用(通常按 token 定价)。
除了生产开销之外,RAG 评估本身也会引入第二层成本,因为使用 LLM-as-a-judge 的指标会消耗额外 token,从而引入额外成本。为了控制开销,评估不应是无差别覆盖全过程;相反,你可以在生产预算之外实现一个评估预算。这涉及一些战略选择,例如使用无参考指标,或在采样流量上运行昂贵评估,而不是对整个查询流运行。
除了直接成本,还必须追踪 CPU、GPU 和内存使用等资源利用指标。优化这些资源会直接转化为更低运营成本,并确保应用长期财务可持续。
这些系统考虑因素对成功至关重要。你可能拥有最好的检索流水线来创建相关 chunks,也拥有最好的 LLM 来生成响应,但如果用户持续遭遇应用宕机,他们最终就会停止使用它。
总结
评估 RAG 应用不仅是一项技术任务;它是构建可信、高性能、生产就绪 AI 系统的基本要求。正如你在本章中看到的,确保 RAG 中高质量响应横跨整条流水线。它从正确摄取合适文档开始,继续到拥有最先进的检索流水线,以确保检索正确 chunks,最后确保生成式 LLM 正常工作,生成基于检索 chunks 且对终端用户有用的响应。
RAG 流水线中的失败可能来自有缺陷的检索、带幻觉或不完整的生成,甚至来自摄取了过时或解析不当的文档。无论是在首次生产部署时,还是之后持续运行中,系统性识别和修复这些问题的唯一方式,都是一个设计良好的 RAG 评估框架。
本章向你介绍了 RAG 评估的完整光谱:
对于检索,你探索了 precision@k、recall@k 和 F1-score 等传统指标,以及 MRR、MAP 和 nDCG 等排名感知指标,它们会考虑相关性排序。
对于生成,你学习了如何衡量对上下文的忠实性、上下文利用、答案准确性、引用精确率和响应一致性。
我们介绍了 UMBRELA 和 AutoNuggetizer 等最先进的无参考方法,它们使不依赖人工标注数据集(也就是 golden answers)的可扩展评估成为可能。
我们讨论了生产级关注点,包括延迟、正常运行时间、成本监控,以及如何在真实世界条件下评估 RAG 系统。
你看到了人类反馈的作用,例如简单的点赞/点踩,作为一种直接捕获用户满意度的强大评估信号。
最后,我们考察了安全性、偏见评估、红队测试,以及不断增长的评估平台套件,包括 Open RAG Eval、Ragas、DeepEval 和 AWS Bedrock。
这些工具和技术结合起来,使你不仅能够衡量性能,还能主动改进性能。衡量和调优这两个双重目的,正是把 RAG 评估从被动的尽力打分任务,转变为战略性业务杠杆的关键。
RAG 评估不是一刀切的。有些使用场景会优先考虑高召回率;另一些则优先考虑忠实性和延迟。关键要点是:让指标选择与你的目标对齐,采用分层方法,将自动指标与真实世界人类反馈结合起来,并让评估成为系统生命周期中不可或缺、持续进行的一部分。
在下一章中,我们将从单查询 RAG 系统走向 agentic RAG,在那里,检索会成为更广泛的、目标驱动推理循环的一部分。
注 1:提醒一下,“lost in the middle” 指的是这样一种现象:当最相关信息位于长输入提示词中间位置时,LLM 性能会显著下降,因为模型倾向于优先关注开头或结尾的数据。不过我们也注意到,即便 “lost in the middle” 有真实影响,排名感知指标对 RAG 中生成式 LLM 的影响,远小于它们对阅读排序结果列表的人类的影响。换句话说,当人类阅读排序结果并试图理解时,更容易受到影响,例如出现某种“阅读疲劳”;而 LLM 更稳健,可以轻松忽略无关结果。