Claude帮忙写的,对应这个项目:https://github.com/NirDiamant/RAG_Techniques?tab=readme-ov-file
概述
本文档基于对RAG_Techniques仓库的深入分析,详细介绍了34种先进的检索增强生成(Retrieval-Augmented Generation, RAG)技术。这些技术涵盖了从基础实现到高级架构的全方位解决方案,旨在提升RAG系统的准确性、效率和上下文丰富度。
技术分类
🌱 基础技术
1. 简单RAG (Simple RAG)
核心原理:最基本的RAG实现,通过向量相似性搜索检索相关文档片段,然后结合LLM生成回答。
工作流程:
1. 文档预处理:使用PyPDFLoader加载PDF文档
2. 文本分块:使用RecursiveCharacterTextSplitter将文档分割成固定大小的块
3. 向量化:使用OpenAI embeddings将文本块转换为向量
4. 存储:使用FAISS构建向量数据库
5. 检索:基于查询向量相似性检索最相关的文档块
6. 生成:将检索结果作为上下文传递给LLM生成答案
伪代码:
def simple_rag(query, vectorstore):
# 检索相关文档
docs = vectorstore.similarity_search(query, k=2)
# 构建上下文
context = "\n".join([doc.page_content for doc in docs])
# 生成回答
prompt = f"Context: {context}\nQuestion: {query}\nAnswer:"
return llm.generate(prompt)
优势:实现简单,易于理解和部署
适用场景:小规模文档集,简单问答任务
2. 可靠RAG (Reliable RAG)
核心原理:在基础RAG基础上增加验证和精炼机制,确保检索信息的准确性和相关性。
关键特性:
- 检索文档相关性验证
- 突出显示用于回答的文档片段
- 增强的错误处理机制
实现要点:
def reliable_rag(query, vectorstore):
docs = vectorstore.similarity_search(query, k=5)
# 相关性验证
relevant_docs = []
for doc in docs:
relevance_score = evaluate_relevance(query, doc)
if relevance_score > threshold:
relevant_docs.append(doc)
return generate_answer(query, relevant_docs)
3. 块大小优化 (Chunk Size Optimization)
核心原理:通过实验不同的块大小找到最佳的平衡点,在保留上下文和维持检索速度之间取得平衡。
优化策略:
- 测试不同chunk_size(512, 1000, 2000等)
- 评估检索质量和响应速度
- 根据文档类型调整chunk_overlap
🔍 查询增强技术
4. HyDE (假设性文档嵌入)
核心原理:将查询问题转换为包含答案的假设性文档,旨在缩小查询和文档在向量空间中的分布差距。
工作流程:
1. 使用LLM根据查询生成假设性文档
2. 对假设性文档进行向量化
3. 使用假设性文档向量在向量数据库中检索
4. 返回最相似的真实文档
伪代码:
class HyDERetriever:
def generate_hypothetical_document(self, query):
prompt = f"Given the question '{query}', generate a hypothetical document that directly answers this question."
return llm.generate(prompt)
def retrieve(self, query, k=3):
hypothetical_doc = self.generate_hypothetical_document(query)
similar_docs = self.vectorstore.similarity_search(hypothetical_doc, k=k)
return similar_docs
优势:
- 提高复杂查询的检索相关性
- 处理语义差距较大的查询
- 适应不同类型的查询和文档领域
5. 查询变换 (Query Transformations)
核心原理:通过修改和扩展查询来提高检索效果。
变换类型:
- 查询重写:重新表述查询以提高检索效果
- 回退提示:生成更广泛的查询以获得更好的上下文检索
- 子查询分解:将复杂查询分解为更简单的子查询
实现示例:
def query_transformation(query):
# 查询重写
rewritten_query = rewrite_query(query)
# 回退提示
step_back_query = generate_broader_query(query)
# 子查询分解
sub_queries = decompose_query(query)
return [rewritten_query, step_back_query] + sub_queries
📚 上下文丰富技术
6. 语义分块 (Semantic Chunking)
核心原理:基于语义连贯性而非固定大小来分割文档,创建更有意义的文本片段。
分块策略:
- 百分位数:在差异大于X百分位数的地方分割
- 标准差:在差异大于X标准差的地方分割
- 四分位距:使用四分位距确定分割点
实现代码:
from langchain_experimental.text_splitter import SemanticChunker
text_splitter = SemanticChunker(
OpenAIEmbeddings(),
breakpoint_threshold_type='percentile',
breakpoint_threshold_amount=90
)
docs = text_splitter.create_documents([content])
优势:
- 保持语义连贯性
- 提高检索相关性
- 适应不同类型的文档结构
7. 上下文压缩 (Contextual Compression)
核心原理:在保留查询相关内容的同时压缩检索到的信息。
压缩流程:
1. 初始检索获取相关文档
2. 使用LLM分析并提取与查询最相关的部分
3. 生成压缩后的上下文
4. 基于压缩上下文生成答案
实现要点:
def contextual_compression(query, docs):
compressed_docs = []
for doc in docs:
prompt = f"Extract only the relevant parts for query: {query}\nDocument: {doc.content}"
compressed_content = llm.generate(prompt)
compressed_docs.append(compressed_content)
return compressed_docs
🚀 高级检索方法
8. 融合检索 (Fusion Retrieval)
核心原理:结合向量检索和关键词检索(BM25)的优势,提供更全面准确的检索结果。
融合策略:
1. 并行执行向量检索和BM25检索
2. 标准化两种方法的评分
3. 使用加权组合计算最终分数
4. 根据组合分数排序并返回top-k结果
核心算法:
def fusion_retrieval(vectorstore, bm25, query, k=5, alpha=0.5):
# 向量检索
vector_results = vectorstore.similarity_search_with_score(query, k=len(all_docs))
# BM25检索
bm25_scores = bm25.get_scores(query.split())
# 分数标准化
vector_scores = normalize_scores(vector_results)
bm25_scores = normalize_scores(bm25_scores)
# 融合计算
combined_scores = alpha * vector_scores + (1 - alpha) * bm25_scores
# 排序返回
return rank_and_return(combined_scores, k)
9. 重排序 (Reranking)
核心原理:对初始检索结果进行重新评估和排序,提供更准确的相关性排序。
重排序方法:
方法1:LLM重排序
def llm_reranking(query, docs):
scored_docs = []
for doc in docs:
prompt = f"Rate relevance (1-10): Query: {query}\nDocument: {doc.content}"
score = llm.generate(prompt)
scored_docs.append((doc, float(score)))
return sorted(scored_docs, key=lambda x: x[1], reverse=True)
方法2:交叉编码器重排序
def cross_encoder_reranking(query, docs):
cross_encoder = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
pairs = [[query, doc.content] for doc in docs]
scores = cross_encoder.predict(pairs)
return sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)
10. 层次索引 (Hierarchical Indices)
核心原理:创建多层次的信息导航和检索系统,包含文档摘要和详细块。
层次结构:
- 顶层:文档摘要
- 底层:详细文本块
- 元数据:指向相同位置的链接
实现逻辑:
def hierarchical_retrieval(query, summary_index, detail_index):
# 首先在摘要层检索
summary_docs = summary_index.similarity_search(query, k=3)
# 根据摘要元数据检索详细块
detail_docs = []
for summary in summary_docs:
chunk_ids = summary.metadata['chunk_ids']
chunks = detail_index.get_by_ids(chunk_ids)
detail_docs.extend(chunks)
return detail_docs
🔁 迭代和自适应技术
11. Self-RAG (自我检索增强生成)
核心原理:动态决定是否使用检索信息以及如何最好地利用它来生成响应的多步骤过程。
核心组件:
1. 检索决策:判断是否需要检索
2. 相关性评估:评估检索文档的相关性
3. 响应生成:基于相关上下文生成响应
4. 支持评估:评估响应的支持度
5. 效用评估:评估响应的有用性
完整流程:
def self_rag(query, vectorstore):
# 步骤1:检索决策
need_retrieval = llm.decide_retrieval(query)
if need_retrieval:
# 步骤2:文档检索
docs = vectorstore.similarity_search(query, k=3)
# 步骤3:相关性评估
relevant_docs = []
for doc in docs:
relevance = llm.evaluate_relevance(query, doc)
if relevance == 'relevant':
relevant_docs.append(doc)
# 步骤4:响应生成
responses = []
for doc in relevant_docs:
response = llm.generate_response(query, doc)
# 步骤5:支持度评估
support = llm.assess_support(response, doc)
# 步骤6:效用评估
utility = llm.evaluate_utility(query, response)
responses.append((response, support, utility))
# 选择最佳响应
best_response = max(responses, key=lambda x: (x[1], x[2]))
return best_response[0]
else:
return llm.generate_response(query, context="No retrieval necessary")
12. 自适应检索 (Adaptive Retrieval)
核心原理:根据查询类型和用户上下文动态调整检索策略。
自适应机制:
- 查询分类:将查询分为不同类别
- 策略选择:为每个类别使用定制的检索策略
- 上下文考虑:考虑用户上下文和偏好
🏗️ 高级架构
13. RAPTOR (递归抽象处理和树状组织检索)
核心原理:通过递归抽象处理和树状组织来处理大型文档集合的层次化检索系统。
核心组件:
- 树构建:创建分层文档摘要结构
- 嵌入和聚类:基于语义相似性组织文档
- 层次检索:在不同抽象层次间导航
树构建算法:
def build_raptor_tree(texts, max_levels=3):
results = {}
current_texts = texts
for level in range(1, max_levels + 1):
# 嵌入文本
embeddings = embed_texts(current_texts)
# 聚类
clusters = perform_clustering(embeddings)
# 生成摘要
summaries = []
for cluster in clusters:
cluster_texts = [texts[i] for i in cluster]
summary = llm.summarize(cluster_texts)
summaries.append(summary)
results[level] = summaries
current_texts = summaries
if len(current_texts) <= 1:
break
return results
14. 图RAG (Graph RAG)
核心原理:整合知识图谱的结构化数据来丰富上下文并改善检索效果。
实现流程:
1. 构建知识图谱:提取实体和关系
2. 图遍历:根据查询检索相关实体和关系
3. 上下文融合:结合结构化和非结构化数据
4. 增强生成:基于丰富上下文生成回答
核心算法:
def graph_rag(query, knowledge_graph, vectorstore):
# 实体识别
entities = extract_entities(query)
# 图遍历
graph_context = []
for entity in entities:
neighbors = knowledge_graph.get_neighbors(entity)
relations = knowledge_graph.get_relations(entity)
graph_context.extend(neighbors + relations)
# 向量检索
vector_context = vectorstore.similarity_search(query, k=3)
# 上下文融合
combined_context = combine_contexts(graph_context, vector_context)
return llm.generate(query, combined_context)
📊 评估技术
15. DeepEval评估
核心原理:使用综合指标评估RAG系统性能。
评估指标:
- 正确性(Correctness)
- 忠实度(Faithfulness)
- 上下文相关性(Contextual Relevancy)
评估实现:
def evaluate_rag_deepeval(questions, retriever):
results = []
for question in questions:
context = retriever.get_relevant_documents(question)
# 评估相关性
relevance = evaluate_relevance(question, context)
# 评估完整性
completeness = evaluate_completeness(question, context)
# 评估简洁性
conciseness = evaluate_conciseness(context)
results.append({
'question': question,
'relevance': relevance,
'completeness': completeness,
'conciseness': conciseness
})
return results
💡 实际应用指南
技术选择建议
- 简单场景:使用基础RAG + 重排序
- 复杂查询:使用HyDE + 融合检索
- 大规模文档:使用RAPTOR + 层次索引
- 实时系统:使用Self-RAG + 自适应检索
- 知识密集型:使用图RAG + 上下文压缩
性能优化策略
- 向量化优化:
- 选择合适的嵌入模型
- 调整chunk大小和重叠
- 使用语义分块
- 检索优化:
- 结合多种检索方法
- 实施重排序机制
- 使用层次索引
- 生成优化:
- 上下文压缩
- 提示工程
- 模型选择
部署考虑
- 延迟要求:选择轻量级模型和简单架构
- 准确性要求:使用多步验证和复杂架构
- 可扩展性:考虑分布式部署和缓存策略
- 成本控制:平衡模型调用次数和性能
🎯 技术发展趋势
- 多模态RAG:集成图像、音频等多种数据类型
- 实时RAG:支持实时数据更新和检索
- 个性化RAG:根据用户偏好动态调整
- 联邦RAG:分布式知识整合
- 可解释RAG:提供检索和生成的可解释性
结论
RAG技术正在快速发展,从简单的检索增强到复杂的自适应系统。每种技术都有其适用场景和优势。实际应用中,往往需要结合多种技术来构建高效、准确的RAG系统。
选择合适的技术组合需要考虑:
- 应用场景和需求
- 数据特性和规模
- 性能和成本要求
- 维护和扩展性
随着技术不断发展,RAG系统将变得更加智能、高效和可靠,为各种应用场景提供强大的支持。
文章评论