跳到主要内容
注册

用官方 OpenAI SDK(Python、Node、Go 与 Java)调用 Router One

官方 OpenAI SDK(PyPI 和 npm 上的 openai 包)只要拿到两个值就能接入 Router One:base URL https://api.router.one/v1 和一把 Router One Key。之后 client.chat.completions.create 可以调用目录里的所有聊天模型,GPT 之外,Claude、Gemini、DeepSeek 和 Grok 的 ID 同样可用,每次请求都有成本和延迟 Trace。但 SDK 的其余部分不能整体照搬:client.responses.create 只适用于模型详情页列出 POST /v1/responses 的 ID,embeddings、音频、文件和 batch 在网关上没有对应路由。本指南依次说明安装与版本下限、两个 SDK 各自读取的环境变量、Python 与 Node 示例、Go 与 Java 小节、每个 SDK 方法对应的端点、流式 usage、Claude 的思考输出、生图、长时间非流式调用返回的 HTTP 200 错误体、重试,以及怎样查看 SDK 实际请求的 URL。按 openai 3.19.2(Python)与 openai 7.23.0(Node)核对(2026-09-27),按 openai-go v3.66.0 与 openai-java 4.70.0 核对(2026-09-29),依据各 SDK 的文档与源码;2026-10-06 又按 openai 3.24.0(Python)、openai 7.28.0(Node)、openai-go v3.71.2 与 openai-java 4.76.0 复核,这些版本的发布说明没有列出与本指南所述设置和行为相关的改动。

安装 SDK 并确认版本下限

Python:pip install -U openai 安装的是 openai 3.x,要求 Python 3.10 或更新版本。3.0.0(2026-08-12)把 SDK 的 HTTP 层换成了 HTTPX2,所以单独安装 openai 不会再顺带装上 httpx 或 certifi;如果你自己的代码导入了 httpx,请把它写进项目依赖。Node.js:npm install openai 安装的是 openai 7.x,要求 Node.js 22 或更新版本(SDK 的 README 把 Node.js 22 列为最低支持版本),本页所有 JavaScript 示例都以 Node.js 22+ 为前提。两个 SDK 在构造客户端时如果没有显式传值,都会读取两个环境变量:OPENAI_BASE_URL 作为 base URL,OPENAI_API_KEY 作为 Key。按下面设置后,不带参数的 OpenAI() 或 new OpenAI() 无需改代码就会连到 Router One。两个 SDK 都不读取 OPENAI_API_BASE。这个旧变量名仍被一些框架使用(LangChain 会先于 OPENAI_BASE_URL 读取它),所以只设置了 OPENAI_API_BASE 的教程会让 SDK 继续连 api.openai.com,而那里不接受 Router One Key。本页示例都显式传入这两个值,并从 ROUTER_ONE_API_KEY 读取 Key(这是本指南自己取的变量名),这样其他项目遗留的 OPENAI_* 变量就改不了请求的去向。请在控制台为每个应用单独创建一把 Key,并设置 maxSpend 上限。

environment
# Read by both SDKs when the client gets no base URL or key of its own
OPENAI_BASE_URL=https://api.router.one/v1
OPENAI_API_KEY=sk-your-router-one-key

把 OpenAI SDK 配置到 Router One base URL

把下面的代码保存为 openai-sdk-example.py,导出 ROUTER_ONE_API_KEY 后运行。base_url 必须以一个且仅一个 /v1 结尾,因为 SDK 会在后面拼上 /chat/completions、/responses 或 /models。少了 /v1,网关会返回 HTTP 404,消息提示 OpenAI 兼容客户端需要以 /v1 结尾的 base_url;路径里出现 /v1/v1,说明 /v1 写了两遍。Key 以 Authorization: Bearer 发送。第一个调用走 Chat Completions,这个端点服务目录里的所有聊天模型,所以同一段代码换成 anthropic/claude-sonnet-5、google/gemini-3.7-flash、deepseek-v4.1-flash、grok-4.7 或 openai/gpt-5.5 都能运行。请从 /models 原样复制 ID,带厂商前缀的要保留前缀:SDK 不检查模型名,写错的 ID 会一路发到网关、在那里失败。max_tokens 设定输出上限;也可以改用 SDK 提供的新名称 max_completion_tokens,Router One 的 Chat Completions 按同样含义处理(两者都传时以 max_completion_tokens 为准)。第二个调用走 Responses API,它只适用于模型详情页列出 POST /v1/responses 的 ID(目前是 GPT 系列模型、DeepSeek ID 与 Grok 对话模型),所以这里用 openai/gpt-5.5。把 Claude 系列 ID 发给 client.responses.create,会在调用任何模型之前被拒绝并返回 HTTP 400。

