A·Agent Guide 从经典智能体到前沿工程 ← 返回主博客
AGENT GUIDE / READING NOTES

第 5 章 RAG、检索与长期记忆

手算 Recall@k,分析证据、引用、版本与长期记忆

5.1 答案为什么需要外部证据

本章目标:能拆出检索、证据选择、答案生成和引用核验四个环节;能测量漏检,并设计可更新的长期记忆。

假设研究助手被问“当前会员运费是多少”。模型可能记得旧规则,也可能编造一个合理数字。更可靠的路径是读取适用于当前用户和版本的政策文档,再依据具体段落回答。

原始 RAG 论文 [导读] 将参数化模型和外部非参数化知识结合。现代工程中的 RAG 常泛指检索后生成,不要求复现论文训练架构。它提供更新知识和追溯来源的机会,但检索错了、解释错了或引用错了,回答仍然不可靠。

从问题到检索证据、回答与可选记忆写入

5.2 从文档到索引:切块不是机械截字

设一份文档包含“普通用户满 100 免运费”“会员免运费”“负数订单不合法”。如果切块只保留“免运费”,丢掉适用条件,后续生成就可能把规则泛化到所有输入。

好的切块应尽量保留标题、条件和完整表格行。过小块丢条件,过大块降低定位精度并占用上下文;重叠可以缓解跨边界信息,但也增加索引和去重成本。对于代码,函数或模块边界通常比固定字数更有解释意义。

{
  "chunk_id": "policy-v2-member-01",
  "source_id": "shipping-policy",
  "version": "v2",
  "section": "会员规则",
  "access_scope": "public",
  "text": "合法订单的会员运费为 0。"
}

来源 ID 与版本必须区别开。相同文档更新后,旧块应删除、失效或进入明确的历史集合。否则向量相似的旧政策可能一直被召回,造成“有来源但过期”的答案。

5.3 召回、重排和证据选择怎样配合

关键词检索适合精确名称、错误码和符号;语义检索适合不同表述的同一意图。BM25 利用词项统计来排序,向量方法利用表示空间的相似性;两者都不会自动判定一段材料对具体结论是否充分。

混合召回把多个候选集合合并,再做去重和重排。不同检索器的原始分数通常不能直接相加,需要校准或使用基于排名的融合。重排器可以更细地比较问题与片段,但增加计算,并不能找回从未进入候选集的相关文档。

因此先检查召回有没有找齐证据,再检查排序有没有把关键证据放在预算内。权限与版本范围应在交给模型前执行;依赖模型读完私有文档后“不要说出来”,已经晚于数据边界。

5.4 离线实验:亲手计算 Recall@k

下载 retrieval_lab.py,或从仓库根目录运行:

python3 agent/examples/retrieval_lab.py

脚本有四份文档:D1 普通规则 v2;D2 会员规则 v2;D3 旧规则 v1;D4 内部例外。它先按公开范围与 v2 过滤,再用英文 token 重叠数排序,平分时按 ID 排序。这是便于手算的检索器,不是 BM25,也不是向量搜索。

查询 标准相关证据 k=1 召回 k=2 召回
standard shipping threshold D1 D1 D1、D2
member shipping fee D2 D2 D2、D1
standard member shipping D1、D2 D1 D1、D2
refund deadline 无可用证据 空 空

Recall@k = 前 k 个结果中命中的相关证据数 / 标准相关证据总数。第三题 k=1 只命中两份中的一份,召回率为 0.5。前三个可回答问题的宏平均分别是 (1+1+0.5)/3=5/6 和 1。无答案问题的分母为零,脚本单独标记应拒答,不硬填一个 Recall 值。

注意 k=2 的前两题多出无关块,召回上升不等于精度提高。Precision@k 关注取出的结果中多少相关。实际检索还要考虑答案是否需要多个来源、段落粒度标注以及文档间条件关系。

5.5 从证据到回答:引用存在不等于支持结论

可以给模型输入带 chunk_id 的证据,再要求每个事实对应来源。回答“会员运费为 0 [D2]”可以获得支持;回答“所有用户任何金额都免费 [D2]”即使链接真实,也误扩展了会员条件。

引用核验至少问四件事:来源可访问吗?版本适用吗?片段表达了这条事实吗?结论遗漏了条件或不确定性吗?查询“退款期限”时没有材料,合理行为是说明当前证据不足并选择进一步检索或停止,而不是用运费文档凑出答案。

遇到冲突要保留条件。v1 阈值 200 与 v2 阈值 100 不应求平均得到 150;它们首先是版本适用性问题。不同地区或用户级别的规则也可能各自正确。先确定查询范围,再比较内容。

5.6 长期记忆:写入后还要能更新与删除

RAG 主要寻找外部事实供本次使用;长期记忆保存跨会话可能有用的信息;上下文保存当前工作所需内容。三者可以共享存储设施,但生命周期不同。

信息 更适合的保存位置 写入条件
用户偏好报告用中文 用户偏好记忆 用户明确表达且允许保存
当前测试失败日志 当前轨迹/产物 本次调试所需,可过期
已验证修复模式 程序性经验或 Skill 说明适用条件并重新评测
当前公开政策 v2 文档索引 来源、版本与访问范围清晰

记忆条目应含内容、来源、确认时间、作用范围和更新规则。模型说“用户应该喜欢表格”只是推断,不应直接写成用户偏好。用户后来说“这次用段落”,可能只是本次选择;若说“以后都用段落”,才涉及更新长期偏好。写入策略需要理解这一区别。

错误经验也会传播。一次测试遗漏负数会员,不应总结成“会员判断永远放最前”。经验应携带反例与适用条件;发现冲突时修订或删除,而不是无限追加相互矛盾的条目。

5.7 练习与参考检查

在检索脚本中移除版本过滤,观察 D3 是否进入某些前 k 结果;把它排除不是为了提高漂亮分数,而是因为本次任务限定当前政策。再给查询增加同义词,观察 token 重叠检索为何漏检,解释语义检索可能帮助的地方。

为四个问题各写一份带证据的回答,标注“事实、适用条件、来源”。参考验收:无内部 D4 泄漏;当前问题不引用 D3;组合查询保留普通与会员两种规则;退款问题明确证据不足。还要保留未达到的指标,不能只展示三个好看的答案。

本章交付物:小型标注集、召回与引用核验表、一份记忆写入/更新规则。这样你能知道检索系统究竟在哪一层失败。


Agent Guide · 从反馈闭环走向可靠系统基于 Markdown 构建