RAG架构核心原理与检索增强生成技术解析
检索增强生成(Retrieval-Augmented Generation,RAG)已成为企业落地大模型应用的主流范式。RAG的核心思路是在大模型生成回答前,先从外部知识库中检索相关文档片段,将检索结果作为上下文拼接到Prompt中,让模型基于真实数据生成回答。这种架构有效解决了大模型知识滞后、幻觉编造和领域知识缺失三大痛点。
RAG系统由三个核心模块组成:文档处理与向量化、向量检索、大模型生成。文档处理模块负责将PDF、Word、HTML等格式文档拆分为合适大小的Chunk,通过Embedding模型将文本转为向量存入向量数据库。检索模块接收用户Query,计算Query向量与文档向量的相似度,返回Top-K相关文档。生成模块将检索到的文档与用户问题拼接后送入大模型,输出最终回答。
文档分块策略与Chunk大小对检索质量的影响
文档分块(Chunking)是RAG系统的基础环节,分块策略直接决定检索精度。常见的分块方式包括固定长度分块、按段落/句子分块、语义分块(Semantic Chunking)三种。
固定长度分块实现简单,按N个Token切割,相邻块之间可设置Overlap重叠区域,避免语义截断。段落级分块保留文档原始结构,适合结构清晰的文档。语义分块利用Embedding相似度判断语义边界,在语义变化处切割,质量最高但计算开销也最大。
Chunk大小选择需要权衡:过小的Chunk信息不完整,检索时缺少上下文;过大的Chunk引入噪声,降低检索精度。实测数据表明,对于中文技术文档,512 Token的Chunk配合50 Token的Overlap,在语义完整性和检索精度之间取得较好的平衡。代码类文档建议使用AST感知的分块方式,按函数/类定义切割。
向量数据库选型对比与性能基准测试
向量数据库是RAG系统的存储和检索核心,选型需从性能、功能、运维三个维度评估。以下对主流方案做对比分析:
Milvus:开源分布式向量数据库,支持水平扩展,GPU加速索引构建,适合千万级以上向量规模的生产环境。提供FLAT、IVF_FLAT、IVF_SQ8、HNSW等多种索引类型,其中HNSW在召回率和延迟之间表现最佳。社区活跃,生态完善,但运维复杂度较高。
Weaviate:内置多模态支持,GraphQL查询接口,开箱即用的混合检索(向量+关键词)。单机部署简单,集群扩展能力弱于Milvus,适合百万级向量的中等规模场景。
Qdrant:Rust实现,内存占用低,过滤性能优秀,支持Payload过滤条件与向量检索的组合查询。适合需要复杂元数据过滤的业务场景。
Pgvector:PostgreSQL扩展,适合已有PG技术栈的团队快速接入,但大规模向量检索性能弱于专用方案,千万级以上不推荐。
混合检索策略与Rerank重排序优化
纯向量检索存在语义漂移问题——用户Query与文档的语义相似但实际不相关时会产生误召回。混合检索(Hybrid Search)同时执行向量检索和关键词检索(BM25),将两路结果融合后排序,显著提升召回质量。
融合方式常用Reciprocal Rank Fusion(RRF),对两路检索结果分别计算排名分数,按公式合并:
rrf_score = sum(1.0 / (k + rank_i)) # k通常取60
RRF无需调参,对两路检索结果的相关性不敏感,鲁棒性好。
进一步优化可引入Rerank模型,在初步检索返回Top-K(如100条)候选后,用Cross-Encoder对Query与每个候选文档做精细相关性打分,取Top-N(如5条)送入大模型。BGE-Reranker、Cohere Rerank是常用选择,Rerank后检索精度可提升15%-30%。
RAG生产环境部署架构与工程实践
生产级RAG系统需要考虑高可用、可观测和持续迭代三个维度:
高可用层面,向量数据库建议至少3节点集群部署,Embedding服务与大模型服务独立扩缩容,检索和生成两个阶段解耦,避免大模型推理慢请求阻塞检索链路。
可观测层面,对检索召回率、生成回答准确率、端到端延迟三个核心指标做监控。检索质量评估可离线构建测试集,定期跑自动化评测;生成质量可通过用户反馈(点赞/踩)持续收集标注数据。
持续迭代层面,知识库需定期更新增量文档,Embedding模型迭代后全量向量需要重新构建索引。建议维护文档版本管理,支持增量索引和全量重建两种模式,配合CI/CD流水线实现知识库自动更新。
# RAG检索+生成核心流程伪代码
def rag_query(user_query, top_k=5):
# 1. 向量检索
query_embedding = embed_model.encode(user_query)
vector_results = vector_db.search(query_embedding, top_k=100)
# 2. 关键词检索
keyword_results = bm25_search(user_query, top_k=100)
# 3. RRF融合
fused = reciprocal_rank_fusion(
[vector_results, keyword_results], k=60
)[:20]
# 4. Rerank重排序
reranked = reranker.rank(user_query, fused)[:top_k]
# 5. 构建Prompt并生成
context = "\n".join([doc.text for doc in reranked])
prompt = f"基于以下参考资料回答问题:\n{context}\n问题: {user_query}"
answer = llm.generate(prompt)
return answer
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rag-jian-suo-zeng-qiang-sheng-cheng-jia-gou-she-ji-yu-xiang/