news 2026/9/19 8:54:12

大模型RAG实战指南:从架构设计到生产落地的全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型RAG实战指南:从架构设计到生产落地的全流程解析

1. 大模型RAG到底是什么,为什么值得你花时间搞懂

RAG这三个字母,全称是Retrieval-Augmented Generation,翻译过来就是检索增强生成。我第一次接触这个概念的时候,脑子里冒出来的第一个问题是:大模型不是已经能回答问题了吗,为什么还要多此一举去“检索”?

后来在实际项目里踩了坑才明白,大模型有两个硬伤是绕不过去的。第一个是知识截止问题,模型训练完之后,新发生的事情它一概不知,你问它上个月的公司财报数据,它要么胡编要么直接说不知道。第二个是幻觉问题,模型在不确定的时候特别擅长“一本正经地胡说八道”,编出来的答案格式工整、语气笃定,但内容完全是错的。

RAG解决的就是这两个问题。它的核心思路特别朴素:既然模型自己不知道,那我就在提问的时候,把相关的资料一起塞给它,让它“看着资料回答”。这就像开卷考试和闭卷考试的区别,闭卷考试靠记忆,容易记错;开卷考试可以翻书,答案的准确率自然高出一大截。

具体来说,RAG做的事情分三步。第一步是检索,从你准备好的知识库里找到和用户问题最相关的几段内容。第二步是增强,把检索到的内容和用户的原始问题拼成一个完整的提示词,一起送给大模型。第三步是生成,大模型基于这些参考资料生成最终的回答。

这套流程听起来简单,但真正落地的时候,每一个环节都有大量的细节需要打磨。检索用什么方式?向量检索还是关键词检索?知识库怎么切分?切多大块合适?检索回来多少条?怎么排序?提示词怎么设计才能让模型老老实实基于资料回答而不是自由发挥?这些问题没有标准答案,需要根据具体场景反复调试。

这篇文章适合谁看?如果你是大模型应用的开发者,正在做企业知识库问答、智能客服、文档助手这类产品,RAG是你必须掌握的核心技术。如果你是产品经理或者技术负责人,想了解RAG能做什么、不能做什么、成本大概多少,这篇文章也能给你一个清晰的判断依据。如果你只是对大模型感兴趣,想搞清楚RAG和微调到底有什么区别,我也会用最直白的方式讲清楚。

我自己的经验是,RAG看起来简单,但要做好非常考验工程能力。一个demo级别的RAG系统可能半天就能搭起来,但要做到生产可用,准确率、响应速度、成本控制这三个指标会把你折磨得够呛。接下来我会把整个RAG系统的设计思路、核心细节、实操步骤、常见坑点全部拆开讲,尽量让你少走弯路。

2. RAG系统的整体架构设计与核心思路拆解

2.1 为什么是RAG而不是微调

很多人第一次接触RAG的时候会问:我想让大模型掌握我自己的数据,为什么不直接微调呢?

这个问题我当初也纠结过。微调的逻辑是,拿你自己的数据去继续训练模型,让模型的参数里“记住”这些知识。听起来很直接,但实际操作下来有几个问题。

第一是成本。微调一个大模型,哪怕是7B参数量的,也需要相当可观的GPU资源。而且每次知识更新都要重新训练,这个成本对于大多数团队来说是不可接受的。RAG不一样,知识更新只需要更新知识库里的文档,模型本身不用动。

第二是灵活性。微调之后,模型的行为会发生变化,可能会影响它在其他任务上的表现。而且微调后的模型很难追溯它到底“记住”了什么、“忘记”了什么。RAG的检索过程是透明的,你能清楚地看到模型是基于哪些资料生成的回答,出了问题也容易排查。

第三是时效性。微调是离线的,训练完就固定了。RAG是在线的,用户提问的时候实时检索最新的资料,天然支持知识的实时更新。

当然,微调也不是没有用武之地。如果你需要模型掌握某种特定的输出风格、特定的推理模式,或者需要模型理解某个领域的专业术语体系,微调是更合适的选择。但在“让模型回答基于特定知识库的问题”这个场景下,RAG是更务实的选择。

实际项目中,RAG和微调经常是配合使用的。比如先用微调让模型学会某个领域的表达方式,再用RAG给它提供实时的知识支撑。但对于大多数团队来说,先把RAG做好,性价比是最高的。

2.2 RAG系统的核心模块拆解

