查询 25 次,耗时 0.5469 秒

生产环境 RAG 的可靠性工程:从离线评测到在线监控

dnb6

New member

dnb6 Rep
0
0
0
Rep
0
dnb6 Vouches
Vouches
0
1 MONTH
1 1 MONTH OF SERVICE
dnb6 获得
0
0
0
获得
0
dnb6 凭证
0
0
0
凭证
0
主题
11
点赞
0
HakB
1 月
在社区成长 1 月
LEVEL 1 1 XP
 
## 背景

RAG(检索增强生成)常被当作“向量数据库加一个大模型”,但生产问题通常不止出在检索或生成中的某一环。文档切分方式会影响召回,重复或过时的片段会污染上下文,提示词不能保证模型始终按格式作答,而评测集若只看答案是否“听起来正确”,也很难发现引用错位、无依据补全和版本回归。要让 RAG 能够持续迭代,重点是把数据、检索、生成和评测连成可复现的工程流程。

本文以一个内部技术文档问答系统为例,说明如何搭建最小但可落地的 RAG 评测闭环。目标不是追求某个单项指标最高,而是回答三个实际问题:相关证据有没有被找回,模型是否依据证据作答,改动是否让整体效果变好。

## 原理与评测对象

典型 RAG 链路包括文档解析与切分、向量化、候选检索、可选的重排、上下文组装以及模型生成。评测时需要分别观察各阶段:

- **检索质量**:人工标注的相关文档或片段是否出现在 Top-K 中。可使用 Recall@K、MRR 等指标。
- **生成质量**:回答是否正确、是否覆盖问题要点、是否存在证据不支持的陈述。
- **引用质量**:答案中的引用能否定位到实际提供的片段,引用内容是否支持对应结论。
- **系统质量**:延迟、超时率、输入输出 token、检索耗时和单位请求成本。

这些指标不能互相替代。检索召回高,不代表生成答案一定正确;回答与参考答案相似,也不代表引用有依据。因此评测集应包含问题、参考答案、相关文档标识和必要的判定说明,而不是只有一列问答文本。

## 前置条件

1. 准备一份有明确授权、可在本地或测试环境使用的文档语料,并记录文档版本和更新时间。
2. 建立一批人工审核的问题。初期可从真实业务问题中脱敏抽样,也要加入无法从语料回答的问题。
3. 固定模型、嵌入模型、提示词、切分参数、Top-K 和重排配置的版本,避免不同实验之间混入多个变量。
4. 记录每次请求的检索片段 ID、片段文本或安全的内容摘要、模型版本、延迟与结果。日志应遵循组织的数据保留和隐私要求。
5. 若使用模型裁判辅助评价,先用人工标注样本验证其一致性。裁判分数只能作为辅助信号,不应直接当作客观真值。

## 分步骤实践

### 1. 固定评测集格式

建议用 JSONL 保存样本,每行一条,便于版本管理和增量运行:

```json
{"id":"q-001","question":"服务的默认重试次数是多少?","reference_answer":"默认重试 3 次。","relevant_chunk_ids":["ops-12"],"answerable":true}
{"id":"q-002","question":"尚未发布的功能具体何时上线?","reference_answer":"当前文档没有提供上线日期。","relevant_chunk_ids":[],"answerable":false}
```

样本要覆盖常见查询、跨段落问题、术语缩写、版本差异、文档中没有答案的问题,以及容易混淆的相似概念。标注相关片段时,尽量标到能够支持结论的最小范围,并约定多个标注者的分歧处理方式。

### 2. 先单独评测检索

在生成之前,先用检索器跑完整个评测集,保存每个问题的 Top-K 结果。若标注的是相关片段 ID,可以直接计算 Recall@K:

```text
Recall@K = 至少一个相关片段进入 Top-K 的问题数 / 可回答问题数
```

同时记录 MRR,即第一个相关片段排名倒数的平均值。K 不应只凭经验决定:比较 K=3、5、10 对召回和上下文长度的影响。若 Recall@K 低,优先检查语料覆盖、切分边界、元数据过滤和嵌入模型,而不是先改生成提示词。

### 3. 复现实验配置

为每组实验保存机器可读配置,例如:

```yaml
embedding_model: "embed-model-v2"
chunk_size: 700
chunk_overlap: 100
top_k: 8
reranker: "reranker-v1"
generation_model: "chat-model-v3"
temperature: 0
prompt_version: "rag-answer-07"
```

