错误码与常见问题
1. 错误响应格式
json
{
"error": {
"code": "node_offline",
"message": "节点 node_be 当前离线,无法投递",
"retriable": false
},
"requestId": "req_..."
}code 是稳定标识,请按它写分支;message 是给人看的,可能调整。 requestId 同时出现在响应头 X-Request-Id,排障时提供它。
2. 错误码
认证与权限
| HTTP | code | 含义 | 处理 |
|---|---|---|---|
| 401 | missing_api_key | 没带 Authorization | 补上 Bearer 头 |
| 401 | invalid_api_key | Key 无效 / 已吊销 / 已过期 | 检查 Key;重新创建 |
| 403 | insufficient_scope | 缺 scope | 给 Key 加权限或换 Key |
| 403 | project_not_allowed | Key 限定了项目范围 | 换 Key 或去掉限制 |
| 403 | node_not_allowed | Key 限定了节点范围 | 同上 |
| 403 | ip_not_allowed | 来源 IP 不在 Key 的白名单里 | 换机器调用,或让管理员把出口 IP 加进白名单 |
请求参数
| HTTP | code | 含义 |
|---|---|---|
| 400 | invalid_request | 参数/JSON 校验失败(消息里有「第 N 条:」定位) |
| 400 | project_mismatch | 项目不在指定节点上 |
| 400 | ambiguous_project | projectId 存在于多个节点,需显式 nodeId |
| 400 | bad_request | Key 管理接口的参数错误(如回调地址不合法) |
| 413 | payload_too_large | 请求体超过 16MB |
资源状态
| HTTP | code | 含义 | 处理 |
|---|---|---|---|
| 404 | node_not_found | 节点不存在或不属于你 | 重新拉 /v1/nodes |
| 404 | project_not_found | 找不到包含该项目的节点 | 重新拉 /v1/projects |
| 404 | job_not_found | 任务不存在或不属于你(不区分,防探测) | — |
| 404 | batch_not_found | 批次不存在 | — |
| 409 | node_offline | 目标节点离线,拒绝投递 | 等节点恢复或换节点 |
| 409 | job_finished | 任务已结束,不能取消 | — |
| 409 | job_not_retryable | 只有 failed/cancelled 能重试 | — |
| 429 | rate_limited | 超过该 Key 的每分钟上限 | 按 Retry-After 退避,或申请更高 rpm |
| 500 | internal_error | 服务端异常 | 带 requestId 联系维护方 |
建议的重试策略
| 场景 | 是否重试 |
|---|---|
| 401 / 403 | ❌ 配置问题,重试无用 |
| 400 / 404 | ❌ 参数或目标错了 |
409 node_offline | ⚠️ 等节点恢复再试(可用 /v1/overview 的 online 判断) |
| 429 / 502 / 503 / 504 | ✅ 指数退避重试 |
| 500 | ✅ 可重试 1–2 次,之后带 requestId 反馈 |
3. 限流
服务端按 Key 做滑动窗口限流,默认 600 次/分钟(可由管理员在 Key 上单独配置 rpm, 0 表示不限)。超限返回:
HTTP/1.1 429 Too Many Requests
Retry-After: 8
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1760000000
{"error":{"code":"rate_limited","message":"请求过于频繁,请按 Retry-After 稍后重试","retriable":true}}即使没超限,也建议调用方自限:
| 维度 | 建议 |
|---|---|
| 提交频率 | ≤ 10 次/秒(每次最多 100 条) |
| 轮询 | 单任务 ≤ 1 次/5 秒;优先用 webhook 或 SSE |
| 总览 | ≤ 1 次/分钟(format=compact) |
计数是进程内的:Hub 多副本部署时每个副本各自计数,实际总配额会成倍。 现阶段 Hub 是单副本部署(队列本身也是单副本假设),无需额外配置。
3.1 IP 白名单
Key 可以限定只允许某些来源地址调用:
json
{ "ipAllowlist": ["203.0.113.10", "198.51.100.0/24"] }- 支持 IPv4 字面量与 CIDR;IPv6 只支持精确匹配(网段限制请放在反代上)。
- 反代后 Hub 读
X-Real-IP/X-Forwarded-For首段;请确保反代覆盖这两个头, 否则白名单看到的是反代地址。 - 不命中返回
403 ip_not_allowed——不是 401,方便区分「Key 对但机器不对」。
4. 常见问题
Q:提交返回 202,但任务一直 queued
依次检查:
GET /v1/jobs/{id}看blocked- 有
blocked.reason = node_offline→ 节点离线,等恢复
- 有
GET /v1/nodes看online- 同一项目是否已有任务在跑(同工作区串行):
GET /v1/jobs?projectId=xxx&status=running - 节点是否有人工会话在跑(此时槽位压到 1)
Q:任务失败,failure.type 是 llm_error
先看 failure.message:
RateLimitError/ 429 → 上游限流。已自动重试过;建议降低并发或给该项目换 providerAuthenticationError/ 401 → 项目的模型 Key 失效,需在控制台更新- 其它 → 看
sessionId,在控制台点进去看完整过程
Q:任务失败,failure.type 是 max_iterations
agent 用满了迭代预算还没完成。说明任务太大或提示太模糊。
处理:拆成多个小任务;或在 prompt 里明确"先输出计划再执行"。
Q:estimateRemainingMs 与实际差很多
它是按"最慢项目"估的,前提是任务耗时稳定。如果同批任务复杂度差异大, 只能当量级参考。精确进度请用 counts。
Q:同一个 Key 能给多个系统用吗
能,但不建议:出问题无法单独吊销,也无法按系统区分用量。 建议一个系统/环境一把 Key。
Q:Key 泄露了怎么办
- 控制台「更换」该 Key(旧 Key 立即失效,
id不变,日志可追溯) - 检查审计日志里的调用来源
- webhook 密钥也会一起更换,记得更新接收端的验签密钥
Q:能限制 Key 只能投递到某些项目吗
能。创建 Key 时填「限定项目」(projectIds)。这样即使 Key 泄露, 影响面也被限制在指定工作区。
5. 与内部 API 的区别
/v1/**(本文档) | /api/hub/**(控制台) | |
|---|---|---|
| 使用者 | 第三方系统 | 浏览器/桌面端 |
| 认证 | API Key | 用户登录 token |
| 稳定性 | 长期兼容 | 随 UI 演进 |
| 能力范围 | 投递任务 + 看资源 | 全部控制面(设备授权、计费等) |
不要把 /api/hub/** 用于集成:它随时可能改字段,且鉴权模型面向浏览器会话。