一个完整的RAG系统,从用户输入到最终输出,中间要经过好几个模块。我把它们拆成四个核心部分来讲。

文档处理模块负责把各种格式的原始文档(PDF、Word、Markdown、HTML、数据库记录等)解析成纯文本,然后按照一定的策略切分成合适大小的片段。这个模块看起来不起眼,但实际项目中大量的坑都在这里。PDF解析出来的格式乱七八糟、表格数据丢失、页眉页脚混入正文,这些问题都会直接影响后续的检索质量。

向量化模块负责把切分好的文本片段转换成向量,存到向量数据库里。同时,用户的问题也要经过同样的向量化处理,才能在向量空间里做相似度匹配。这个模块的核心是Embedding模型的选择,不同的模型在中文、英文、多语言场景下的表现差异很大。

检索模块负责根据用户的问题,从向量数据库里找到最相关的文本片段。最简单的做法是纯向量检索,但实际项目中往往需要混合检索,把向量检索和关键词检索的结果融合在一起,才能达到比较好的效果。检索之后通常还需要一个重排序的步骤,用更精细的模型对候选结果进行二次排序。

生成模块负责把检索到的文本片段和用户问题组装成提示词,送给大模型生成最终回答。这个模块的关键在于提示词的设计,要让模型明确知道“基于以下资料回答”,同时要处理好资料中没有相关信息时的情况。

这四个模块串起来就是一条完整的RAG流水线。每个模块都有很多可选的方案和参数,接下来我会逐个拆解。

2.3 不同场景下的架构选型差异

RAG不是一套固定的架构,不同的应用场景需要不同的设计。

企业知识库问答是最常见的场景。这种场景的特点是文档量大、更新频率中等、对准确率要求高。架构上通常会选择成熟的向量数据库(比如Milvus、Pgvector),配合混合检索和重排序,知识库的更新通过定时任务或者手动触发。

智能客服是另一个典型场景。这种场景的特点是问题重复率高、对响应速度要求高、答案需要严格控制。架构上可以加入缓存层,对常见问题直接返回缓存答案;检索策略上可以偏向关键词匹配,因为客服场景中很多问题是固定的表述。

文档助手场景,比如让用户上传一份合同然后针对合同提问。这种场景的特点是文档数量少但单文档很长,检索的粒度需要更细,可能需要做到段落级别甚至句子级别的检索。同时因为文档是用户临时上传的,向量化需要实时完成,对性能有一定要求。

代码问答场景比较特殊。代码的检索不能简单地按文本相似度来做,需要考虑代码的结构信息,比如函数名、类名、调用关系。有些方案会用AST(抽象语法树)来辅助切分和检索。

我自己的经验是,不要一上来就追求最复杂的架构。先用最简单的方案跑通全流程,然后根据实际效果逐步优化。很多问题在demo阶段是看不出来的,只有真实用户用起来才会暴露。

3. 文档处理与向量化:RAG系统的地基怎么打

3.1 文档解析的坑比你想的多

文档解析是RAG系统的第一步,也是最容易被低估的一步。很多人觉得把PDF转成文本有什么难的,实际做起来才发现问题一大堆。

PDF是最麻烦的格式。PDF本质上是一种排版格式,它记录的是“在某个位置画某个字符”,而不是“这段文字属于哪个段落”。所以从PDF提取文本的时候,经常会出现段落顺序错乱、表格内容混入正文、页眉页脚重复出现等问题。我试过好几种PDF解析库,PyMuPDF的速度快但表格处理一般,pdfplumber对表格支持好但速度慢,unstructured功能全但依赖重。实际项目中往往需要组合使用,针对不同类型的PDF选择不同的解析策略。

Word文档相对好一些,python-docx可以比较准确地提取段落和表格。但要注意的是,Word文档里的批注、修订记录、文本框内容,默认是不提取的,需要额外处理。

HTML文档的解析相对简单,BeautifulSoup或者trafilatura都能用。关键是要把导航栏、广告、页脚这些噪音去掉,只保留正文内容。

Markdown文档是最友好的,本身就是结构化的文本,直接按标题层级切分就行。

实操心得:文档解析阶段一定要做质量检查。我的做法是随机抽取一批解析后的文本,人工看一眼有没有明显的格式问题。如果解析质量不过关,后面再怎么优化检索策略都是白搭。

3.2 文本切分策略:切多大、怎么切

