RAG 和把文档直接喂给大模型有什么区别?
直接把整本手册塞进上下文既超出长度限制,也会稀释关键信息;检索出来的片段如果本身不对,模型再强也无法给出正确答案。RAG 先用检索找出与问题相关的片段,再让模型基于这些片段作答,因此效果取决于整条链路,而不仅是模型本身。
把公司文档丢给模型,得到的往往是过期的制度、混淆的流程,或者看似合理却不存在的答案。问题多半不在模型,而在从文档到答案之间的工程链路。这篇文章讨论 RAG 落地的每个环节,以及效果不好时该从哪里查起。
很多团队对知识库问答的第一印象是「把公司文档丢进去,模型就能回答」。真正动手后会发现:模型确实能回答,但答案时常不对——说的是过期的制度、混淆了两个相似的流程、或者干脆编了一段看起来合理但文档里并不存在的内容。
问题通常不在模型本身,而在从文档到答案之间的那段工程链路。文档是一堆非结构化的文本,模型需要的是与问题相关的、准确的、量合适的上下文。把整本手册塞进去既超出上下文长度,也稀释了关键信息;检索出来的片段如果本身就不对,模型再强也无力回天。
RAG(Retrieval-Augmented Generation,检索增强生成)要解决的就是这一段:先检索出相关片段,再让模型基于这些片段作答。这篇文章讨论 RAG 从零到可用的落地要点——切分、向量化、召回与重排、上下文组织和评测,以及效果不达预期时的排查方向。相关能力说明见 AI 应用与 AIGC 服务。
在讨论细节之前,先明确这条链路由哪些环节组成。它通常包含两侧:
离线侧(索引构建):文档解析 → 切分 → 向量化 → 写入向量库。这一步决定了「知识库里有什么」。
在线侧(问答):问题改写 → 向量检索(必要时加关键词检索)→ 重排 → 组织上下文 → 模型生成 → 输出。这一步决定了「每次回答用了哪些知识」。
后面的问题几乎都能定位到某个具体环节。反过来说,如果效果不理想,第一步不是换模型,而是搞清楚是召回没找到,还是找到了但没用好。这个区分能省下大量试错。
切分是 RAG 里最被低估的环节。切得太粗,一个片段里混了多个主题,检索命中后模型要自己筛选;切得太细,一个完整的规则被拆成几段,单看任何一段都不完整。
优先利用文档自身的结构:章节标题、条款编号、表格边界、列表项。按结构切出来的片段,语义更完整,也更容易追溯来源。只有在没有明显结构的长文本里,才退而求其次用固定长度加重叠的方式切分。
标题应当被保留在片段里。一个只写「不得超过三个工作日」的片段,脱离「报销审批时限」这个标题就没有意义。把标题层级拼进片段的开头,能显著提升检索与作答的准确度。
相邻片段之间保留一定重叠,可以减少「答案横跨两个片段边界」时被切断的情况。重叠的比例没有统一答案,需要按文档类型实测:结构清晰的文档可以用较小重叠,行文连贯的长段落需要更大重叠。
另一种常见做法是父子片段:用较小片段做检索,命中后返回它所属的较大片段作为上下文。这样既保证了检索的精度,又保证了生成时有足够的上下文。
表格是 RAG 效果最容易翻车的地方。表格被按行切开后,一行数据往往脱离了表头,失去含义。对表格的处理通常是把它转成「表头 + 单元格值」的自然语言描述,或整体作为一个片段保留。
图文混排的文档还需要处理图片中的文字。这部分如果依赖 OCR,要预料到识别错误,并在评测时把这类文档单独统计,避免整体指标掩盖了局部问题。
向量模型(Embedding 模型)把片段转成向量,决定了「语义相近」是怎么被度量的。选择时要考虑几点:是否支持中文、支持的输入长度、向量维度带来的存储与检索成本。索引与查询必须使用同一个向量模型,中途更换意味着要全量重建索引。
纯向量检索擅长语义匹配,但对精确匹配类问题较弱——比如查询某个编号、某个专有名词。这类场景下,关键词检索(如 BM25)反而更准。把向量检索与关键词检索结合(混合检索),再对两路结果做融合排序,通常比单一路线更稳。
召回数量不是越多越好。召回太多会把不相关的片段带进上下文,稀释关键信息,也增加生成成本;召回太少则可能漏掉真正相关的内容。合理的做法是先召回一个较大的候选集,再通过重排精选出少量片段。
这里有一个常见误区:把「召回率」当成越高越好。实际上召回率与精度是一对需要权衡的指标。如果为了追求召回率而把候选集放得很大,重排环节的压力和出错概率也随之上升。更实际的目标是「相关的内容不被漏掉」,而不是「尽可能多召回」。在评测时,应当同时看召回率与最终答案的正确率,而不是只盯前者的某个绝对值。
另一个容易忽略的点是查询改写。用户的问题往往带有口语化表述、省略或多重意图,直接拿去检索效果不稳定。常见的处理包括:把口语化问题改写成适合检索的关键词组合、把复合问题拆成多个子问题分别检索、以及结合对话历史补全指代。查询改写不需要很复杂,但对多轮对话和长问题的效果提升比较直接。
重排(Rerank)是效果提升中投入产出比较高的一步。检索阶段的模型为了速度,通常对片段只做粗略的相关性判断;重排模型则对「问题—片段」这一对做更精细的打分,把真正相关的片段排到前面。
经过重排之后,进入上下文的片段数量可以大幅减少,同时相关性提升。对多数知识库问答来说,这一环节往往比更换更大的生成模型更有效,因为它直接改善了「模型看到的内容」。
重排有一点需要提前规划:它是一个额外的模型调用,会带来延迟与成本。因此重排的候选集不宜过大,通常从几十条里精选几条即可。对于延迟敏感的场景,可以把重排做成可开关的能力——简单问题走快速路径,复杂问题才触发重排。无论采用哪种策略,都应当用评测集确认重排确实带来了提升,而不是想当然地认为「加了就更准」。
检索出来的片段如何组织成一个给模型的上下文,同样影响结果。
拒答是很多 RAG 系统缺失的一环。当知识库里没有相关内容时,一个设计得好的系统应当明确回答「未找到依据」,而不是用通用知识拼一个似是而非的答案。拒答策略要在提示设计、阈值设置和评测三处同时落实。
在长对话场景里,上下文组织还要考虑历史轮次的影响。把全部历史对话拼进上下文,会挤占知识片段的位置,也可能让模型被早先不准确的回答带偏。常见的做法是只保留最近若干轮,或者把历史压缩成简短的摘要。无论哪种方式,都应当在评测集里包含多轮对话类型的样本,因为单轮表现良好的系统在多轮场景里未必稳定。
没有评测,RAG 的优化就只能靠感觉,而感觉在检索类系统里往往不可靠——你调整了一个参数,在某几个问题上变好了,在另外几个问题上变差了,仅凭零散试用无法判断整体是否进步。
评测集是一组「问题 + 期望答案(或期望命中的文档)」。它的质量决定评测的价值。建议:
把评测拆成两个层次,定位问题会快很多:
分开之后,如果召回都对了但答案不对,问题在生成与提示;如果召回就不对,后面的功夫都白费。
结合上面的链路,效果不好通常落在几个具体位置:
这七条里,属于「模型能力」的其实很少。多数是工程与数据的问题,这也解释了为什么同一个模型在不同团队手里效果差别明显。
如果要推进一个知识库问答项目,建议按下面的顺序。
第一步,先治理文档,而不是先调模型。 确认知识库里的内容是最新的、无矛盾的,把已废止的文档移出或标记。这一步的收益往往高于任何参数调整。
第二步,按结构切分并保留标题。 让每个片段独立看也能明白它在说什么。
第三步,用混合检索加少量重排。 不必一开始就追求复杂方案,先搭出「召回 + 重排」的最小闭环。
第四步,建一组评测问题。 哪怕只有几十条,也能让后续优化有依据。这与我们在 工程与质量保障 中强调的「可验证」原则一致。
第五步,加上拒答与来源标注。 让用户知道答案来自哪里、以及系统什么时候没有依据。
完整的实施方式可以参考 交付流程;不同行业对知识库的约束差异,可以参见 行业解决方案 中对应的场景说明。
RAG 的落地,本质上是把一个概率性的组件接到一套确定性的数据处理链路上。模型只是链路末端的一环,前面每一环——文档治理、切分、检索、重排、上下文组织——都会影响最终答案。
一个务实的判断是:当问答效果不好时,先查召回,再查切分,最后才考虑换模型。 把这条顺序坚持下来,多数问题都能在工程层面解决,而不必依赖更强的模型。
广州科芃科技有限公司技术团队在知识库与智能问答类项目中,会把文档治理与评测集建设作为方案的一部分,而不是等效果不理想时再回头补。
直接把整本手册塞进上下文既超出长度限制,也会稀释关键信息;检索出来的片段如果本身不对,模型再强也无法给出正确答案。RAG 先用检索找出与问题相关的片段,再让模型基于这些片段作答,因此效果取决于整条链路,而不仅是模型本身。
优先按文档自身的结构切,例如章节标题、条款编号、表格边界、列表项,切出来的片段语义更完整也更容易追溯。在没有明显结构的长文本里才用固定长度加重叠的方式。标题应保留在片段里,因为脱离标题的片段往往失去含义。相邻片段保留一定重叠,可减少答案横跨边界时被切断。
纯向量检索擅长语义匹配,但对精确匹配较弱,例如查询某个编号或专有名词时命中不准。把向量检索与关键词检索结合成混合检索,再对两路结果做融合排序,通常比单一路线更稳。检索后还应加重排,对「问题—片段」做更精细的相关性打分,把真正相关的片段排到前面。
先建一组「问题 + 期望答案或期望命中的文档」的评测集,问题要覆盖真实用户会问的类型,包括知识库里没有答案的问题。评测要分两层:召回评测看正确文档是否被检索到,生成评测看答案是否正确、是否引用来源、无依据时是否拒答。这样如果召回都对了但答案不对,问题在生成与提示;如果召回就不对,后面的功夫都白费。
常见原因包括:切分把语义切碎、文档本身过时或新旧矛盾、只有向量检索导致编号类查询不准、缺少重排、上下文塞得太满稀释关键信息、缺少拒答机制、以及没有评测导致优化靠感觉。这些多数属于工程与数据问题而非模型能力问题,因此排查顺序应当是先查召回、再查切分、最后才考虑换模型。
当知识库里没有相关内容时,缺少拒答的系统会用通用知识拼一个似是而非的答案,用户难以分辨真伪。拒答要求系统在无依据时明确回答「未找到依据」,并需要在提示设计、相似度阈值设置和评测三处同时落实。在长对话场景里还要控制历史轮次,避免早先不准确的回答影响后续判断。