AI Agent限流策略:防止API调用超限和费用失控
Agent 没做限流,10 秒就能把月度额度调完。限流不是限制功能,是保护钱包和下游服务。这篇分并发、速率、预算三层给出具体配置方法和参数推导公式。
💡 你将学到
Agent 没做限流,10 秒就能把月度额度调完。限流不是限制功能,是保护钱包和下游服务。这篇分并发、速率、预算三层给出具体配置方法和参数推导公式。
AI Agent限流策略:并发、速率、预算三层保护的完整配置
一个没有限流的 Agent 能多快烧完额度
限流出问题的场景几乎一样:批量任务跑起来,Agent 开足并发对着 API 猛调,几十秒后开始大面积报 429,再往后是账户被临时封禁,最后账单出来发现超支。整个过程没有一行代码是"错"的,只是没人给出口装阀门。
限流要做三层,缺一层都会漏:并发防的是瞬时压垮,速率防的是持续超配额,预算防的是单次任务失控。三层配合,才既有性能上限也有成本上限。
三层限流一览
| 层 | 控制什么 | 单位 | 触发后的行为 |
|---|---|---|---|
| 并发控制 | 同时在飞的任务数 | 个 | 排队等待 |
| 速率限制 | 单位时间调用次数/token | 次/分、token/分 | 等待或拒绝 |
| 预算熔断 | 累计花费 | 元/天、元/月 | 停止调用并告警 |
第一层:并发控制
最简单也最有效的一层。用信号量把同时在跑的任务数钉死:
import asyncio
sem = asyncio.Semaphore(5) # 最多 5 个任务同时在飞
async def run_one(task):
async with sem:
return await agent.run(task)
async def main(tasks):
return await asyncio.gather(*(run_one(t) for t in tasks))
要点:并发数该按下游 API 的并发上限设,不是按你机器能开多少协程。多数托管 API 对同账号并发有硬限制,设高了就是批量 429。同时给每个任务加独立超时,避免个别任务卡死占着信号量不放。
第二层:速率限制
并发控制不了"每分钟总调用量",因为每个任务可能连续调多次。两种常见算法:
- 令牌桶:桶按固定速率补令牌,取不到就等。允许短时突发,实践中最常用
- 滑动窗口:统计最近 N 秒的调用次数,超了拒绝。更严格,适合配额硬的场景
多进程或多实例部署时,计数器必须放在共享存储里(例如 Redis),否则每个进程各算一份,总量轻松翻几倍。
另一个必做的动作是尊重服务端的退避信号:遇到 429 时读 Retry-After(若有),按指数退避加抖动重试。不带抖动的重试会形成"重试风暴"——所有任务在同一秒一起回来,把刚恢复的配额再次打满。
import random, asyncio
async def call_with_backoff(fn, max_retries=4):
for i in range(max_retries):
try:
return await fn()
except RateLimited as e:
wait = getattr(e, "retry_after", None) or (2 ** i) + random.random()
await asyncio.sleep(wait)
raise RuntimeError("rate limited after retries")
第三层:预算熔断
前两层管频率,管不了"单次任务又贵又长"。预算层做两件事:
- 记账:每次调用记录输入/输出 token 与按价目折算的成本,按天累计
- 熔断:超过日/月上限就停止发起新调用,并告警
关键是记账要覆盖所有出口(流式、工具调用、重试也算),并且要给单个任务设成本上限——一个跑飞的循环能在几分钟里吃掉一天预算,这在 Agent 场景里非常常见。
参数怎么定
不要照抄别人的数字,从你自己的配额反推。三个公式:
| 目标 | 算法 |
|---|---|
| 每分钟调用上限 | 每分钟 token 配额 ÷ 单次调用平均 token |
| 并发上限 | 每分钟调用上限 × 单次平均耗时(秒)÷ 60,再取不超过服务端并发限制 |
| 单任务预算上限 | 日均预算 ×(预期单任务占比),通常取日均预算的 1%-5% |
先按估算值上线,再根据实际的 429 比例微调:429 比例长期高于 1%,说明速率设高了;队列等待时间长期超过几分钟,说明设低了。
常见坑
- 只在前端限制,后台批处理没走同一套限流
- 多实例各算各的计数器,实际总量是配额的 N 倍
- 重试用固定间隔,形成同步重试风暴
- 流式响应不统计 token,账单和记账对不上
- 只限调用次数不限成本,遇到超长上下文照样超支
常见问题
Q:并发和速率,先做哪个? A:先做并发控制。几行代码,能立刻挡住最常见的"批量任务打爆 API"。
Q:供应商 SDK 自带重试,还要自己做限流吗? A:要。SDK 重试解决的是单次请求失败,解决不了整体调用量超过配额。
Q:预算上限设多少合适? A:先设成你日预算的 1.5 倍做熔断线,观察一周的实际分布再收紧。同时给单个任务设上限,防单点失控。
Q:队列排太长会有什么副作用? A:用户端表现为"点了没反应"。要么给任务加优先级(交互式请求插队),要么把排队中的任务状态回传前端显示进度。
相关文章
本站文章由编辑人工撰写,收录的工具均经过实测或公开资料核验。文中链接指向工具官网或 GitHub 仓库,仅作信息参考,不构成付费推广。