文本切分是RAG系统里最需要反复调试的环节。切得太大,检索回来的内容包含太多无关信息,会干扰大模型的判断;切得太小,单段内容不完整,模型可能理解不了。

最常见的做法是固定长度切分,比如每500个字符切一段,段与段之间保留50个字符的重叠。重叠的目的是避免一个完整的语义单元被切断。这种做法的优点是简单、均匀,缺点是可能把一个完整的段落从中间切开。

更好的做法是递归切分。先按段落切,如果某个段落还是太长,再按句子切,如果句子还是太长,再按字符切。LangChain的RecursiveCharacterTextSplitter就是这种思路,它会尝试用一组分隔符(比如\n\n、\n、。、.、空格)依次尝试切分,直到每段都在目标长度以内。

对于结构化的文档,比如Markdown或者有明确标题层级的文档,按标题切分是更好的选择。每个小节作为一个独立的片段,这样检索回来的内容语义完整性最好。

实际项目中,我通常会根据文档类型选择不同的切分策略。技术文档按标题切分,聊天记录按对话轮次切分,法律合同按条款切分。切分后的片段大小控制在300到800个字符之间,这个范围在大多数场景下效果比较均衡。

还有一个细节是元数据的保留。每个片段除了文本内容,还应该保留来源文档、章节标题、页码等信息。这些元数据在检索的时候可以用来做过滤,在生成回答的时候可以用来标注引用来源。

3.3 Embedding模型怎么选

Embedding模型负责把文本转换成向量。这个环节的选择直接决定了检索的质量。

目前主流的选择分几类。OpenAI的text-embedding-3系列效果稳定,支持多语言,但需要调用API,有网络和成本方面的考虑。开源的BGE系列(比如bge-large-zh、bge-m3)在中文场景下表现很好,可以本地部署,适合对数据隐私有要求的场景。M3E系列也是中文场景下常用的选择,模型体积小,推理速度快。

选择Embedding模型的时候,我主要看三个指标。第一是检索准确率,这个需要在你的实际数据上测试,不能只看论文里的 benchmark 分数。第二是向量维度,维度越高表达能力越强,但存储和计算成本也越高。第三是推理速度,如果知识库很大,每次检索都要实时编码用户问题,推理速度太慢会影响用户体验。

注意事项:Embedding模型一旦选定,知识库里的所有向量都要用同一个模型生成。如果中途换模型,整个知识库都需要重新向量化。所以选型的时候要慎重,尽量选一个长期可用的模型。

3.4 向量数据库的选型对比

向量数据库负责存储向量并支持相似度检索。市面上的选择很多,我列一个对比表格。

数据库类型优势适用场景
Milvus专用向量库性能强,支持大规模数据千万级以上向量
PgvectorPostgreSQL扩展和关系数据统一管理已有PG的中小项目
Chroma轻量级向量库部署简单,上手快原型验证和小规模应用
FAISS向量检索库速度快,Facebook出品离线检索和研究
Elasticsearch搜索引擎支持向量和关键词混合检索已有ES的项目
Qdrant专用向量库过滤功能强,API友好需要复杂过滤的场景

我自己的项目里,原型阶段用Chroma最多,因为pip install就能用,不需要额外部署服务。生产环境用Pgvector比较多,因为大多数项目本来就有PostgreSQL,不用额外维护一套数据库。数据量特别大的时候会考虑Milvus。

选择向量数据库的时候,除了性能,还要考虑过滤功能。实际项目中经常需要“只在某个部门的文档里检索”或者“只检索最近三个月更新的文档”,这要求数据库支持向量检索和元数据过滤的组合查询。

4. 检索策略与生成优化:决定RAG效果的关键环节

4.1 纯向量检索的问题在哪里

很多人搭RAG系统,第一步就是纯向量检索:把用户问题向量化,然后在向量数据库里找最相似的top-k个片段。这个方案在demo阶段看起来效果不错,但实际用起来会发现几个问题。

第一个问题是,向量检索对精确匹配不敏感。比如用户问“XX-2000型号的参数是什么”,向量检索可能会返回一堆关于“XX系列产品”的片段,但就是找不到精确提到“XX-2000”的那一段。因为向量模型关注的是语义相似度,而不是字面匹配。

第二个问题是,向量检索对长尾问题效果差。如果知识库里关于某个问题的内容很少,向量检索可能找不到真正相关的那几条,反而返回一些语义上泛泛相关的片段。

