RAG检索失败率降低49%?Anthropic-Contextual-RAG方案解析-兼看老刘的课堂三部曲
今天来聊两件事,都和最近圈里的动态有关。
第一件,是Anthropic放出的一个RAG检索方案——
Contextual Retrieval embeddings + contextual BM25
第二件,是关于老刘课堂的一个阶段性总结。最近一直在琢磨,怎么把社区已经沉淀下来的知识,以更高效、更精准的方式再挖掘出来。于是就有了“老刘课堂三部曲”这个想法——把原本线上分享的内容,进一步剪辑、整理,拆成一个个小的知识点,形成
知识图谱、大模型、RAG
这其实是和技术社区相对独立的一条线,也算是一种新的尝试。供大家参考,也欢迎一起思考。关注技术进展,总会有收获。
一、先看Anthropic发布的RAG检索方案
传统RAG的做法,是把文档切分成更小的块(chunk),再去做检索。这个方法在很多场景下都没问题,但有时也会遇到一个棘手的情况——单个chunk,缺乏完整的上下文。
举个例子。假设你往知识库里塞了一套美国SEC的财务文件,然后问:“ACME Corp在2023年第二季度的收入增长如何?”
检索系统可能会命中这样一个chunk:“公司收入比上一季度增长了3%。”——看起来没问题,但单独看这个块,它压根没提是哪家公司、哪个时间段。这就导致系统很难准确命中,或者即使命中了,后续的大模型也没法正确理解这个“3%”说的是什么。
这个问题的本质,是
chunk丢失了上下文
Anthropic这次的做法,思路非常直接:
用Claude为每个chunk,生成专属的上下文描述


核心机制说清楚了,但落地会遇到两个现实问题:
一是上下文怎么生成;二是chunk数量巨大,怎么生成得快、生成得便宜
1、如何生成上下文
给几百万个chunk挨个手动写上下文,显然不现实。Anthropic的做法是直接用Claude,写了一条prompt,让模型基于整篇文档的语境,给每个chunk生成一段简洁但针对性很强的上下文解释。

比如,原始chunk是“公司收入比上一季度增长了3%”,经过Claude处理后,生成的上下文可能会是“这是ACME Corp在2023年第二季度财报中披露的收入增长数据”。然后这段上下文会被拼接到chunk前面,再去构建embedding和BM25索引。
2、如何快速生成上下文
这里的关键,是prompt caching。简单说,如果你有一个很长的prompt(比如整个参考文档),在多轮请求中会被反复用到,那么可以把这些内容缓存起来,避免每次都重新计算。
基本流程是这样的:
- 系统检查当前请求的prompt前缀,是否已经被缓存。
- 如果是,直接复用缓存结果,大幅减少处理时间和成本。
- 如果不是,则完整处理prompt,并缓存前缀以备后续使用。
这种方法对于那些“带大量例子的prompt、包含大量上下文的背景信息、一致性指令的重复任务、多轮对话”场景,收益尤其明显。官方数据说,延迟最高能降低2倍以上,成本最高能降低90%。
假设每个chunk 800个token、每篇文档8000个token、上下文指令50个token、每个chunk生成的上下文100个token,那么生成一次上下文的一次性成本大约为1.02美元/百万文档token。
不过需要注意,缓存的寿命只有5分钟,每次使用缓存内容时都会刷新。
在生成完上下文后,配合Contextual Embedding和Contextual BM25,根据Anthropic的评估脚本,
检索失败率确实降低了49%
整套方案的消融实验数据也很有意思,不同embedding的组合差异还是挺大的。
总结一下
对于超长文档,把所有内容都喂给大模型生成上下文,本身就是一件不太现实的事
次数并没有减少
不过话说回来,这个思路和我们前几天讨论的memo方案,在精神上有异曲同工之妙,值得放在一起对比着看。