九月十六日,AWS 在 builder 体验公告里上线了项目级月度支出上限。
公告标题是「New AWS experience helps builders get started and ship faster」。
用量触顶之后,项目当月直接暂停,没有宽限期,也没有邮件商量。
十月三日,Simon Willison 用一篇文章把这件事抬到了行业议程上。
他的判断很直接:所有按量计费的服务都需要默认硬预算帽。
这篇文章在 Hacker News 拿到 463 个赞与 228 条评论(抓取时点)。
评论区罕见地没有撕裂,最高赞几乎是一边倒的「早该如此」。
七月,Google Cloud 在成本管理官方博客官宣 Spend Caps 上线。
三个月内两家头部云厂商同向落子,信号已经足够清晰。
按量付费的默认形态,正在从「先用后算」转向「超支即断」。
这篇拆解回答三个问题:为什么是现在、硬帽怎么落地、Agent 扮演什么角色。
三个月,两家云厂商把「断供」做成了产品
先看 AWS 这次到底发布了什么。
新的 builder 体验允许为每个项目设置月度支出上限。
达到上限后,项目资源在当月剩余时间里被整体暂停。
官方文档把入口放在账户设置的 Spend Limit 页面。
页面同时警告:新体验目前只对部分客户灰度开放。
也就是说,存量全量账户暂时还用不上这个保护。
但方向已经写进公开公告,回头的可能性不大。
AWS 的措辞很值得玩味:让 builder 更快上手、更快交付。
预算保护被包装成新手体验的一部分,而不是成本中心的补丁。
这恰恰呼应了 Willison 的核心主张:保护应该是默认配置。
谷歌云这条 Spend Caps 来自其成本管理博客的正式公告。
它允许对项目内的指定服务设置月度财务上限。
触顶后对应服务停止计费,项目内其余服务不受影响。
粒度比 AWS 的项目级更细,工程姿态却是同一个。
两家都把「停」做成了一个可配置的、确定性的动作。
再往前翻,模型 API 厂商早有类似的额度能力。
OpenAI 与 Anthropic 的后台都支持给账户设月度硬上限。
差异在于它们是深藏的可选项,而云厂商正在把它变成默认。
默认值迁移,才是这轮变化里真正的分水岭。
历史上云账单事故的重灾区,恰恰是从未点开过预算页的人。
为什么硬预算帽在 2026 年集中爆发
第一层推力,是编码智能体把起项目的摩擦降到了接近零。
一个下午跑起来的服务,背后可能挂着十几个计费 API。
第二层推力,是个人智能体把部署能力交给了非工程师。
他们中的大多数,不知道账单可以在一夜之间失控。
第三层推力,是 LLM 调用的非确定性让用量无法靠直觉预估。
一段失控的重试逻辑,可以在凌晨跑掉数千美元的 token。
账单事故的当事人往往没有任何操作失误,只是少了保护。
过去的默认假设是使用者会主动配置告警,这个假设已经破产。
HN 评论区里最高频的词是「惊喜账单」,几乎人人有故事。
有人贴出过一张一万两千美元的月度账单截图。
也有人因为恐惧,干脆拒绝用 AWS 做任何个人项目。
恐惧本身是平台的损失,这笔账云厂商终于算清了。
对平台来说,硬预算帽不是慈善,是获客漏斗的补漏。
对个人来说,它是敢不敢把侧项目放上云的前提条件。
供需两端在「默认保护」上找到了罕见的利益一致。
这是它能被两家竞品在三个月内先后产品化的深层原因。
而压倒性的最后一根稻草,是 Agent 开始自主调用付费工具。
机器替人花钱的速度,第一次超过了人看账单的速度。
硬帽与软告警之间,隔着一整套默认值政治
接下来是全文最关键的区分:硬帽与软告警。
软告警的逻辑是「到线发邮件」,责任仍然压在使用者身上。
午夜送达的告警邮件等同于没有告警,人睡着时系统不会睡。
更糟的是告警疲劳,预算邮件很快会被归入静音文件夹。
硬帽的逻辑是「到线断供」,让错误成为系统的正常输出。
反对意见很标准:业务不能因为预算耗尽而开始抛错。
Willison 的反驳同样标准:错误好过一万美元的惊喜账单。
这不是技术之争,而是风险偏好的默认值之争。
默认断供把「冒险」变成一次显式的、可读的选择。
他建议的交互是一个醒目复选框:移除预算帽,后果自负。
勾选动作本身就是一次责任确认,是签字画押的电子化。
默认值的政治学在于,大多数人永远不会改动默认。
所以默认安全等于全民安全,默认裸奔等于全民裸奔。
浏览器默认拦截弹窗之后,弹窗广告这个物种几乎灭绝。
HTTPS 默认警告之后,明文 HTTP 站点在十年内萎缩殆尽。
预算帽正在走同一条路:从可选功能变成心智底线。
对厂商而言,默认断供还有一个隐蔽的收益。
它把账单纠纷从客服工单,前移到了产品设计层面。
争议少了,退款少了,信任账户的余额反而涨了。
当然,默认硬帽不等于唯一配置。
企业可以为生产项目显式放宽,同时给实验项目收紧。
默认值决定的是起跑线,而不是终点线。
工程拆解:不超卖的预算网关怎么写
价值观讲完,进入工程师最关心的部分:硬帽怎么落地。
难点从来不在「存一个数字」,而在并发下的不超卖。
想象八个 Agent 协程同时派发调用,各自检查余额都够。
如果检查与扣费不是原子的,八个请求会同时穿过闸门。
这就是经典的 check-then-act 竞态,账单超卖的根因。
解法是把预算闸门做成两段式:先预留,后结算。
派发前按 max_tokens 预估一笔上限,原子地从余额里冻结。
调用结束后按真实用量结算,扣减被钳制在预留之内。
上游再把 max_tokens 裁剪到预留额度,实际用量不可能爆表。
不变式只有一条:已用加冻结,永远小于等于月度上限。

