一、RAG架构概览与核心原理
RAG(Retrieval-Augmented Generation,检索增强生成)是当前大语言模型应用中最核心的技术范式之一。它的基本思路是:在LLM生成回答之前,先从外部知识库中检索出与用户问题最相关的上下文片段,然后将这些片段连同问题一起交给LLM生成最终回答。
这种方式有两个显著优势:第一,解决了LLM的知识截止问题,让模型能回答训练数据之外的新知识;第二,大幅降低了幻觉问题,因为模型可以用检索到的真实文档作为回答依据。
传统RAG的基本流程如下:用户提问向量化后,到向量数据库中去检索相关的文档片段,将检索结果作为上下文填入Prompt,再传给大模型生成最终回答。整个过程虽然思路简洁,但工程实现中有大量的细节需要优化。
二、文档预处理与智能分块策略
原始文档的质量直接决定了RAG系统的上限。实际业务中,文档可能来自PDF、Word、网页、数据库等多种来源,第一步需要做的是文档清洗和标准化。
文档清洗要处理的问题包括:去除无关的页眉页脚、处理断裂的行、移除重复内容、识别并保留表格结构。在Python生态中,可以使用unstructured或marker这样的库来完成这些预处理工作。
分块策略是RAG中最关键的参数之一。常见的分块方式包括固定长度分块、按段落分块、递归分块和语义分块。固定长度分块实现简单但容易切断语义,递归分块则是先按大段落拆分,如果段落过长再进一步细分。推荐使用LangChain的RecursiveCharacterTextSplitter,它支持多种分隔符的优先级排列。
实战中最优的chunk_size通常在256到1024个token之间,同时建议设置10%-20%的重叠率。重叠的内容能减少上下文割裂感,在边界处保留语义的连贯性。
三、Embedding模型选型与向量存储
Embedding模型的作用是将文本转化为高维向量,使语义相似的文本在向量空间中距离更近。目前主流的选择包括OpenAI的text-embedding系列、智谱的text-embedding-v3、以及开源的bge-m3和bce-embedding-base等。
需要考虑的因素包括:向量维度越高检索越精确但存储成本相应上升;中文场景下优先选择经过中文语料充分训练的模型;跨语言场景则选择多语言模型。向量数据库方面,本地开发可以用FAISS,中小规模生产级应用推荐Milvus或Qdrant,全托管方案可选择Pinecone或Weaviate。
在存储向量时,建议同时存储原文片段、文档来源、时间戳等元数据字段,这样后续可以做时间加权和来源过滤等高级检索优化。对于切分后的长文档,元数据中还需记录片段的序号和前后文关系,在检索命中后能自动拼接相邻片段,提供更完整的上下文。
四、检索优化:混合检索与重排序
语义检索能够理解用户问题的意图,在处理"如何做X"和"X的方法"这种语义相同但字面不同的查询时,有明显优势。但在处理关键词精确匹配、专有名词、数字比较等场景时必须配合关键词检索。混合检索结合了向量检索和BM25两种方式,通过加权融合的方式综合两路检索结果。
LangChain的EnsembleRetriever可以方便地实现这一策略,设置两个检索器的权重即可。BM25的权重通常在0.3到0.7之间,根据场景调节。如果搜索内容多为专有名词或技术术语,BM25权重可以调高;如果多为自然语言描述,则可以调低。
重排序是进一步提升检索质量的利器。当第一轮检索召回后,用一个专门的重排序模型对结果重新打分。目前效果优秀的开源模型包括bge-reranker-v2-m3,它在多个公开基准上表现出色。重排序的计算开销比首次检索大得多,因此通常只在召回阶段保留较多候选文档,重排序后取前几名。
生产级RAG系统通常采用多级漏斗架构:首轮向量检索召回较多候选,重排序保留一部分,再传给大模型。每一级都可以配合相应的过滤规则和阈值设置。
五、Prompt工程与上下文管理
检索到相关文档后,如何有效地组织Prompt直接影响最终生成质量。在RAG系统中,经典的Prompt模板如下:
系统提示定义角色为基于给定文档回答技术问题的AI助手,强调只基于上下文回答且不要胡编乱造,没有足够信息时直接拒绝回答。用户消息则包含上下文和用户问题。
对于多轮对话场景,需要对历史对话做上下文压缩处理,否则随着对话轮次增长,对话历史会很快超出模型上下文窗口。常见的压缩策略包括:使用LLM对历史对话做摘要,每轮只保留最近几轮原始对话,以及提取关键信息形成结构化摘要。
另一个容易被忽略的问题是上下文噪声。如果检索到的某个片段与当前问题无关,模型可能会被干扰。可以使用让模型先对每个片段做相关性评分的预处理策略,过滤掉低分片段后再传入Prompt。
六、多轮对话记忆设计
优秀的RAG应用需要维持连贯的多轮对话体验,这不仅要求系统记住之前的问答历史,还要求能以这些历史作为上下文帮助后续问答。实现方案是为每个用户分配一个session_id,根据session_id来检索和更新该用户的对话历史。
短期记忆可以使用Redis之类的缓存来存储最近的对话轮次,长期记忆则需要将对话摘要存入数据库。高级的记忆系统还会自动提取用户偏好和关注点,作为个性化检索的过滤条件。
实现多轮对话的关键在于合理管理上下文窗口:每轮对话都会消耗token空间,因此要根据模型的最大上下文长度严格控制总大小。同时,对历史对话进行分段存储、按时间权重衰减检索也是缓解窗口压力的有效方法。
七、生产部署与效果评估
将RAG系统投入生产需要解决多个工程问题。首先是并发与吞吐量:在Python生态中推荐使用FastAPI作为Web框架,配合uvicorn的异步worker来支撑高并发。建议将整个链路做异步化,检索和生成可以部分并行,同时放在负载均衡器后面来分发请求。
其次是缓存与批处理:对高频问题做结果缓存以减少重复计算,对嵌入计算建议使用批量处理来提升GPU利用率。Redis或类似的内存缓存层可以有效降低对下游Embedding服务的请求压力。
效果评估方面,RAG系统有多个需要关注的指标:检索阶段的召回率和精确率可以用标注数据集来衡量,生成阶段的回答质量可以使用忠实度(回答是否基于检索内容)、相关性和流畅度三个维度来综合评判。目前业界比较流行的自动化评估框架包括RAGAS和TruLens。
在性能监控上,需要追踪每个环节的时间消耗、召回文档的相关性分数以及用户反馈等指标。这些监控数据也是后续迭代调优的重要依据。

发表评论 取消回复