Token 配额高峰时段:AI Agent 夜间 cron 的 RateLimit 实战
本文最后更新于 2026年8月14日 凌晨
凌晨 3:45,是我这套 AI Agent 系统的发刊时间。5 个 profile、12 个 cron 任务一起撞墙,new-api 直接 429。这篇文章记录从撞墙到稳定运行的全过程。
现象:半夜的 429 风暴
问题暴露得很快。某夜 3:55,韩梅梅的 blog-helper cron 报 HTTP 429: RateLimit,同一时段李雷的 ReShare 同步、AutoQuant 的回测 cron、日记 cron、Git 心跳 cron 全部失败。凌晨日志里一片 [429] Too Many Requests。
排查时看到的现象:
1 | |
5 个 cron 在 3 分钟内全部启动。new-api 代理层背后是 deepseek-ai/DeepSeek-V4-Flash 和 HauhauCS/Qwen3.6-35B-A3B-Uncensored 两条 channel。并发请求一多,上游 openai-compatible 接口直接限流。
根因:cron 时间集中 + 每个 cron 内又开多 Agent 并发
两个层级的并发叠加:
- cron 层:多个 profile 的 cron 默认在 03:45 触发,彼此只有分钟级偏差,实际效果等于并发启动。
- Agent 层:blog-helper 一个 draft 里会并发调 3 个 LLM(MoA 梯队),ReShare 同步单次请求会带多轮上下文,Heartbeat 心跳每次也要 LLM 判定。
两层相乘:30 分钟内 60+ 次 LLM 调用挤在同一条代理 channel 上。
修复一:错开 cron 触发时间
先解决最直接的叠加——把 cron 触发时间打散。原则是每个 profile 错开 5 分钟以上。
Hermes 的 cron 定义在 profile 的 cron.yaml 里。示例:
1 | |
把 5 个 profile 的 cron 打散到 03:50 – 05:00 这一小时窗口内,峰值并发从 5 降到 1。
修复二:草稿 MoA 改为串行,单模型 Fallback
blog-helper 的 draft.py 默认会并发调用 3 个模型(MoA 梯队)。在夜间窗口窄的情况下,并发 MoA 等于把 1 个 cron 变成 3 个 LLM 请求。
在 config.yaml 里加 writing_mode: creative 之外,把 MoA 强制降级为串行单模型,让单次 draft 只占一条 channel:
1 | |
实际执行时用 --single 参数直接跳过 MoA,减少 2/3 并发。
修复三:LLM 端显式限速(client-side backoff)
单模型调用的代码里,遇到 429 后不立即重试,而是指数退避:
1 | |
关键点:退避时间要足够长。new-api 的上游一般是 RPM(每分钟请求数)限制,2^attempt * 30s 意味着 30s / 90s / 270s / 810s,4 次重试覆盖 15 分钟,足够越过限流窗口。
修复四:关键 cron 设优先级,允许低优先级失败
不是所有 cron 都要跑完。把 12 个 cron 分三级:
- P0 关键:blog 发布、Git 心跳、AutoQuant 策略计算
- P1 重要:diary、ReShare 同步、心跳
- P2 可延迟:review、proofread 复读、封面图生成
P2 在遇到 429 时直接退出让路,让 P0 优先吃 token。用 cron 的 on_failure: skip_next 控制退避窗口。
效果
实施完四步之后,凌晨观察日志:
1 | |
429 完全消失,5 个 profile 错峰跑完,最长 cron(blog draft)从 9 分钟缩短到 4 分钟(因为不再 MoA 并发)。
教训
- cron 时间是共享资源。多 profile 系统里,触发时间就是隐式同步点,必须显式错开。
- MoA 不是免费的并发。每个 Agent 的每一个阶段,都要算清楚 LLM 请求数再决定并发。
- 退避要用指数级。线性退避在 RPM 限流下几乎无解——30s/90s/270s 才有希望错开限流窗口。
- 低优先级要会主动让路。P2 任务失败不算失败,P2 撑住才导致 P0 饿死。
参考文献
- Hermes Agent 文档 — cron 配置与任务管理
- HTTP 429 Too Many Requests (MDN)
- new-api 官方文档 — 模型代理与 RateLimit 处理
- 本机事实库
~/.hermes/.blog-helper/facts.md— ModelBase 服务器与 LLM channel 配置