第三个问题是,向量检索的结果不稳定。同一个问题,换一种问法,检索结果可能差别很大。这在生产环境里是很要命的,用户会感觉系统“时灵时不灵”。

4.2 混合检索:向量加关键词的组合拳

解决纯向量检索问题的最直接方案是混合检索,也就是同时做向量检索和关键词检索,然后把两路结果融合。

关键词检索可以用BM25算法,这是信息检索领域的经典算法,对精确匹配非常有效。Elasticsearch内置了BM25,如果不想引入ES,也可以用rank_bm25这个Python库在内存里做。

融合两路结果的时候,常用的方法是RRF(Reciprocal Rank Fusion)。它的逻辑很简单:对于每个文档,分别看它在向量检索结果里的排名和在关键词检索结果里的排名,然后计算一个融合分数。公式是 score = sum(1 / (k + rank)),其中k是一个常数,通常取60。

RRF的好处是不需要调权重,两路检索的分数尺度不一样也没关系,只看排名。我实测下来,混合检索比纯向量检索的准确率能提升10到20个百分点,尤其是在有大量专有名词、型号、编号的场景下。

还有一种做法是加权求和,给向量检索和关键词检索分别设一个权重,然后对归一化后的分数加权求和。这种做法的效果取决于权重的设置,需要根据实际数据调参。

4.3 重排序:让最相关的片段排到最前面

检索回来top-k个片段之后,还有一个重要的步骤是重排序。向量检索用的是双塔模型,问题和文档分别编码,速度快但精度有限。重排序用的是交叉编码器,把问题和文档拼在一起输入模型,精度高但速度慢。

常见的做法是:先用向量检索召回较多的候选(比如50条),然后用重排序模型对这50条进行精细排序,取前5条送给大模型。这样既保证了召回率,又保证了精度。

重排序模型的选择上,BGE-reranker系列是比较常用的,有base和large两个版本。Cohere的rerank API效果也很好,但需要调用外部服务。如果对延迟要求不高,用large版本效果更好;如果延迟敏感,用base版本或者更小的模型。

实操心得:重排序的收益在知识库内容比较杂的时候特别明显。如果知识库本身就很干净、内容高度相关,重排序的提升可能没那么大。所以要不要加重排序,取决于你的实际场景。

4.4 提示词设计:让模型老实基于资料回答

检索做完之后,最后一步是把资料和问题组装成提示词,送给大模型生成回答。这一步的提示词设计直接决定了最终输出的质量。

一个基本的提示词模板大概长这样:

你是一个知识库助手,请基于以下参考资料回答用户的问题。 如果参考资料中没有相关信息,请直接说“根据现有资料无法回答该问题”,不要编造答案。 参考资料: {context} 用户问题:{question} 请用简洁、准确的语言回答:

这个模板看起来简单,但有几个细节需要注意。

第一是“不知道”的处理。如果不明确告诉模型“资料里没有就说不知道”,模型很可能会用自己的知识来补充,这就失去了RAG的意义。我试过在提示词里加一句“只使用参考资料中的信息”,效果会好很多。

第二是引用的标注。如果希望回答里标注信息来源,可以在提示词里要求模型在回答中注明引用了哪段资料。这对于需要追溯的场景很有用。

第三是上下文的长度控制。检索回来的片段不能无限往提示词里塞,要考虑模型的上下文窗口限制。一般来说,3到5个片段是比较合适的,太多反而会稀释关键信息。

第四是格式要求。如果需要模型输出结构化的内容(比如JSON),要在提示词里明确说明格式要求,并给出示例。

4.5 多路召回与查询改写

在实际项目中,用户的问题往往不是最优的检索查询。比如用户问“你们这个产品怎么退”,直接拿这句话去检索,可能效果不好。这时候就需要查询改写。

查询改写的思路是,用大模型把用户的原始问题改写成更适合检索的形式。比如把“你们这个产品怎么退”改写成“产品退货流程 退货政策 退款方式”。这样检索的时候命中率会高很多。

还有一种做法是多查询生成。让大模型针对用户问题生成多个不同角度的查询,分别检索后合并结果。比如用户问“RAG和微调的区别”,可以生成“RAG的优势”、“微调的劣势”、“RAG适用场景”、“微调适用场景”等多个查询,每个查询检索一批结果,最后合并去重。

