关于如何实现Anthropic的上下文检索技术并结合异步处理的博客文章。这篇文章来自Instructor网站,讨论了在RAG(Retrieval-Augmented Generation)系统中,如何通过上下文检索技术来保留关键上下文信息,从而提高检索效率。
背景:RAG 中的上下文问题
在传统的RAG系统中,文档被分割成多个块时会丢失上下文信息。
想象一下,你的知识库中嵌入了一系列财务信息(例如,美国证券交易委员会文件),并且你收到以下问题:‘ACME Corp 在 2023 年第二季度的收入增长是多少?
相关块可能包含以下文本:“该公司的收入比上一季度增长了 3%。”但是,这部分内容本身并未指定其指的是哪家公司或相关时间段。
也就是说:仅仅靠一个包含“公司收入比上一季度增长了3%”的块是不够的,因为它没有指明是哪个公司或相关时间段。
Anthropic 的解决方案:上下文检索
通过在嵌入之前添加特定块的解释性上下文来解决这个问题。
例如,将原始块“公司收入比上一季度增长了3%”上下文化为:“这个块来自ACME公司2023年第二季度的SEC文件;上一季度的收入为3.14亿美元。公司收入比上一季度增长了3%”。
Anthropic 的示例:
original_chunk = "The company's revenue grew by 3% over the previous quarter." |
实现上下文检索
Anthropic 使用 Claude 来生成上下文。他们提供了以下提示:
<document> |
性能改进
Anthropic 报告了显著的改进:
- 上下文嵌入将前 20 个块检索失败率降低了 35% (5.7% → 3.7%)。
- 结合上下文嵌入和上下文 BM25,失败率降低了 49% (5.7% → 2.9%)。
- 增加重新排序后,失败率进一步降低了 67% (5.7% → 1.9%)。
Instructor的异步处理实现:
我们可以使用异步处理来实现 Anthropic 的技术以提高效率:
from instructor import AsyncInstructor, Mode, patch |
本实施方案的主要特点
- 异步处理:用于asyncio并发块处理。
- 结构化输出:使用 Pydantic 模型进行类型安全的响应。
- 即时缓存:利用 Anthropic 的即时缓存来提高效率。
- 分块:实现具有重叠的基本分块策略。
- Jinja2 模板:使用 Jinja2 模板将变量注入提示中。
Anthropic 文章中的思考
Anthropic 提到了几个实施注意事项:
- 块边界:对块大小、边界和重叠进行试验。
- 嵌入模型:他们发现 Gemini 和 Voyage 嵌入有效。
- 自定义情境提示:考虑特定领域的提示。
- 块的数量:他们发现使用 20 个块最有效。
- 评估:始终针对您的具体用例进行评估。
进一步增强
根据 Anthropic 的建议:
- 根据内容复杂性实现动态块大小调整。
- 与矢量数据库集成,实现高效存储和检索。
- 添加错误处理和重试机制。
- 尝试不同的嵌入模型和提示。
- 实施重新排名步骤以进一步提高性能。
该实现为利用 Anthropic 的上下文检索技术并提高异步处理的效率提供了一个起点。