openai-sdk-example.py
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.router.one/v1",
    api_key=os.environ["ROUTER_ONE_API_KEY"],
)

# Chat Completions: every chat model in the catalog
chat = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=512,
)
print(chat.choices[0].message.content)

# Responses: only IDs whose model page lists POST /v1/responses
resp = client.responses.create(model="openai/gpt-5.5", input="Hello!")
print(resp.output_text)

Node.js 里的同一个客户端

Node SDK 用驼峰命名接收同样的两个值:baseURL 和 apiKey,返回的响应结构也相同。把下面的代码保存为 router-one.mjs,在 Node.js 22 或更新版本上运行 node router-one.mjs;.mjs 扩展名让文件成为 ES 模块,顶层 await 需要这一点。第一个请求是对 deepseek-v4.1-flash 的普通聊天调用。第二个请求以流式调用 anthropic/claude-sonnet-5,并带上 stream_options.include_usage,所以流的最后一个 chunk 带 usage 对象、choices 为空数组,这也是循环里用可选链读取 choices[0] 的原因。与 Python SDK 一样,Node SDK 默认对失败的请求重试两次,超时时间为 10 分钟;可在构造函数或单次请求里设置 maxRetries 和 timeout。在 TypeScript 里,SDK 没有定义类型的字段(例如请求里的 thinking、响应里的 reasoning_content)需要做类型断言,但 SDK 会按原样发送额外的请求字段。

router-one.mjs
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.router.one/v1",
  apiKey: process.env.ROUTER_ONE_API_KEY,
});

const chat = await client.chat.completions.create({
  model: "deepseek-v4.1-flash",
  messages: [{ role: "user", content: "Hello!" }],
  max_tokens: 512,
});
console.log(chat.choices[0]?.message.content);

// Streaming: the last chunk has empty choices and the usage object
const stream = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5",
  messages: [{ role: "user", content: "Count to five." }],
  stream: true,
  stream_options: { include_usage: true },
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  if (chunk.usage) console.log(chunk.usage);
}

Go:openai-go 用 option.WithBaseURL

openai-go 是 OpenAI 官方的 Go SDK(github.com/openai/openai-go/v3),2026 年 10 月 5 日的版本为 v3.71.2,从 v3.45.0 起要求 Go 1.25 或更新版本。openai.NewClient 会先从环境变量读取 OPENAI_BASE_URL 和 OPENAI_API_KEY,再应用你传入的选项,所以示例里的 option.WithBaseURL 和 option.WithAPIKey 会覆盖遗留的环境变量;与 Python、Node SDK 一样,它不读取 OPENAI_API_BASE。client.Chat.Completions.New 可以调用目录中的所有聊天模型,Model 直接接收字符串形式的目录 ID,带厂商前缀的要保留前缀。MaxTokens 以 max_tokens 发送,MaxCompletionTokens 以 max_completion_tokens 发送;Router One 的 Chat Completions 把两者都当作输出上限(都设置时以 max_completion_tokens 为准)。这个 SDK 默认对连接错误以及 HTTP 408、409、429 和 5xx 重试两次(可用 option.WithMaxRetries 调整),自身不设超时,所以耗时长的调用请给 context 设截止时间,或用 client.Chat.Completions.NewStreaming 流式接收。client.Responses.New 只适用于模型详情页列出 POST /v1/responses 的 ID。

main.go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/option"
)