多路召回还包括从不同数据源召回。比如同时从文档库、FAQ库、历史对话记录里检索,然后融合结果。这种架构在客服场景下特别常见。

5. 实操落地:从零搭建一个可用的RAG系统

5.1 技术栈选择与项目结构

我以Python技术栈为例,给一个可以直接参考的项目结构。这套方案在多个项目中验证过,稳定性和开发效率都比较均衡。

核心依赖包括:LangChain用于串联各个模块,Pgvector作为向量数据库,BGE-m3作为Embedding模型,BGE-reranker-base作为重排序模型,FastAPI提供HTTP接口。

项目目录结构大概是这样:

rag-system/ ├── app/ │ ├── main.py # FastAPI入口 │ ├── config.py # 配置管理 │ ├── ingest/ │ │ ├── parser.py # 文档解析 │ │ ├── splitter.py # 文本切分 │ │ └── embedder.py # 向量化入库 │ ├── retrieve/ │ │ ├── vector.py # 向量检索 │ │ ├── keyword.py # 关键词检索 │ │ └── fusion.py # 结果融合 │ ├── generate/ │ │ ├── prompt.py # 提示词模板 │ │ └── llm.py # 大模型调用 │ └── api/ │ ├── chat.py # 问答接口 │ └── admin.py # 知识库管理接口 ├── data/ │ └── docs/ # 原始文档 ├── tests/ └── requirements.txt

这个结构的好处是模块职责清晰,每个环节都可以独立替换和测试。比如想换一个Embedding模型,只需要改embedder.py;想换一个向量数据库,只需要改vector.py。

5.2 知识库入库的完整流程

入库流程分四步:解析、切分、向量化、存储。

解析这一步,我通常会根据文件扩展名选择不同的解析器。PDF用PyMuPDF,Word用python-docx,Markdown直接读取,HTML用trafilatura提取正文。

切分这一步,用LangChain的RecursiveCharacterTextSplitter,chunk_size设为500,chunk_overlap设为50。对于有明确标题层级的文档,先用MarkdownHeaderTextSplitter按标题切分,再对过长的段落做二次切分。

向量化这一步,用BGE-m3模型对每个片段编码。BGE-m3支持多语言,输出1024维向量,在中文场景下表现很好。编码的时候建议批量处理,一次编码32到64条,速度比逐条编码快很多。

存储这一步,把向量和对应的文本、元数据一起写入Pgvector。表结构大概是这样:

CREATE TABLE documents ( id SERIAL PRIMARY KEY, content TEXT NOT NULL, embedding VECTOR(1024), source VARCHAR(255), section VARCHAR(255), chunk_index INTEGER, created_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);

ivfflat索引的lists参数需要根据数据量调整,一般设为数据量的平方根。数据量小的时候(几万条以内),不建索引直接暴力检索也够快。

5.3 检索与生成的代码实现

检索部分的核心逻辑是:用户问题向量化,向量检索top-50,关键词检索top-50,RRF融合,重排序取top-5。

def retrieve(query, top_k=5): # 向量检索 query_vector = embedder.encode(query) vector_results = vector_search(query_vector, top_k=50) # 关键词检索 keyword_results = bm25_search(query, top_k=50) # RRF融合 fused = rrf_fusion(vector_results, keyword_results, k=60) # 重排序 reranked = reranker.rerank(query, fused[:20], top_k=top_k) return reranked

生成部分的逻辑是:把检索结果拼成上下文,填入提示词模板,调用大模型。

def generate(query, contexts): context_text = "\n\n---\n\n".join([c.content for c in contexts]) prompt = PROMPT_TEMPLATE.format(context=context_text, question=query) response = llm.invoke(prompt) return response

大模型的选择上,如果对数据隐私要求高,可以用本地部署的开源模型,比如Qwen2.5-7B-Instruct,用vLLM做推理加速。如果对效果要求高且可以接受API调用,GPT-4o或者Claude的效果会更好。实际项目中,我通常会用本地模型做开发和测试,上线时根据成本和效果要求决定用哪个。

5.4 效果评估与迭代优化

RAG系统上线之后,需要持续评估和优化。评估的指标主要有三个:检索命中率、回答准确率、用户满意度。

检索命中率的评估方法是,准备一批测试问题,每个问题标注好应该检索到哪些片段,然后看系统实际检索的结果里有没有包含这些片段。这个指标反映的是检索模块的质量。

