| 编辑推荐: |
本文主要介绍了生产
RAG 必须从答不准,走到可诊断、可追溯、可迭代等相关内容 。希望对你的学习有帮助。 本文来自于微信公众号烹小鲜也,由火龙果软件Alice编辑,推荐。 |
|
很多团队的知识库 AI,早就已经不是 demo 了。向量库、ES、reranker、权限过滤、query
rewrite、多路召回,能上的基本都上了。
但真实用户一问,问题还是会冒出来:
- 查公告 2026-031,回答成上市公司为什么要发公告。
- 查基金 7 天内赎回费,引用了旧合同,还是另一类份额的费率。
- 查贷款为什么没批,只找到授信制度,没串起财报、征信、担保材料和风控规则。
更麻烦的是,答案看着还挺顺。它给你一段像模像样的解释,再挂几个引用。但你点开才发现,引用根本撑不起结论。
生产 RAG 最磨人的地方就在这儿:通常不是某一层彻底坏了,而是每一层都偏一点。解析错一点,召回漏一点,排序偏一点,上下文少一点,引用虚一点,最后答案就偏了。
所以向量库和 ES 之后,缺的往往不是某个神奇组件,而是一条能持续改的链路:资料进来要处理对,问题进来要找准证据,答案出去要能追,答错以后还能回放、能回归。
继续加组件当然有用,但前提是先知道问题卡在哪。否则换 embedding、加
reranker、上 Agentic RAG,都可能只是在无关紧要的地方用力。
因此,本篇文章不会着重于名词解释,而从朴素 RAG 聊起:它为什么能演示,为什么到生产会露馅;生产
baseline 要补什么;最后哪些问题才值得上更重的方案。
朴素 RAG 为什么会不够用
RAG 的定义其实很简单:模型回答前,先去资料库里找证据,再带着证据回答。
这个定义没问题,但是太干净了。
最简单的 RAG,一般是这条链路:
- 把文档解析出来。
- 切成一块块 chunk。
- 把每个 chunk 转成向量(embedding),存进向量库。
- 用户提问时,也把问题转成向量。
- 去向量库里找最相似的几段,拼进上下文,让模型回答。
这个版本很适合 demo。路径短,效果也容易演示。你上传几篇文档,问一个语义接近的问题,它确实能找到相关段落,然后回答得像那么回事。很多团队第一次做知识库
AI,也都是从这里开始的。
但它有几个默认假设,到了生产环境中很快就露馅了。
它默认:所有问题都适合按语义相似去找。
这在问基金赎回规则时还行。可你查公告编号、年报字段、贷款状态,核心不是意思接近,而是精确命中。向量检索找来一堆看着相关的材料,真正那条记录可能没进来。
它默认:每个 chunk 离开原文以后,意思仍然完整。
很多文档不是这样。chunk 里只有字段值,表头在上一块;条款里只写华东区除外,产品线和生效时间在标题里。单独拿出来
embedding,意思很容易变味。
它默认:top-k 结果可以直接交给模型。
真实情况是,top-k 里经常混着重复内容、旧版本内容、半截证据。正确答案就算被召回,也可能排在后面,最后没塞进上下文。模型不是不会答,是没看到该看的东西。
它默认:模型会严格按照证据回答。
这也太乐观了。模型拿到一堆相似材料,很容易把制度条款、业务常识和用户问题混在一起,补出一个听起来合理的答案。引用看着有,点开却支撑不住那句话。
朴素 RAG 不是没用,但只能当起点。
到了生产环境,RAG 要从一根向量检索管道,变成一条可诊断、可过滤、可排序、可追责的链路。
生产 baseline RAG 要补 6 个基本功
生产 RAG 的 baseline 可以画成这样:
看起来比 demo 复杂不少,但不是为了堆组件。到了生产,baseline
至少要补 6 个基本功:资料进来要干净,权限和时间要处理对,召回不能只靠向量,融合和 rerank
要分工清楚,上下文不能只取 top-k,答案要能回到证据。
第一,资料进来要干净。
RAG 的第一批坑,常常在整个 RAG 链路的开头。PDF 页眉页脚、表格表头、OCR、标题、产品线、部门、版本、生效时间、权限范围,任何一项没进索引,后面
embedding 再好也救不回来。
企业知识库尤其如此。同一句本产品不适用于风险承受能力 C2 以下客户,必须知道它属于哪只产品、哪个渠道、哪个时间段、哪类客户。不是语义不对,是适用范围不对。
所以 baseline 的第一件事,不是换向量库,而是把解析和入库(ingestion)做成可检查的数据链路:原文是什么,解析后是什么,chunk
怎么切,metadata 怎么继承,索引什么时候更新,失败文件有没有报警。
第二,权限和时间要先处理对。
权限不能只写进 prompt。最好检索前过滤,检索后再校验;只要无权限内容进了上下文,风险就已经发生了。模型就算最后没说出来,trace
里也可能留下敏感片段。
时间也一样。一篇 2026 年写的文章,可能分析的是 2025 年财报;2024
年发布的基金合同,2026 年可能仍然有效。用户问去年财报,看 content_period;问今年有哪些分析文章,看
publish_date;问现在能不能买,还要看 effective_date、expired_date
和产品状态。
第三,召回不能只靠向量。
向量擅长找意思接近的内容,BM25 / ES 擅长找关键词、编号、专有名词,SQL
或业务 API 擅长查结构化状态。公告 2026-031 不需要理解,先要命中;经营性现金流可能在现金流量表字段里,不在普通知识库段落里。
现在做词面召回,也不只是传统 BM25 了。SPLADE、BGE-M3
这类学习型稀疏向量,也经常和 dense vector 一起放进 hybrid retrieval
里。中文和多语言场景里,BGE-M3 很常见。
第四,融合和 rerank 要分工清楚。
多路召回以后,不能直接把向量分数和 ES 分数相加。BM25 分数可能没有上限,向量相似度通常在固定区间里,SQL
命中又不是同一种分数。生产里通常先用 RRF 做安全基线;有评测集以后,再做 Weighted RRF
或归一化融合,按问题类型调权重。
权重不是拍脑袋来的,而是在同一批真实问题上看 Recall@k、MRR、Context
Precision 和最终答案准确率。
Reranker 是在候选里重新排序。bge-reranker-v2-m3、Cohere
Rerank 这类模型很常见,收益通常很实。但它不能凭空变出没召回的证据。recall@50 里没有正确证据,先查解析、切块、索引、metadata、query
rewrite 和 hybrid retrieval;正确证据在候选里但排不上,再看 reranker。
第五,上下文不能只取 top-k。
召回和排序都还行,也可能输在 context packing。比如
top-k 里一堆旧公告挤掉了新公告;正确答案需要连续两段,却只塞了一段;chunk 没带标题、章节、版本、生效时间,模型看到内容,也不知道它适用哪里。
更稳的做法,是同一文档去重或合并,关键 chunk 带上父级标题和相邻片段,按版本和权限再检查一次,给模型的上下文里保留来源、页码、章节、生效时间。
第六,答案必须能回到证据。
企业里用 RAG,citation 粒度不能太粗。答案说 A 公司经营性现金流下降主要因为存货增加,引用却只指向一篇现金流管理方法的文章,这种引用没有意义。
关键结论要尽量映射到具体 chunk、段落、表格行或结构化字段。做不到的时候,就不要假装有证据。宁可回答我找到了相关研报,但没有找到
A 公司 2025 年年报里的现金流量表和附注,也比编一个顺滑答案强。
baseline 之后,哪些问题需要更重的方案
baseline 打稳以后,还是会有几类问题很顽固。这时候才轮到一些更重的方案。
图注:四类顽固问题,四种处理办法,以及它们各自作用在链路的哪一层。
第一类:资料找到了,但 chunk 没带身份。
资料明明找到了,模型却用错范围。比如基金费率表被切碎,chunk 里只剩持有
7 天以内赎回费率为 1.5%,但它到底适用于哪只基金、哪个份额类别、哪个版本,已经不在这个 chunk
里了。
这时候可以看 Contextual Retrieval、late chunking、parent-child
retrieval、sentence window、summary index。它们的共同目标不是炫技,而是让
chunk 带着身份进索引,或者用小块召回、大块生成。
Anthropic 的 Contextual Retrieval 实验里,Contextual
Embeddings、Contextual BM25 和 reranking 组合后,把 top-20
chunk 检索失败率从 5.7% 降到 1.9%。这个数字不一定能原样迁移到你的业务,但方向很清楚:chunk
自己带上上下文,检索会更稳。
第二类:一次检索回答不了。
用户问这笔企业贷款为什么没批,背后可能要查贷款申请、企业财报、征信记录、担保材料、行业准入规则、历史风控例外、当前用户权限。一次向量检索很可能只找到授信制度。它不是完全错,但只拿到了一块拼图。
Agentic RAG 解决的不是多开几个 agent,而是让检索流程带上判断:问题要不要拆,查哪个系统,证据够不够,不够是改写
query 再查,换一个数据源,还是停下来告诉用户缺什么。
但它慢、贵、难排查。每多一个判断节点,就多一次模型调用;每多一轮检索,就多一次延迟。只有多跳问题真的占比高时,才值得上。
第三类:问题问的是关系和全局。
比如最近一个季度,金融客户投诉主要集中在哪些流程?这不是问某一条制度,也不是问某个公告编号。答案可能散在客服记录、产品流程、客户行业、地区、上线记录、历史投诉摘要里。向量搜
top-k,很容易找到几条相关记录,但这些记录未必代表整体情况。
GraphRAG 的价值在这里。它先从文档里抽实体、关系、claim,再组织成图;查询时不只拿相似文本,还可以沿着实体、关系和社区摘要去找上下文。
LazyGraphRAG、LightRAG、HippoRAG 2 这一波,正在把图路线做轻。成本和增量更新压力已经比早期低很多。但
GraphRAG 仍然不是默认升级。实体消歧、关系抽取、引用追溯、权限隔离都更复杂。它更适合关系问题、全局问题、跨文档主题总结,不适合拿来替代
SQL、ES 或 baseline RAG。
第四类:上下文变长以后,噪声也会变多。
long context 会让单篇长文档阅读、代码仓库局部分析、会议材料总结变简单。但它不是万能解法。上下文越长,旧公告、相似条款、无关表格、历史聊天、工具说明都可能挤进来,真正关键的证据反而容易被淹掉。
Chroma 2025 年把这个问题叫 context rot:上下文越长,模型表现不一定稳定变好,反而会出现不均匀退化。从
Transformer 的 attention 看,模型也不是平均地看上下文里的每一段。
所以未来不是上下文越长越好,而是系统越来越会挑上下文:该塞什么,怎么排,怎么压缩,哪些证据必须保留,哪些噪声必须剔除。
上线以后,靠 Trace 和 Eval 查清楚错在哪
把这些能力都补上,系统也不会从此不犯错。区别只是,真到线上,不能再靠感觉调。
上线以后,真正有用的是两件事:Trace 还原现场,Eval 把错误分清楚。
先看 Trace。一次失败请求,不能只留下用户问了什么、模型答了什么。至少要能看到
query 怎么改写,metadata 和权限怎么过滤,各路召回拿到了哪些候选,rerank 以后谁排在前面,最后哪些内容被塞进上下文,答案引用到了哪里。
没有 trace,你看到的永远只是答错了。到底是证据没进候选,还是进了候选没排上;是排上了没进上下文,还是进了上下文以后模型自己发挥,基本只能猜。
这时候,故障图才有用。它不是让你背名词,而是给排查顺序:先看证据有没有进来,再看有没有排上、有没有被正确拼进上下文,最后才看模型有没有按证据回答。
如果正确证据根本没进候选,reranker 再强也救不了。如果证据已经在候选里,但没进上下文,就查
rerank 和 context packing。如果答案写得很顺,引用却支撑不住结论,就查 citation
和 grounding。
现在 tracing 也在往标准化走。OpenTelemetry GenAI
和 OpenInference 这类语义约定,正在把 LLM 调用、retriever、reranker、tool
call、agent step 都记录成 span。长期做的话,埋点最好尽量贴近这类约定,后面换平台或者接公司自己的观测系统,不至于重埋一遍。
再看 Eval。Eval 最怕做成一个漂亮总分。
比如你给系统打了个 RAG score:0.82。看起来不错,但没法告诉你该改哪里。好的
eval 指标,必须能指向动作。
简单说:
- Context Recall 低,先查关键证据有没有被召回。
- Context Precision 低,先查融合排序、reranker、top-k 和去重。
- Groundedness / Faithfulness 低,先查生成约束、引用和证据支撑。
- Answer Relevance 低,先查意图理解、回答格式或 planner。
工具上不用从零造。Ragas、DeepEval、TruLens 更偏评测指标,Phoenix、LangSmith、Langfuse
更偏 trace 和观测,RAGChecker 会把 retrieval 和 generation
拆开诊断。选哪一个不是重点,重点是别只记最终答案,要把中间过程留住。
但工具不是最终裁判,LLM judge 也不能全信。它们适合做初筛、趋势监控和坏样本筛选,不适合替代业务判断。金融场景里,日期口径、监管口径、权限口径错了,答案写得再顺也没用,最后还是要靠
golden set、人工抽检和业务规则校准。
Trace 让你知道一次请求错在哪里,Eval 让你知道这类错误是不是反复出现。两件事连起来,RAG
才能从一次次救火,变成一轮轮迭代。
诊断清楚后,再决定从哪里改起
坏样本分清楚以后,重点就不是还能上哪些方案,而是先从哪里动手。
如果我是项目负责人,不会一上来追高级方案。顺序会很朴素:先让问题看得见,再把
baseline 补齐,最后才按失败类型上更重的方案。
先让问题看得见。
至少补齐几件事:完整 trace、50 到 200 个真实失败样本、最小
golden set、正确证据位置。再把 metadata、权限、版本、时间字段这些基础缺口盘一遍,把失败分到解析
/ 入库、召回、排序、上下文、生成、引用、权限或时效几类里。最后跑一版 baseline 指标,比如
Recall@k、MRR、groundedness、answer relevance、latency、cost。
这一步不一定马上提升答案质量,但会把主要矛盾暴露出来:到底是资料没进来,证据没找对,还是模型拿到证据以后没按证据答。
再把 baseline 补齐。
该补的不是一个神奇组件,而是生产 RAG 的基本盘:解析和 chunk、metadata、权限、版本和时间字段、hybrid
search、reranker、context packing、citation 校验。每次改动都用同一批问题回归,别今天改召回,明天换问题集,最后谁也不知道效果到底有没有变好。
线上反馈也要回流。只靠用户点踩不够,很多生产系统里,真正点击反馈按钮的用户不到
1%。低分抽样、重复追问、点击引用、转人工、用户改问,这些隐式信号也要进失败样本库。核心回归集可以挂进
CI,关键指标没过就别上线。
最后才按失败类型上重方案。
chunk 失忆严重,再看 Contextual Retrieval
或 parent-child;多跳问题占比高,再看 query routing、sub-question、轻量
Agentic RAG;关系和全局总结需求明确,再试 GraphRAG 或 summary tree;实时状态和权限敏感问题,优先走源系统
API。
这时候再谈 Agentic RAG、GraphRAG 才稳。因为你不是为了追新名词,而是已经知道哪一类失败需要它。
走到这一步,系统就不该只有一条链路了。更合理的是做 router。这类做法现在常被归到
Adaptive RAG 里:先判断问题类型、风险和成本,再决定走快链路还是慢链路。
这张表背后的意思很简单:不要把所有问题塞进同一条链路。朴素 RAG
处理复杂问题会断,agent loop 处理简单问题又慢又贵,GraphRAG 处理精确事实反而更难追引用。
问题进来,先判断类型、风险、权限、实时性和成本。简单问题快速答,精确事实查
ES、SQL 或 API,中等复杂问题再加 rewrite、rerank、sub-question,复杂低频问题才走
agent 或图。风险高、证据不足、权限不确定,就停下来,补证据,或者转人工复核。
RAG 不会消失,只会变成上下文工程
读到这里,很多人会冒出一个问题:RAG 这么麻烦,以后会不会被长上下文和
agent 替代?
我的判断是:朴素 RAG 会过时。
那种 PDF 切块、embedding、向量搜索、拼进上下文的 RAG,会越来越像原型。它能演示,但撑不起企业生产系统。
但 RAG 要解决的事不会消失。只要模型还需要最新数据、企业私有数据、权限控制、证据引用、成本控制和可追责,检索就还会存在。只是它不会一直作为一个孤立的
RAG 模块存在,而是会被揉进更大的 context engineering 里。业界也有人把这层叫
context engine。
下面这张图不是让你全建,而是让你看到生产 RAG 最复杂时会长成什么样。真正落地时,不同业务只会用到其中一部分。
图注:这张图只是把生产 RAG 可能长出来的能力摊开,方便你知道自己现在缺的是哪一块。
未来更现实的样子,不是 RAG 被替代,而是 RAG 变成这层里的一个能力。长上下文、agentic
search、源系统 API、memory、eval 和 trace 都会进来。系统要决定查哪里、查几轮、塞什么上下文、哪些证据必须保留,证据不足时什么时候停下来。
做到最后,一个好的生产 RAG 应该是这样:
简单问题不绕远路,精确问题命中原始记录,复杂问题拆开查,关系问题走图,实时状态查源系统,证据不足就停下来。答错了,还能查清楚为什么错。
这比喊下一代 RAG 朴素,但更接近生产。
所以这篇文章真正想说的,不是向量库之后还要堆多少组件,而是生产 RAG
必须从答不准,走到可诊断、可追溯、可迭代。资料进来要处理对,问题进来要找准证据,答案出去要能追,答错以后还能回放、回归、继续改。
后面值得单独聊的,也就是这几个最影响效果的地方:融合召回怎么调权重,rerank
为什么经常比换 embedding 更有效,Trace 和 Eval 怎么真正定位问题,Agentic
RAG 和 GraphRAG 到底该什么时候上。
RAG 落地到最后,靠的不是名词堆得多,而是上下文拿得准、证据追得清、系统能一轮轮调稳。 |