func main() {
	client := openai.NewClient(
		option.WithBaseURL("https://api.router.one/v1"),
		option.WithAPIKey(os.Getenv("ROUTER_ONE_API_KEY")),
	)
	chat, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
		Model:     "anthropic/claude-sonnet-5",
		Messages:  []openai.ChatCompletionMessageParamUnion{openai.UserMessage("Hello!")},
		MaxTokens: openai.Int(512),
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(chat.Choices[0].Message.Content)
}

Java:openai-java 用 baseUrl

openai-java 4.76.0(2026 年 10 月 4 日发布)支持 Java 8 及更高版本。OpenAIOkHttpClient.fromEnv() 读取 OPENAI_BASE_URL 与 OPENAI_API_KEY,或者 openai.baseUrl 与 openai.apiKey 这两个系统属性,系统属性优先于环境变量;也可以像下面这样用 builder 的 baseUrl 和 apiKey 在代码里设置。与其他 SDK 一样,它不读取 OPENAI_API_BASE。model 直接接收字符串形式的目录 ID。maxTokens 发送的是 max_tokens,SDK 把它标为已弃用、推荐 maxCompletionTokens;Router One 的 Chat Completions 把两者都当作输出上限,所以也可以改用 maxCompletionTokens(都设置时以 max_completion_tokens 为准)。客户端默认对连接错误以及 HTTP 408、409、429 和 5xx 重试两次,10 分钟超时,都可以在 builder 上用 maxRetries 和 timeout 调整;设置 OPENAI_LOG=debug 可打开 SDK 的请求日志。README 建议一个应用只创建一个客户端,因为每个客户端都有自己的连接池和线程池。它的 openai-java-spring-boot-starter 已停在 4.45.0,所以 Spring 应用可以把这个客户端声明为 Bean,或者改用 Spring AI。

RouterOne.java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;

public class RouterOne {
    public static void main(String[] args) {
        OpenAIClient client = OpenAIOkHttpClient.builder()
                .baseUrl("https://api.router.one/v1")
                .apiKey(System.getenv("ROUTER_ONE_API_KEY"))
                .build();

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("anthropic/claude-sonnet-5")
                .addUserMessage("Hello!")
                .maxTokens(512)
                .build();
        ChatCompletion chat = client.chat().completions().create(params);
        System.out.println(chat.choices().get(0).message().content().orElse(""));
    }
}

每个 SDK 方法对应 Router One 的哪个端点

SDK 覆盖的 OpenAI API 远多于网关提供的端点。Router One 在 /v1 下提供 Chat Completions、Responses、Anthropic Messages、模型列表、钱包余额、生图与改图以及视频生成;其他路径都没有路由。把代码迁过来之前,先按下表逐一核对用到的方法:

每个 SDK 方法对应 Router One 的哪个端点
SDK 调用(Python 与 Node)Router One 端点能用什么
chat.completions.createPOST /v1/chat/completions目录里的所有聊天模型;工具调用、流式与图片输入以各模型详情页为准
responses.createPOST /v1/responses只限模型详情页列出该端点的 ID:GPT 系列(例如 openai/gpt-5.5、azure/gpt-6-astra、codex-auto-review)、deepseek-v4.1-flash、deepseek-v4-flash 与 Grok 对话模型;background: true 和 image_generation 工具会被 400 拒绝
models.listGET /v1/models当前目录的模型 ID,与 /models 页面显示的一致
images.generate、images.editPOST /v1/images/generations、POST /v1/images/editsgpt-image-2、gemini-3.1-flash-image-preview 等生图模型 ID,按张计费;改图以 multipart 表单上传参考图
embeddings、audio、files、batches、vector_stores、conversations、responses.retrieve没有路由Key 有效时返回 HTTP 404(网关不接受的 Key 会先得到 401);这些调用请留在提供它们的供应商那里

流式拿 usage,读取 Claude 的思考内容