回答准确率的评估方法是,人工判断模型的回答是否正确、是否基于资料、有没有编造。这个指标反映的是端到端的质量。

用户满意度可以通过点赞点踩、追问率等行为数据来间接衡量。

优化的方向根据评估结果来定。如果检索命中率低,优先优化切分策略和检索策略;如果检索命中率高但回答准确率低,优先优化提示词和生成模型。

实操心得:我建议在项目初期就建立一套评估集,哪怕只有几十条测试数据。有了评估集,每次改动都能量化对比效果,避免凭感觉调参。

6. 常见问题与排查技巧实录

6.1 检索结果不相关怎么办

这是最常见的问题。排查思路是从后往前查。

先看检索回来的片段本身是不是相关的。如果检索结果里根本没有相关片段,说明是检索环节的问题。可能的原因包括:Embedding模型不适合你的领域、切分粒度不合适、向量数据库索引参数不对。

如果检索结果里有相关片段但排名靠后,说明是排序环节的问题。可以加重排序模型,或者调整RRF的融合参数。

如果检索结果相关但模型回答不对,说明是生成环节的问题。检查提示词是否清晰、上下文是否太长、模型是否适合这个任务。

6.2 模型不按资料回答怎么办

模型不按资料回答,通常有两个原因。一是提示词不够明确,模型不知道应该基于资料回答。二是因为资料里确实没有相关信息,模型只能用自己的知识补充。

对于第一种情况,强化提示词里的约束。我常用的做法是在提示词开头和结尾都强调“只基于以下资料回答”,并且在资料前后加明确的分隔符。

对于第二种情况,需要在提示词里明确告诉模型“如果资料中没有相关信息,请直接说不知道”。同时,可以在检索环节加一个相关性阈值,如果所有检索结果的相关性都低于阈值,直接返回“没有找到相关信息”,不调用大模型。

6.3 响应速度太慢怎么优化

RAG系统的延迟主要来自三个环节:检索、重排序、生成。

检索环节的优化包括:向量数据库建索引、减少检索数量、用更快的Embedding模型。如果知识库不大,可以考虑把向量加载到内存里用FAISS检索,速度比数据库查询快很多。

重排序环节的优化包括:用更小的重排序模型、减少重排序的候选数量、把重排序和检索并行化。

生成环节的优化包括:用更快的模型、用流式输出让用户先看到部分结果、控制上下文长度。

实际项目中,我通常会把端到端延迟控制在3秒以内。如果超过5秒,用户就会明显感觉到卡顿。

6.4 知识库更新了但检索不到新内容

这个问题通常是因为向量化没有及时更新。知识库的更新流程应该是:文档更新后,重新解析、切分、向量化,然后更新数据库里的记录。

需要注意的是,更新的时候要先删除旧的向量记录,再插入新的。如果只插入不删除,会出现重复内容。另外,如果文档只是部分修改,可以考虑只重新处理修改的部分,而不是整个文档重新入库。

还有一个容易忽略的点是缓存。如果系统里有检索结果缓存,知识库更新后要记得清缓存,否则用户还是会看到旧的结果。

6.5 常见问题速查表

问题现象可能原因排查方向
检索结果不相关Embedding模型不适配换模型或微调Embedding
检索结果不相关切分粒度不合适调整chunk_size
精确匹配找不到缺少关键词检索加入BM25混合检索
回答编造信息提示词约束不够强化“只基于资料”约束
回答不完整上下文太长减少检索片段数量
响应太慢检索或生成瓶颈分别计时定位
新内容检索不到向量未更新检查入库流程
同一问题结果不稳定检索策略单一加入重排序和融合

6.6 几个容易被忽略的细节

第一个细节是文本预处理。入库之前,把文本里的多余空格、换行、特殊字符清理一下,能提升检索质量。特别是从PDF解析出来的文本,经常有很多无意义的换行和空格。

第二个细节是元数据的利用。检索的时候可以用元数据做过滤,比如只检索某个分类下的文档。生成的时候可以用元数据标注来源,方便用户追溯。

第三个细节是查询预处理。用户输入的问题可能包含错别字、口语化表达、指代不明的情况。可以在检索之前做一轮查询改写,把口语化的表达转成更规范的检索查询。

第四个细节是兜底策略。当检索不到相关内容时,不要让模型硬答,而是返回一个友好的提示,引导用户换一种问法或者联系人工客服。

7. 进阶方向:RAG系统还能怎么优化

