高级开发指南
本指南介绍RAG(检索增强生成)系统的高级架构和优化技术,帮助开发者构建更智能、更高效的AI应用。
高级RAG架构模式
多步骤RAG
传统的单步骤RAG在复杂查询中可能不够高效,多步骤RAG通过分解查询-检索-生成过程提高性能:
from langchain.chains import create_retrieval_chain
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
# 1. 查询理解与分解
def decompose_query(query):
decompose_prompt = f"""
将以下复杂问题分解为2-3个简单的子问题,每个子问题应该能独立回答:
问题: {query}
子问题:
"""
response = llm(decompose_prompt)
# 解析响应获取子问题列表
sub_queries = [q.strip() for q in response.split('\n') if q.strip()]
return sub_queries
# 2. 子查询检索
def retrieve_for_subqueries(subqueries):
all_documents = []
for query in subqueries:
docs = retriever.get_relevant_documents(query)
all_documents.extend(docs)
return all_documents
# 3. 信息综合
def synthesize_answer(query, documents):
# 使用所有检索到的文档和原始查询生成最终答案
synthesize_prompt = f"""
基于以下信息回答问题: {query}
信息:
{documents}
请综合以上信息提供完整回答:
"""
return llm(synthesize_prompt)
# 组合成完整流程
def advanced_rag_query(query):
subqueries = decompose_query(query)
documents = retrieve_for_subqueries(subqueries)
answer = synthesize_answer(query, documents)
return answer
迭代式RAG
迭代RAG通过多轮检索和生成过程提高答案质量:
# 迭代式RAG基本流程
def iterative_rag(query, max_iterations=3):
context = []
answer = ""
for i in range(max_iterations):
# 结合当前上下文优化查询
augmented_query = query
if context:
augmented_query = f"""
原始问题: {query}
已知信息: {context}
基于以上信息,我还需要查询什么以完整回答原始问题?
"""
augmented_query = llm(augmented_query)
# 检索新信息
new_docs = retriever.get_relevant_documents(augmented_query)
# 将新信息添加到上下文
new_content = "\n".join([doc.page_content for doc in new_docs])
context.append(new_content)
# 生成回答
answer_prompt = f"""
基于以下信息回答问题: {query}
信息:
{context}
回答:
"""
answer = llm(answer_prompt)
# 检查答案是否足够完整
completeness_check = f"""
问题: {query}
当前答案: {answer}
这个答案是否已经完整地回答了问题?
回复 "完整" 或 "需要更多信息"。
"""
check_result = llm(completeness_check)
if "完整" in check_result:
break
return answer
检索增强重排序
利用LLM对检索结果进行重排序,提高相关性:
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMRerank
# 创建LLM重排序器
reranker = LLMRerank(
llm=llm,
query_key="query",
document_key="context",
top_n=4 # 保留前4个结果
)
# 创建重排序检索器
rerank_retriever = ContextualCompressionRetriever(
base_retriever=vector_retriever,
base_compressor=reranker
)
# 使用示例
query = "什么是向量数据库的量化技术?"
reranked_docs = rerank_retriever.get_relevant_documents(query)
高级检索技术
混合检索策略
结合多种检索方法可以提高相关性和覆盖面:
# 导入必要库
from langchain.retrievers import BM25Retriever, EnsembleRetriever
from langchain.retrievers.multi_query import MultiQueryRetriever
# 创建关键词检索器
bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 5 # 每次检索5个文档
# 创建向量检索器
vector_retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": 5})
# 多查询生成器
def generate_queries(question):
prompt = f"""
基于以下问题,生成3个不同角度的相关查询:
{question}
"""
response = llm(prompt)
queries = [q.strip() for q in response.split('\n') if q.strip()]
return queries
# 创建多查询检索器
multi_query_retriever = MultiQueryRetriever(
retriever=vector_retriever,
llm=llm,
query_generator=generate_queries,
parser_key="lines"
)
# 创建集成检索器
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, multi_query_retriever, vector_retriever],
weights=[0.2, 0.4, 0.4] # 各检索器权重
)
# 使用示例
query = "神经网络如何进行反向传播?"
docs = ensemble_retriever.get_relevant_documents(query)
语义压缩检索
减少检索内容冗余,提高效率:
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.retrievers.document_compressors import DocumentCompressorPipeline
from langchain.retrievers.document_compressors import EmbeddingsFilter
from langchain.retrievers import ContextualCompressionRetriever
# 创建文本分割器
splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=30)
# 创建嵌入相似度过滤器
embeddings_filter = EmbeddingsFilter(
embeddings=embeddings,
similarity_threshold=0.8 # 相似度阈值
)
# 创建LLM提取器
llm_extractor = LLMChainExtractor.from_llm(llm)
# 创建压缩管道
compressor = DocumentCompressorPipeline(
transformers=[splitter, embeddings_filter, llm_extractor]
)
# 创建压缩检索器
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vector_retriever
)