Anthropic Cookbook提供者检索:多模型检索实现
引言:检索增强生成(RAG)的核心挑战
在构建企业级AI应用时,检索增强生成(Retrieval Augmented Generation,RAG)已成为连接大语言模型与领域专业知识的关键技术。然而,传统RAG系统面临着一个根本性挑战:如何在保证检索精度的同时,提升系统的整体性能表现?
Anthropic Cookbook通过精心设计的"提供者检索"架构,展示了如何通过多模型协同工作来解决这一难题。本文将深入解析这一架构的实现细节,帮助开发者构建更高效的RAG系统。
多模型检索架构概览
Anthropic Cookbook的检索系统采用三级递进式架构,每一级都针对特定的性能瓶颈进行优化:
三级检索架构性能对比
| 检索层级 | 核心技术 | 精度提升 | 召回率提升 | F1分数提升 | MRR提升 |
|---|---|---|---|---|---|
| Level 1 | 基础向量检索 | 基准 | 基准 | 基准 | 基准 |
| Level 2 | 摘要索引 | +2.3% | +4.5% | +3.8% | +17.6% |
| Level 3 | 智能重排序 | +4.7% | +8.2% | +6.9% | +34.2% |
Level 1:基础向量检索实现
核心组件:VectorDB类
基础检索层构建了一个高效的向量数据库管理系统,支持文档嵌入、相似度搜索和结果缓存:
class VectorDB:
def __init__(self, name, api_key=None):
if api_key is None:
api_key = os.getenv("VOYAGE_API_KEY")
self.client = voyageai.Client(api_key=api_key)
self.name = name
self.embeddings = [] # 存储文档嵌入向量
self.metadata = [] # 存储文档元数据
self.query_cache = {} # 查询缓存优化性能
self.db_path = f"./data/{name}/vector_db.pkl"
def load_data(self, data):
"""加载并嵌入文档数据"""
if self.embeddings and self.metadata:
print("Vector database is already loaded. Skipping data loading.")
return
if os.path.exists(self.db_path):
print("Loading vector database from disk.")
self.load_db()
return
# 构建文档文本表示
texts = [f"Heading: {item['chunk_heading']}\n\n Chunk Text:{item['text']}"
for item in data]
self._embed_and_store(texts, data)
self.save_db()
print("Vector database loaded and saved.")
检索算法实现
def search(self, query, k=3, similarity_threshold=0.75):
"""执行相似度搜索"""
# 查询缓存优化
if query in self.query_cache:
query_embedding = self.query_cache[query]
else:
query_embedding = self.client.embed([query], model="voyage-2").embeddings[0]
self.query_cache[query] = query_embedding
if not self.embeddings:
raise ValueError("No data loaded in the vector database.")
# 计算余弦相似度
similarities = np.dot(self.embeddings, query_embedding)
top_indices = np.argsort(similarities)[::-1]
top_examples = []
# 阈值过滤和结果收集
for idx in top_indices:
if similarities[idx] >= similarity_threshold:
example = {
"metadata": self.metadata[idx],
"similarity": similarities[idx],
}
top_examples.append(example)
if len(top_examples) >= k:
break
self.save_db()
return top_examples
Level 2:摘要索引增强检索
SummaryIndexedVectorDB类扩展
第二级检索通过摘要信息增强文档表示,提升语义理解能力:
class SummaryIndexedVectorDB(VectorDB):
def __init__(self, name, api_key=None):
super().__init__(name, api_key)
self.db_path = f"./data/{name}/summary_indexed_vector_db.pkl"
def load_data(self, data):
"""增强版数据加载:包含摘要信息"""
if self.embeddings and self.metadata:
print("Vector database is already loaded. Skipping data loading.")
return
if os.path.exists(self.db_path):
print("Loading vector database from disk.")
self.load_db()
return
# 增强的文本表示:标题 + 内容 + 摘要
texts = [f"{item['chunk_heading']}\n\n{item['text']}\n\n{item['summary']}"
for item in data]
self._embed_and_store(texts, data)
self.save_db()
print("Summary indexed vector database loaded and saved.")
摘要生成策略
摘要索引的关键在于如何生成高质量的文档摘要:
def generate_document_summary(document_text, chunk_heading):
"""生成文档摘要的提示词模板"""
prompt_template = """
请为以下文档内容生成一个简洁的摘要:
标题: {heading}
内容: {content}
要求:
1. 摘要长度控制在50-100字
2. 突出文档的核心概念和关键信息
3. 保持专业性和准确性
4. 便于后续的语义检索匹配
"""
return client.messages.create(
model="claude-3-haiku-20240307",
max_tokens=150,
messages=[{"role": "user", "content": prompt_template.format(
heading=chunk_heading, content=document_text[:1000])}],
temperature=0
).content[0].text
Level 3:智能重排序检索
重排序算法实现
第三级检索引入Claude模型进行智能重排序,显著提升检索质量:
def _rerank_results(query: str, results: List[Dict], k: int = 3) -> List[Dict]:
"""使用Claude进行智能重排序"""
# 准备带索引的摘要列表
summaries = []
for i, result in enumerate(results):
summary = "[{}] Document: {}".format(
i,
result['metadata']['chunk_heading'],
result['metadata']['summary']
)
summary += " \n {}".format(result['metadata']['text'])
summaries.append(summary)
# 构建重排序提示词
joined_summaries = "\n".join(summaries)
prompt = f"""
Query: {query}
你将被提供一组文档,每个文档前面有方括号中的索引号。你的任务是选择最相关的{k}个文档来回答查询。
{joined_summaries}
请只输出最相关的{k}个文档的索引号,按相关性顺序排列,用逗号分隔,包含在XML标签中:
<relevant_indices>索引号列表</relevant_indices>
"""
# 调用Claude进行重排序
client = Anthropic(api_key=os.environ.get('ANTHROPIC_API_KEY'))
try:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=50,
messages=[{"role": "user", "content": prompt},
{"role": "assistant", "content": "<relevant_indices>"}],
temperature=0,
stop_sequences=["</relevant_indices>"]
)
# 解析重排序结果
response_text = response.content[0].text.strip()
indices_str = response_text
relevant_indices = []
for idx in indices_str.split(','):
try:
relevant_indices.append(int(idx.strip()))
except ValueError:
continue
# 返回重排序后的结果
reranked_results = [results[idx] for idx in relevant_indices[:k]]
for i, result in enumerate(reranked_results):
result['relevance_score'] = 100 - i
return reranked_results
except Exception as e:
print(f"重排序过程中发生错误: {str(e)}")
return results[:k] # 降级处理
评估体系构建
多维度评估指标
Anthropic Cookbook建立了全面的评估体系,涵盖检索和端到端性能:
| 评估维度 | 核心指标 | 计算方式 | 优化目标 |
|---|---|---|---|
| 检索精度 | Precision | TP / (TP + FP) | 减少误检 |
| 检索完整性 | Recall | TP / (TP + FN) | 提高覆盖率 |
| 综合性能 | F1 Score | 2 * (P * R) / (P + R) | 平衡精度和召回 |
| 排名质量 | MRR | 1/rank₁ + 1/rank₂ + ... | 提升排名准确性 |
| 端到端性能 | Accuracy | 正确答案比例 | 整体系统效果 |
评估数据集设计
# 评估数据集示例结构
evaluation_sample = {
"id": "efc09699",
"question": "如何在Anthropic评估工具中创建多个测试用例?",
"correct_chunks": [
"https://docs.anthropic.com/en/docs/test-and-evaluate/eval-tool#creating-test-cases",
"https://docs.anthropic.com/en/docs/build-with-claude/develop-tests#building-evals-and-test-cases"
],
"correct_answer": "在Anthropic评估工具中创建多个测试用例,点击'添加测试用例'按钮,为提示词中的每个变量填写值,重复此过程以创建额外的测试用例场景。"
}
性能优化策略
批量处理优化
def _embed_and_store(self, texts, data):
"""批量嵌入处理优化"""
batch_size = 128 # 优化的批处理大小
result = [
self.client.embed(
texts[i : i + batch_size],
model="voyage-2"
).embeddings
for i in range(0, len(texts), batch_size)
]
self.embeddings = [embedding for batch in result for embedding in batch]
self.metadata = data
缓存机制设计
def search(self, query, k=3, similarity_threshold=0.75):
"""智能查询缓存"""
if query in self.query_cache:
query_embedding = self.query_cache[query] # 缓存命中
else:
query_embedding = self.client.embed([query], model="voyage-2").embeddings[0]
self.query_cache[query] = query_embedding # 缓存未命中时存储
# ... 其余搜索逻辑
self.save_db() # 定期持久化缓存
return top_examples
实战应用案例
客户支持场景实现
def customer_support_rag(query, customer_context=None):
"""客户支持RAG系统实现"""
# 多级检索协同工作
level1_results = retrieve_base(query, db)
level2_results = retrieve_level_two(query, db_summary)
level3_results = retrieve_level_three(query, db_rerank)
# 结果融合策略
combined_context = merge_results(level1_results, level2_results, level3_results)
# 个性化回答生成
personalized_prompt = f"""
基于以下客户上下文和检索到的文档,请提供专业、准确的回答:
客户查询: {query}
客户上下文: {customer_context or '无额外上下文'}
相关文档:
{combined_context}
请确保回答:
1. 准确基于文档内容
2. 考虑客户的具体情况
3. 提供清晰的解决方案
4. 保持专业友好的语气
"""
return generate_response(personalized_prompt)
知识管理场景
def knowledge_base_search(user_query, department=None):
"""企业知识库搜索实现"""
# 部门特定的检索优化
if department:
enhanced_query = f"{user_query} [部门: {department}]"
else:
enhanced_query = user_query
# 多模型检索执行
results = []
for retrieval_level in [1, 2, 3]:
try:
level_results = execute_retrieval(enhanced_query, level=retrieval_level)
results.extend(level_results)
except Exception as e:
logging.warning(f"Level {retrieval_level} retrieval failed: {e}")
# 去重和排序
unique_results = remove_duplicates(results)
sorted_results = sort_by_relevance(unique_results)
return format_knowledge_response(sorted_results, user_query)
性能监控与调优
监控指标设计
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