7.1 多模态RAG

现在的RAG系统大多只处理文本。但实际场景中,很多知识是以图片、表格、图表的形式存在的。多模态RAG的思路是,用多模态Embedding模型(比如CLIP)把图片和文本映射到同一个向量空间,检索的时候可以同时检索文本和图片。

对于表格数据,可以先让大模型把表格转成文本描述,再入库。或者用专门的表格理解模型提取表格的结构化信息。

7.2 知识图谱增强的RAG

传统RAG是基于文本片段的检索,片段之间是孤立的。知识图谱增强的RAG会把知识库里的实体和关系抽取出来,构建一个图谱。检索的时候,除了检索文本片段,还可以沿着图谱的关系进行推理,找到间接相关的信息。

这种方案在需要多跳推理的场景下特别有用。比如问“A公司的CEO毕业于哪所大学”,传统RAG可能检索不到直接答案,但知识图谱可以通过“A公司-CEO-某人-毕业院校-某大学”这条路径找到答案。

7.3 Agentic RAG

Agentic RAG的思路是,把RAG系统做成一个智能体,它可以根据问题的复杂程度自主决定检索策略。简单问题直接检索一次就回答,复杂问题可能需要多轮检索、查询改写、结果验证。

这种方案的好处是灵活性强,能处理各种复杂问题。缺点是延迟高、成本高,而且需要更精细的工程实现。目前这个方向还在快速发展中,适合对效果要求极高且能接受较高成本的场景。

7.4 持续学习与反馈闭环

RAG系统上线之后,用户的每一次提问和反馈都是宝贵的优化信号。可以建立一个反馈闭环:记录用户的提问、系统的回答、用户的评价,定期分析这些数据,找出系统的薄弱环节,针对性地优化。

比如发现某类问题经常检索不到相关内容,就补充这方面的知识库内容。发现某类问题的回答经常被点踩,就优化这类问题的提示词或者检索策略。

这个闭环建立起来之后,RAG系统就能持续进化,效果越来越好。

我自己在实际项目中的体会是,RAG系统的优化是一个长期的过程,没有一劳永逸的方案。每次觉得“差不多了”的时候,换一批真实用户的问题来测试,总能发现新的问题。保持对bad case的敏感度,持续迭代,才是做好RAG的关键。另外一个小技巧是,在提示词里加上“如果你不确定,请说明不确定的原因”,这样模型在遇到模糊问题时会更谨慎,减少胡编乱造的概率。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 8:51:39

Python GUI选型指南:PySide6与PyQt6版本兼容性及安装避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 8:49:54

浏览器渲染机制与前端性能优化:从URL到页面呈现的核心原理

Day-11了。前十天咱们把HTML、CSS基础、JS闭包、原型链、事件循环这些常规考点过了一遍,今天聊一个面试官几乎必问、但大量候选人答不到点子上的主题:浏览器渲染机制,以及由此引出的前端性能优化问题。这个主题在初级前端开发面试里属于“送分…

作者头像 李华
网站建设 2026/9/19 8:49:17

Git入门实战:从安装配置到首次提交与远程仓库

1. 环境准备:先把Git装好再谈其他不管你是刚入行的前端新人,还是写了几年业务代码的老兵,换台新电脑或者刚接手一台公司分配的机器,第一件事往往不是装IDE,而是把Git环境拉起来。这个工具现在已经是开发者的基础设施&a…

作者头像 李华
网站建设 2026/9/19 8:48:26

Unity数字孪生实战:PiXYZ工业CAD模型轻量化与优化全攻略

工业数字孪生项目里,模型处理往往是第一个卡脖子的环节。你拿到甲方给的原始CAD数据,动辄几百兆甚至几个G,图层混乱、面数爆炸、材质丢失,直接拖进Unity轻则卡死,重则导入报错。我做过好几个工厂产线、制冷站、变电站的…

作者头像 李华
网站建设 2026/9/19 8:41:58

OpenVINS从零搭建到RGB-D实时建图:VIO原理、标定与避坑实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 8:41:52

Codex不是模型而是API协议:本地部署的真相与工程实践

1. Codex不是模型,是接口协议——先破除三个最普遍的认知误区很多人点开“Codex下载与本地部署”这个标题时,第一反应是:这又是一个类似Ollama、LM Studio那样的大模型运行工具?点进去才发现官网打不开、GitHub仓库找不到、pip in…

作者头像 李华