核心指南

让 Agent 读懂 API 错误

直接读取错误码、等待时间和可选模型,不必猜测报错文案

本页介绍供应用和编程 Agent 读取的公共 API 错误,不授予工作区请求调查或客服权限。排查自己的工作区请求,请从请求排错指南开始。

TokenLab 的 OpenAI 兼容错误可能带有结构化提示,Agent 和应用都可以直接读取。判断处理方式时请以 HTTP 状态和 code 为准,不要从 message 文案里猜原因。

Anthropic Messages 与 Gemini API 保留各自的错误格式。本页字段只适用于 OpenAI 兼容的 Chat Completions 和 Responses 错误。

可选字段

以下字段都位于 error 对象中,并非每次都会返回。

字段类型用途
did_you_meanstring最接近的可用模型 ID
suggestionsarray可能适合这次请求的模型
hintstring简短原因或处理建议
retryableboolean稍后重试同一请求是否可能成功
retry_afternumber再次请求前需要等待的秒数
balance_usdnumber当前美元余额
estimated_cost_usdnumber这次请求的预估费用

客户端必须能处理这些字段不存在的情况。它们用于补充信息,不能代替状态码和错误码。

模型名不正确

模型名拼错或不可用时会返回 400 model_not_found。如果响应带有 did_you_mean,可以把建议显示给用户;只有产品本来就允许自动换模型时,才直接重试。

{
  "error": {
    "message": "Model not found: please check the model name",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_found",
    "did_you_mean": "gpt-5.6-terra",
    "suggestions": [
      {"id": "gpt-5.6-terra"},
      {"id": "gpt-5.6-luna"}
    ],
    "hint": "Did you mean 'gpt-5.6-terra'? Use GET https://api.tokenlab.sh/v1/models to list all available models."
  }
}

余额不足

402 insufficient_balance 可能包含当前余额和所需金额。应用可以提供充值入口、价格更低的模型,或让用户缩小请求。

{
  "error": {
    "message": "Insufficient balance: need ~$0.3500 for claude-sonnet-4-6, but balance is $0.1200.",
    "type": "insufficient_balance",
    "code": "insufficient_balance",
    "balance_usd": 0.12,
    "estimated_cost_usd": 0.35,
    "suggestions": [
      {"id": "gpt-5.6-luna"},
      {"id": "deepseek-v3-2"}
    ],
    "hint": "Try a cheaper model, or top up at https://tokenlab.sh/dashboard/billing."
  }
}

模型不可用

503 all_channels_failed 或 503 delivery_tier_unavailable 不一定是临时故障。如果所选 Delivery 档位没有支持当前操作的供应,retryable 为 false,且不返回 retry_after,不要原样重试。更换模型前,通过 GET /v1/models 检查对应操作和 Delivery 的可用性。名称相近不代表可用;未经验证的替代模型不会列出。

{
  "error": {
    "message": "This model is unavailable for the requested operation and Delivery tier.",
    "type": "all_channels_failed",
    "code": "all_channels_failed",
    "retryable": false,
    "hint": "Check the model's operation and Delivery availability with GET /v1/models. Repeating the same request will not resolve this."
  }
}

请求过于频繁

收到 429 rate_limit_exceeded 后,等待 retry_after 指定的秒数,或读取标准 Retry-After 响应头。

{
  "error": {
    "message": "Rate limit: 1000 rpm exceeded",
    "type": "rate_limit_exceeded",
    "code": "rate_limit_exceeded",
    "retryable": true,
    "retry_after": 8,
    "hint": "Retry after 8s."
  }
}

输入超过上下文长度

400 context_length_exceeded 不能靠原样重试解决。请缩短输入,或让用户改用上下文更长的模型。

{
  "error": {
    "message": "This model's maximum context length is 128000 tokens...",
    "type": "invalid_request_error",
    "code": "context_length_exceeded",
    "retryable": false,
    "suggestions": [
      {"id": "gemini-2.5-pro"},
      {"id": "claude-sonnet-5"}
    ],
    "hint": "Reduce your input or switch to a model with a larger context window."
  }
}

确认可用的 API 格式

使用模型专属 API 前,从 GET /v1/models/{model} 读取 tokenlab.accepted_request_formats。

值API
openai_chat_completions/v1/chat/completions
openai_responses/v1/responses
anthropic_messages/v1/messages
gemini_generate_content/v1beta/models/{model}:generateContent

这里确认的是 API 格式。具体工具和字段仍可能因模型而异,请以模型页面为准。

按任务查找模型

Models API 可以返回图片、视频等任务的当前候选模型:

curl "https://api.tokenlab.sh/v1/models?recommended_for=image"

recommended_for 支持 image、video、music、3d、tts、stt、embedding、rerank 和 translation。创建任务时仍要明确传入模型 ID;TokenLab 不会在未告知的情况下替换模型。

给 Agent 读取的 API 概览

下面的地址提供精简版 API 说明:

GET https://api.tokenlab.sh/llms.txt

内容包括第一条请求、常用接口、模型筛选方式和错误处理。

读取错误,不自动重发请求

示例只发送一次请求,保留选定模型并报告结构化排错信息。关闭 SDK 自动重试后,由应用判断能否安全重试。模型建议应交给用户明确选择;已经受理或超时的生成请求不要自动重发。

import os
from openai import OpenAI, APIStatusError

with OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,
) as client:
    try:
        response = client.chat.completions.create(
            model="gpt-5.6-terra",
            messages=[{"role": "user", "content": "Reply only with OK."}],
        )
        print(response.choices[0].message.content)
    except APIStatusError as exc:
        body = exc.body if isinstance(exc.body, dict) else {}
        error = body.get("error", body)
        if not isinstance(error, dict):
            error = {}
        print({
            "status": exc.status_code,
            "request_id": exc.request_id,
            "code": error.get("code"),
            "hint": error.get("hint"),
            "suggested_model": error.get("did_you_mean"),
            "retry_after": exc.response.headers.get("Retry-After") or error.get("retry_after"),
        })
        raise

本页内容