外观
RAG 评测与生产工程
目录
- 1. 学习目标
- 2. 面试结论
- 3. 面试官为什么问
- 4. 概念与边界
- 5. 原理剖析
- 6. 实现与代码
- 7. 实际项目案例
- 8. 方案权衡与常见误区
- 9. 面试题与参考答案
- 10. 递进追问
- 11. 实践任务
- 12. 相关知识与参考资料
- 13. 简明总结
1. 学习目标
- 建立覆盖语料、解析、检索、上下文、生成与系统运行的分层 RAG 评测体系;
- 能够推导 Recall@k、MRR、nDCG、引用精确率/召回率和拒答指标,并说清各自边界;
- 能够设计含可回答、无答案、冲突、时效、权限和攻击样本的评测集;
- 能够实现最小离线指标程序,并设计模型/Prompt/语料/索引联合版本门禁;
- 能够沿 Trace 诊断质量下降、索引陈旧、尾延迟、成本突增、缓存污染和越权泄露。
2. 面试结论
2.1 30 秒回答
生产级 RAG 不能用几个 Demo 验收。我会把评测拆成四层:语料与索引是否正确,检索是否召回必要证据,生成是否正确、忠实且引用完整,系统是否满足延迟、成本、安全和新鲜度要求。离线用固定且分桶的数据集做 Recall@k、MRR/nDCG、答案正确性、groundedness、引用和拒答评测;线上记录每层 Trace、SLO 和用户反馈。任何模型、Prompt、Chunk、Embedding 或索引变化都要带版本、回归门禁、灰度和回滚。
2.2 一分钟复述版
我会先定义评测样本契约:问题、是否可回答、必要证据 ID、参考答案或关键事实、权限域、时间版本和风险标签。然后把端到端失败归因:语料没有事实、解析丢失、检索没命中、正确候选被过滤或上下文截断、模型没有依据证据回答、引用错误,或者服务超时。检索层用 Recall@k、MRR、nDCG;生成层把 correctness 与 groundedness 分开,再评估引用正确性/完整性和无答案拒答;系统层看分阶段 p50/p95/p99、错误率、索引延迟、Token、缓存与安全事件。LLM-as-a-judge 可以扩展评测,但必须用人工样本校准、固定评审 Prompt/模型,并承认偏差。上线采用版本化离线门禁、影子或灰度流量、线上监控和可重放 Trace。
3. 面试官为什么问
- 核心考察点:是否能把概率系统变成可验证、可观测、可回归的生产系统;
- 对应岗位与级别:中高级 AI 应用、AI 后端和平台工程师;架构岗位会追问 SLO、数据版本、安全和事故复盘;
- 优秀回答的区分度:
- 能区分检索指标、回答指标和业务指标;
- 能设计无答案与权限测试,而不只收集成功问题;
- 能说明 LLM Judge 的校准、偏差与版本风险;
- 能从 Trace 重放中间候选和最终上下文;
- 能将线上事故沉淀为回归样本与发布门禁。
4. 概念与边界
4.0 小白先这样理解:侦探交卷前要过四道检查
侦探说“嫌疑人在仓库”,警长不会只问“结论像不像真的”,而会依次检查:案卷里是否存在这条事实、侦探是否找到了关键证物、报告中的每个判断是否由证物支持、整次办案是否及时且没有把机密泄露给无权人员。这里,案卷与证物对应语料和 Chunk,找线索对应检索,结案报告对应生成答案,证物编号对应引用,办案日志对应 Trace,时限与保密纪律对应 SLO 和安全门禁。
类比边界: 报告引用了证物,只能说明“有依据”,不保证证物本身真实或仍然有效;LLM 裁判也像另一位侦探,会受措辞和顺序影响。因此不能用一个总分代替分层指标、人工校准、版本回归、权限攻击样本与线上观测。
4.1 是什么
RAG 评测是对完整因果链的验证:
生产工程则把这条链变成:
- 可追溯:每个结果对应明确版本和证据;
- 可观测:每层有输入、输出、耗时和错误;
- 可恢复:超时、重试、降级、回滚和重建可控;
- 可治理:权限、隐私、安全、成本和审计有边界;
- 可演进:变更经过评测、灰度和反馈闭环。
4.2 不是什么
- 单一“答案准确率”不能说明失败在哪一层;
- 检索 Recall 高不等于答案忠实;
- groundedness 高不等于答案正确:模型可能忠实复述一份错误或过期文档;
- 引用了文档不等于引用支持对应主张;
- LLM Judge 不是绝对真值,可能受措辞、位置、模型和 Prompt 影响;
- 用户点赞不是完整质量标签,会有选择偏差、延迟和业务混杂;
- 线上无报错不代表无数据泄露或静默质量退化。
4.3 评测对象与责任边界
| 层 | 要回答的问题 | 典型证据 |
|---|---|---|
| 语料 | 事实是否存在、正确、当前有效 | source/version/owner/更新时间 |
| 解析 | 文字、表格、标题和位置是否保留 | parser 输出与原文抽样 |
| 索引 | 当前版本是否完整可查 | chunk/embedding/index build |
| 检索 | 必要证据是否进入候选并排序合理 | ranked chunks、Recall/MRR/nDCG |
| 上下文 | 正确证据是否真正进入模型输入 | final_context、Token 截断记录 |
| 生成 | 答案是否正确、忠实、完整、会拒答 | answer、claims、citations |
| 服务 | 是否及时、稳定、经济、安全 | latency、errors、cost、security events |
| 业务 | 是否改善用户任务 | 任务完成、人工接管、合规指标 |
4.4 输入、输出与前置条件
- 评测输入:带版本的系统配置、评测样本、检索 Trace、答案和引用;
- 评测输出:总体与分桶指标、置信区间或不确定性、失败样本、回归结论;
- 生产输入:查询、身份、当前语料和依赖服务;
- 生产输出:答案/拒答、引用、状态、用量和审计记录;
- 前置条件:
- 清晰定义“相关证据”和“可回答”;
- 评测集与训练/调参数据边界明确;
- 配置与数据版本可重放;
- 隐私和权限允许保存必要诊断信息;
- 发布标准来自业务风险,而不是照搬行业阈值。
4.5 离线、在线与人工评审的边界
| 方法 | 优点 | 局限 | 适合 |
|---|---|---|---|
| 确定性指标 | 快、稳定、可回归 | 依赖标注,难覆盖开放回答 | 检索、格式、引用映射 |
| 人工评审 | 能理解业务语义 | 成本高、有评审差异 | 高风险样本和校准集 |
| LLM Judge | 扩展快、可解释评分理由 | 偏差、漂移、成本、可能被答案诱导 | 大规模候选筛查与辅助评分 |
| 在线 A/B | 接近真实分布 | 归因慢、有业务与安全风险 | 已通过离线门禁的方案 |
| 用户反馈 | 真实任务信号 | 稀疏、选择偏差、含糊 | 发现样本和长期趋势 |
5. 原理剖析
5.1 评测集的样本契约
一条高质量样本至少包含:
- query_id 与用户问题;
- answerable:当前知识域能否回答;
- relevant_evidence_ids:回答所需证据,可为多个;
- reference_facts 或参考答案;
- allowed_scope:租户、角色、地区、产品版本;
- as_of_time 与 corpus_version;
- query_slice:精确实体、同义、多跳、否定、时效等;
- risk_tags:隐私、越权、提示注入、高风险操作;
- annotator 与审阅状态。
评测集来源应组合:
- 真实问题经脱敏与授权后抽样;
- 领域专家编写关键流程和高风险问题;
- 线上失败与事故样本;
- 系统化生成的边界变体,但必须人工抽查;
- 无答案、冲突文档、旧版本和越权反例。
不能把同一问题的轻微改写随机分到调参与最终测试两侧,否则产生评测泄漏。应按来源文档、意图簇或时间分割,并保留独立的发布门禁集。
5.2 检索指标
设查询集合为
Recall@k
适合检查必要证据覆盖。若多跳问题需要两个证据,命中一个不应算完整成功。
Precision@k
它衡量候选纯度,但当标注只覆盖“已知必要证据”而未穷举所有相关文档时,会低估真实精确率。
MRR@k
rank 是第一个相关结果位置。适合第一个证据最重要的任务,不适合评估多个必要证据是否齐全。
nDCG@k
适合分级相关性与完整排序。标注成本更高,且无相关证据时需预先定义该样本是否排除或记零。
Context Precision@k
本文采用便于工程落地的集合口径:经过融合、重排、去重、父块回填和 Token 截断后,最终送给模型的前 k 个上下文中,有多少真正支持回答:
其中 C_q^k 是 final_context 中实际保留的前 k 个 Chunk。它与候选阶段的 Precision@k 不同:前者评估模型真正看到的上下文纯度,后者评估某一召回或排序阶段的候选纯度。如果实际只放入 3 个上下文,分母应为 3,而不是机械写成 5。
部分评测框架中的 Context Precision 是考虑相关证据出现顺序的排名敏感指标,并不等于上式的简单比例。项目必须记录评测库、版本、公式和 Judge 配置,不能把两种口径混报。
四个带 K 指标如何区分
把一次检索想成图书管理员帮人找资料:先从书库拿出 20 本候选,再看前 10 本中第一本有用资料出现多早,然后检查前 5 本是否按价值排好,最后只把 5 份资料摊在答题桌上。四个指标分别检查不同阶段:
| 指标 | @K 的含义 | 回答的问题 | 单查询示例 | 主要盲区 |
|---|---|---|---|---|
| Recall@20 | 只检查前 20 个候选 | 所有必要证据召回了多少? | 共 4 个相关证据,Top20 找到 3 个,结果为 3/4=75% | 不关心证据排在第 1 还是第 20,也不惩罚噪声 |
| MRR@10 | 只在前 10 名寻找第一个相关结果 | 第一个正确证据是否足够靠前? | 第一个相关结果排第 2,本查询得分为 1/2=0.5;前 10 没有则为 0 | 只看第一个命中,后续必要证据全部缺失也可能很高 |
| nDCG@5 | 只评价前 5 名,并考虑分级相关性与位置折损 | 前五名的整体顺序是否接近理想排序? | 实际相关等级为 [0,2,3,0,1],理想顺序为 [3,2,1,0,0],前者会因高价值证据靠后而扣分 | 依赖可靠的相关等级标注,不直接衡量答案是否正确 |
| Context Precision@5 | 只检查最终真正交给模型的前 5 个上下文 | Prompt 里的资料有多少确实支持回答? | 最终 5 个 Chunk 中 4 个有用,结果为 4/5=80% | 不保证必要证据齐全,也不保证模型会正确使用证据 |
这里的 20、10、5 都是截断位置,不是百分比,也不是固定行业标准。它们通常对应不同漏斗深度:k_recall=20 保证候选覆盖,k_rerank=10 检查第一条有效证据的前排位置,k_context=5 约束最终上下文质量与 Token 成本。
若 1,000 条单证据问题中有 927 条在 Top20 找到必要证据,Recall@20 为 92.7%;多证据问题则应先逐题计算“找回证据数 / 标注证据数”,再做 Macro Average,若要求全部证据都命中,应另报 AllEvidenceHit@20,不能混叫 Recall。若 MRR@10 为 0.811,只能说明第一个相关结果整体很靠前,不能用 1/0.811 直接声称平均排名为 1.23,因为倒数是在每条问题上计算后再求平均;nDCG@5 为 0.842 表示前五名排序总体较接近理想顺序,不等于“准确率 84.2%”;Context Precision@5 为 78.9% 则可直观理解为最终五块上下文平均约有四块有用,但仍需结合必要证据覆盖率判断是否完整。
类比边界: 真实 Chunk 可能部分相关、相互重复或必须组合后才能回答,不能总按“有用/没用”二分。多跳任务还要先约定 Recall 使用逐证据平均、所有必要证据完整命中,还是至少命中一个的 HitRate 口径。
5.3 生成质量指标
5.3.1 正确性与忠实度
- Answer correctness:答案是否符合权威参考事实;
- Groundedness/Faithfulness:答案中的可验证主张是否由本次给定证据支持。
可将答案拆成可验证 claim 集
这是一个评测定义,不是自动真值。实际需要人工或 Judge 判断“支持”,并处理不可验证陈述、部分支持和推理结论。
四种组合说明为什么两者要分开:
| 正确性 | 忠实度 | 解释 |
|---|---|---|
| 高 | 高 | 证据正确且答案依据证据 |
| 高 | 低 | 可能靠模型记忆猜对,仍不可审计 |
| 低 | 高 | 忠实复述了错误、过期或不适用证据 |
| 低 | 低 | 检索/上下文/生成均可能失败 |
5.3.2 引用指标
把答案主张与引用的证据关系显式标注:
引用精确率防止“随便挂一个来源”,引用召回率防止关键事实无来源。还要检查引用 ID 是否映射到用户有权访问的当前文档版本。
5.3.3 拒答指标
把“应该拒答”视为正类:
精确率低表示误拒多,召回率低表示对无证据问题仍强答。阈值取决于业务风险:医疗、财务或权限场景通常更重视避免无依据回答,但具体目标必须由业务和合规确定。
5.4 LLM-as-a-Judge 的正确使用
Judge 适合开放文本的规模化辅助评测,但应:
- 给出明确 rubric 和每档定义;
- 提供 query、参考事实、实际证据与答案,而不是只看答案风格;
- 将正确性、忠实度、完整性分开评分;
- 用双盲人工校准集检查相关性和系统偏差;
- 固定 judge_model、judge_prompt_version 与采样设置;
- 对发布边界附近和高风险样本人工复核;
- 防止被评答案中的指令影响 Judge;
- 报告 Judge 不确定或分歧,而非强行产生单一分数。
不要用与被测系统完全同源且未经校准的模型作唯一裁判,也不要让更长、更礼貌的答案因为风格获得不应有的事实分。
5.5 系统指标与 SLO
质量以外至少记录:
- 分阶段 p50/p95/p99 延迟:查询处理、检索、重排、模型首 Token、完整生成;
- 请求成功率、超时率、限流率、重试次数、降级率;
- 输入/输出 Token、模型调用数、查询扩展倍数和成本;
- 缓存命中率、陈旧命中率与权限域;
- ingest lag、index build duration、index freshness、删除/撤权传播时间;
- 候选数、过滤数、最终上下文 Token 和引用数;
- 队列深度、并发、连接池和依赖错误;
- Prompt injection、越权、敏感数据和审计事件。
SLO 必须对应用户旅程,例如“请求成功”不能把返回空白或错误旧答案算成功。具体阈值需结合业务风险、基线和容量测试制定,本文不虚构通用目标。
5.6 可视化辅助
图 1:离线门禁、线上观测与失败回流闭环
替代文本: 版本化语料和系统配置先在离线评测集运行,未通过门禁则阻断;通过后进入影子或灰度发布。线上 Trace、系统指标、用户反馈和安全事件进入失败分桶,经人工复核后补入评测集,驱动下一轮修复与回归。
图表加载中…
读图结论: 评测不是上线前的一次考试,而是“版本门禁 → 灰度 → 观测 → 失败入库 → 回归”的持续控制环。
5.7 Trace 设计与版本矩阵
一条可重放 Trace 至少关联:
- request_id、timestamp、身份/租户的脱敏标识;
- raw_query、normalized_query、rewrite 列表;
- corpus_version、parser_version、chunker_version;
- embedding_model、index_version、retriever_config;
- 每路候选 rank/score、过滤原因、reranker_version;
- final_context 的 chunk_id、顺序、Token 和截断原因;
- model、prompt_version、输出、引用、refusal/status;
- 分阶段耗时、用量、缓存键版本、错误与降级路径。
高基数 ID 适合 Trace/日志,不应无界地进入指标标签。敏感原文按最小化、脱敏、加密、保留期和访问审计策略处理。
版本必须以一个可重放清单绑定,而不是只记 model 名:
任何一个元素变化都可能改变输出;评测报告和缓存键至少要包含影响结果的版本维度。
5.8 复杂度与评测成本
设有
- Recall/Precision/MRR 用哈希相关集计算约为
; - nDCG 计算同样约为
,另需理想相关性排序; - Claim 级忠实度取决于 claim 数
和证据长度,人工或 Judge 成本随总样本与 Token 增长; - 对每个候选版本重跑完整端到端评测,成本近似随版本数、样本数和模型调用数相乘;
- 在线保存完整 Trace 提升可诊断性,但增加存储、隐私与检索成本;
- Bootstrap 置信区间需要重复重采样,适合离线计算,不能用单一均值掩盖小样本波动。
因此可采用分层门禁:快速确定性单测 → 检索指标 → 小规模高质量 Judge/人工集 → 全量回归 → 性能与安全测试。高风险项不能因成本而完全省略。
6. 实现与代码
6.1 最小可运行指标程序
以下只依赖 Python 标准库,实现 Recall@k、MRR、nDCG@k、引用指标和拒答指标,并包含断言。
python
import math
from dataclasses import dataclass
@dataclass(frozen=True)
class EvalCase:
query_id: str
relevance: dict[str, int] # evidence_id -> graded relevance, 0 means irrelevant
retrieved: list[str]
def __post_init__(self) -> None:
if len(self.retrieved) != len(set(self.retrieved)):
raise ValueError("retrieved evidence_id must be unique")
if any(rel < 0 for rel in self.relevance.values()):
raise ValueError("graded relevance must be non-negative")
def recall_at_k(case: EvalCase, k: int) -> float:
if k <= 0:
raise ValueError("k must be positive")
relevant = {doc_id for doc_id, rel in case.relevance.items() if rel > 0}
if not relevant:
raise ValueError("Recall@k requires at least one labeled relevant item")
return len(relevant.intersection(case.retrieved[:k])) / len(relevant)
def reciprocal_rank(case: EvalCase) -> float:
for rank, doc_id in enumerate(case.retrieved, start=1):
if case.relevance.get(doc_id, 0) > 0:
return 1.0 / rank
return 0.0
def dcg(relevances: list[int]) -> float:
return sum(
(2 ** rel - 1) / math.log2(rank + 1)
for rank, rel in enumerate(relevances, start=1)
)
def ndcg_at_k(case: EvalCase, k: int) -> float:
if k <= 0:
raise ValueError("k must be positive")
actual = [case.relevance.get(doc_id, 0) for doc_id in case.retrieved[:k]]
ideal = sorted(case.relevance.values(), reverse=True)[:k]
ideal_score = dcg(ideal)
return dcg(actual) / ideal_score if ideal_score else 0.0
def citation_metrics(
claims_that_need_citation: set[str],
cited_claims: set[str],
claims_with_correct_citation: set[str],
) -> tuple[float, float]:
correctly_cited = cited_claims & claims_with_correct_citation
# Precision: 已引用的 claim 中,引用真正支持多少。
precision = (
len(correctly_cited) / len(cited_claims)
if cited_claims else 0.0
)
# Recall: 所有应引用 claim 中,多少有正确支持。
recall = (
len(claims_that_need_citation & correctly_cited)
/ len(claims_that_need_citation)
if claims_that_need_citation else 1.0
)
return precision, recall
def abstention_metrics(labels_should_abstain: list[bool],
predictions_abstain: list[bool]) -> tuple[float, float]:
if len(labels_should_abstain) != len(predictions_abstain):
raise ValueError("label and prediction lengths differ")
true_positive = sum(
label and prediction
for label, prediction in zip(labels_should_abstain, predictions_abstain)
)
predicted_positive = sum(predictions_abstain)
actual_positive = sum(labels_should_abstain)
precision = true_positive / predicted_positive if predicted_positive else 0.0
recall = true_positive / actual_positive if actual_positive else 0.0
return precision, recall
if __name__ == "__main__":
case = EvalCase(
query_id="q1",
relevance={"d1": 2, "d2": 1},
retrieved=["d3", "d1", "d2"],
)
assert recall_at_k(case, 2) == 0.5
assert reciprocal_rank(case) == 0.5
assert 0.0 < ndcg_at_k(case, 3) <= 1.0
citation_p, citation_r = citation_metrics(
{"claim-a", "claim-b"},
{"claim-a", "claim-c"},
{"claim-a"},
)
assert citation_p == 0.5
assert citation_r == 0.5
assert citation_metrics({"claim-a"}, set(), {"claim-a"}) == (0.0, 0.0)
try:
EvalCase("duplicate", {"d1": 3, "d2": 1}, ["d1", "d1"])
raise AssertionError("duplicate evidence_id should be rejected")
except ValueError:
pass
abstain_p, abstain_r = abstention_metrics(
[True, True, False, False],
[True, False, True, False],
)
assert abstain_p == 0.5
assert abstain_r == 0.5
print("all metric checks passed")6.2 关键实现说明
- 每个查询的
retrieved必须使用唯一、稳定的 evidence_id;重复结果会虚增 DCG、占用 Top-k,并可能让 nDCG 大于 1,因此示例在指标入口直接拒绝; - relevance 用非负分级整数支持 nDCG,Recall 只把大于 0 视为相关;
- 无相关证据的查询不适合计算普通 Recall,应进入 answerable=false 的拒答评测;
- MRR 查第一个相关证据,多跳完整性另用 Recall 或专门指标;
- Citation 指标需要 claim 与证据支持关系,
correctly_cited必须同时属于“实际已引用”和“引用正确”两个集合,不能只检查答案是否出现 [1]; - 拒答将“应拒答”设为正类,便于解释 precision/recall;
- 示例约定“系统从不拒答”时 Abstention Precision 为 0;正式报告应同时给出 TP/FP/FN 与样本量,避免把未定义边界藏在单个数值里;
- 生产报告应在查询级先算指标再聚合,并输出分桶、样本量和不确定性。
6.3 边界条件与验证
需要补充测试:
- 空 retrieved、k 大于结果长度和重复 doc_id;
- 多个必要证据只命中一部分;
- 无相关证据查询不误入 Recall 分母;
- 引用了错误版本但文本相似,应判引用不正确;
- 答案无任何可验证主张时,groundedness 的处理约定;
- Judge 与人工分歧时不静默覆盖人工标签;
- 指标聚合按 query 等权还是按流量加权,要在报告中明确。
代码可在无外部依赖条件下运行;它验证指标实现,不代表完整 RAG 评测平台。
6.4 技术栈与横向选型
评测框架只是执行和记录载体,指标定义、金标数据、人工复核和发布门禁才决定结论是否可信。下表保持三个主 TP,以控制本篇增量。
| 技术点 ID | 技术点/环节 | 类型 | 采用方案 | 链路职责 | 版本/证据边界 |
|---|---|---|---|---|---|
| TP-RE-01 | RAG 质量指标执行 | 评测框架 | Ragas 作快速基线;DeepEval 作同层候选;关键指标保留自定义实现 | 批量运行检索、忠实性、引用和端到端评测,输出分切片报告 | LLM-as-Judge 受评审模型和 Prompt 影响;框架 API 需按目标版本复核 |
| TP-RE-02 | 在线链路观测 | 协议/可观测平台 | OpenTelemetry 作中立 Trace 标准;LangSmith 作托管 AI 观测候选 | 串联 request、检索、重排、生成、引用与版本指纹,支持失败重放 | Trace 不应无界保存敏感 Prompt/原文;托管能力和定价会变化 |
| TP-RE-03 | 回归集与发布门禁 | 测试工具/CI | pytest + 版本化 EvalCase 作确定性基线;promptfoo 作多模型/Prompt 矩阵候选 | 重放固定失败样本,执行质量、安全、延迟与成本门禁 | 门槛必须来自业务风险和基线;本文不虚构通用通过线 |
| 技术点 ID | 候选方案 | 优点 | 缺点/代价 | 适用场景 | 不适用场景 | 选择结论与依据 |
|---|---|---|---|---|---|---|
| TP-RE-01 | Ragas | RAG 常见评测抽象集中,便于快速建立离线基线 | 高层指标不一定匹配业务,LLM Judge 存在偏差与成本 | RAG 原型、需快速建立检索/生成评测骨架 | 高风险结论只依赖默认指标与单一 Judge | 作首个执行基线,与金标指标和人工一致性对齐后使用 |
| TP-RE-01 | DeepEval | 断言、数据集和 LLM 评测流程面向测试工程整合 | 同样受 Judge、Prompt 和框架版本影响,需额外校准 | 希望把 AI 指标纳入测试套件与 CI | 业务指标只能通过自定义 SQL/标注计算 | 与 Ragas 在同一 EvalCase 上比较可解释性、稳定性与 CI 集成成本 |
| TP-RE-02 | OpenTelemetry | 开放协议,可同时连接 Trace、Metric 与日志后端 | AI 语义字段、重放 UI 和数据治理需自行设计 | 已有可观测平台、需中立协议与后端可替换 | 团队需开箱即用 AI 调试 UI 且无平台建设能力 | 作长期中立基础,只采集排障所需且已脱敏的字段 |
| TP-RE-02 | LangSmith | 面向 LLM/RAG 的 Trace、数据集和评测工作流集成 | 托管依赖、数据出域、成本与产品演进需评估 | 合规允许、希望快速获得 AI 专用调试与评测 UI | 严格本地化或必须保持后端中立 | 只在隐私、成本、导出与故障演练通过后作上层平台 |
| TP-RE-03 | pytest + 版本化 EvalCase | 确定性断言、数据指纹和 CI 失败语义清晰 | 多模型矩阵、报表和 Judge 管理需自行实现 | 关键黄金用例、权限与可用性回归 | 只需临时大规模比较且不想写执行器 | 作不可替代的确定性底座,AI 评分作额外信号 |
| TP-RE-03 | promptfoo | 声明式运行多 Prompt/模型组合,便于快速比较 | 关键业务状态、复杂数据准备和长链路故障注入仍需代码 | Prompt/模型矩阵、红队与快速候选比较 | 需模拟真实数据库状态机或精确事务语义 | 作矩阵比较工具,不替代 pytest 黄金用例与发布脚本 |
6.5 架构与技术调用流程
图:架构|RAG 评测控制面与线上证据回流
替代文本: 版本化 EvalCase 经评测运行器调用候选 RAG,指标层同时运行确定性指标与经校准 Judge,发布门禁控制灰度;线上 OpenTelemetry 或受审核平台收集脱敏证据,失败样本经人工复核后回流。
图表加载中…
读图结论: 评测不是上线前的一次报表,而是“固定回归—发布门禁—灰度观测—失败回流”的控制面。
架构图将线下决策与线上证据用相同版本指纹连接。未经脱敏与人工确认的用户反馈不应自动成为金标答案。
图:技术调用流程|RAG 候选从离线门禁到灰度回滚
替代文本: CI 调用评测运行器与候选 RAG,固定门禁失败立即阻断;通过后进入灰度,观测系统按同一指纹检查质量与系统指标,越界时自动停止扩流并回滚,只有成功灰度才提升别名。
图表加载中…
读图结论: 离线通过只是灰度的入场条件,灰度任一关键维度越界都必须停止扩流并恢复健康别名。
时序图明确了阻断、回滚与提升的状态所有者。为保持因果可归因,一次灰度不应同时更换模型、Prompt、语料、索引和重排器。
7. 实际项目案例
示例项目,非本仓库真实业务;所有阈值、规模和效果都需项目实测后填写。
7.1 背景、目标与约束
将内部运维知识助手从原型升级为生产服务。风险包括:
- 旧流程回答导致错误操作;
- 用户无权查看其他团队事故记录;
- 无答案问题被强行回答;
- 模型或索引更新造成静默回归;
- p95/p99 尾延迟和重试放大成本;
- 日志保存敏感 Prompt 或文档原文。
目标是建立质量门禁、可重放 Trace、灰度回滚和事故入库机制。
7.2 架构与调用链
图:评测闭环|RAG 离线门禁、在线观测与发布控制三泳道
替代文本: 离线泳道把语料、索引、模型和 Prompt 指纹绑定到候选版本并依次执行数据、检索、端到端、安全和性能门禁;发布泳道只让通过门禁的版本进入影子和灰度,越界时立即停止扩流或回滚;在线泳道记录分阶段 Trace、告警与反馈,经脱敏人工复核后把根因样本送回固定回归集。
图表加载中…
读图结论: 评测、发布和线上运行不是三张孤立清单;它们通过版本指纹、Trace、回滚和失败样本回流形成闭环,任何没有根因证据的异常都不能只靠调 Prompt 结束。
图中 Version Manifest 是跨泳道主键,应至少绑定语料、Parser、Chunk、Embedding、Retriever、Reranker、Prompt、Model、权限策略和评测集版本。这样线上异常才能重放到同一候选系统,而不是用已经变化的环境复现旧问题。
7.3 方案选择与工程约束
- 使用固定发布门禁集防止调参污染,同时维护滚动线上集观察分布变化;
- 检索与生成分开评分,减少根因混淆;
- 高风险问题必须规则或权威工具二次确认,不仅依赖 Judge;
- 缓存必须分层设计:Embedding 缓存绑定规范化文本与模型版本;检索/上下文缓存绑定 Query、corpus/index、检索器,以及由可信权限服务计算的完整 entitlement fingerprint 和 policy version,不能只用 tenant/role;
- 命中检索缓存后仍对候选文档重新授权;撤权、删除和权限策略变更必须主动失效相关缓存;
- 最终答案缓存还要绑定独立查询或会话状态、最终上下文哈希、Prompt/model 和回答语言;多轮回答不能跨会话直接复用;
- 重试只用于明确可恢复错误,指数退避并设总时间预算;写操作使用幂等键;
- Reranker 或主模型超时可降级,但响应需记录 degraded,不把降级结果混入正常指标。
7.4 技术难点与方案亮点
以下内容来自该示例项目的设计推演与验证方案,不代表已经发生过真实事故,也不声明未经实测的收益。
| 技术难点 | 为什么难 | 关键处理 | 验证证据或方式 |
|---|---|---|---|
| 端到端质量难归因 | 同一错误答案可能来自语料、解析、召回、过滤、截断、生成或引用映射 | 为每层保留稳定 ID、输入输出、版本和分阶段指标,支持从 request_id 重放 | 固定其他变量分别替换检索、上下文和生成版本,确认失败层能够被单独复现 |
| 多组件版本组合容易静默回归 | Corpus、Parser、Chunk、Embedding、Index、Retriever、Prompt 和 Model 任一变化都可能改变结果 | 用不可变版本清单绑定评测报告、缓存键和发布记录 | 同一门禁集重放旧版与候选版;影子流量、灰度和回滚演练能定位到具体版本差异 |
| 质量、延迟、成本和安全互相牵制 | 增大 Top-k、启用重排或保存完整 Trace 可能改善某一维度,却恶化其他维度 | 分层 SLO、风险分级门禁、总时间/Token 预算和敏感数据最小化 | 容量与故障注入测试同时检查质量分桶、Span 延迟、调用数、缓存和权限用例 |
| 方案亮点 | 要解决的问题 | 关键决策 | 验证证据或方式 | 适用边界 |
|---|---|---|---|---|
| 分层评测与可重放 Trace | 总分无法解释“为什么错” | 将语料、索引、检索、上下文、生成和服务拆开评测,并保存最终上下文与版本矩阵 | 控制变量重放失败 request_id,检索正确但生成错误等故障可稳定归层 | 依赖稳定 evidence_id、版本元数据和合规的 Trace 留存策略 |
| 版本化发布门禁 | 模型或索引升级可能无报错但质量下降 | 冻结门禁集,候选版本必须经过离线、影子、灰度和可回滚发布 | 候选版与基线按同一分桶比较;回滚后能恢复对应版本与缓存命名空间 | 门禁阈值必须由业务风险和实测基线确定,不能照搬通用数字 |
| 权限感知的分层缓存 | 缓存降低延迟,但可能复用旧版本或越权内容 | 缓存键绑定完整 entitlement fingerprint、policy 与数据/索引版本,命中后再次授权,撤权事件主动失效 | 跨用户 ACL、撤权传播、旧版本和降级结果隔离测试 | 对强会话状态、高风险实时事实或无法可靠失效的数据,应禁用或缩短缓存 |
| 线上失败回流为回归资产 | 固定离线集覆盖不了新分布和真实失败 | 失败样本脱敏、人工复核、标注根因后进入滚动评测集和发布门禁 | 修复前样本可复现、修复后通过,且相邻分桶无新增回归 | 需要处理隐私、反馈偏差和调参集污染,不能把未复核流量直接当真值 |
7.5 生产问题闭环:异常处理、监控与测试
下表是生产风险演练模板。每一行都要形成“现象 → 影响 → 证据 → 根因 → 止损 → 修复 → 验证 → 防复发”闭环;表中内容不是实际事故记录。
| 现象 | 影响 | 定位证据 | 可能根因 | 止损 | 修复 | 验证 | 防复发 |
|---|---|---|---|---|---|---|---|
| Recall 稳定但答案正确性下降 | 错答增加且检索指标无法告警 | request_id、final_context、Prompt/model 版本、截断记录 | Prompt/model 变更;证据顺序或截断改变 | 停止扩量,回滚生成版本或切换为引用式保守回答 | 重放 final_context,修 Prompt、上下文排序或冲突处理 | 固定上下文对比新旧生成;正确性和忠实度分开恢复 | 将失败样本、上下文长度和冲突证据加入门禁与告警 |
| 某类查询 Recall 下降 | 特定意图或实体问题无法获得必要证据 | query_slice、rewrite、各路候选、过滤原因、Embedding/索引版本 | 分词、rewrite、Embedding 或过滤回归 | 对受影响分桶回退检索配置,必要时启用可靠备选检索 | 按查询分桶逐路修复召回、过滤或索引配置 | 对应分桶 Recall/MRR 恢复,且其他分桶无回归 | 门禁强制报告分桶指标,不允许总体均值掩盖长尾 |
| 新文档长期查不到 | 用户读取旧知识,时效性任务不可用 | source_id、ingest 队列、解析产物、index build、别名和 freshness | ingest backlog、构建失败、别名未切换 | 标记知识陈旧,暂停依赖最新数据的回答或回退权威源 | 补偿重放失败任务,修构建/别名切换并重建缺失数据 | source 到 chunk/index 全链可查,index lag 恢复 | 建立摄取对账、新鲜度 SLO、死信队列和重建演练 |
| p50 正常、p99 激增 | 长尾请求超时,重试可能放大流量和成本 | 各 Span p99、队列深度、连接池、重试次数、依赖错误 | 队列拥塞、连接池耗尽、Reranker 长尾或重试风暴 | 限并发、停止无界重试、超时降级或熔断慢依赖 | 调整容量和超时预算,隔离慢路径并修重试策略 | 队列深度、各 Span p99、超时率和降级率回到基线 | 容量压测、重试预算、依赖隔离和尾延迟告警 |
| Token 或调用成本突增 | 预算超限并可能拖慢整体服务 | 单请求调用数、Query 改写数、上下文 Token、缓存命中和重试记录 | 多查询开启、上下文膨胀、缓存失效或重复重试 | 限制每请求预算,关闭非必要扩展,阻断重试风暴 | 修缓存版本、上下文裁剪和调用编排 | 调用数、Token、重试数和命中率按版本恢复 | 成本分解仪表盘、预算门禁和异常版本自动降级 |
| 无答案问题仍强答 | 产生无依据答案,高风险场景可能误导操作 | answerable 标签、候选相关性、最终上下文、拒答状态 | 拒答规则弱;Top-k 总返回噪声 | 切换为明确拒答或人工/权威工具兜底 | 增加最小证据门禁,校准 answerability 与拒答策略 | Abstention recall 恢复且误拒受控,高风险样本人工复核 | 无答案、冲突和旧版本样本持续进入发布门禁 |
| 引用存在但不支持答案 | 用户被错误来源误导,审计链失效 | claim-citation 映射、chunk_id/version、原文位置 | 引用生成与 claim 未对齐;引用指向旧版本 | 暂停自动引用或降低回答确定性,保留可核验来源 | 做 claim 级支持校验,稳定证据 ID 与版本映射 | Citation precision/recall 和抽样审查通过 | 引用映射单测、版本迁移检查和高风险人工复核 |
| 跨用户或跨权限缓存泄露 | 未授权内容暴露,形成安全与合规风险 | 缓存键、权限决策日志、entitlement/policy 版本、撤权事件 | 只按 tenant/role 隔离;撤权未失效;命中后未再授权 | 立即停用受影响缓存、清理命名空间、阻断相关流量并启动安全审计 | 完整权限指纹和策略版本入键,命中后二次授权,撤权事件主动失效 | 同租户同角色不同 ACL、撤权传播和审计用例通过 | 默认拒绝跨权限复用,权限回归纳入门禁并监控异常命中 |
| 离线全绿但线上质量差 | 发布门禁失去代表性,错误进入真实流量 | 线上 query_slice、失败样本、Judge/人工分歧、训练与评测来源 | 测试集泄漏、分布漂移或 Judge 偏差 | 停止扩量,回滚候选版本并加强人工抽检 | 重建独立门禁集,按新分布分桶并重新校准 Judge | 线上失败可离线复现,人工与 Judge 一致性报告达到项目门槛 | 时间切分、独立测试集、滚动线上集和定期校准 |
故障处理顺序:
- 先控制风险:停灰度、降级、禁用受影响租户或回滚;
- 固定失败 request_id 和版本清单;
- 从权威语料到 final_context 逐层重放;
- 明确根因层和影响范围;
- 修复并加入回归样本;
- 验证离线、影子、灰度和线上指标;
- 复盘为什么原门禁或告警未捕获。
7.6 结果与复盘
完成证据应包括:
- 评测集 Schema、标注指南和双人复核策略;
- 每个发布版本的检索、生成、性能与安全报告;
- 可从 request_id 找到完整版本和中间候选;
- 文档新增、修改、删除、撤权的端到端测试;
- 模型、检索、缓存和依赖故障的降级演练;
- 至少一次回滚演练与事故样本防回归验证。
面试表达重点是:“我没有只看端到端分数,而是把系统拆成可归因层;线上失败能通过 Trace 重放,修复后进入回归集和发布门禁。”
7.7 可复用经验卡
以下经验卡由架构分析和故障演练抽象而来,落地到真实项目时仍需用该项目的日志、指标、Trace 和测试结果补证据。
| 经验卡 | 核心规则 | 固化动作 | 验收证据 | 适用边界 |
|---|---|---|---|---|
| 先归因再调参 | 端到端错答不是“模型问题”的同义词 | 固定 request_id 和版本,从语料到 final_context 逐层重放 | 能指出第一个偏离预期的层,并用控制变量复现 | 若缺稳定 ID 或版本,需要先补观测,不能靠猜测归因 |
| 版本矩阵就是回滚单元 | 单记模型名无法重建一次 RAG 输出 | 将数据、解析、切块、Embedding、索引、检索、Prompt 和模型绑定为不可变清单 | 旧版可重放、候选版可比较、回滚后缓存和索引一致 | 外部动态数据还需记录 as_of_time 或权威快照 |
| 失败样本必须变成门禁 | 只修线上个例会让同类问题再次出现 | 脱敏复核、标根因、加入对应分桶和回归任务 | 修复前稳定失败、修复后稳定通过,并检查相邻分桶 | 未经复核的用户反馈不能直接当标签 |
| 权限隔离不能交给模型 | 模型拒答不是数据访问控制 | 在检索、缓存命中、文档读取和引用返回处执行可信服务端授权 | 跨用户、撤权、策略升级和缓存复用测试全部通过 | 权限事实必须来自认证/授权系统,而非 Prompt 或模型参数 |
| 降级结果单独治理 | “返回了答案”不等于达到正常质量 | 响应和 Trace 标记 degraded,使用独立指标、缓存命名空间和恢复条件 | 可区分正常/降级质量与 SLO,恢复后不复用降级缓存 | 高风险问题没有安全降级路径时应拒答或转人工 |
7.8 怎么回答:难点、亮点与生产问题
以下两段都基于本节的示例项目,只演示答题结构,不代表真实任职经历、线上事故或已经取得的业务收益。
7.8.1 30 秒专业短答示例
生产级 RAG 不能只看一个端到端总分。我会把语料与索引、检索、上下文、生成和服务分层评测,并用 request_id 和版本矩阵重放异常。上线采用离线门禁、灰度、回滚和失败样本回流;如果没有 Trace、测试或实测指标,我只说明验证方案,不声称已经提升效果。
7.8.2 2~3 分钟完整复述示例
建议节奏为:背景与事实边界 20 秒,架构与约束 30 秒,技术难点和方案亮点 40 秒,生产问题闭环 40 秒,验证、经验与停止点 30 秒。
这是一个内部运维知识助手的示例设计,不是我已经上线的真实项目。它要解决的是旧知识误答、无答案强答、权限越界和版本升级静默回归;方案把离线语料构建、分层评测、版本化发布门禁和线上 Trace 串成闭环。
最大难点是端到端错答难归因,因为问题可能出在语料、解析、召回、过滤、上下文截断、生成或引用映射。我把每层的稳定 ID、输入输出和版本记录下来,通过控制变量重放定位第一个偏离点。方案亮点不是简单“用了 RAG”,而是把版本矩阵作为评测、缓存和回滚单元;验证方式是固定门禁集、影子/灰度对比、回滚演练和分层 Trace。
一个代表性生产风险演练是跨权限缓存复用:现象是撤权后仍可能命中旧内容,影响是未授权信息暴露;定位证据包括缓存键、权限决策日志、policy 版本和撤权事件。止损时先停用受影响缓存并阻断相关流量,长期修复是完整权限指纹入键、命中后二次授权和撤权主动失效;再用同租户不同 ACL、撤权传播和审计用例验证,并把安全回归加入发布门禁。
最终能复用的经验是先归因再调参、失败样本必须进入门禁、权限不能交给模型。如果当前只有设计文档,我会停在“设计与验证方案”;只有故障注入时,我会说“演练通过”;只有拿到真实日志、Trace、测试和版本报告后,才会描述已验证结果,绝不补造延迟、准确率或业务收益。
7.8.3 证据停止点
| 当前拥有的证据 | 可以回答到哪里 | 必须停止或明确保留的内容 |
|---|---|---|
| 只有架构或设计文档 | 说明问题、关键决策、风险和计划如何验证 | 停在“工程建议/待验证”,不能说已经上线、已经解决或带来收益 |
| 有自动化测试或故障注入结果 | 说明对应测试场景和通过/失败事实 | 只能称“测试/演练结果”,不能包装成真实线上事故或线上效果 |
| 有日志、指标、Trace 和版本记录 | 说明观察到的现象、影响范围、根因链和技术验证结果 | 业务收益、长期稳定性和因果提升仍需独立业务数据或实验支持 |
| 有代码、提交、评审或任务记录 | 说明能够被证据定位的个人实现与决策 | 团队方案、平台能力和他人工作不能表述为个人贡献 |
到达证据停止点后应直接说“当前只能确认到这里,下一步需要补充某项日志、测试或实验”,不要用模型常识填补项目事实。
8. 方案权衡与常见误区
8.1 适用与不适用评测
- Exact Match 适合短实体和标准答案,不适合等价开放表达;
- 语义 Judge 适合开放回答,不适合无人工校准地裁决高风险事实;
- Recall@k 适合证据覆盖,不反映噪声对生成的影响;
- nDCG 适合分级排序,但标注成本高;
- 在线 A/B 适合已通过安全门禁的候选,不应拿真实用户测试明显越权风险。
8.2 关键权衡
| 决策 | 收益 | 成本/风险 | 控制方法 |
|---|---|---|---|
| 保存完整 Trace | 强诊断与重放 | 隐私、存储、高基数 | 脱敏、采样、权限、保留期 |
| LLM Judge 扩量 | 开放答案评测快 | 偏差、漂移、调用成本 | 人工校准、版本固定、分歧复核 |
| 强拒答 | 降低无依据回答 | 误拒与任务失败 | 拒答 precision/recall 双指标 |
| 更严格发布门禁 | 减少回归 | 发布慢、评测成本高 | 分层快速门禁和风险分级 |
| 缓存答案 | 降低延迟成本 | 陈旧、权限污染 | 全版本/权限键、TTL、事件失效 |
| 自动降级 | 提高可用性 | 降级质量可能隐藏 | degraded 标签与独立 SLO |
8.3 常见错误回答
- “用 RAGAS 一个总分就够了”:总分掩盖层级和分桶,且自动 Judge 有边界;
- “检索 Recall 高,RAG 就完成了”:还要看上下文、忠实度、正确性和服务;
- “有引用就可信”:引用可能不支持 claim 或指向过期/越权文档;
- “temperature=0 所以回归稳定”:模型、索引、服务和输入仍可能变化;
- “用户点赞率就是准确率”:反馈稀疏且有选择偏差;
- “重试能提高稳定性”:无界重试会放大尾延迟、成本和副作用;
- “日志越多越好”:敏感内容和高基数指标会带来合规与成本问题。
8.4 生产上线清单
- 数据:owner、version、freshness、删除与 ACL;
- 索引:构建完整性、别名切换、回滚、Embedding 兼容;
- 质量:检索、正确性、忠实度、引用、拒答与分桶;
- 性能:容量、并发、p95/p99、超时、队列和连接池;
- 韧性:限流、退避、熔断、降级、幂等和依赖故障;
- 安全:注入、越权、隐私、敏感数据、日志与审计;
- 发布:版本清单、影子/灰度、告警、回滚负责人;
- 反馈:失败入库、标注复核、门禁更新和复盘。
9. 面试题与参考答案
问题 1:如何评测一个 RAG 系统?
- 难度:中级;
- 考察点:分层评测;
- 合格答案要点:语料/解析、检索、生成、系统和业务分开;
- 优秀答案加分项:无答案、安全分桶、版本、Trace、灰度和回滚;
- 常见错误:只说答案准确率或看 Demo;
- 可继续追问:检索正确但回答错误怎么定位?
问题 2:Correctness 和 Groundedness 有何区别?
- 难度:中级;
- 考察点:答案事实与证据依赖;
- 合格答案要点:正确性对权威答案,忠实度对本次上下文支持;
- 优秀答案加分项:给出“忠实复述旧文档”和“脱离证据猜对”的反例;
- 常见错误:认为两者等价;
- 可继续追问:文档本身错误时谁负责?
问题 3:如何评测无答案拒答?
- 难度:中高级;
- 考察点:选择性回答;
- 合格答案要点:构造 answerable/unanswerable,报告拒答 precision/recall;
- 优秀答案加分项:按风险设置阈值、人工复核边界样本、监控分布变化;
- 常见错误:只追求拒答率越高越好;
- 可继续追问:怎样区分语料没有答案与检索没找到?
问题 4:LLM-as-a-Judge 有什么风险?
- 难度:高级;
- 考察点:自动评测可靠性;
- 合格答案要点:偏差、漂移、Prompt 依赖、成本与可被答案影响;
- 优秀答案加分项:人工校准、固定版本、分项 rubric、分歧与置信度;
- 常见错误:把 Judge 分数当真值;
- 可继续追问:如何度量 Judge 与人工的一致性?
问题 5:如何定位线上 RAG 质量突然下降?
- 难度:高级;
- 考察点:生产排障;
- 合格答案要点:按版本和查询分桶,从语料、索引、检索、上下文到生成重放;
- 优秀答案加分项:先止损、固定 request_id、检查变更矩阵、回滚并补回归;
- 常见错误:立刻换模型或增大 Top-k;
- 可继续追问:p50 正常、p99 异常时查什么?
问题 6:RAG 缓存键应包含哪些维度?
- 难度:高级;
- 考察点:一致性与安全;
- 合格答案要点:按缓存层区分键;检索与上下文包含规范化查询、完整 entitlement fingerprint/policy version、语料/索引和检索版本,最终答案再包含会话或独立查询状态、上下文哈希与 Prompt/model;
- 优秀答案加分项:撤权/删除事件失效、TTL、降级结果隔离和审计;
- 常见错误:只用 query 文本;
- 可继续追问:哪些版本变化不应复用旧答案?
10. 递进追问
- 基础概念:为什么检索 Recall@k 不能代表最终答案正确?
- 原理细节:一个多证据问题中,MRR 为什么可能很高但回答仍不完整?
- 实现边界:如何定义并验证“引用真正支持某个 claim”?
- 工程权衡:保存完整 Trace 与隐私、成本冲突时如何取舍?
- 系统设计:设计一套跨语料、Embedding、索引、Reranker、Prompt 和模型的版本门禁。
- 项目复盘:一次越权答案事故后,怎样从止损到防回归闭环?
参考回答线索:
- Recall 只证明候选覆盖,不证明最终上下文保留或模型忠实;
- 第一个证据靠前即可获得高 MRR,第二个必要证据可能完全缺失;
- Claim 分解、证据蕴含标注、版本/权限核对,并用人工校准自动 Judge;
- 最小化内容、脱敏、采样、分级保留、高风险全量审计,ID 放 Trace 而非无界指标;
- 不可变版本清单、固定门禁集、分层指标、影子/灰度、缓存隔离和原子回滚;
- 停止受影响流量、撤权与清缓存、锁定 Trace、修 ACL 根因、越权回归、灰度验证和门禁补强。
11. 实践任务
- [ ] 最小实现:运行第 6 节指标程序,增加 Precision@k 和宏平均;
- [ ] 评测集设计:为一个自有小知识库标注可回答、必要证据、答案事实、版本和风险标签;
- [ ] 分层实验:固定生成模型,只替换检索;再固定上下文,只替换 Prompt,练习控制变量;
- [ ] Judge 校准:让人工与一个自动 Judge 独立评分同一批样本,分析分歧而不是只算均值;
- [ ] 故障注入:模拟索引延迟、Reranker 超时、缓存跨租户、模型限流和引用映射失效;
- [ ] 事故复盘:将一次故障注入写成“现象 → 影响 → 证据 → 根因 → 止损 → 修复 → 验证 → 防复发”;
- [ ] 面试口述:用一分钟讲清分层评测与发布闭环。
12. 相关知识与参考资料
12.1 相关知识
- 前置知识:RAG 基础链路;
- 前置知识:RAG 检索优化;
- 关联主题:LLM 推理与服务优化;
- 关联主题:Prompt 与结构化输出。
12.2 参考资料
以下均为原始论文、官方文档、标准机构资料或官方源码,访问日期均为 2026-07-10:
- Thakur et al., BEIR: A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models, NeurIPS Datasets and Benchmarks 2021:跨数据集检索评测与 nDCG;
- Es et al., RAGAS: Automated Evaluation of Retrieval Augmented Generation, EACL 2024 Demo:RAG 自动评测框架原始论文;
- Saad-Falcon et al., ARES: An Automated Evaluation Framework for Retrieval-Augmented Generation Systems, 2023:RAG 自动评测与 Judge 校准研究;
- OpenAI, Evaluation best practices:官方评测集、比较和持续评测建议;
- OpenAI, Evals source repository:可复现评测框架官方源码;
- OpenTelemetry, Documentation:Trace、Metrics、Logs 与上下文传播官方规范入口;
- NIST, AI Risk Management Framework:AI 风险识别、测量、治理与管理的标准机构框架;
- OWASP, GenAI Security Project:Prompt injection、敏感信息和系统安全的官方项目资料。
13. 简明总结
一句话记忆: 生产级 RAG 要把每个回答变成“证据可追、指标可分、版本可重放、故障可回滚”的受控链路。
- 检索、正确性、忠实度、引用、拒答和系统 SLO 必须分层评测;
- 评测集要包含无答案、冲突、时效、权限和攻击样本,并防止调参泄漏;
- LLM Judge 只能辅助,必须用人工样本校准并固定版本;
- 线上用分阶段 Trace 定位语料、索引、检索、上下文或生成根因;
- 面试中应讲清技术难点、方案亮点,以及“离线门禁 → 灰度观测 → 证据归因 → 失败入库 → 回归与防复发”的完整闭环,并在项目证据不足时明确停止。