字段名称应按实际平台适配。核心要求是配置可以追溯,不要只把参数留在临时脚本或控制台里。切分长度还要注明单位是字符、token 还是模型 tokenizer 的 token,否则不同实现之间无法比较。

### 4. 约束答案与引用格式

提示词应明确告诉模型:仅依据给定证据回答;证据不足时说明无法确认;结论要附带引用标识。示例:

```text
你是内部文档问答助手。只使用“证据”部分的信息回答。
如果证据不足以支持结论,明确回答“现有资料无法确认”,不要自行补全。
对每个事实性结论标出支持它的片段 ID。

问题:{question}
证据:
{retrieved_chunks}
```

程序侧还要校验输出结构:引用 ID 是否属于本次检索结果,必填字段是否存在,拒答问题是否出现无依据的具体日期或数字。提示词是约束手段,不是安全边界;模型仍可能产生格式错误或编造内容。

### 5. 同时检查答案和证据

对每个版本至少抽查以下情况:答案是否符合参考结论、每个关键陈述是否被引用片段支持、引用是否指向正确片段、不可回答问题是否恰当拒答。可采用二元标签或小型量表,并记录错误类别,例如“未召回证据”“证据已召回但未使用”“引用错位”“过度拒答”。分类比单一总分更能指导下一步改动。

如用 LLM 裁判,可把问题、参考答案、生成答案和证据同时交给裁判,要求逐条给出判断依据;并随机抽样人工复核。不要让裁判只根据生成答案与参考答案的字面相似度打分,因为表达不同可能语义正确,措辞相似也可能缺少证据支持。

### 6. 做小步消融与回归比较

每轮只改一个主要变量,例如切分长度、Top-K、重排器或提示词。保存基线结果,比较检索指标、答案质量、引用质量和延迟。若 Recall@K 上升但回答变长、延迟显著增加,应结合业务阈值判断是否值得;若离线指标改善但线上用户反馈下降,检查评测集是否覆盖真实流量分布。

将评测接入发布流程:模型或索引更新后运行固定回归集;核心质量低于阈值时阻止发布或要求人工审批。阈值需要根据业务风险制定,不能照搬其他团队的分数。

## 风险与注意事项

- **评测集泄漏**:提示词或参数反复针对同一小集合调优,会造成过拟合。保留一份不参与调参的留出集,并周期性加入新问题。
- **文档版本错配**:参考答案基于新版本,检索索引却是旧版本,会让评测结论失真。样本、文档和索引都应有版本标识。
- **平均数掩盖长尾**:总体分数可能不错,但少数高风险问题仍会失败。按问题类型、文档来源和可回答性分组报告结果。
- **上下文预算失控**:提高 K 可能增加 token、延迟和噪声。监控实际上下文长度,并测试截断、去重与重排策略。
- **日志包含敏感信息**:评测记录可能保存用户问题和内部文档片段。按数据分类设置访问控制、脱敏与保留期限。
- **裁判偏差**:不同模型或提示词可能改变裁判分数。固定裁判版本,并用人工样本定期校准。

## 常见问题

**Recall@K 很高,答案仍然经常错,先查什么?**
先检查召回片段是否真正包含完整依据,再检查上下文排序、冲突版本、提示词约束和引用校验。高召回只表示“找到了候选”,不表示模型正确使用了它们。

**没有人工标注资源,能不能直接用 LLM 生成评测集?**
可以用来扩充候选问题或发现边界案例,但需要人工审核关键样本和参考证据。未经审核的合成集可能重复模板、偏向容易问题,不能代表真实用户需求。

**应该先优化检索还是换更强的生成模型?**
先分阶段定位。如果相关证据不在 Top-K,换生成模型通常不能解决根因;如果证据清晰且充分,但答案仍忽略证据或格式不稳,再比较提示词、上下文组织和模型版本。

**温度设为 0 是否就能保证结果稳定?**
不能。服务端实现、模型版本、并行推理和采样细节仍可能造成差异。对需要审计的任务,应保存实际输入上下文、模型标识和输出,并通过重复运行评估稳定性。

## 总结

可靠的 RAG 不靠一次提示词调整完成,而是依赖可追溯的数据版本、分阶段指标和持续回归。先验证检索是否找到证据,再验证生成是否依据证据回答,最后把延迟与成本纳入同一张评测表。每次只改变少量变量,保留独立留出集,并对失败样本做分类,团队才能把“感觉回答变好了”转化成可复现、可审查的工程结论。
 
顶部