错误、限流与重试
统一错误结构
业务错误响应保留可读说明,并提供稳定字段:
json
{
"code": "RATE_LIMITED",
"detail": "rate limit exceeded",
"retryable": true,
"request_id": "..."
}所有响应都可能包含 X-Request-ID。调用方日志应记录请求方法、路径、状态码、 request_id 和重试次数,但不要记录完整 Token。
按状态码处理
| 状态码 | 自动重试 | 处理方式 |
|---|---|---|
400 | 否 | 修正业务参数 |
401 | 否 | 重新探测鉴权;需要时提示申请或配置 Token |
404 | 否 | 核对能力 ID、资源 ID 或快照是否存在 |
422 | 否 | 按能力契约修正类型、枚举和必填参数 |
429 | 是 | 严格遵守 Retry-After |
503 | 是 | 指数退避并加入随机抖动 |
响应中的 retryable 是当前错误的直接判断依据;状态码表用于兜底。
限流
限流额度可能随认证模式和服务策略调整。客户端应以响应头为准:
X-RateLimit-LimitX-RateLimit-RemainingRetry-AfterX-Auth-ModeX-RateLimit-Policy
不要在 Skill 中永久写死每分钟请求数。降低请求量的首选方式是:
- 缓存
bootstrap和能力清单的ETag。 - 使用
detail=compact。 - 分页从 10 条开始。
- 只为最终使用的板块拉取证据。
- 跨接口需要同一版本时复用
snapshot_id。
重试策略
建议最多尝试 4 次:
text
attempt 1: 立即调用
attempt 2: Retry-After 或约 2 秒
attempt 3: Retry-After 或约 5 秒
attempt 4: Retry-After 或约 10 秒每次退避加入随机抖动,避免多个 Agent 同时再次冲击服务。若服务持续不可用:
- 当前查询失败时可以使用最后一个完整版本,但必须明确其
as_of。 - 不把实时材料与旧版本结果混成同一时间口径。
- 向用户说明数据时间,不伪造缺失结果。
- 日志保留最后一个
request_id供排障。
鉴权降级
调用前先读 bootstrap.authentication.mode:
- 从
optional变为required时,停止匿名业务调用并提示配置 Token。 - Token 返回
401时,不要自动回退成匿名请求绕过错误。 - Token 申请地址使用
bootstrap返回的apply_url,不要在多个适配器中分别硬编码。
参数错误恢复
422 不应通过重复请求解决。Agent 应:
- 读取错误中的字段位置。
- 查询对应能力详情。
- 使用契约中的枚举、默认值和格式重建请求。
- 最多修正一次;仍失败时返回可操作的错误说明。