Appearance
5.3 RAG·评估与防幻觉
RAG 上线后最怕两件事:该找到的没找到(检索失败)、找到了但答错/编造(生成幻觉)。这一节教你分层评估,并用工程手段把幻觉压下去。
RAG 会在两个地方出错
用户问题
│
├─【检索层】没召回到相关文档 → 后面再聪明也白搭(巧妇难为无米之炊)
│
└─【生成层】召回对了,但模型没好好用
├─ 编造了检索内容里没有的事(幻觉)
└─ 检索到无关内容,被带偏评估要分这两层来做,因为修法完全不同:检索差→改分块/检索策略(5.1/5.4);生成差→改 Prompt/加约束。
检索层评估
先准备一批"问题 → 它该命中哪些文档"的标注集,然后看检索结果:
- Recall@k(召回率):该命中的文档,有没有出现在 top-k 里?(最关键——没召回到,一切免谈)
- Precision@k(精准率):top-k 里有多少是真相关的?
- MRR:第一个正确结果排在多靠前?(越靠前越好)
💡 实战里先盯 Recall@k:把 k 调大点(如 top-10)看相关文档到底进没进候选池。进了但排名靠后 → 加 Reranking;压根没进 → 是分块或检索策略的问题。
javascript
// 检索层评估骨架
const testset = [
{ q: "退款多久到账", relevantIds: [2] },
{ q: "怎么升级会员", relevantIds: [3] },
]
let hit = 0
for (const t of testset) {
const got = (await search(t.q, { topK: 5 })).map(r => r.id)
if (t.relevantIds.some(id => got.includes(id))) hit++ // Recall@5 命中
}
console.log(`Recall@5: ${(hit / testset.length * 100).toFixed(0)}%`)生成层评估:忠实度(Faithfulness)
生成层最重要的指标是忠实度:回答里的每一句,是不是都能在检索到的内容里找到依据?没依据的就是幻觉。
用 LLM-as-Judge(2.5)来判:
javascript
async function checkFaithfulness(context, answer) {
const res = await chat.chat.completions.create({
model: MODEL,
messages: [{
role: "user",
content: `参考资料:\n${context}\n\nAI 回答:\n${answer}\n\n` +
`请判断"AI 回答"里的每个事实是否都能在"参考资料"里找到依据。` +
`如果全部有依据输出 PASS;如果有任何编造/无依据的内容输出 FAIL 并指出哪句。`
}]
})
return res.choices[0].message.content
}另外两个常看的:Answer Relevance(回答有没有答到问题)、Context Relevance(检索到的内容跟问题相不相关)。
防幻觉的四个工程手段
评估是发现问题,下面是把幻觉压下去的手段(按性价比排序):
1. Prompt 里立规矩:只能用资料,没有就说没有
你只能根据"参考资料"回答。资料里没有的,直接说"暂无相关信息",
绝对不要用你自己的知识补充或推测。2. 强制引用(Citation)——让它标出每句话来自哪条资料,既能溯源,又逼它"言出有据":
javascript
const prompt = `根据带编号的资料回答问题,每个结论后用 [编号] 标注来源。
无法从资料得出的,不要回答。
资料:
[1] 退款需在购买后7天内提交。
[2] 退款3-5个工作日原路退回。
问题:${question}`
// 期望输出:"需在7天内申请[1],到账约3-5个工作日[2]。"3. 检索为空就别硬答:检索分数都很低(没相关内容)时,直接回"没找到",根本不调生成。
4. 生成后校验:用上面的 checkFaithfulness 对回答做一道 Guardrail,FAIL 就重答或兜底(2.7)。
💡 性价比最高的是 1+2:把"无依据不要答 + 强制引用"写进 Prompt,几乎零成本,效果立竿见影。要求高的关键场景再叠加 4。
把评估变成回归测试
每次改分块、换 Embedding、调 Prompt,跑一遍评估对比数字,而不是凭感觉:
改动前:Recall@5 = 72%,忠实度 PASS 率 = 85%
↓ 加了查询改写 + 强制引用
改动后:Recall@5 = 88%,忠实度 PASS 率 = 96% ✅ 数字说话🛠️ 实战练习:给你的 RAG 建评估闭环
- 准备 10 个问题,标注每个该命中哪些文档(检索集)+ 一句参考答案(生成集)
- 跑出当前 Recall@5 和 忠实度 PASS 率两个数字
- 给生成 Prompt 加上"无依据不要答 + 强制引用",再跑一遍
- 对比两个数字,确认幻觉是否下降
进阶挑战:故意问一个知识库里没有的问题,验证你的 RAG 是老实说"没找到",还是开始编——如果编,回去补手段 1 和 3。
📌 关键结论
- RAG 分两层评估:检索层(召回没有)和生成层(答得忠不忠实),修法不同
- 检索先盯 Recall@k:相关文档进没进候选池;进了排后→Rerank,没进→改分块/检索
- 生成层最重要是忠实度:回答每句是否都有检索依据,用 LLM-as-Judge 判
- 防幻觉性价比最高:Prompt 立规矩"无依据不答" + 强制引用,再按需加生成后校验
- 把评估做成回归测试,每次改动用数字判断好坏
下一节:5.4 RAG·真实文档处理