高级开发指南
本指南介绍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
)
高级生成技术
结构化输出生成
引导模型生成特定结构的输出:
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
# 定义输出模式
response_schemas = [
ResponseSchema(name="answer", description="对问题的直接回答"),
ResponseSchema(name="sources", description="用于回答的信息来源"),
ResponseSchema(name="confidence", description="对答案准确性的信心程度,从1-10"),
ResponseSchema(name="follow_up", description="可能的后续问题")
]
# 创建输出解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式说明
format_instructions = output_parser.get_format_instructions()
# 在提示中使用格式说明
prompt_template = """
基于以下上下文信息回答问题。
上下文信息:
{context}
问题: {question}
{format_instructions}
"""
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template(prompt_template)
# 创建链
chain = prompt | llm | output_parser
# 运行链
result = chain.invoke({
"context": "...",
"question": "...",
"format_instructions": format_instructions
})
# 结果是一个字典,包含所有定义的字段
print(f"回答: {result['answer']}")
print(f"信心: {result['confidence']}/10")
多步骤推理生成
通过拆解复杂问题提高回答质量:
# 思维链提示模板
cot_template = """
问题: {question}
让我们一步步思考:
1. 首先,我需要理解问题要求什么。
2. 然后,检查我有哪些相关信息。
3. 根据这些信息,分析可能的答案。
4. 检查我的推理是否合理。
5. 得出最终答案。
上下文信息:
{context}
逐步思考:
"""
# 使用思维链提示
cot_prompt = PromptTemplate(
template=cot_template,
input_variables=["question", "context"]
)
# 创建链
cot_chain = LLMChain(llm=llm, prompt=cot_prompt)
# 运行推理
reasoning = cot_chain.run(question="...", context="...")
# 提取最终答案
final_answer_prompt = f"""
基于以下推理过程,总结一个简洁的最终答案:
{reasoning}
最终答案:
"""
final_answer = llm(final_answer_prompt)
性能优化技术
向量数据库优化
优化向量存储的 检索性能:
# FAISS IVF-PQ索引配置示例
import faiss
import numpy as np
# 假设我们有嵌入向量集合
embeddings_array = np.array(embeddings_list).astype('float32')
dimension = embeddings_array.shape[1] # 向量维度
num_vectors = embeddings_array.shape[0] # 向量数量
# 创建IVF-PQ索引
nlist = min(4096, int(np.sqrt(num_vectors))) # 聚类中心数量
m = 16 # 子量化器数量 (通常为维度/2或维度/4)
nbits = 8 # 每个子量化器的位数
quantizer = faiss.IndexFlatL2(dimension) # 用于聚类的量化器
index = faiss.IndexIVFPQ(quantizer, dimension, nlist, m, nbits)
# 训练索引 (需要有足够的训练数据)
index.train(embeddings_array)
# 添加向量到索引
index.add(embeddings_array)
# 设置搜索参数
index.nprobe = 64 # 搜索时检查的聚类数量
# 保存优化后的索引
faiss.write_index(index, "optimized_index.faiss")
并行处理
利用并行处理提高RAG系统性能:
import asyncio
from concurrent.futures import ThreadPoolExecutor
from functools import partial
# 并行文档处理
async def process_documents_parallel(documents, chunk_size=1000, max_workers=4):
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size)
# 定义单文档处理函数
def process_single_doc(doc):
chunks = text_splitter.split_text(doc.page_content)
return [Document(page_content=chunk, metadata=doc.metadata) for chunk in chunks]
# 创建线程池
with ThreadPoolExecutor(max_workers=max_workers) as executor:
# 并行处理所有文档
tasks = []
for doc in documents:
tasks.append(
asyncio.get_event_loop().run_in_executor(
executor, partial(process_single_doc, doc)
)
)
# 等待所有任务完成
results = await asyncio.gather(*tasks)
# 合并结果
all_chunks = []
for chunks in results:
all_chunks.extend(chunks)
return all_chunks
# 并行嵌入生成
async def generate_embeddings_parallel(texts, batch_size=64, max_workers=4):
# 分批处理
batches = [texts[i:i+batch_size] for i in range(0, len(texts), batch_size)]
# 定义单批处理函数
def process_batch(batch):
return embeddings.embed_documents(batch)
# 并行处理所有批次
with ThreadPoolExecutor(max_workers=max_workers) as executor:
tasks = []
for batch in batches:
tasks.append(
asyncio.get_event_loop().run_in_executor(
executor, partial(process_batch, batch)
)
)
# 等待所有任务完成
results = await asyncio.gather(*tasks)
# 合并结果
all_embeddings = []
for batch_result in results:
all_embeddings.extend(batch_result)
return all_embeddings
高级RAG评估框架
设计全面的评估系统测量RAG性能:
from langchain.evaluation import EvaluatorType, StringEvaluator
from langchain.evaluation.schema import EvaluationResult
# 创建自定义评估器
class RAGEvaluator:
def __init__(self, llm, criteria=None):
self.llm = llm
self.criteria = criteria or {
"relevance": "回答与问题的相关性",
"accuracy": "回答的事实准确性",
"completeness": "回答的完整性",
"coherence": "回答的逻辑连贯性",
"citation": "引用来源的正确性"
}
def evaluate_response(self, query, response, reference=None, retrieved_docs=None):
# 构建评估提示
prompt = f"""
评估以下AI回答的质量。
问题: {query}
AI回答: {response}
"""
if reference:
prompt += f"\n 参考答案: {reference}"
if retrieved_docs:
doc_texts = "\n\n".join([f"文档 {i+1}: {doc.page_content}"
for i, doc in enumerate(retrieved_docs)])
prompt += f"\n\n检索到的文档:\n{doc_texts}"
prompt += "\n\n请对以下标准进行1-5分的评分,并解释原因:\n"
for criterion, description in self.criteria.items():
prompt += f"- {criterion}({description}): [1-5]\n"
# 获取评估结果
evaluation = self.llm(prompt)
# 解析评估结果
parsed_results = self._parse_evaluation(evaluation)
return parsed_results
def _parse_evaluation(self, evaluation_text):
results = {}
for criterion in self.criteria:
# 使用正则表达式提取分数
import re
pattern = f"{criterion}.+?(\d+)"
match = re.search(pattern, evaluation_text, re.IGNORECASE)
if match:
score = int(match.group(1))
results[criterion] = score
# 计算总分
if results:
results["average_score"] = sum(results.values()) / len(results)
# 添加原始评估文本
results["explanation"] = evaluation_text
return results
# 使用评估器
evaluator = RAGEvaluator(llm=ChatOpenAI(model="gpt-4"))
test_cases = [
{
"query": "什么是向量数据库?",
"reference": "向量数据库是专门设计用于存储和检索向量嵌入的数据库系统。它们使用特殊的索引算法来实现高效的相似性搜索。"
},
# 添加更多测试用例
]
evaluation_results = []
for case in test_cases:
# 运行RAG系统获取回答
response = qa_chain({"query": case["query"]})
# 获取检索到的文档
retrieved_docs = retriever.get_relevant_documents(case["query"])
# 评估回答
eval_result = evaluator.evaluate_response(
query=case["query"],
response=response["result"],
reference=case.get("reference"),
retrieved_docs=retrieved_docs
)
evaluation_results.append({
"query": case["query"],
"response": response["result"],
"evaluation": eval_result
})
# 分析评估结果
def analyze_evaluation_results(results):
criteria = results[0]["evaluation"].keys()
criteria = [c for c in criteria if c != "explanation" and c != "average_score"]
# 计算每个标准的平均分
avg_scores = {}
for criterion in criteria:
scores = [r["evaluation"].get(criterion, 0) for r in results]
avg_scores[criterion] = sum(scores) / len(scores)
# 添加总平均分
avg_scores["overall"] = sum(avg_scores.values()) / len(avg_scores)
return avg_scores
analysis = analyze_evaluation_results(evaluation_results)
print("RAG系统评估结果:", analysis)
高级部署策略
向量数据库选择指南
不同规模应用的向量数据库选择建议:
| 数据规模 | 推荐数据库 | 部署方式 | 注意事项 |
|---|---|---|---|
| 小型(100K向量) | FAISS, Chroma | 单机内存或持久化 | 简单设置但扩展性有限 |
| 中型(100K-10M向量) | Qdrant, Weaviate, Milvus | 单服务器或小型集群 | 需考虑索引方式和查询优化 |
| 大型(10M+向量) | Pinecone, Elasticsearch(kNN), Vespa | 分布式集群 | 需专注分片策略、容错和扩展性 |
多阶段部署架构
一个生产级RAG系统的高级部署架构:
+------------------+ +------------------+ +---------------+
| | | | | |
| 前端应用/API网关 +------>+ 应用服务层 +------>+ RAG核心服务 |
| | | | | |
+------------------+ +------------------+ +-------+-------+
|
v
+------------------+ +------------------+ +-------+-------+
| | | | | |
| 监控与分析系统 +<------+ 缓存层 |<------+ 向量数据库 |
| | | | | |
+------------------+ +------------------+ +---------------+
- 前端应用/API网关:处理用户请求、认证和负载均衡
- 应用服务层:业务逻辑处理、会话管理和请求转发
- RAG核心服务:查询处理、检索和生成逻辑
- 向量数据库:存储和检索向量嵌入
- 缓存层:缓存常见查询结果和嵌入
- 监控与分析系统:跟踪性能指标和用户反馈
高效RAG系统的关键性能指标
监控以下指标评估系统性能:
- 检索相关性得分:检索结果与查询的相关性
- 生成质量评分:最终回答的质量评估
- 端到端延迟:从查询到响应的总时间
- 检索延迟:向量检索所需时间
- 生成延迟:LLM生成回答所需时间
- 检索精确率/召回率:检索结果的准确性和完整性
- 用户满意度:用户反馈和满意度指标
- 系统吞吐量:系统每秒处理的查询数
- 成本效率:每次查询的平均成本
- 知识覆盖率:系统能回答的查询比例
结论
本指南介绍了RAG系统的高级架构和优化技术。通过采用多步骤RAG、混合检索策略和高级生成技术,开发者可以构建更智能、更高效的AI应用。随着RAG技术的不断发展,持续学习和实验将帮助您保持竞争优势。
下一步建议探索更多RAG相关资源,如开源框架、研究论文和实际案例研究,以进一步提升您的RAG开发技能。