两个端点都支持流式。在 Chat Completions 上加 stream_options 并打开 include_usage,流的最后一个 chunk 就会带上 token 用量;这个 chunk 的 choices 是空列表,所以读取前先判断 chunk.choices。不加 include_usage 时,流里完全没有 usage,不过控制台 → 日志仍会记录这次请求的 tokens 和费用。产生过输出的流式请求,日志里在总耗时旁还显示首字延迟(TTFT)。客户端测得的首个可见 Token 时间与日志中的首字延迟之差,来自你的网络、客户端和网关接收请求的环节;首字延迟本身就长,则指向排队、故障转移前的失败尝试或模型本身的等待。Claude 的思考内容放在消息(或每个流式 delta)里一个非标准的 reasoning_content 字段中。目录中以 -thinking 结尾的 ID(anthropic/claude-sonnet-4.6-thinking、anthropic/claude-opus-4.7-thinking 和 anthropic/claude-opus-4.6-thinking)默认开启思考,无需在请求里加字段。SDK 没有为 reasoning_content 定义类型:Python 里按下例用 getattr 读取,或从 model_extra 里取;Node 里通过类型断言读取 message.reasoning_content。如果要自己发送 thinking 对象,注意 Python 的 create() 没有 thinking 参数,传了会抛出 TypeError,所以要写成 extra_body={"thinking": {...}};Node SDK 则按原样发送这个字段。模型接受哪些思考设置由模型本身决定。对 Claude 系列 ID,reasoning_effort 不会被转换成思考设置;唯一的例外是 Claude Opus 5.5,网关会把它映射为该模型的 effort 设置。思考产生的 token 按模型的输出单价计费。

