RAG检索增强生成工程实践:从向量检索到知识库问答系统搭建

RAG技术原理与架构选型

检索增强生成(Retrieval-Augmented Generation,RAG)是人工智能领域解决大模型幻觉与知识时效性问题的主流方案。核心思路是在大模型生成回答之前,先从外部知识库检索相关文档片段,将检索结果注入提示词上下文,让模型基于真实资料组织答案。

一套完整的RAG系统包含三个核心模块:文档处理与向量化、向量检索引擎、大模型推理接口。文档处理阶段需要将PDF、Word、网页等异构数据清洗为纯文本,按语义边界切分为合适长度的chunk,再通过Embedding模型转换为高维向量写入向量数据库。检索阶段接收用户查询,同样做向量化后在向量库中做近似最近邻搜索(ANN),返回Top-K相关片段。生成阶段将检索到的上下文与用户问题拼接为完整提示词,交由大模型生成最终答案。

当前主流架构选型:Embedding模型推荐bge-large-zh-v1.5或m3e-base(中文场景),向量数据库选用Milvus(分布式大规模)或ChromaDB(轻量单机),大模型接口对接vLLM或Ollama本地部署的Qwen2.5系列。开源框架层面,LlamaIndex适合快速原型搭建,LangChain灵活度更高但学习曲线陡峭,直接用Python手写RAG管线对生产环境更可控。

文档切分策略与向量化实践

文档切分直接影响检索质量。固定长度切分(如每chunk 512 token)实现简单,但容易截断完整语义段落。推荐按段落标题层级切分:先提取Markdown或HTML的h1/h2结构,在每个标题下的内容块做切分,chunk上限设为800 token,overlap 100 token保留上下文衔接。

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    separators=["\n## ", "\n### ", "\n\n", "\n", "\u3002", " "],
    chunk_size=800,
    chunk_overlap=100,
    length_function=lambda x: len(x)
)
chunks = splitter.split_text(document_text)

向量化阶段要注意Embedding模型的max_length限制,bge-large-zh-v1.5支持最长512 token输入,超出部分会被截断。因此chunk长度控制在512以内能保证信息完整编码。批量写入向量数据库时,推荐batch size为256,避免单次请求payload过大。

from pymilvus import Collection, connections

connections.connect(host="localhost", port=19530)
collection = Collection("knowledge_base")

embeddings = embedding_model.encode(chunks, batch_size=256, normalize_embeddings=True)
entities = [
    {"name": "vector", "values": embeddings.tolist()},
    {"name": "text", "values": chunks},
    {"name": "source", "values": sources}
]
collection.insert(entities)

混合检索与重排序优化

纯向量检索在关键词精确匹配场景(如产品型号、错误码)表现不佳,需要引入BM25关键词检索做补充。混合检索(Hybrid Search)将向量相似度分数与BM25分数加权融合,典型权重配比为向量0.7、关键词0.3,可根据实际数据集调整。

重排序(Rerank)是提升检索精度的关键步骤。先用向量+BM25混合检索召回Top-20候选文档,再通过交叉编码器(Cross-Encoder)对query-document对做精细打分重排,取Top-5注入大模型上下文。bge-reranker-v2-m3是当前中文场景表现较好的重排模型,推理延迟约50ms/query,在准确率和速度间取得平衡。

from sentence_transformers import CrossEncoder

reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
pairs = [[query, doc] for doc in candidate_docs]
scores = reranker.predict(pairs)
ranked_indices = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)
top_docs = [candidate_docs[i] for i in ranked_indices[:5]]

上下文窗口管理与生成质量控制

注入大模型的检索上下文长度需要精细控制。假设模型上下文窗口8K token,系统提示词占1K,对话历史占2K,留给检索上下文的空间约3K,剩余2K为模型生成预留。5条检索结果平均每条600 token,刚好填满3K预算。

生成质量的常见问题与应对策略:幻觉输出可在系统提示词中强制要求”仅根据提供的参考资料回答,无法回答时直接说明”;重复检索可通过query改写(将用户口语化提问扩展为多个检索query)提升召回率;多轮对话场景需维护对话摘要,避免上下文窗口溢出。

system_prompt = """你是一个专业的知识库问答助手。请严格根据以下参考资料回答用户问题。
如果参考资料中没有相关信息,请直接回答"根据现有资料无法回答该问题",不要编造内容。

参考资料:
{context}
"""

prompt = system_prompt.format(context="\n\n".join(top_docs)) + f"\n\n用户问题:{query}"

生产环境部署与性能调优

RAG系统上线需要关注三个性能指标:检索延迟、生成延迟、端到端响应时间。向量检索在Milvus中HNSW索引查询延迟通常在10ms以内,瓶颈在大模型推理。vLLM部署Qwen2.5-72B-Instruct在A100上单请求推理约800ms(生成256 token),批量推理配合continuous batching可提升吞吐3-5倍。

缓存策略对降低延迟效果显著:对高频query做语义缓存,将query的Embedding与已有缓存做余弦相似度比较,阈值0.95以上直接返回缓存答案,避免重复检索和生成。Redis存储缓存结果,TTL设为24小时,知识库更新时主动清除相关缓存。

监控维度包括:检索召回率(离线标注query-doc对计算Recall@K)、答案正确率(人工评测抽样)、幻觉率(生成内容与检索上下文不一致的比例)、P95端到端延迟。推荐用LangSmith或自建评测流水线定期跑自动化测试集,量化跟踪RAG系统质量变化趋势。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rag-jian-suo-zeng-qiang-sheng-cheng-gong-cheng-shi-jian/

(0)
小编小编
上一篇 3小时前
下一篇 2小时前

相关推荐