很多团队已经能把向量检索跑通,也试过让模型调函数,但真把两者拼进一个问答应用就开始出问题:检索慢拖着整条链路、工具循环停不下来、答案没人能复盘。这篇不重复原理,只给落地做法——链路怎么编排、每一步超时和并发怎么设、降级走哪条路、日志记哪些字段、评测怎么小成本跑起来。适合已经写过 demo、正要把 RAG 加 Agent 推上生产的开发者。
很多团队已经能把向量检索跑通,也试过让模型调函数,但真把两者拼进一个问答应用就开始出问题:检索慢拖着整条链路、工具循环停不下来、答案没人能复盘。问题往往不在模型选得对不对,而在编排、超时、降级、日志、评测这五件工程事没定死。
这篇不重复原理,只给落地做法。适合已经写过 demo、正要把 RAG 加 Agent 推上生产的开发者。全程不依赖任何写死的数字,凡是涉及价格、模型口径的,都请到站内页面核对你当时看到的数据。
组合方式先定下来:谁调谁、跑几轮
组合方式两种主干先选一种,别犹豫着两种都试。检索先行的固定链路:先召回再生成,实现简单、延迟可预测,适合单跳事实问答。检索当工具的循环链路:模型自己决定要不要查、查几次,灵活但必须设上限,多跳和跨文档对比才值得上。
| 链路 | 适合的问题 | 主要风险 |
|---|---|---|
| 检索先行固定链路 | 单跳事实问答、FAQ | 检索没命中就答偏 |
| 检索当工具的循环链路 | 多跳推理、跨文档对比 | 轮数失控、延迟不可预测 |
- 循环链路必须给死预算:最大轮数、单次检索返回条数、总 token 上限各写一个常数,超了强制收口出答案。
- 收口策略提前想好:轮数用完没结论时,是输出已召回片段的部分答案加一句说明,还是直接回兜底话术,别让模型自由发挥。
- 判断点:连续几轮检索回来的片段高度重复,说明不是轮数不够,是检索或切分有问题,继续加轮数只是烧钱。
- 固定链路也要留一个「检索为空」的分支,否则模型会拿空上下文硬编答案。
超时和并发:卡在哪一步就限哪一步
超时按段设,别用一个全局超时糊过去。把链路拆成检索调用、模型首次响应、整体请求三段,各自独立计时。整体超时要大于各段之和,给编排本身留出开销,否则会出现「每段都没超,整体却超了」的怪事。
- 量延迟基线先到站内测速页跑一遍自己的调用延迟,记下检索和模型各自的分布,而不是只看平均值。
- 分段设超时检索、模型首字、整体请求分别设阈值,任何一段超时就走该段的降级分支。
- 限内外两层并发外层限应用能同时接多少请求,内层限每个请求内部允许并行发几个检索或工具调用。内层最容易被忽略,一个请求扇出十几个调用,限流来得莫名其妙。
- 压测验证重点看长尾请求会不会把整体拖垮,平均值好看不代表没问题。
并发数要和你的中转站或自建服务实际能扛的量对齐,动手前到 /tools/speed-test 量一遍延迟基线,再到 /tools/verify 看目标服务的当前状态,别拿测速之外的数字当依据。内部工具类应用、并发极低的批处理场景,可以不设内层并发,但整体超时和轮数上限仍然要有。
降级路径:哪一步挂了,退到哪里
降级按依赖分级来写,而不是一出错就整个请求失败。检索挂了退成纯模型回答并提示「未引用资料」;模型主通道挂了切备用通道;工具调用连续失败两次就跳过该工具并继续出答案。关键是把降级写在编排层,每个环节包一层,定义清楚失败几次算失败、失败后返回什么默认值。
| 挂掉的一环 | 退到哪里 | 给用户看什么 |
|---|---|---|
| 检索 | 纯模型回答 | 说明未引用资料 |
| 模型主通道 | 备用通道 | 无感知,日志记原因 |
| 单个工具 | 跳过该工具 | 不提示,日志记原因 |
| 全部失败 | 兜底话术加重试入口 | 明确告知可重试 |
备用通道要提前验证过,不能等出事才切。切换后按站内 /relay-switch-api-verification 的思路走一遍连通性确认。对答案准确性要求极高、宁可报错也不能给无依据回答的场景,就别做静默降级,改成明确告知用户并给重试入口。
日志和评测:让每次请求都能复盘
每次请求至少落这几个字段:请求 id、走了哪条链路、检索命中条数与耗时、模型调用次数与各自耗时、是否触发降级、总 token。少一个,事后就没法定位是贵还是慢,是检索空转还是重试太多。
- 请求 id:串起链路里所有环节的日志。
- 链路标识:区分固定链路还是循环链路,方便分组对比。
- 检索命中条数与耗时:判断是检索问题还是生成问题。
- 模型调用次数与耗时:定位重试和空转。
- 是否降级及原因:上线后统计降级比例。
- 总 token:对照站内 /usage 的消耗趋势看是否有异常。
评测别一上来搭大平台:准备十到三十条有标准答案的问题,每次改提示词、换切分方式、调轮数上限后跑一遍,记录命中率和平均调用次数。探索期、需求还没定型的产品先别投入做评测集,但上面那几个日志字段从第一天就该记。
上线前的排查顺序
- 查超时确认检索、模型首字、整体请求三段超时都设了,而不是共用一。
- 查并发确认外层和内层都有上限,内层扇出没有失控。
- 手动触发降级把检索关掉、把备用通道切走,各模拟一次,看降级路径是否真的生效。
- 核对日志字段抽查几条真实请求,看字段是否齐全、能不能复盘出慢在哪。
- 核对厂商口径到 /providers 和 /models 确认当前可用厂商与模型口径,涉及价格一律到 /official-api 看你当时的数据。
常见问题
RAG 一定要和 Agent 组合吗?
不一定。单跳事实问答用固定检索链路就够,上 Agent 只会增加延迟和不确定性。只有当问题需要多步推理、自己判断要不要查资料、或者要调外部工具取实时数据时,组合才划算。可以先看站内 /rag-vs-agent-boundary 那篇判断边界,再决定要不要引入循环链路。
组合后延迟明显变高,先查哪里?
先按段拆开计时:检索、模型首次响应、整体请求各花多少。多数情况是循环轮数太多或者内层并发扇出过大。把轮数上限压到最小可用值,同时确认没有重复召回同一批片段。到 /tools/speed-test 量一遍基线,能快速区分是链路问题还是服务本身慢。
怎么判断是检索的锅还是模型的锅?
看日志里检索返回的片段和最终答案对不对得上。片段里有答案但答错,是生成环节的问题,查提示词和上下文拼装;片段里根本没有答案,是检索的问题,回头查切分粒度和召回数量。别凭感觉换模型,先做这个对照。