stream_thinking.py
stream = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6-thinking",
    messages=[{"role": "user", "content": "Is 221 prime?"}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices:
        delta = chunk.choices[0].delta
        thinking = getattr(delta, "reasoning_content", None)
        if thinking:
            print(thinking, end="", flush=True)
        if delta.content:
            print(delta.content, end="", flush=True)
    elif chunk.usage:
        print(chunk.usage)

长时间的非流式调用可能返回带错误的 HTTP 200

stream: false 的调用运行超过约 25 秒后,网关会先返回 HTTP 200,并在答案生成期间持续写入 JSON 空白字符,这样连接不会因为迟迟等不到第一个字节而被断开。如果调用在这之后失败,状态码已经无法再改:失败会以 HTTP 200 加顶层 error 对象的形式返回,里面没有 choices。两个 SDK 都不会因此抛出异常。Python 返回一个 choices 为 None 的 ChatCompletion,错误放在 model_extra 里;Node 返回的对象 choices 为 undefined,error 字段里是网关的错误消息。这时再读取 choices[0],就会在离原因很远的地方抛出一个看似无关的 TypeError。对推理模型和其他耗时较长的生成,请使用流式,或者像下面这样在读取 choices 之前先检查错误。/v1/responses 上的非流式调用行为相同,同样要检查 error 字段。在保活开始之前就完成或失败的调用,状态码照常返回,SDK 也会照常抛出对应的错误类型。

long_call.py
completion = client.chat.completions.create(
    model="openai/gpt-5.5",
    messages=[{"role": "user", "content": "Plan a 12-step data migration."}],
)
error = (completion.model_extra or {}).get("error")
if error or not completion.choices:
    raise RuntimeError(f"Router One returned an error body: {error}")
print(completion.choices[0].message.content)

SDK 的重试和超时叠加在网关的故障转移之上

两个 SDK 默认都会对失败的请求重试两次,触发条件是连接错误以及 HTTP 408、409、429 和 5xx,并按 Retry-After 响应头的要求等待;默认超时都是 10 分钟。网关在返回之前已经做过一轮自己的故障转移:请求由你指定的模型处理,某条线路出现 429、5xx 或超时时,会换到同一模型的另一条线路重试。所以到达你代码的 429 或 5xx 已经经过了这一步,而 SDK 的每次重试都是发往网关的一个新请求,有自己的 request_id。Router One 自身对 Key 或账户的限额触发的 429,在调用任何模型之前就被拒绝,带 Retry-After 和取值为 api_key、subject 或 subject_model 的 X-RateLimit-Scope 响应头;控制台 → 日志里有记录的 429,是网关重试之后上游仍返回的。两者怎么区分,见错误码速查页。批处理任务请调低 max_retries(Python)或 maxRetries(Node),免得一条失败的输入变成三次尝试;单次调用可以在 Python 里用 client.with_options(max_retries=0),在 Node 里通过请求选项传入 maxRetries。耗时长的生成请用 stream=True,而不是一味调长超时。

OpenAI SDK 该填哪个模型 ID?

从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 OpenAI SDK 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个客户端或应用单独建 API Key,并设置 maxSpend 消费上限。

OpenAI SDK 用的是哪种 API 协议?

OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。

在请求日志里核对 OpenAI SDK 的调用

先在 OpenAI SDK 发出一次简单文本请求,再到控制台 → 日志按时间、模型和 request_id 找到这条记录,核对 Token、花费、总耗时和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,要么请求没到达网关(客户端配置或网络问题),要么网关在调用模型之前就拒绝了它——Key 问题的 401、余额不足或 Key 达到 maxSpend 上限的 402、Key 或账户自身限额触发的 429,或模型 ID、端点不对的 400 / 404;在输出任何内容之前就失败的流式请求也可能没有日志。看客户端收到的状态码和错误消息就能区分是哪一种;先确认这一点,再判断是不是网关或上游故障。

常见问题

改用 Router One 只需要换 base URL 吗?

对 chat.completions.create 来说是的:设置 base URL 和 Key,model 填精确的目录 ID 即可。有三件事不在这次切换的范围内。responses.create 只适用于模型详情页列出 POST /v1/responses 的 ID;把 Claude 系列 ID 发过去会返回 HTTP 400,消息为 model '<id>' must be called via /v1/messages or /v1/chat/completions,所以 Claude、Gemini 等 ID 请继续用 chat.completions.create。非标准字段,例如请求里的 thinking 和响应里的 reasoning_content,在 Python 里通过 extra_body 和 model_extra 传递与读取,在 Node 里通过类型断言处理。网关不提供的端点(例如 embeddings、音频和文件)会返回 404,用到它们的代码需要另外保留一个连接其他供应商的客户端。

还能继续用 client.responses.create 吗?

能,前提是模型详情页列出了 POST /v1/responses:目前包括 GPT 系列模型(例如 openai/gpt-5.5、openai/gpt-5.6-sol、azure/gpt-6-astra 和 codex-auto-review)、deepseek-v4.1-flash 与 deepseek-v4-flash,以及 grok-4.7 等 Grok 对话模型。在这些 ID 上,网关接受文本和多段输入、instructions、流式、函数工具、自定义工具,以及 previous_response_id、conversation 和 prompt 引用。web_search 等服务端托管工具字段会被接受并计量,但 Router One 自己不执行工具。background: true 和 image_generation 工具会被 HTTP 400 拒绝,生图请改用 images.generate。在这个端点上,只有 Claude 系列 ID 会得到固定的 must be called via 消息,其他 ID 在依赖 Responses 之前,请先查看它的模型详情页。

同一个客户端能生图吗?

能。client.images.generate(model="gpt-image-2", prompt="...") 用同一把 Key 发往 /v1/images/generations,目录里的其他生图 ID(gpt-image-2.5-flare、gpt-image-2.5-sunburst、gemini-3-pro-image-preview、gemini-3.1-flash-image-preview、gemini-nano-banana-2.1、grok-imagine-image 和 grok-imagine-image-quality)用法相同。每张图按模型详情页上的固定单价计费,不按 token 计。图片可能以 data[].b64_json 或 data[].url 的形式返回,两种都要处理,拿到后立即保存。client.images.edit 以 multipart 表单把参考图上传到 /v1/images/edits,适用于接受图片输入的生图模型。

embeddings、音频或 Files API 能通过 Router One 调用吗?

不能。Router One 提供聊天、Responses、模型列表、余额查询以及图片和视频生成;client.embeddings.create、语音转写与语音合成、文件、batch、向量库和 conversations 都没有路由,会返回 HTTP 404。RAG 流水线请把 embedder 留在提供 embeddings 的供应商那里,用该供应商自己的 Key,只把聊天调用发到网关。

怎样查看 SDK 实际请求的是哪个 URL?

控制台 → 日志记录每次请求的模型、API Key、tokens、费用、总耗时和状态,但不记录请求路径,所以请在客户端这一侧查看路径。在 Node 里设置 OPENAI_LOG=debug(或在客户端上设置 logLevel: 'debug'),SDK 会打印每个请求的方法和 URL。Python SDK 不打印 URL,可以给客户端传一个带事件钩子的 HTTP 客户端:OpenAI(base_url=..., api_key=..., http_client=DefaultHttpx2Client(event_hooks={'request': [lambda r: print(r.method, r.url)]})),其中 DefaultHttpx2Client 从 openai 导入。如果请求发到了 https://api.router.one/chat/completions(少了 /v1),或者路径以 /v1/v1 开头,问题就出在 base URL 上。

需要哪个版本的 Python 和 Node?为什么在精简容器里 TLS 会失败?

openai 3.x 需要 Python 3.10 或更新版本,openai 7.x 需要 Node.js 22 或更新版本。从 3.0.0 起,Python SDK 改用 HTTPX2,它用操作系统的信任库校验 TLS 证书,也不再安装 certifi。因此,没有 CA 证书的精简 Docker 镜像,或者位于会解密 TLS 流量的企业代理之后的网络,连接 https://api.router.one 时可能报证书错误。解决办法是在镜像里安装 CA 证书,把 SSL_CERT_FILE 或 SSL_CERT_DIR 指向你的证书包,或者通过 OpenAI(http_client=DefaultHttpx2Client(verify=ssl_context)) 传入一个 ssl.SSLContext。DefaultHttpxClient 这个名字仍然可用,现在构造的是 HTTPX2 客户端;传入 httpx.Client、httpx.Timeout 或 httpx transport 对象的代码,需要换成对应的 httpx2 版本。

Go 和 Java 需要哪个版本?

openai-go v3.45.0 及之后的版本需要 Go 1.25 或更新版本;按其 README,想继续使用 Go 1.22 到 1.24,请固定在 v3.44.0。openai-java 支持 Java 8 及更高版本。客户端没有在代码里拿到值时,两者都读取 OPENAI_BASE_URL 与 OPENAI_API_KEY,也都不读取 OPENAI_API_BASE。

怎样列出我能调用的模型 ID?

client.models.list() 调用 GET /v1/models,返回当前目录的模型 ID,生图模型也包括在内;Python 里直接遍历,Node 里用 for await。/models 页面和 https://router.one/zh/models.md 列出同样的 ID,并附上下文窗口、端点和能力。请按列出的样子原样传入 ID,SDK 不会替你检查。

OpenAI SDK 能通过网关用哪些模型?

选用当前目录中同时支持 OpenAI SDK 所用端点和所需功能的模型。精确 ID、当前单价与能力以 /models 及模型详情为准;不要仅按 GPT、Claude 等系列名判断兼容性。客户端能列出模型,只说明它从自身配置或 GET /v1/models 读到了这个 ID,仍需验证实际调用。

能列出模型,但调用报 400 或 404,怎么办?

先记录实际请求路径和错误消息,再核对精确模型 ID。400 可能是参数、工具类型或模型与端点不匹配;404 可能是请求路径或资源不存在,不能直接判定模型下线。若错误提示 must be called via,按它指明的端点调整客户端 provider,或换用支持当前端点的模型。不要在所有工具里统一增删 /v1 或 /chat/completions。

中国大陆能直连吗?

能。网关在大陆可直连、无需 VPN,配置与全球环境完全一致。

报 401/402/403/429 怎么排查?

先看客户端收到的响应:状态码、错误消息和 X-Request-ID 响应头。401(Key 缺失、不存在、已吊销或已过期)、402(钱包余额不足,或这把 Key 达到 maxSpend 上限)以及 Key 或账户自身限额触发的 429,都在调用任何模型之前被拒绝,不会出现在控制台 → 日志里;模型 ID 或端点写错导致的 400 / 404 也一样。401 查 Key 是否完整传入、在控制台 → API 密钥里是否仍有效;402 充值或调高这把 Key 的 maxSpend;403 请保留完整错误消息。429 请退避后重试;日志里能查到的 429 是网关重试之后上游仍返回的。保留 request_id,再按错误码速查页逐项排查。