
后台更换供货线路,客户看到的价签保持不变。
Flashduty AI SRE 是一个专注 SRE 领域、帮助团队做故障根因分析和日常运维的 AI Agent 产品。这是《Flashduty AI SRE 技术揭秘》第 18 篇,分享我们在 Agent 工程中的设计、踩坑和取舍。
一个 Agent 会话进行到一半,正在使用的 LLM 供应商出故障了。为了让任务继续,平台把请求切到备用供应商。备用线路的成本可能更高,那么,这部分差价应该出现在客户账单上吗?
我们的选择是:客户按所选模型档位付费,故障切换不改变单价;备用线路带来的成本差额由平台承担。 这个承诺听起来只是一条定价规则,落到系统里却涉及故障切换配置、异步计费和金额精度。
为什么价格绑定档位
如果按实际服务的供应商直接查价,同一个会话的前半段可能按 A 的费率收费,后半段因故障切到 B,又按 B 的费率收费。客户并没有选择切换,也无法控制供应商故障,却要承担价格变化。
因此我们引入计费档位(billing tier)。客户使用某个档位,档位有自己的费率;主供应商和允许切换到的备用供应商都归属于这个档位。无论本次调用临时切到哪一级,还是故障后会话改绑到新的服务方,实际服务者可以变化,计费档位和单价保持不变。
这里说的“账单不变”指相同用量适用的单价不因切换而变化;总费用仍取决于实际产生的用量。平台则需要承担备用线路可能更贵的成本。
启动时先检查,切换链是否真的在同一档
要让这条规则成立,不能只在文档中约定“备用供应商应当同价”。假如一条故障切换链的主线路属于档位 A,备用线路却属于档位 B,切换之后再按实际服务方查档位,价格就会变。
所以服务加载配置时会做检查,任何一项不满足就拒绝启动:
- 每个可能被绑定的模型 key 都必须属于一个计费档位,且只能属于一个档位。
- 每条 failover 链上的所有 key,必须与链头属于同一档位;缺少归属或跨档都报错。
- 费率必须为正,配置中也不能包含指向不存在供应商的条目。
费率检查有过实际教训。费率文件没有 schema 保护,如果把 outputPerMillion 拼错,错误字段可能被忽略,而正确字段保留零值。结果是输出 token 按零计价:账本里写入的零是合法数值,异步计费任务也可能正常完成。启动时检查费率大于零,才能在错误进入账本之前拦住它。我们也曾人工发现三个无效供应商条目:一个已经退役,一个从未存在,还有一个只出现在注释里。
免费账号由准入侧的免费模式控制,不靠零费率表达。因此在费率表里,零是配置错误。同样,找不到档位时系统返回明确错误,不拿其他档位的费率兜底。对账单来说,一个显式失败比一笔看似成功、实际价格错误的记录更容易处理。
账本记录实际服务方,计价时再找到档位
故障切换之后,系统仍需要知道究竟是哪条线路提供了服务。因此用量记录保存实际服务方的模型 key。但最终定价不是直接用这个 key 查价格,而是先用 key 找到所属档位,再使用档位费率。

实际服务方可以变化;同一条切换链上的 key 都解析到同一个计费档位。
这一步对异步计费尤其重要。计费任务在请求结束后读取已落库的用量记录,不能依赖当时请求内存里的上下文。记录中的实际服务方 key,加上经过启动校验的档位映射,足以让任务找到应使用的费率。既保留了实际服务方的信息,也保证同一条切换链上的各级使用同一档价格。
生成账本时,记录还会带上计费档位和当时的费率版本。日后调整费率只影响未来的计费,不追溯修改历史账目。
为什么金额用整数计算
价格选对之后,还要保证大量用量记录累计出来的金额可靠。我们使用 int64 定点数保存金额:1 credit 等于 10⁹ nano-credits。可以把 nano-credit 理解成内部记账使用的更小单位,类似用整数分而不是浮点元来记账,只是这里的换算比例更大。
费率配置允许人写入小数,例如每百万 token 0.15 credit。系统先将这个配置值一次性换算为定点数,后续每次计价都使用整数,避免浮点误差随着大量调用反复累积。
整数计算也要处理溢出。直接用 token 数乘费率再除以一百万,中间乘积可能先超过整数范围,即使最后的结果本来装得下。实现中先把 token 数按商和余数拆开,再分别计算;这是等价变形,不是先丢掉余数。原稿记录,这种方式把相关溢出阈值推远了一百万倍,测试中也保留了旧写法会溢出的对照用例。
舍入统一使用 round-half-up(半数向上),负数分支也有对应处理,覆盖红冲和调整场景。沙箱计时则按实际时长连续计费:90 分钟按 1.5 小时计算,不向上凑成两个整小时。
credit 和货币的换算单独管理
最后还有一个容易写进各处代码的假设:1 credit 等于多少钱。当前配置恰好是 1:1,但这只是当前商业配置,不应成为金额类型的固定含义。我们把换算收敛到一对函数中,定价或换算关系变化时不需要逐处寻找硬编码。
从供应商 key 找回档位、记录费率版本、用整数计算金额,这些步骤共同支撑了同一个承诺:平台为保持服务而切换线路时,相同用量仍按客户选定档位的单价计费。我们也为故障切换链写了测试,检查链上任意一级的计价与链头一致。
下一篇进入评测话题,介绍如何用一份失败模式分类同时服务线上审计和离线评测。