今天来聊聊两个话题,都与近期行业动态密切相关。
第一个,是Anthropic推出的一个RAG检索方案——Contextual Retrieval embeddings + contextual BM25。不少媒体都在报道,称该方案能将检索失败率降低49%。这背后的原理是什么?实际落地的可能性有多大?我们详细拆解一下。
第二个,是关于老刘课堂的一次阶段性总结。最近一直在思考,如何将社区积累的知识,以更高效率、更精准的方式重新挖掘出来。于是便诞生了“老刘课堂三部曲”的构想——把原本线上分享的内容,经过二次剪辑和整理,拆分成一个个独立的知识点,形成知识图谱、大模型、RAG等多个专题集合。这样一来,大家可以根据自身需求自由观看,也能更迅速地找到感兴趣的内容。
这条线与技术社区相对独立,也算是一种全新的探索。供大家参考,也欢迎一起交流。持续关注技术前沿,总能获得启发。
一、先看Anthropic发布的RAG检索方案
传统RAG的做法通常是将文档切分成较小的块(chunk),然后进行检索。这种方法在多数场景下表现良好,但有时也会遇到一个棘手的难题——单个chunk缺少完整的上下文信息。
举个例子。假设你向知识库中上传了一套美国SEC的财务文件,然后提问:“ACME Corp在2023年第二季度的收入增长情况如何?”
检索系统可能会命中这样一个chunk:“公司收入比上一季度增长了3%。”——表面上没问题,但单独看这个块,它完全没有提及公司名称和时间范围。这就导致系统难以准确命中,即使命中,后续的大模型也无法正确理解这个“3%”具体指向什么。
此问题的本质在于chunk丢失了上下文。过去已有多种尝试,比如为chunk附加文档摘要,或者采用HyDE(假设文档嵌入)进行检索增强。但这些方法各有局限性,要么过于粗略,要么额外开销过大。
Anthropic这次的做法思路非常直接:利用Claude为每个chunk自动生成专属的上下文描述。在建立embedding和BM25索引之前,先将这段生成的上下文(通常为50-100个token)附加到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%。如果再结合rerank,这个数字还能进一步提升到67%。
整套方案的消融实验数据也很有参考价值,不同embedding的组合效果差异明显。
总结一下:该方法的核心理念是“用大模型为chunk生成上下文”。想法很巧妙,但落地时存在一个明显的矛盾——对于超长文档,将所有内容喂给大模型生成上下文本身就不太现实。prompt caching虽然解决了单次生成的时间和费用问题,但生成的次数并未减少。因此,真正要实现大规模落地,仍面临不少挑战。
不过,这个思路与我们前几天讨论的memo方案在精神上有异曲同工之妙,值得放在一起对比研究。
