RAG检索增强生成系统的核心架构
检索增强生成(Retrieval-Augmented Generation,RAG)是大模型应用落地的关键技术路径。传统大模型存在知识截止、幻觉问题和领域知识缺失三大短板,RAG通过在生成前从外部知识库检索相关文档,将检索结果注入Prompt上下文,有效缓解上述问题。一套完整的人工智能RAG系统包含文档处理、向量嵌入、检索引擎和生成模型四个核心模块。
文档处理模块负责将PDF、Word、HTML等非结构化数据清洗、分块(Chunking)。分块策略直接影响检索质量,常见做法是按固定token数(如512)滑动窗口切分,重叠区域设10%-20%防止语义截断。向量嵌入模块使用Embedding模型将文本块转化为高维向量,主流选择包括OpenAI text-embedding-3-small、BGE-large-zh和m3e-base等开源模型。
向量数据库选型与Embedding模型对比
向量数据库是RAG系统的存储与检索引擎。Milvus、Qdrant、Weaviate和Chroma是主流选择。Milvus适合大规模生产环境,支持十亿级向量检索;Qdrant用Rust编写,内存占用低,单机性能出色;Chroma适合轻量级原型验证。
Embedding模型的选择需要平衡效果、速度和成本。BGE-large-zh在中文检索任务上表现突出,MTEB榜单排名靠前;m3e-base模型体积小,适合本地部署。维度越高检索精度通常越好,但存储和计算成本也相应增加。
使用Milvus搭建向量检索引擎
以下代码展示如何用Milvus和Sentence Transformers搭建一个基础向量检索引擎:
from sentence_transformers import SentenceTransformer
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection
# 加载Embedding模型
model = SentenceTransformer('BAAI/bge-large-zh-v1.5')
# 连接Milvus
connections.connect(host='localhost', port='19530')
# 定义集合Schema
fields = [
FieldSchema(name='id', dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, dim=1024),
FieldSchema(name='text', dtype=DataType.VARCHAR, max_length=4096),
FieldSchema(name='source', dtype=DataType.VARCHAR, max_length=256)
]
schema = CollectionSchema(fields, 'RAG知识库向量集合')
collection = Collection('rag_kb', schema)
# 创建IVF索引
collection.create_index(
field_name='embedding',
index_params={'index_type': 'IVF_FLAT', 'metric_type': 'L2', 'params': {'nlist': 1024}}
)
# 插入文档向量
documents = [
'RAG通过检索外部知识库增强大模型生成能力',
'向量数据库支持高效的语义相似度检索'
]
embeddings = model.encode(documents)
collection.insert([
embeddings.tolist(),
documents,
['doc1.pdf', 'doc2.pdf']
])
# 检索Top-K相关文档
query = '大模型如何获取外部知识'
query_vec = model.encode([query])
collection.load()
results = collection.search(
data=query_vec.tolist(),
anns_field='embedding',
param={'metric_type': 'L2', 'params': {'nprobe': 16}},
limit=5,
output_fields=['text', 'source']
)
for hit in results[0]:
print(f'Score: {hit.score:.4f}, Text: {hit.entity.get("text")[:80]}')
Prompt工程与检索结果融合策略
检索到相关文档后,如何将文档内容融入Prompt直接影响生成质量。常见策略包括:
直接拼接:将检索到的文档片段按相关度排序,截取Top-K后直接拼接到用户问题前面。简单有效,但文档过长时容易超出上下文窗口。
摘要压缩:先用小模型对每个检索文档生成摘要,再将摘要拼入Prompt。减少token消耗,但可能丢失细节信息。
重排序(Reranking):用Cross-Encoder模型对初次检索结果做二次排序,提升精度。BGE-reranker-large是常用的重排序模型,效果显著优于纯向量相似度。
构建检索增强生成的完整调用链
以下代码展示完整的RAG调用流程,包含检索、重排序和生成三个阶段:
import requests
def rag_pipeline(query, collection, embed_model, rerank_model, llm_api):
# 第一步:向量检索
query_vec = embed_model.encode([query])
collection.load()
search_results = collection.search(
data=query_vec.tolist(),
anns_field='embedding',
param={'metric_type': 'L2', 'params': {'nprobe': 16}},
limit=20,
output_fields=['text', 'source']
)
# 第二步:重排序
candidates = [hit.entity.get('text') for hit in search_results[0]]
rerank_scores = rerank_model.predict([(query, c) for c in candidates])
ranked = sorted(zip(candidates, rerank_scores), key=lambda x: x[1], reverse=True)
top_docs = [doc for doc, score in ranked[:5]]
# 第三步:构造Prompt并调用LLM
context = '\n\n'.join(top_docs)
prompt = f'请根据以下参考信息回答问题。\n\n参考信息:\n{context}\n\n问题:{query}\n\n回答:'
resp = requests.post(llm_api, json={
'messages': [{'role': 'user', 'content': prompt}],
'temperature': 0.3,
'max_tokens': 1024
})
return resp.json()['choices'][0]['message']['content']
# 调用示例
answer = rag_pipeline(
query='RAG系统如何解决大模型幻觉问题',
collection=collection,
embed_model=model,
rerank_model=rerank_model,
llm_api='https://api.example.com/v1/chat/completions'
)
print(answer)
RAG系统评估指标与优化方向
评估RAG系统需要从检索质量和生成质量两个维度度量。检索质量用召回率(Recall@K)和精确率(Precision@K)衡量,生成质量用Faithfulness(生成内容是否忠于检索文档)和Answer Relevance(回答与问题的相关度)衡量。RAGAS框架提供了自动化评估工具,支持批量评测。
优化方向包括:调整Chunk大小和重叠比例、更换更强大的Embedding模型、引入混合检索(向量+BM25关键词)、优化重排序模型、迭代Prompt模板。每个环节的微小改进都可能显著提升端到端效果。生产环境中建议建立持续评估机制,每次迭代后跑全量评测集,用数据驱动优化决策。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rag-jian-suo-zeng-qiang-sheng-cheng-xi-tong-da-jian-shi/