how to build a rag model

接入与开发

给准备动手写 RAG 的开发者一份工程落地清单:检索链路怎么串、超时并发怎么设、出错怎么降级、日志记什么、上线前怎么评测。

很多人第一次写 RAG,向量库跑通了,一上真实数据就出问题:检索偶尔超时、并发一高就限流、答错时不知道是召回还是生成的问题。这篇不讲概念,只按工程顺序把要做的动作列出来,每一步都告诉你卡住时先查什么。数字和模型版本一律到站内页面看当时的口径。

很多人第一次写 RAG,向量库跑通了,一上真实数据就出问题:检索偶尔超时、并发一高就限流、答错时不知道是召回还是生成的问题。这篇不讲概念,只按工程顺序把要做的动作列出来,每一步都告诉你卡住时先查什么。

数字和模型版本一律到站内页面看当时的口径。你在代码注释里写死的那些数,过一阵就对不上,反而误导后面接手的人。下面按链路骨架、超时并发、降级、日志评测四段走,每段末尾都给了排查顺序。

先把链路骨架搭直,别急着调效果

一次提问先拆成固定几段:清洗后的文档进库、问题改写、召回、重排、拼上下文、生成、返回引用。每段之间用统一的中间结构传递,方便单独替换某一段而不动其他代码。

  1. 跑最小闭环先用一条真实问题端到端打通,只保留向量召回加生成,确认能出答案并带引用。
  2. 补重排与多路召回闭环稳定后再加,一次只动一处,每加一段都保留加之前的输出样本做对照。
  3. 存输入输出样本每一段各存一份输入输出,后面排查「答案不对」时能一眼定位是召回没拿到还是生成跑偏。

顺序反了会同时面对太多变量,调不动。查链路位置和名词口径可以对照 /glossary 里的基础概念词条,别自己另起一套叫法,否则和同事沟通时对不上。

超时、重试与并发:按段分别设,不要一个值套到底

串行链路里任何一段拖长都会顶到上游网关。先量出请求进入时间与响应时间,算出各段延迟基线,再定超时值;没有基线就设超时,只能靠猜,一上线就被误杀。

环节超时怎么定重试要不要开
向量库查询按历史 P95 延迟上浮一档可开,确认不会重复计费或重复写入
重排模型按批量大小分档设,别一个值套所有批量可开,限制次数与总预算
生成模型按上下文长度分档,长上下文给更宽裕的值可开,但要在总预算内统一计次
  • 并发按最窄的那一环设上限,通常不是你的应用,而是向量库连接数、嵌入接口或生成接口的限流;超过就排队,别硬冲。
  • 限流报错不要靠无脑退避硬扛,按失败比例触发降级,分档做法参考站内已有的限流与退避清单。
  • 重试要确认幂等性:查询类一般安全,写入类如果不带去重键,重试可能产生重复文档。
  • 给整条链路设一个总预算,单段重试次数再多也不能让总耗时突破它,否则用户早走了。

降级路径:答不出比答错好

降级的目标是让系统在部分组件不可用时仍能给出可用的回答,而不是硬撑着输出一个可能错的答案。准备三档:重排超时就退回纯向量召回;生成接口不可用就换备用通道;全部不可用就返回「暂无法回答加可看的原文片段」。

触发条件降级动作返回给用户什么
重排连续失败超阈值退回纯向量召回,跳过重排正常答案,标注召回方式
生成接口不可用切备用通道答案加「备用通道」标记
全部不可用返回原文片段暂无法回答加可查阅的片段

触发条件要写进代码而不是靠人临时判断,否则高峰期没人来得及切。降级时要标记返回值来源,让前端能显示「这条是降级结果」,避免用户把残缺答案当权威答案。备用通道的能力差异要提前验证:换模型后提示词里的格式要求可能不再成立,先跑一遍小样本用例再挂上去。

日志与评测:让每次答错都能复盘

一次请求至少记这些字段:问题原文、召回命中的文档 ID 与分数、拼进上下文的片段长度、实际用的模型与通道、各段耗时、token 用量、是否降级。字段够全,复盘时才不用靠回忆。

  • 建一条固定的小评测集,用几十条真实问题加参考答案要点,改分块、换嵌入模型、换生成模型时都跑一遍,只看通过率有没有掉。
  • 上线前用评测集确定「够用」的线,别用单条对话的观感做决策。
  • 线上再用量榜与监控页核对延迟与错误率的整体水位,看是否偏离基线。
  • 分块策略改过之后,旧评测集要重新确认还适用,否则你会拿过期的标准判断新链路。

词条、模型规格和价格口径变化快,写文档时引用站内页面而不是抄数字进代码注释。想对照不同嵌入模型与生成模型的规格,去 /models 看当时的口径;想确认调用成本再定预算,去 /price-watch 核对当时的数字。

下一步把上面四段拆成 checklist 逐项过一遍,再对照站内的模型规格与价格口径确定你的技术选型。

常见问题

RAG 一定要用重排吗,不用行不行?

不一定。数据量小、问题表达和文档用词高度一致时,纯向量召回就够。只有当「检索回来的前几条经常不含答案」时才值得加重排,而且要先确认是召回问题而非分块问题,否则重排只是把错的东西重新排一遍。

检索偶尔超时,先改哪里?

先测各段延迟,确认是向量库还是生成接口拖慢;再检查并发是否超过最窄环节的上限;最后才考虑降超时值。盲目调小超时会推高失败率,调大又会顶到上游网关限制,得先有延迟基线数据再动手。

为什么本地跑得好,上线就答错?

多半是并发和降级路径没测过:线上触发限流后静默降级,返回的是残缺上下文。先在日志里区分正常返回和降级返回,再复现一次高并发场景,看降级条件是不是设得太松。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。