大模型 rag 应用开发 构建智能生成系统

接入与开发

面向应用开发者,把 RAG 智能生成系统从离线跑通推进到线上可用的工程动作:超时、并发、降级、日志与评测五件事怎么落地。

很多团队的 RAG 演示都能跑,一接真实流量就原形毕露:检索慢把整体拖到超时、并发一上来就限流、答案偶发跑偏却查不到是哪一环出的问题。这篇不讲原理,只给工程落地清单——每个环节该设什么、什么时候不适用、出了问题按什么顺序查。

很多团队的 RAG 演示都能跑通,一接真实流量就原形毕露:检索慢把整体拖到超时、并发一上来就限流、答案偶发跑偏却查不到是哪一环出的问题。原因通常不在模型,而在于链路没有被切段、超时没有分档、日志不足以还原一次请求。

这篇不讲原理,只给工程落地清单:每个环节该设什么、什么时候不适用、出了问题按什么顺序查。目标是让系统从「能演示」变成「敢放量」,同时保留随时把问题定位到具体环节的能力。想先确认模型本身的延迟水位,可以到 /tools/speed-test 核对当时的数字,把它当作对比基线。

先把链路切段,再谈优化

优化前先能看见。把一次问答拆成清洗入库、检索召回、重排、拼装生成四段,每段单独打点计时并落库。没有分段耗时,你只能知道「整体慢」,却不知道是向量库慢、embedding 接口慢还是模型慢,改起来就是碰运气。

链路分段主要耗时来源上线前该确认的事
清洗入库解析、分块、embedding 批处理是离线任务还是阻塞在线请求
检索召回向量库查询、网络往返超时值与返回条数上限是否明确
重排重排模型或规则打分失败时是否可跳过而不是直接报错
拼装生成上下文长度、模型输出长度上下文截断策略是否固定且可复现
  • 先量基线:用 /tools/speed-test 把模型侧的延迟单独测出来,把「模型慢」和「检索慢」分清楚,避免误判。
  • 给每段定超时预算:检索段一般不该比生成段还长,哪段先超预算就优先查哪段。
  • 分段计时用一个统一的埋点字段收口,不要把耗时散落在各服务的日志里,否则复盘时要手动拼时间线。
  • 不适用情况:单文档、低并发的小工具,全链路一个总超时值就够了,拆太细反而增加维护成本。

超时、并发与降级怎么设

超时不要只设一个总开关。总超时太短会把正常的长回答掐死,太长又会让请求卡住却不报错。正确做法是由内到外分三档逐层放宽:连接超时、单次检索超时、整体请求超时。只要有一档没设,就会出现「页面一直转圈但日志里没有错误」这种最难查的状态。

  1. 设定三档超时连接、单次检索、整体请求各给一个值,内层必须小于外层;上线后观察是否有请求正好卡在某一档,那就是该放宽或该优化的信号。
  2. 按下游最紧的一环定并发并发上限通常先卡在向量库或 embedding 接口上。用分批加队列的方式限流,不要一上来就堆协程,否则只是把压力原样转给下游。
  3. 写清降级触发条件召回为空、重排超时、生成超时这三种情况各返回什么要提前定。宁可显式返回「暂时答不了」,也不要让模型在没有依据的情况下硬编一段话。
  4. 验证降级路径主动把向量库或模型接口断开,确认前端拿到的是可解释的提示,而不是空白或超时报错页。

不适用情况:对延迟不敏感的内部工具可以不做复杂降级,但失败必须显式暴露,不能让接口静默返回空答案——那等于把问题推给了下一个排查的人。

日志要能还原一次请求

日志的目的不是记录系统跑了,而是出事时能复现那一次回答。判断标准很简单:给你一个请求 ID,能不能还原出当时检索了哪些文档、分数多少、各段耗时多久、最后是否走了降级。缺任何一项,复盘都会退化成猜测。

请求 ID
贯穿全链路,前端报错时能一把捞出所有相关日志
命中文档与分数
判断是没召回、召回了没排上,还是排上了没被用好
分段耗时
定位瓶颈落在检索还是生成,避免凭感觉换模型
降级标记
区分「模型答得差」和「系统根本没正常答」两类问题
  • 检索结果与模型输出成对存下来,这是后续做评测集的原始素材。
  • 日志做脱敏,不要整段原文入库;本地处理场景可以参考 /tools/card-batch 这类批量脱敏的思路。
  • 排查顺序固定:先看有没有命中,再看分数排位,最后看提示词拼装,不要一上来就怀疑模型。
  • 日志保留周期与知识库更新节奏对齐,否则旧日志对不上新文档,复盘会失真。

小规模评测,别靠肉眼

肉眼抽查最大的问题是不可比:同一批问题,今天觉得答得不错,明天换了提示词又觉得差不多,其实已经变差。做法是固定一小批问题当基准,覆盖「能答」「该说不知道」「需要多文档拼接」三类,每次变更都跑一遍。

评测项看什么什么时候要重跑
命中率正确文档有没有被召回进上下文换 embedding、改分块、调 top-k
忠实度回答有没有超出检索到的内容改提示词、换生成模型
拒答表现该说不知道的时候有没有说实话知识库删改或新增之后

命中率和忠实度要分开看:命中率低是检索的问题,忠实度高但命中率低,说明模型没瞎编,只是没拿到对的材料。两个指标混在一起看,就分不清该调检索还是调生成。

  • 换模型、换分块策略、调 top-k 都算变更,变更前后各跑一次并留档,不做对比等于没测。
  • 评测集规模不用大,但要稳定;问题描述写具体,避免同一个问题每次理解都不一样。
  • 不适用情况:知识库每周大改的项目,评测集要定期换血,否则分数会虚高,给你一种变好了的错觉。
  • 拿不准某个环节是不是瓶颈时,先回到 /rankings 和 /price-watch 看当时可选的模型与接口水位,再决定是换件还是改架构。
下一步把上面的超时档位、并发上限、日志字段、评测集四样当成上线检查表逐条打勾;需要对比不同接口的延迟与稳定性时,到 /tools/speed-test 核对当时的数字再定方案。

常见问题

RAG 应用里检索和生成的超时该怎么分开设?

内层检索设短一点,外层生成设长一点,整体超时放在最外层兜底。检索一旦超预算就先返回空结果走降级,别让整条链路一起挂着。改完记得用真实并发压一次,单请求跑通不代表并发下也稳。

并发一提高就报限流,是加机器还是改调用方式?

先确认限在谁身上:向量库、embedding 接口还是生成模型。多数情况是下游按 QPS 或并发数卡的,加机器没用。做法是分批加队列、控制同时在飞的请求数,再配合指数退避重试,具体阈值以你实际套餐为准。

怎么判断 RAG 答错是检索的问题还是生成的问题?

看日志里命中的文档片段。命中了正确片段但答案跑偏,是拼装和提示词的问题;压根没命中,就是分块、embedding 或 top-k 的问题。两类改动方向完全不同,不分清容易白改。

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