下面是一个可以直接运行的最小预算网关,仅依赖标准库。
python
import threading
class BudgetExceeded(Exception):
"""预算耗尽,调用方应停止派发并向用户返回 429。"""
class BudgetGate:
"""月度硬预算帽:预估预留 + 真实结算,两段式扣费保证并发不超卖。"""
def __init__(self, limit_cents):
self.limit = limit_cents
self.used = 0
self.reserved = 0
self.lock = threading.Lock()
def available(self):
return self.limit - self.used - self.reserved
def reserve(self, estimate_cents):
with self.lock:
if estimate_cents > self.available():
raise BudgetExceeded(
f"剩余 {self.available()} 分,不足预估 {estimate_cents} 分")
self.reserved += estimate_cents
return self.available()
def settle(self, estimate_cents, actual_cents):
with self.lock:
self.reserved -= estimate_cents
# 上游 max_tokens 已按预留裁剪,真实用量不会超过预留
charge = min(actual_cents, estimate_cents)
self.used += charge
return charge
def call_llm(prompt, gate, max_tokens):
estimate = max_tokens # 演示口径:1 token 计 1 分
gate.reserve(estimate)
try:
actual = (len(prompt) * 7) % max_tokens + 1 # 模拟真实用量
return gate.settle(estimate, actual)
except Exception:
gate.settle(estimate, 0) # 失败必须释放预留
raise
if __name__ == "__main__":
gate = BudgetGate(limit_cents=1000)
blocked = []
def worker(n):
for i in range(30):
try:
call_llm(f"任务{n}-{i}", gate, max_tokens=20)
except BudgetExceeded:
blocked.append(n)
return
threads = [threading.Thread(target=worker, args=(n,)) for n in range(8)]
for t in threads:
t.start()
for t in threads:
t.join()
print(f"已用 {gate.used}/{gate.limit} 分,熔断劝退 {len(blocked)} 个 Worker")
assert gate.used <= gate.limit, "超卖!"
这段代码的骨架,就是生产系统预算网关的全部核心逻辑。
reserve 在锁内完成检查与冻结,竞态在入口就被消灭。
settle 按真实用量扣减,扣减额被钳制在预留额度之内。
不变式因此恒成立,末尾的 assert 在压测下永远不会触发。
演示里八个线程共抢一千分预算,最终多数被熔断劝退。
BudgetExceeded 在真实系统里映射为 HTTP 429。
响应头应带上剩余额度与重试时点,让调用方体面降级。
生产化时把内存账本换成 Redis,用 Lua 脚本保持原子性。
单进程锁与分布式 Lua 语义相同,只是作用域不同。
还有一类隐蔽超卖来自流式响应,token 边产出边计费。
对策是在流开始前按上限预留,流中断则按已产出结算。
异常路径必须释放预留,否则预算会被僵尸占用慢慢拖死。
这就是代码里 try 与 settle 零结算配合的原因。
审计侧建议给每次扣减落一条不可变日志。
月底对账时,日志流就是争议仲裁的唯一事实源。
两条产品路线并排看:粗粒度与细粒度的取舍
把两家云厂商的方案并排看,设计取舍一目了然。
| 维度 | AWS Spend Limit | Google Cloud Spend Caps |
|---|---|---|
| 上线时间 | 2026 年 9 月 16 日 | 2026 年 7 月 |
| 控制粒度 | 项目级月度上限 | 项目内指定服务月度上限 |
| 触顶行为 | 项目当月整体暂停 | 超限服务停止计费 |
| 当前状态 | 部分客户灰度中 | 已正式发布 |
AWS 选择了最粗的粒度,换取最简单的心智模型。
谷歌选择了服务级粒度,换取不停整站的灵活性。
对新手而言,AWS 的「整项目暂停」反而更安全。
对有存量业务的企业,谷歌的细粒度更容易被采纳。
两条路线大概率会在未来一年内向中间收敛。
项目级硬帽做底线,服务级细帽做精调,是可预期的终局。
值得注意的还有灰度策略,AWS 没有一步到位。
预算系统自身出错的代价极高,谨慎是对的。
一次错误熔断对信任的伤害,可能超过一次超支。
所以可观测性与人工旁路,是硬帽系统的标配。
仪表盘至少要回答三个问题:用了多少、冻结多少、剩多少。
当 Agent 自己成为预算的守门人
Willison 文章里最容易被忽略的,是最后一段。
他期待 Agent 主动向用户推荐带硬上限的厂商。
并对无上限的服务,向新手用户发出明确警告。
这等于把预算治理从平台能力,上移到了 Agent 行为层。
今天的编码智能体,已经在事实上替用户挑选服务。
它写哪家的 SDK,用户就去开通哪家的账户。
在推荐权重里加入「是否有硬预算帽」,只是举手之劳。
更进一步,Agent 可以在部署前自检预算配置。
没有设上限的项目,部署按钮旁应该挂一个黄色警告。
再进一步,Agent 自己的调用链也应该过预算网关。
上一节的代码,插在 Agent 与模型 API 之间即可工作。
工具调用与子智能体委派,都应共享同一个预算池。
否则主循环省下的钱,会被失控的子代理加倍烧掉。
多智能体系统里,预算池是天然的分布式资源。
每个子代理领到的应该是额度,而不是无限信用卡。
委派协议里带上预算字段,会成为明年的标配。
从这个角度看,预算帽是 Agent 经济的清算基础设施。
没有清算层,自主 Agent 的商业化就是空中楼阁。
边界、反例与默认值共同的命运
任何默认值都有反例,硬预算帽也不例外。
医疗监护、安防告警这类场景,断供本身不可接受。
解法是分级:保护级服务走白名单,其余服务默认带帽。
白名单的进入门槛要足够高,防止一切服务都自称特殊。
另一个边界是组织预算,个人帽与企业帽会打架。
项目帽、部门帽、组织帽需要一套层级化的继承语义。
子级不能超过父级,这条约束要写进分配协议。
还有时间维度,月度帽对日内的消耗突刺无能为力。
成熟的系统会叠加小时级与分钟级的速率帽。
预算帽管总量,速率帽管形状,两者缺一不可。
恶意场景同样存在,攻击者可以故意烧穿受害者预算。
熔断把经济损失封了顶,但服务不可用仍然是攻击面。
所以预算事件要接入安全告警,而不只是进账单系统。
异常消耗曲线本身,就是入侵检测的高价值信号。
凌晨三点突然拉满的 token 用量,往往不只是一个 bug。
最后是所有默认值共同的命运:被有经验的人绕过。
老用户会第一时间勾选那个「移除预算帽」。
这不影响默认值的价值,它要保护的从来不是这批人。
它保护的是第一次部署应用的十九岁学生。
是半夜被告警邮件叫醒、翻个身继续睡的小店主。
回看这条时间线,脉络其实非常朴素。
七月谷歌,九月 AWS,十月开发者社区形成共识。
按量付费跑了将近二十年,终于补上了默认刹车。
讽刺的是,逼出这个功能的不是技术突破,而是事故账单。
是无数张过万美元的截图,堆出了这个产品优先级。
Agent 时代只是把同样的风险,放大到了每个人头上。
当机器开始替人花钱,花钱的规则必须先替人设好。
默认硬预算帽,就是这条规则的第一个实体形态。
接下来值得观察的,是灰度转全量的速度。
以及谁会第一个把预算字段写进 Agent 委派协议。
刹车已经造出来了,剩下的是把它装到每一辆车上。