编码智能体多模型路由策略:为何缓存失效会导致成本激增
编码智能体在多模型间路由会导致提示词缓存失效,从而大幅增加 API 调用成本。本文深入分析缓存定价机制,揭示为何在智能体任务中锁定单一模型比动态路由更经济,并提供具体的成本计算逻辑与最佳实践建议。
多模型路由对编码智能体的作用
多模型路由会将每个请求发送至能够处理该任务且成本最低的模型。对于聊天流量,这种方式效果良好。但对于编码智能体,它通常会导致成本增加而非节省,因为智能体的费用主要由每个模型缓存的提示词前缀决定,而切换模型会使该缓存失效。
本文主张的原则是:仅在任务边界处为了成本考虑进行跨层级路由,为了可用性进行跨服务商路由,而在任何涉及智能体操作的会话中,应锁定使用单一模型。以下是具体论证。
定义四个术语。路由器 (router) 为每个请求选择模型。网关 (gateway) 是请求经过的代理,它可能具备也可能不具备路由功能。提示词缓存 (prompt cache) 指服务商存储已处理的提示词前缀,后续请求若重复该前缀,则仅按输入价格的一小部分计费。KV 缓存 (KV cache) 即键值缓存,是指在您自行运行的服务器中实现相同的机制。
为什么聊天流量路由顺畅而代理流量却不然
聊天请求是一次性的。请求到达、被分类、进入模型、返回结果。后续请求不依赖前序状态。路由器可以将此问题发送给小型模型,将下一个问题发送给大型模型,两者互不感知。这是几乎所有路由基准测试衡量的负载类型,优秀的路由器确实能很好地处理此类任务。
代理交互并非单一请求。一条诸如“修复失败的测试”的指令会转化为 20 到 60 次 API 调用。每次调用都会重新发送整个对话内容:系统提示词、所有工具定义、代理已读取的每个文件以及它所见过的每条命令输出。上下文只会不断增长。到第 30 次调用时,重复的前缀可能已达数万个 token,而每次调用中真正新增的内容仅有几百个。
这种形态改变了“昂贵”一词的定义。在聊天场景中,成本大致等于模型单价乘以请求次数。而在代理循环中,成本在于每次调用都要重新计费的前缀。本文后续内容均基于这一事实展开。
提示词缓存按模型划分,且 Agent 驻留在缓存中
Anthropic 对缓存读取的定价为基础输入价格的 0.1 倍,对 5 分钟缓存写入的定价为 1.25 倍。以上为截至 2026 年 8 月公布的标价。
The data behind this chart
[
{
"label": "Opus 5",
"uncached_input_usd": "5.00",
"cache_read_usd": "0.50"
},
{
"label": "Sonnet 5",
"uncached_input_usd": "2.00",
"cache_read_usd": "0.20"
},
{
"label": "Haiku 4.5",
"uncached_input_usd": "1.00",
"cache_read_usd": "0.10"
}
]请横向对比两组数据,而非纵向对比。Opus 5 的缓存读取价格为每百万 token 0.50 美元。列表中最便宜的模型 Haiku 4.5 的未缓存输入价格为每百万 token 1.00 美元。因此,在最昂贵的模型上重新读取热缓存前缀,其单位输入 token 的成本,低于在最便宜的模型上读取相同前缀的冷数据成本。
这一对比打破了大多数路由规划。将任务下发到低层级的路由器通常基于标价进行比较。但处于会话中期的 Agent 支付的并非所用模型的标价,而是缓存读取价格,该价格本身已低于廉价模型的未缓存费率。
缓存基于提示词前缀的哈希值进行键值映射,且按模型划分。对不同模型的请求会在从未见过该前缀的存储中进行哈希匹配,因此无法命中缓存并需支付全额费用。缓存还具有层级结构:工具优先,其次是系统提示词,最后是消息。任何层级的变动都会导致该层级及其后续内容失效,这意味着修改一个工具定义会丢弃其后的系统提示词缓存。在运行时注册工具的 Agent 即使不经过路由器,也会触发此问题。
单次会话切换的实际成本
假设会话拥有 40,000 token 的稳定前缀,这是代理读取少量文件后的常见规模。下表根据上述标价计算了单次交互的前缀成本。
The data behind this chart
[
{
"label": "Opus 5, cache warm",
"prefix_cost_usd": "0.020"
},
{
"label": "Sonnet 5, turn after switch",
"prefix_cost_usd": "0.100"
},
{
"label": "Opus 5, cache re-warmed",
"prefix_cost_usd": "0.250"
}
]在 Opus 5 上保持热缓存,该轮交互的前缀成本为 0.020 美元。路由切换至 Sonnet 5 后的第一轮交互成本为 0.100 美元,因为 Sonnet 没有该前缀的缓存条目,必须重新写入。切回 Opus 5 的成本为 0.250 美元,因为原始条目在会话离开期间已过期。
因此,往返切换需支付两次缓存写入费用,以避免两次缓存读取。作为交换,切换使该轮输出按 Sonnet 的输出价格计费,而非 Opus 的价格。详情区块展示了完整的计算过程:节省的金额仅为几分钱,而缓存惩罚却高达几角钱。惩罚金额比节省金额高出一个数量级以上,且随着前缀长度增加,惩罚会持续增长,而节省金额则保持不变。
计算方法说明
此处所有数字均基于首个图表中的公开标价计算得出。这是一个成本模型而非基准测试,计算过程未发送任何实际请求。若更改前缀大小,比例也会随之改变。
前缀:40,000 tokens,在交互过程中保持不变。
Opus 5, warm read 40,000 x $0.50 / 1e6 = $0.020
Sonnet 5, cache write 40,000 x $2.50 / 1e6 = $0.100 (1.25 x $2 base)
Opus 5, cache write 40,000 x $6.25 / 1e6 = $0.250 (1.25 x $5 base)往返切换总计:$0.100 + $0.250 = $0.350。被替换的两轮 Opus 热缓存交互成本为:$0.040。绕道产生的额外成本为:$0.310。
在 800 token 输出的单轮交互中,节省的金额为 Opus 5(每百万 token $25)与 Sonnet 5(每百万 token $10)之间的输出价格差:
800 x ($25 - $10) / 1e6 = $0.012花费 $0.310 以节省 $0.012,成本效益比严重倒挂,约为 25 倍。节省金额随输出 token 数量波动,而输出 token 每轮大致固定。惩罚金额则随前缀大小波动,且会随会话时长不断增长。会话越长,该方案越不划算。
不同提供商的工具调用格式不统一
Agent 是一个工具调用循环,因此工具调用格式的重要性远超普通聊天场景。Anthropic 的 Messages API 返回 tool_use 内容块,并要求返回 tool_result 块。兼容 OpenAI 的 API 则返回一个 tool_calls 数组,其中 function.arguments 是一个 JSON 编码的字符串,而非嵌套对象。网关负责在两者间进行转换,对于常规调用,这种转换非常简洁。
问题出现在边缘情况。并行工具调用(即模型在一次响应中发出多个调用)在不同平台上的表示方式不同,且支持程度也不一致。严格的模式强制执行是特定于提供商的功能,因此在一个端点上能保证模式有效的参数,在另一个端点上往往只能趋向于有效。Agent 会将此差异视为包含解析错误的工具结果,随后会尝试通过额外的一轮对话进行修复。这些修复轮次会按完整的预填充价格计费,因此格式不匹配不仅会出现在对话记录中,还会体现在账单上。
自托管端点需要显式配置此项。vLLM 的兼容 OpenAI 服务器需要 --enable-auto-tool-choice,并配合与模型系列相匹配的 --tool-call-parser(如 hermes、mistral、llama3_json 等),此外还需要一个处理工具角色消息的聊天模板。vLLM 文档明确指出了该路径的局限性:在使用 tool_choice="auto" 且没有严格模式约束的情况下,vLLM 从原始文本中提取工具调用,因此参数偶尔会出现格式错误或违反函数参数模式的情况。为模型选择了错误的解析器属于配置错误,表现为 Agent 无法调用工具;在向其路由流量之前,了解这一点非常重要。Ollama 与 vLLM 在自托管模型服务上的区别在此处至关重要,因为两者提供工具调用的方式各不相同。
任务执行中途的后备路由会导致行为变更且无报错
后备路由是最容易被误启用的功能。网关通常配置为:当首选模型返回速率限制或 5xx 错误时,自动重试其他模型,并将失败的模型置于冷却状态。对于聊天流量,这种机制非常有效。但在长代理任务中,这意味着任务的后半部分是在你未指定的模型上运行的。
系统不会对此进行任何报告。任务不会失败,代理不会发出警告,退出状态也显示为成功。最终结果是:任务的规划由一个模型完成,而编辑由另一个模型执行,导致任务中途的语气和习惯发生变化。唯一可靠的判断依据是网关请求日志或响应元数据中的 model 字段。因此,如果启用了后备路由,请务必记录每条请求的该字段,并在结果异常时进行核对。在不知道具体模型的情况下调试行为,所浪费的时间远超后备路由节省的时间。
上下文压缩也会陷入同样的陷阱。许多代理通过调用小型模型来总结长历史记录。如果该调用使用了不同的模型或不同的系统提示词,它会写入独立的缓存条目,而不会刷新主会话的缓存,导致下一次完整交互时必须重新加载冷前缀。这种压缩节省了 Token,却丢失了缓存。
路由开销确实存在,但延迟并非痛点所在
路由器确实会为每个请求增加额外工作,准确评估其影响很有必要。DigitalOcean 报告称,其 Arch-Router 模型在自有评估中,路由意图解析耗时约 51 毫秒,路由准确率为 93.17%。这些数据源自其自身的测量与基准测试,并非我们的数据,也非通用结果。若按字面理解,结论令人宽慰:在 40 次代理调用中,51 毫秒的延迟仅为运行数分钟的任务增加了约 2 秒的开销。
在此场景下,路由的昂贵之处并非这 2 秒延迟。真正造成伤害的开销是路由器通过完整模型调用进行分类,因为这意味着每个请求都要进行第二次推理,且需像其他请求一样计费并排队。在这两者之下,是前述的缓存计算,这根本不算开销,而是路由本应优化的目标成本。
在自托管服务器上,同样的规则适用,但回旋余地更小。提示词缓存(prompt cache)在本地的等效实现是 KV 缓存中的前缀缓存,它驻留在 GPU 显存中。在单张 GPU 上托管两个模型会分割显存,导致每个模型保留的 KV 缓存更小,从而更快地驱逐前缀。因此,在两个本地模型之间进行路由可能会同时降低两者的缓存命中率。如果您正在为此规划硬件,从 编码代理在 VPS 上实际所需的内存和 CPU 入手,要比从路由器入手更有参考价值。
决策规则
- 跨服务商路由以确保可用性。 当替代方案是请求失败时,任何成本都是合理的。将故障转移锁定在具有相同工具调用格式的模型上,以确保智能体的循环能够持续运行,并记录每个调用由哪个模型处理。
- 仅在任务边界处跨层级路由以控制成本。 在会话开始前,决定对重命名任务使用 Haiku、对重构任务使用 Opus 是合理的决策。如果在会话进行到第 30 轮时才做此决定,则是不明智的。
- 对于任何智能体任务,每个会话锁定一个模型。 会话的价值在于其热缓存。切换模型等同于清除缓存,因为这正是切换所带来的后果。
- 自由路由子智能体。 从全新的小上下文开始的子智能体没有需要保留的热缓存,因此可以在适合其任务的任何模型上运行。这是智能体内部唯一可以近乎零成本进行路由的地方。
关于如何构建此功能,网关承担了相应工作:模型别名和显式故障转移列表。一个最小化的 LiteLLM 代理配置如下所示。
model_list:
- model_name: agent-primary
litellm_params:
model: anthropic/claude-opus-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: agent-standby
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
router_settings:
fallbacks: [{"agent-primary": ["agent-standby"]}]
num_retries: 2
cooldown_time: 30将智能体指向 agent-primary,它将保持使用同一个模型,直到该模型无法访问。两个条目位于同一服务商,因此当故障转移触发时,工具调用格式不会改变。尽管此时接受了层级变更,但考虑到替代方案是请求失败,这种权衡是值得的。这就是不涉及成本路由的可用性路由,也是大多数编程智能体所追求的组合。包括密钥和预算在内的完整构建过程,已在 在您的 VPS 上运行自托管 LiteLLM 网关 中介绍,本文特意不再赘述。
当精心选择的模型优于任何路由策略时
路由是解决请求难度差异的一种方案。编程智能体(coding agent)的难度差异比表面看起来要小,因为无论请求内容为何,每次调用中开销最大的部分都是相同的前缀。一旦前缀占据主导,廉价层级与昂贵层级之间的成本差异就会缩小到仅剩输出价格的差距,而输出仅占智能体 token 总量的一小部分。
因此,最稳妥的默认方案是选择单一模型,开启缓存,并设置足够长的 TTL(生存时间),以覆盖你停下来阅读代码差异(diff)的间隙。Anthropic 提供 1 小时的缓存写入,价格为基础输入价格的 2 倍,在读取两次后即可回本,这通常比任何路由策略都更有效。请通过 Opus、Sonnet 和 Haiku 的直接对比 审慎选择层级。如果账单依然超支,应通过预算控制和缩减上下文(如 在 VPS 上控制 AI 智能体成本 所述)来降低费用,而不是在会话中途切换模型。
当请求相互独立且简短,或者子智能体以全新上下文启动时,可以使用路由。当你进行单一任务的长会话时,应锁定模型。大多数编程智能体的工作属于后者,这就是为什么在聊天产品中能节省成本的路由策略,在这里反而会悄悄增加你的开销。如果你尚未确定智能体选型,Claude Code 与 Cursor、Codex 及 Copilot 的对比 涵盖了各工具如何处理模型选择,其中一些工具会自动为你做出决定。
FAQ
在会话中切换模型真的会丢失提示词缓存吗?
是的。提示词缓存基于提示词前缀的哈希值,且按模型存储。发送到不同模型的请求会根据该模型从未见过的前缀进行哈希计算。系统找不到匹配项,因此会支付完整的未缓存输入费用,如果启用了缓存,还会额外支付缓存写入费用。切换回原模型也无法恢复之前的条目,因为默认的 5 分钟生命周期通常已经过期。请检查响应 usage 对象中的 cache_read_input_tokens 和 cache_creation_input_tokens 字段:如果长会话中读取的缓存 token 数为 0,即为该问题的征兆。
将任务路由到更便宜的模型对 Agent 来说更划算吗?
仅当没有可用的热缓存时才划算。Anthropic 的缓存读取成本仅为基础输入价格的 0.1 倍,这使得 Opus 5 的热读取成本低于 Haiku 4.5 的未缓存输入价格。一旦会话拥有较大的缓存前缀,当前模型在输入成本上已经是更便宜的选择。只有在上下文较新且较小时,路由才划算:例如在任务开始时,或在仅携带所需上下文的子 Agent 中。
为什么我的 Agent 在任务执行中途表现不一致?
检查是否触发了网关故障转移。当主模型触发速率限制或返回 5xx 错误时,网关会重试备用模型,并将主模型置于冷却状态几秒钟,导致任务的剩余部分在其他模型上运行。此过程不会产生错误或警告,任务仍会报告成功。网关请求日志或响应元数据中的 model 字段是唯一的可靠记录,因此如果您启用了故障转移,请务必按请求记录该字段。
工具调用在所有提供商之间表现一致吗?
并不完全一致。Anthropic 的 Messages API 使用 tool_use 和 tool_result 内容块,而兼容 OpenAI 的 API 使用 tool_calls 数组,其中 function.arguments 是 JSON 编码的字符串。网关可以很好地转换常见情况,但并行工具调用和严格的模式强制执行在不同提供商之间存在差异。在自托管的 vLLM 上,必须设置 --enable-auto-tool-choice 以及与模型系列匹配的 --tool-call-parser。vLLM 文档指出,如果没有严格的模式约束,服务器会从原始文本中提取工具调用,因此参数偶尔可能会格式错误。
编码会话的缓存 TTL 应该设置为多久?
连续工作时使用默认的 5 分钟生命周期,当人类需要阅读轮次之间的差异(diff)时使用 1 小时选项。Anthropic 的 5 分钟写入价格为基础输入的 1.25 倍,1 小时写入为 2 倍,而读取价格为 0.1 倍。5 分钟写入只需一次读取即可回本,1 小时写入需两次。因此,在任何预期会返回并继续工作的会话中,较长的生命周期通常比支付冷前缀的费用更划算。