🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度
1. 429 不是一类错误:先给 OpenHands 限流分层
OpenHands 跑任务时冒出 429。TaoToken(https://taotoken.net/?utm_source=taotoken_aicg_blog_generate&utm_content=)是这次验证的统一 API 基线:先用同一把 Key 对 https://taotoken.net/api 发一条最小请求,再回 OpenHands 复现,判断限流来自上游模型还是应用层。这个顺序很关键,因为 OpenHands 只是调用方,日志里的 429 可能来自模型服务端,也可能来自兼容通道的账户并发限制,还可能是 OpenHands 内部重试、任务队列或多会话同时打上去造成的。把 429 当成一个症状,先分层,再修参数,才不会被日志里的 Rate limit 四个字牵着走。
429 和 401、404 不一样。401 基本是 Key 写错或没带 Authorization,404 多半是 Base URL 路径、模型 ID 或接口格式不对,而 429 表示请求本身能被服务端理解,但当前时间窗口内不允许继续以这个速率调用。麻烦在于,上游模型服务、统一 API 网关、OpenHands 内部的 LiteLLM 重试层,都可能把最终错误包装成 429。你只盯 OpenHands 的报错,很容易把“模型端限流”误判成“OpenHands 有 bug”,或者反过来,把 OpenHands 同时跑了三个任务导致的自我限流,当成模型端不稳定。
更稳妥的排查策略是固定变量。固定同一把 Key、同一个模型 ID、同一个 Base URL、同一个 Prompt,只改变调用位置:先用 curl 直连 https://taotoken.net/api,再在 OpenHands 里复现。直连 curl 是最小请求,它不带 Agent 循环、不带工具调用、不带超长上下文,也不带多任务并发。如果最小请求都 429,说明问题至少已经落到统一 API 通道或上游模型这一层;如果最小请求 200,而 OpenHands 里同一模型同一 Key 却 429,那就要优先看 OpenHands 的并发、重试和任务编排。
1.1 上游、通道、应用三层各自会怎么给出 429
上游模型层通常按 RPM、TPM、账户并发或模型维度做限流。表现是:单条短请求可能通过,但连续快速请求、长上下文请求、多个 Agent 同时请求同一个模型时开始 429。这类 429 往往会在响应体里出现 rate limit、too many requests、retry after 之类的字段,也可能在响应头里给 Retry-After。它的特点是和模型 ID 强相关,换一个模型可能立刻恢复,或者降低请求频率后恢复。
统一 API 通道层会把上游的限流信号转出来,也可能有自己的账户级配额或并发保护。你用的是同一把 Key,请求走 https://taotoken.net/api,那么 Key 对应账户的调用量、并发数、模型可用性都会影响结果。这里要特别注意:通道层返回 429 不一定等于“封号”,更多时候是速率窗口被打满。排查时不要靠猜,先看直连 curl 的 HTTP 状态码和响应体,再去控制台看用量和时间分布,才能知道是短时突发还是持续超限。
应用层则是 OpenHands 自己的问题。OpenHands 不是单次问答,它会规划、调用工具、读文件、执行命令、把结果塞回上下文,再继续请求模型。一个任务里可能连续发很多次 LLM 请求。如果同时开了多个 OpenHands 任务,或者 LiteLLM 在 429 后自动重试,瞬时并发会放大。日志里常见的 Retrying request、RateLimitError、429 Too Many Requests,可能并不是第一发请求就 429,而是重试风暴把窗口打爆了。
1.2 最小请求为什么必须先做
最小请求的价值是把“模型能不能用”和“OpenHands 能不能跑”拆开。你可以在终端里发一条只有 ping 的请求,max_tokens 设得很小,不挂工具、不塞上下文。返回 200,说明 Key、Base URL、模型 ID、接口路径至少这条链路是通的;返回 401,先修 Key;返回 404,先修路径或模型 ID;返回 429,才进入限流判断。这个结论比在 OpenHands 里反复重跑任务可靠得多,因为 OpenHands 的一次失败可能混合了工具报错、上下文过长、沙箱超时和模型限流。
还有一个容易忽略的点:429 不一定在第一次请求就出现。上游可能允许你短时间发几条,超过窗口后才拒绝;OpenHands 也可能先成功几步,到第十几次 LLM 调用才 429。所以直连测试不能只发一次就结束,最好补一个很小的串行测试,比如间隔一秒发五次,观察第几次开始 429。这个数字不需要很大,目的不是压测,而是看限流窗口的形状。本文不含排行分数,也不把任何一次运行当成公榜快照,只讨论 429 的定位路径。
2. 用 TaoToken 的 Key 做最小 curl:状态码先说话
如果你还没有 Key,先在 TaoToken 创建,模型 ID 以模型广场展示为准,不要凭记忆写一个看起来像的模型名。拿到 Key 后,不要急着填进 OpenHands,先在终端做一条最小请求。Base URL 用 https://taotoken.net/api,末尾不要带 /v1,也不要把任何 UTM 参数拼到 API 地址上;UTM 只用于官网落地页和文末 CTA,不用于接口调用。
下面这条 curl 走 OpenAI 兼容的 chat completions 路径。如果你的 OpenHands 配置选的是 Anthropic 兼容 provider,请求体和路径会不同,但 Base URL 仍然是 https://taotoken.net/api,Key 仍然是同一把 YOUR_API_KEY,模型 ID 仍然以模型广场为准。
export BASE_URL="https://taotoken.net/api"
export API_KEY="YOUR_API_KEY"
export MODEL_ID="YOUR_MODEL_ID"
curl -sS -i \
-X POST "$BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"ping\"}],\"max_tokens\":16}"
-i 一定要加,它会把响应头一起打出来。429 时你要看的不只是状态码,还要看有没有 Retry-After,响应体里有没有 rate limit 或 quota 字段。很多人只复制了报错最后一行,结果把 401 当成 429,把 404 当成限流。把完整响应留下来,后面和 OpenHands 日志对照时才有依据。
| 状态码 | 常见响应特征 | 说明 | 下一步 |
|---|---|---|---|
| 200 | 返回 choices 或等价内容 | Key、Base URL、模型 ID、路径至少这条链路通 | 进 OpenHands 复现,比较是否 429 |
| 401 | invalid api key、unauthorized | Key 缺失、写错、带了多余空格或 Bearer 格式不对 | 重新创建或复制 YOUR_API_KEY,确认请求头 |
| 404 | model not found、not found | 模型 ID 不在当前通道,或路径拼错 | 回模型广场核对 ID,检查 Base URL 是否被加了 /v1 |
| 429 | rate limit、too many requests、retry after | 当前窗口请求过多,或账户并发到顶 | 先看 Retry-After,降低频率,再复现对照 |
| 400 | context length、invalid request | 请求体格式或上下文长度问题,不是限流 | 缩小 max_tokens,检查 messages 结构 |
| 500/502/503 | upstream error、bad gateway | 上游或通道临时异常,不是典型限流 | 隔一段时间重试,保留响应和时间点 |
看到 200 后,再补一个很小的串行测试,确认限流窗口。下面这段只发五次,每次隔一秒,适合本地观察第几次开始 429。不要拿它做压测,也不要同时开十个终端一起打。
for i in 1 2 3 4 5; do
echo "--- request $i ---"
curl -sS -o /dev/null -w "%{http_code}\n" \
-X POST "$BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"ping $i\"}],\"max_tokens\":16}"
sleep 1
done
如果单次 200、五次串行也 200,但 OpenHands 一跑就 429,基本可以把注意力转到应用层。如果单次 200、五次里第 3 次开始 429,说明窗口比较紧,OpenHands 的连续调用很容易触发。如果单次就 429,先不要改 OpenHands,检查这个 Key 是否在别处被大量调用,或者当前模型是否处于高负载。这个判断顺序能避开大部分无效折腾。
3. 把同一把 Key 接进 OpenHands:配置、复现、看日志
OpenHands 的配置入口通常在 Settings 里的 LLM 部分。Provider 选 OpenAI 兼容或 Custom,Base URL 填 https://taotoken.net/api,API Key 填 YOUR_API_KEY,Model 填模型 ID。模型 ID 以 TaoToken 模型广场为准。有些 OpenHands 版本要求模型字符串带 provider 前缀,比如 openai/YOUR_MODEL_ID 或 anthropic/YOUR_MODEL_ID,具体以你安装版本的界面提示为准,但主体 ID 不要自己编。
如果你用环境变量启动 OpenHands,可以先用下面三行做最小配置。改完后重启 OpenHands,让配置生效。注意 LLM_BASE_URL 只写 https://taotoken.net/api,不要带 UTM,也不要写成官网落地页。
export LLM_BASE_URL="https://taotoken.net/api"
export LLM_API_KEY="YOUR_API_KEY"
export LLM_MODEL="YOUR_MODEL_ID"
复现时不要一上来就跑大型任务。先关掉其他 OpenHands 会话,只留一个任务,Prompt 用和 curl 接近的短指令,让 Agent 做一步简单操作,比如读取一个测试文件并总结。然后观察日志里第一次 429 出现的位置:是在第一次 LLM 请求,还是在工具调用之后,还是在多次重试之后。这个位置比错误全文更有信息量。
| OpenHands 日志里可能出现 | 直连 curl 同 Key 同 Model | 更可能的层 | 处理 |
|---|---|---|---|
litellm.exceptions.RateLimitError 附带 429 | 也是 429 | 上游模型或通道账户限流 | 看 Retry-After,降低频率,换模型或等窗口恢复 |
429 Too Many Requests 但只出现一次 | 200 | OpenHands 请求瞬时并发或重试参数偏激 | 单任务运行,降低重试次数,增加退避等待 |
Retrying request 连续出现 | 200 或偶发 429 | 应用层重试风暴 | 降低并发,别让多个任务同时重试 |
| 401 unauthorized 被包装成 LLM 调用失败 | 401 | Key 或 Authorization 配置错 | 重新填 YOUR_API_KEY,检查 Bearer 和空格 |
| model not found、404 | 404 | 模型 ID 或路径错 | 回模型广场核对 ID,Base URL 不要加 /v1 |
| context length exceeded | 400 | 上下文或工具输出过长 | 缩小任务范围,减少一次性读入文件 |
还有一种情况是 OpenHands 配置里同时存在旧的环境变量和界面配置,最后实际生效的不是你以为的那一个。表现是 curl 用新 Key 200,OpenHands 却一直 401 或 429。排查时先看 OpenHands 启动日志里打印的 LLM 配置,确认 Base URL 是 https://taotoken.net/api,确认模型 ID 和 Key 来源。不要只看设置页面,设置页面显示的不一定等于进程实际读取的。
OpenHands 可以执行命令、读写文件,但它不该直连你的生产库或生产机。需要 SQL 或运维命令时,让模型生成命令,你在本地或隔离环境执行,再把结果贴回对话。这样即使 429 排查过程中需要看数据库状态,也不会把 Agent 的工具调用直接落到生产环境。这个边界和限流无关,但值得在配置 OpenHands 时一起定好。
4. 串行、并发、换模型:把 429 复现成可判断的矩阵
单次 curl 只能回答“现在能不能通”,不能回答“为什么 OpenHands 里会 429”。你需要一个小矩阵,把串行、并发、OpenHands 单任务、OpenHands 多任务、换模型这几组结果放在一起。每项只做最小次数,不追求压测,目的是看 429 出现在哪一层。下面这张表可以作为记录模板,跑完把结果填进去。
| 测试 | 操作 | 直连结果 | OpenHands 结果 | 结论方向 |
|---|---|---|---|---|
| 单次最小请求 | 一条 ping,max_tokens 16 | 200 或 429 | 不涉及 | 判断 Key、模型、路径是否可用 |
| 五次串行 | 间隔 1 秒,同一模型 | 第几次 429 | 不涉及 | 判断模型窗口是否很紧 |
| 两次并发 | 两个 curl 同时发,然后停止 | 是否 429 | 不涉及 | 判断上游或通道并发限制 |
| OpenHands 单任务 | 只开一个会话,短任务 | 之前已知 | 首次请求是否 429 | 判断应用层是否额外放大 |
| OpenHands 双任务 | 同时开两个短任务 | 之前已知 | 是否比单任务更早 429 | 判断多会话并发 |
| 换模型 ID | 同一 Key,换广场另一个可用模型 | 是否恢复 | 换模型后再跑单任务 | 判断是否模型维度限流 |
如果两次并发 curl 就 429,而单次和串行都 200,说明并发窗口很窄。OpenHands 一个任务内部可能连续发请求,但通常不是严格同时发;真正危险的是你开了多个任务,或者 Agent 在多个工具调用后并发请求模型。如果 OpenHands 双任务 429,单任务不 429,优先限制同时运行的会话数,而不是急着换 Key。Key 换来换去并不能解决应用层自己制造的并发。
如果只有某个模型 429,换到模型广场里另一个可用模型后恢复,说明限流和模型维度有关。这时候不要写死一个模型 ID,可以在 OpenHands 配置里准备一个备份模型。但备份模型也要以模型广场为准,不要凭记忆填一个名字。换模型后仍然要跑一遍单次 curl,确认新模型在你的 Key 和 Base URL 下能返回 200,再让 OpenHands 使用。
记录时间点很重要。429 往往和窗口有关,可能是分钟级,也可能是短时突发。你可以在测试表里加一列“发生时间”和“Retry-After”,后面回看时能判断是固定窗口还是随机高负载。不要只写“报错了”,要写清楚第几次请求、距离上一次多久、当时是否还有别的任务。这个记录习惯能让下一次 429 排查快很多。
5. 修复顺序:先降并发,再调重试,最后换模型或通道
确认是上游或通道限流后,第一步不是改代码,而是降低请求频率。把 OpenHands 的其他任务停掉,单任务运行,观察是否恢复。如果响应头里有 Retry-After,就按它给的时间等,不要立刻重试。很多 429 会被自动重试放大:LiteLLM 看到 429 后马上再发,OpenHands 又在同一时间继续跑,窗口一直打满。先把并发降下来,再谈参数。
第二步检查 OpenHands 的重试和迭代配置。Agent 任务天然会比聊天多很多次 LLM 调用,如果重试次数设置得很激进,短时间内的请求量很容易超过窗口。可以适当增加重试间隔,减少同时运行的任务数,缩短单次任务的上下文。不要把所有问题都推给模型端,先看 OpenHands 日志里 429 前后的请求密度。如果每隔几秒就出现 Retrying request,说明应用层在持续打。
第三步才是换模型或换调用通道。模型广场与用量在 TaoToken 看,以广场展示的可用模型为准。换模型时仍然保持同一把 Key、同一个 Base URL,这样能判断是模型维度限流还是账户整体限流。如果换模型恢复,保留两个模型 ID 做故障切换;如果换模型也 429,检查账户级用量和并发,而不是继续换名字。
最后再考虑通道选择。临时拼凑的调用通道经常在限流时缺少明确响应头,出了问题只能靠猜,也不方便对账和开票。正规做法是走统一 API 兼容通道,把 Key、Base URL、模型 ID、用量记录固定下来。TaoToken 在这里的角色是提供统一入口和对照基线,不是被评测对象。你用它验证 429 来自哪一层,再把结论带回 OpenHands 的配置里。
如果直连 curl 返回 401 或 404,不要进入限流排查。401 先重新创建 Key,确认请求头是 Authorization: Bearer YOUR_API_KEY;404 先核对模型 ID 和 Base URL 路径,确认没有把落地页地址填进 OpenHands。把非 429 错误先清掉,剩下的 429 才有分析价值。这个顺序能避免在错误配置上浪费大量时间。
6. 把这次 429 排查留成可复现记录
一次 429 排查结束后,至少留下这几项:直连 curl 的 HTTP 状态码和响应头,OpenHands 日志里第一次 429 的位置,使用的模型 ID,是否开了多任务,Retry-After 的值,以及当时的时间点。下次再遇到 429,你可以先比较这些字段,而不是从头试配置。如果直连 200、OpenHands 429,重点看应用层;如果直连也 429,重点看模型窗口和账户并发。
排查完,打开 模型对话 确认这次调用是否入账,顺便核对模型 ID 与模型广场是否一致。长期开发可以看 Coding Plan,把 OpenHands 常用的模型固定下来。Key 在 创建 Key 创建,然后重新跑一遍本文的 curl 和 OpenHands 单任务对照表,确认 429 是窗口问题、并发问题,还是模型选择问题。
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度




被折叠的 条评论
为什么被折叠?



