跳到正文

devlog/token-math/one-big-model-call-or-many-small-ones-a-cost-breakdown-1114.md

一次大调用还是十次小调用:终端账单里那些容易踩的坑

把整个仓库塞进一次大调用之后

在编辑器里重构一个模块时,最省事的动作是把改动文件、依赖文件、测试报错和最近十条对话一起塞进一条请求,心里想着反正只有一次调用,能有多贵。问题在于价格按真实 token 结算,一次大调用的输入可能就有七八万 token,而其中大部分是你根本没读过的样板代码、生成物和无关目录。

更隐蔽的是重复成本。第一次回答方向错了,你在末尾补一句“再试一次”,整段上下文又会被重新计费一遍;改一次参数重跑十次,等于为同一批背景 token 付十遍。这正是很多人月末看到账单会愣住的原因:不是模型单价离谱,是同一个问题被反复完整地问了很多遍。

  • 把整段仓库上下文塞进一次请求,往往只是为了回答一个定位明确的小问题。
  • 上下文里混入了未压缩的日志、编译输出和锁文件内容,让输入规模悄悄膨胀好几倍。
  • 每次重跑都把相同的背景重新发送一遍,等于为同一批 token 反复支付费用。
  • 一次请求里塞进多个互不相关的任务,其中一个失败就只能整段重新发送。
  • 请求前没有粗略估算输入规模,结果预算和实际账单差出整整一个数量级。
  • 忽略了输出长度失控带来的成本,让模型把同样的结论写成了冗长的复述。

对应的处理方式是先在终端把上下文裁到只剩函数签名、报错栈和相关改动,明确一个验收标准再发请求。Fluxo 用同一个 base URL(https://api.fluxorelay.com)和一把密钥就能调到 Claude、GPT、Gemini、DeepSeek、Kimi、GLM、Qwen、Grok 等模型,想换一个模型做对照实验时不用重写客户端,也不用为每个厂商维护一套鉴权逻辑。

为了省钱把一个任务硬拆成十次小调用

另一个极端是把每个问题都拆成最小调用,觉得调用次数少就一定便宜。实际情况恰恰相反:每次调用都要重新带上系统规则、文件清单、代码约定这些固定前缀,十次小调用的固定开销加起来,往往超过一次粒度合适的中等调用,而且你还得在十次之间手工维护上下文,翻车概率更高。

  • 每个小调用都重复携带相同的规则、目录结构和风格约定,固定前缀被计费了十次。
  • 拆分后的各次调用彼此不知道对方的结论,导致后面的调用又去重做前面的工作。
  • 为了省一次调用而省略必要的约束,结果输出不符合约定,反而需要额外的修正调用。
  • 在多次调用之间手工搬运上下文,容易漏掉关键信息,让模型给出方向错误的答案。
  • 把本来一次就能完成的评审流程拆成七八轮对话,每轮都重新解释一遍背景。

更合适的粒度是“一次调用完成一个有明确验收标准的单位”,比如改完一个函数并补齐它的测试。档位也要跟着任务走:用 Claude Haiku 4.5 跑补全、摘要这类高频小活,用 Claude Sonnet 5.5 处理跨文件重构和复杂调试,比全线用旗舰档省得多。Fluxo 按真实 token 计费,缓存读取和写入都如实计入,没有月费,所以这种分档策略能直接反映在账单上,不会被套餐包月的固定支出掩盖。

把缓存读写当成免费午餐之后

缓存确实能显著省钱,但前提是你理解它的工作方式:只有稳定且逐字节一致的前缀才可能被命中,命中之后的读取便宜,写入则是要照常付费的。很多人只看到“命中很便宜”,于是每次都往请求最前面插一句时间戳、随机 ID 或者当天的日期,结果缓存从来没被命中过,每次都在支付完整输入的费用。

  • 在请求最前面加入时间戳或随机标识,导致稳定前缀每一轮都在变化。
  • 频繁改动系统提示的顺序和格式,让已有的缓存写入无法被后续请求复用。
  • 把变动最频繁的文件内容放在前缀里,使缓存写入的复用价值趋近于零。
  • 只关注单次请求的账单,却从不对比缓存命中前后的输入费用变化。
  • 为了一次性省事把所有工具定义都塞进前缀,结果写入成本长期高于读取收益。

可操作的做法是把最稳定的部分放最前面:系统提示、工具定义、代码规范、目录约定;把变动最频繁的部分放最后:当前改动、报错信息、临时问题。这样一次写入可以被后面很多次读取摊平。顺带一提,你邀请来的人实际付费之后,你会拿到一份分成,这笔收入同样来自真实用量,而不是某个拉新活动的固定奖金。

小任务上了旗舰档,大任务反而被缩水

在终端里配置默认模型时,很多人习惯直接填一个旗舰档,觉得“反正不会错”。于是把 JSON 格式化、变量重命名、注释翻译这类一行级任务,也交给了最贵的档位;而真正需要长推理的性能分析和架构权衡,又因为输出上限被截断,被迫缩减范围。

  • 用旗舰档执行格式化、转写和简单改写,单价与任务价值完全不成比例。
  • 在长推理任务上把最大输出限制得过低,导致结果被截断后需要第二次补全调用。
  • 为了省事全程只用一个模型,无法针对补全、评审、生成各自匹配更合适的档位。
  • 没有先用便宜模型跑通提示和上下文,就把大量预算花在反复调试旗舰档上。
  • 换模型时连同 prompt 模板一起重写,白白浪费了本来可以直接复用的调用结构。

经验是先用便宜档位把提示、上下文和工具定义调通,确认输出稳定后再上更贵的档位处理真正难的部分。Fluxo 在 Claude Code、Codex、Gemini CLI 以及任何 OpenAI SDK 里都能直接使用,切换模型只需要改一个字符串,所以把调用做成可替换的配置项,几乎不需要额外成本。

重试、截断和日志里的隐性调用

最后一类成本很少被写进预算表:失败调用。限流后的自动重试、超时后的并发补发、输出被截断后的追加请求,这些调用照样产生 token 费用,却不会出现在“我今天发了几次请求”的直觉里。开发机上的调试脚本如果没设退避,一个断网的午休就可能把同一个请求重放上百次。

  • 自动重试没有设置次数上限和指数退避,一次瞬时故障被放大成上百次重复调用。
  • 输出达到上限被截断后,又用一次完整调用去补全剩余部分,上下文被计费了两遍。
  • 并发脚本失败后整批重新提交,成功过的请求也被一并重新发送并计费。
  • 本地日志把完整提示和响应都打印出来,既拖慢终端又让排障时的上下文越来越臃肿。
  • 调试脚本硬编码了昂贵档位,长期在后台跑,形成一条没人注意到的持续账单。

在脚本里加上最大重试次数、指数退避、请求级超时和失败时保留请求标识,就能把这类浪费压到很低;排查时只保留必要的片段,不要把完整响应原样追加到下一轮上下文。想把这些实验直接跑起来的话,欢迎创建一个 Fluxo 账号,同一把密钥就能接进你的编辑器和终端。如果在缓存配置或账单口径上有拿不准的地方,登录后在联系页留一条备注即可,不需要另外找邮箱。

缓冲区里的下一篇