本文面向第一次使用 Terminal、第一次配置 OpenCode,或者需要把 OpenCode 接入第三方 AI Gateway 的用户。
完成本文后,你将能够:
- 安装并确认 OpenCode;
- 安全输入 AI Gateway 的 Base URL 和 API Key;
- 查询自己的 API Key 可以看到的模型;
- 判断模型应使用 OpenAI Chat、OpenAI Responses 还是 Anthropic Messages;
- 把通过测试的模型写入正确的 OpenCode provider;
- 用一条真实消息确认 OpenCode 已经连接成功;
- 根据错误信息判断是网络、认证、模型路由、请求协议还是 OpenCode 配置问题。
本文以 macOS Terminal 为例,示例 AI Gateway Base URL 为:
如果你的 AI Gateway 不同,只需要替换 Base URL、API Key 和模型 ID。本文中的模型名称仅用于演示协议和配置写法,实际模型范围以你的 API Key 和中转站返回结果为准。不要把真实 API Key 发到聊天、工单、截图、Git 仓库或公开网页。
本文配置示例按 OpenCode
1.18.18 编写。OpenCode 的配置格式会随版本变化;如果你的版本不同,请先执行 opencode --version,不要直接把新旧版本的配置格式混用。
先看结论:模型厂商和请求协议是两件事
OpenCode 不会根据模型名称自动选择请求协议。真正决定请求格式的是 provider 使用的 AI SDK runtime。
本文使用三个容易识别的 provider 名称:
| OpenCode provider | AI SDK runtime | AI Gateway 端点 | 什么时候使用 |
|---|---|---|---|
| | | 模型的 OpenAI Chat 请求成功 |
| | | 模型的 OpenAI Responses 请求成功 |
| | | 模型的 Anthropic Messages 请求成功 |
如果你已经有其他 provider 名称,不需要为了匹配本文示例而重命名。继续沿用原名称,并把本文命令中的 provider ID 替换为你的实际名称。provider 名称是本机配置名称,不是模型厂商名称。
按模型厂商选择第一条测试路径
下面的表格用于选择起始路径,不代表某个厂商的所有模型都开放相同协议。具体模型必须以自己的
/models 和对应 curl 结果为准:
| 模型厂商或系列 | OpenAI Chat | OpenAI Responses | Anthropic Messages | OpenCode 配置建议 |
|---|---|---|---|---|
| Anthropic Claude | 通常不是首选 | 需要单独测试 | 原生接入路径,优先测试 | 使用 |
| OpenAI GPT、Codex 系列 | 常见兼容路径 | OpenAI 原生路径,需单独测试 | 通常不是首选 | Chat 成功使用 ;Responses 成功使用 |
| DeepSeek 系列 | 网关提供时可用 | 按模型单独测试 | 网关提供时可用 | 按实际成功协议选择 provider |
| Qwen 系列 | 网关提供时可用 | 按模型单独测试 | 网关提供时可用 | 按实际成功协议选择 provider |
| 其他厂商或自定义模型 | 不能推断 | 不能推断 | 不能推断 | 先查目录,再按协议测试 |
最重要的规则是:
只需要为准备使用的协议配置 provider。只用 Claude 时可以只配置 Anthropic provider;只用 OpenAI Chat 时可以只配置 OpenAI Compatible provider;只有在
/responses 测试成功且确实需要该接口时,才配置 Responses provider。
0. 完整操作路线
第一次配置时,请按以下顺序操作:
真正成功必须同时满足:
- 当前协议的模型目录能看到模型;
- 标准 curl 返回 HTTP 200;
- 响应中有实际模型文本;
- OpenCode 通过正确的 provider 返回实际模型文本。
只看到模型名称,不能直接说明模型可用。模型目录、协议路由和客户端实际调用必须分别验证。
0.1 如何阅读模型信息
本文中的模型信息分成三层,含义不同:
| 信息层 | 说明 | 你应采取的动作 |
|---|---|---|
| API Key 实时目录 | 当前 API Key 通过某种认证头查询 能看到的模型 ID | 先作为候选,再继续做请求测试 |
| 协议调用结果 | 某个模型在 OpenAI Chat、OpenAI Responses 或 Anthropic Messages 下的实际 HTTP 结果 | 只在对应协议下使用,并记录成功或失败原因 |
| OpenCode 配置结果 | OpenCode provider、AI SDK runtime 和客户端参数组合后的实际结果 | 按文档中的 provider 写法调用;高级能力需单独确认 |
因此,请按以下优先级判断:
本文中的“可以使用”默认指“最小文本请求返回了最终文本”。它不自动包含工具调用、流式、多模态、结构化输出、长上下文或模型专属参数。
你最终能否调用某个模型,取决于四个条件同时成立:
因此,“中转站可以路由某模型”与“你的 API Key 当前可以调用某模型”是两个不同问题。后者还会受到租户、套餐、权限和实时上游状态影响。
0.2 配置完成后的预期效果
完成本文后,你应能做到:
- 在 OpenCode 中看到自己 API Key 可用的 provider 和模型;
- 用
调用 OpenAI Compatible Chat 模型;my-relay - 在模型的
请求成功时,用/responses
调用该模型;my-relay-responses - 用
调用 Anthropic Messages 模型,包括 Claude;my-relay-anthropic - 根据厂商和协议规则选择正确的 provider,不再把 Claude 放入 OpenAI provider;
- 用最小文本请求确认模型确实返回最终文本;
- 遇到认证、网络、协议、路由或客户端参数错误时,判断问题属于哪一层。
完成第 8 步后,你已经具备基础文本对话能力。工具调用、图片、文件、结构化输出和其他高级能力的适用范围见第 11.6 节和第 12 节。
如果只完成 JSON 编辑但没有完成 curl 和 OpenCode 实际调用,配置还没有完成验证。
1. 准备信息
开始前准备三项内容。
1.1 Base URL
Base URL 是 AI Gateway 接口地址。本示例使用:
地址已经包含
/v1。不要手动拼成 /v1/v1,也不要把它写成具体端点,例如 /chat/completions 或 /messages。OpenCode 的 provider runtime 会自动追加端点。
1.2 API Key
请到 AI Gateway 后台创建 API Key,并确认:
- API Key 没有过期;
- API Key 有模型调用权限;
- 复制时没有多余空格或换行;
- API Key 与 Base URL 属于同一个环境;
- 如果中转站按协议区分权限,API Key 拥有你准备使用的 OpenAI、Responses 或 Anthropic 路由权限。
API Key 的权限可能比产品目录更窄。不同用户、不同套餐或不同租户看到的模型范围可能不同,所以请先查询自己的 OpenAI 和 Anthropic 两个认证视图,再把实际使用的模型加入配置。
1.3 是否需要 VPN
OpenCode 请求的是你配置的 AI Gateway,不是直接请求 Anthropic 或 OpenAI。只要本机能访问中转站,一般不需要 VPN。
先执行第 6 节的
/models 和第 7 节的 curl:
- 能建立 TLS 连接但返回
、401
或No upstream candidates
:通常是 API Key、模型 ID、协议或上游路由问题,不是 VPN 问题;502 - 出现 DNS 失败、连接超时、TLS 握手失败:才优先检查网络、公司代理、防火墙或 VPN。
1.4 在哪里操作
所有命令都在 macOS Terminal 执行。按 Command + Space,输入 Terminal,按回车打开。
终端提示符可能类似:
不要复制提示符本身,只复制代码框中的命令。
**下一步:**执行第 2 节,检查基础工具和 OpenCode。
2. 确认基础工具和 OpenCode
2.1 检查 curl、jq、Node.js
在 Terminal 执行:
看到
curl、jq 的文件路径,并且 Node.js、npm 能返回版本号,就可以继续。
如果 jq 不存在:
如果 brew 存在:
如果 brew 也不存在,请先安装 Homebrew,再安装 jq。后面的模型目录和响应解析命令需要 jq。
**下一步:**确认 OpenCode 命令是否已经安装。
2.2 安装或确认 OpenCode
先执行:
如果已经返回路径和版本号,可以直接进入第 3 节。
type -a opencode 如果显示多个路径,后续排查时要确认 Terminal 使用的是哪一个版本。
如果还没有安装,可以使用 npm:
也可以使用 OpenCode 官方安装脚本:
正常返回版本号即可,例如:
如果显示
opencode: command not found,先确认 npm 的全局 bin 是否在 PATH 中:
如果命令已经安装但当前 Terminal 找不到,请把实际 npm 全局 bin 目录加入
~/.zshrc,重新打开 Terminal,再执行 opencode --version。不要为了绕过 PATH 直接重复安装很多次。
**下一步:**确认 OpenCode 版本后,进入第 3 节保存 API Key。
3. 在当前 Terminal 安全输入 API Key
不要把 API Key 直接写在命令行参数中,因为它可能进入 Terminal history。在同一个 Terminal 执行:
粘贴 API Key 时屏幕不会显示字符,这是正常的。
export 只对当前 Terminal 会话有效,关闭窗口后变量会消失。
检查变量是否存在时不要打印实际内容:
3.1 新 Terminal 为什么需要重新加载
上面的变量只在当前 Terminal 窗口有效。关闭窗口或重启电脑后,如果看到
API Key: missing,通常不是 OpenCode 配置失效,而是新 Terminal 尚未加载环境变量。
临时使用时,在每个新 Terminal 中重新执行本节的
read -s 命令即可。
3.2 长期使用:保存到 macOS Keychain(推荐)
完成前面的
read -s 后,可以把当前变量保存到 macOS Keychain。下面命令中的 API Key 仍然通过变量传入,不要把真实值直接写进命令:
以后打开新 Terminal,执行下面命令加载,不会在屏幕上打印 API Key:
首次读取时 macOS 可能要求确认 Keychain 访问,这是正常现象。如果不再使用,可以删除该条目:
如果不是 macOS,请使用系统密码管理器或权限受限的本地密钥方案。不要把真实值写进本文、Git 仓库、截图、项目目录、公开的
opencode.json 或可同步到云端的 shell 配置文件。
**下一步:**先不要打开 OpenCode,按照协议分别查看模型目录。
4. OpenCode 配置文件在哪里
本节只确认配置文件位置并做好备份。先不要把未测试的模型全部写进去;模型目录和 curl 测试在第 6、7 节完成,真正写入配置在第 8 节。
macOS 默认配置文件为:
也就是:
先检查目录和文件:
第一次修改已有配置前先备份:
4.1 重要:OpenCode 版本格式差异
本文基于 OpenCode
1.18.18,使用下面这些字段:
OpenCode 新版文档可能使用
providers、package、settings 等字段。不要把两套格式拼在同一个文件中。最可靠的做法是:先看本机 opencode --version,再按本版本的 schema 写配置。
如果你使用的版本不是
1.18.18,先执行:
如果报配置 schema 错误,先按该版本的配置格式迁移,不能简单地把
provider 改成 providers 或反过来。
**下一步:**先理解第 5 节的 provider 与协议对应关系,再查询模型目录。
5. 先理解 OpenCode 的三个 provider
OpenCode 不会根据模型 ID 自动选择请求协议。协议由 provider 的 runtime package 决定。
本指南使用三个 provider:
模型引用格式是:
例如:
这里的
my-relay-anthropic 是 OpenCode 的 provider ID,anthropic/claude-opus-5 是中转站的模型 ID。模型 ID 中出现 anthropic/,不会自动把 my-relay 切换为 Anthropic 协议。
以下写法协议不匹配:
**下一步:**执行第 6 节,按认证方式分别查询模型目录。
6. 获取实时模型目录
模型目录必须按协议分别查询。不能只执行一次
/models,然后认为返回结果就是中转站全部模型。
6.1 OpenAI 视图
OpenAI Compatible 使用 Bearer 认证:
HTTP 200 后执行:
返回含义:
| 返回 | 含义 | 下一步 |
|---|---|---|
| HTTP 200 | 网络和 Bearer 认证正常 | 查看目录并测试具体模型 |
| HTTP 401/403 | API Key 错误、失效或权限不足 | 检查 API Key、租户和权限 |
| HTTP 404 | Base URL 或 路径错误 | 检查地址,避免重复 |
| HTTP 429 | 限流、额度或并发限制 | 等待后重试,或检查额度 |
| HTTP 5xx | 网关或上游暂时异常 | 稍后重试并保存脱敏错误 |
| 没有 HTTP 状态、DNS 或超时 | 请求没有正常到达网关 | 检查网络、代理、防火墙或 VPN |
模型出现在目录中,只表示当前 API Key 能看到该 ID;它不代表该模型在 Chat、Responses 和 Anthropic 三种协议下都可用。继续执行第 7 节的具体请求测试。
6.2 Anthropic 视图
Anthropic Messages 使用不同认证头:
HTTP 200 后执行:
如果 OpenAI 视图和 Anthropic 视图不同,这是正常现象。请求头和协议上下文不同,AI Gateway 可以返回不同的模型目录。请使用自己的 API Key 重新查询两个视图,不要复制某一份静态清单。
6.3 OpenCode 自带模型目录的含义
直接执行:
会看到 OpenCode 内置目录中的许多 provider,例如
amazon-bedrock/anthropic.claude-*。这些条目属于 AWS Bedrock provider,不是本中转站模型,不代表你已经获得了 AWS 凭据,也不代表 OpenCode 会自动通过中转站调用它们。
OpenCode 的内置目录与中转站目录是两套目录。只有写入
opencode.json 的 provider 才会通过本中转站请求。
6.4 如何使用自己的模型目录
你不需要把本文示例中的模型全部复制到配置文件。推荐按下面规则处理:
- 保存自己 API Key 的 OpenAI 和 Anthropic
输出;/models - 只把自己目录中存在的模型 ID 放入对应 provider;
- 对每个准备使用的模型执行第 7 节对应协议的最小文本请求;
- 只有返回 HTTP 200 且包含最终文本的模型,才进入 OpenCode 实际调用;
- 如果模型在目录中但请求返回
或No upstream candidates
,保留记录但不要标记为可用;502 - 如果自己的目录与预期不一致,先以实时目录为准,再联系中转站支持人员确认权限或路由。
模型目录是权限和路由的实时快照,不是需要手工维护的“模型总表”。能否使用某个模型,必须同时看模型 ID、协议、provider 和实际调用结果。
**下一步:**从对应目录复制一个完整模型 ID,执行第 7 节的协议请求。
7. 用标准 curl 验证协议和模型
7.1 OpenAI Chat Completions
请求端点:
从第 6.1 节的结果中复制一个完整模型 ID:
执行:
提取最终文字:
成功时应看到:
如果成功,可以在第 8 节只配置
my-relay。
7.2 OpenAI Responses
请求端点:
从第 6.1 节的结果中复制一个完整模型 ID:
执行。Responses 使用
input 和 max_output_tokens,不能直接复制 Chat Completions 的 messages 请求体:
提取最终文字:
不同网关或 SDK 的 Responses 响应结构可能不同,通常从
output[].content[].text 或 output_text 读取。
成功时应看到:
Responses 结果不能由 Chat 结果推断:同一个模型在两个端点的上游路由可能不同。OpenCode 本指南的
my-relay 没有配置 Responses runtime,因此不要把 curl 的 Responses 成功当成 OpenCode 已启用 Responses。
Responses 是可选接入路径。只有同一模型先通过本节的
/responses 标准 curl,再按第 8.4 节配置 my-relay-responses,并通过第 10.2 节的 opencode run 返回最终文本,才能判断 Responses 在你的环境中可用。文档提供配置模板,不代表你的 API Key 或上游路由已经开放该协议。
7.3 Anthropic Messages
请求端点:
从第 6.2 节的结果中复制一个完整模型 ID:
对本文示例 AI Gateway,Claude 当前优先且已经验证的接入路径是 Anthropic Messages,因此使用下面的请求结构:
提取最终文字:
成功时应看到:
测试时不要把
max_tokens 设得过小;某些带思考过程的响应可能只返回思考内容,导致误判为没有最终文本。建议从 1024 开始进行最小文本测试。
下面是模型 ID 写法示例。实际使用时,只把模型 ID 换成自己的 Anthropic 目录中存在、并且请求验证成功的 ID:
如果成功,可以在第 8 节只配置
my-relay-anthropic。
7.4 HTTP 200 但没有最终文字
部分推理模型可能先生成 thinking 或 reasoning 内容。输出预算太小时,请求可能返回 HTTP 200,但没有最终文字。
可以把对应请求中的:
先提高到
1024,仍然不足时再提高到 4096。如果提高后仍然只有 thinking 或 reasoning、没有最终文字,请只在本机查看完整 JSON,确认响应结构是否与当前协议一致;此时不能把该模型标记为这个协议下可用,也不要把未经脱敏的完整 JSON 粘贴到聊天或工单。
**下一步:**只把刚才 curl 成功的模型写入对应 OpenCode provider,执行第 8 节。
8. 写入 OpenCode 配置
下面是 OpenCode
1.18.18 的基础配置模板。它使用 my-relay 对应 OpenAI Compatible Chat,my-relay-anthropic 对应 Anthropic Messages;只有 /responses 测试成功时才按第 8.4 节加入 my-relay-responses。配置文件中不保存 API Key,API Key 通过环境变量 CLICKZETTA_API_KEY 注入。
8.1 复制配置前先区分“固定部分”和“可变部分”
| 配置内容 | 是否可以直接沿用 | 说明 |
|---|---|---|
的对象结构 | 可以 | OpenCode 使用单数 ;不要与新版格式混用 |
| 可以 | 只用于 OpenAI Compatible Chat,不代表启用 Responses |
| 按需使用 | 只用于已通过 测试的模型;配置在独立 provider 中 |
| 可以 | 用于 Anthropic Messages;本文示例网关的 Claude 使用此 provider |
| 必须替换 | 使用你自己的中转站 Base URL,并确保只包含一个 |
| 必须替换 | 使用自己的 API Key,不写入 JSON |
根级别的 | 按需替换 | 必须指向你已验证成功的 |
下的模型 ID | 按需替换 | 只保留自己 能看到且通过最小请求验证的模型 |
、 | 按需调整 | 是 OpenCode 客户端预算,不是中转站永久承诺 |
8.2 方案 A:用 Terminal 写入 OpenAI Chat provider
这是推荐方式。它只修改
my-relay provider,保留配置文件中的其他内容。必须先完成第 7.1 节,并且当前 Terminal 中仍然存在 CHAT_MODEL_ID。
如果你已有其他 provider 名称,可在执行前设置
OPENAI_PROVIDER_ID;不设置时默认使用 my-relay。
8.3 方案 B:用 Terminal 写入 Anthropic provider
这是 Claude 的推荐方式。必须先完成第 7.3 节,并且当前 Terminal 中仍然存在
ANTHROPIC_MODEL_ID。
如果你已有其他 provider 名称,可在执行前设置
ANTHROPIC_PROVIDER_ID;不设置时默认使用 my-relay-anthropic。
如果需要多个协议,分别执行已通过 curl 测试的方案。每段命令会写入独立 provider,不会把 Claude 放进 OpenAI provider,也不会把 Responses 模型误当成 Chat 模型;最后执行的方案会把对应模型设置为默认模型,之后仍可使用
--model 临时切换。
8.4 方案 C:用 Terminal 写入 OpenAI Responses provider(按需)
只有第 7.2 节返回 HTTP
200 且提取到最终文字时,才需要执行本节。不要因为模型名称中带有 openai 或 gpt,就跳过 Responses 测试。
如果你已有其他 provider 名称,可在执行前设置
RESPONSES_PROVIDER_ID;不设置时默认使用 my-relay-responses。
@ai-sdk/openai 和 @ai-sdk/openai-compatible 的模型 ID 可以相同,但它们不是同一个 runtime。Responses provider 不会替代 Chat provider;如果同一模型在两种协议下都成功,可以同时保留两个 provider。
8.5 手动编辑配置文件
如果你不希望使用 Terminal 写入命令,也可以用编辑器打开配置文件:
下面 JSON 是最小手动编辑示例。保存前,将示例模型 ID 换成第 7 节已经测试成功的模型;不要把不存在于自己目录的模型直接复制进去。
配置文件中不保存 API Key,OpenCode 会从环境变量
CLICKZETTA_API_KEY 读取令牌。
如果需要手动加入 Responses provider,请以第 8.4 节的
my-relay-responses 对象为准,作为第三个 provider 条目加入;不要把已有 my-relay 的 npm 改成 @ai-sdk/openai。
8.6 目录中出现但请求失败的模型
有些模型会出现在
/models,但实际请求仍可能返回 No upstream candidates、model_not_found 或 HTTP 502。这通常表示模型权限、协议路由或上游状态还没有准备好,不是 OpenCode 配置文件语法错误。
遇到这种情况,不要为了让模型出现在 OpenCode 列表中而继续保留它。先记录模型 ID、请求协议、HTTP 状态码和脱敏错误,联系中转站确认路由;只有对应协议返回最终文本后,再加入配置。
8.7 按自己的目录调整模型
当自己的模型目录与本文示例配置不同,只调整
models 对象,不要随意修改 provider runtime:
- OpenAI 目录没有的模型,从
删除;my-relay.models - Anthropic 目录没有的模型,从
删除;my-relay-anthropic.models - 同一个 Qwen 或 DeepSeek ID 如果多个协议都验证成功,可以分别放入对应 provider;
- 对本文示例网关,Claude 放入
,不要因为 ID 中有my-relay-anthropic.models
就直接放进anthropic/
;只有 Claude 同时出现在 OpenAI 认证视图,并且 Chat curl 与 OpenCode 调用都返回最终文本时,才可以额外配置 OpenAI Chat 路径;my-relay - 新增模型前必须先执行对应协议的 curl,并确认响应中有最终文本;
- 不要为了让模型出现在 OpenCode 列表中而伪造模型 ID,列表显示不等于实际可用。
**下一步:**保存 JSON 后,先做语法和 OpenCode 配置校验。
9. 校验 OpenCode 配置
9.1 校验 JSON 语法
没有任何输出且退出码为 0,表示 JSON 语法正确。
9.2 校验 OpenCode schema
正常情况下会输出解析后的配置,不能出现
Config validation failed、expected object、unknown key 等错误。
如果出现:
通常是把 provider 对象写成了字符串,或者把新版本
providers 格式和本版本 provider 格式混用。请检查 provider.my-relay 和 provider.my-relay-anthropic 是否都是 JSON 对象。
9.3 查看已配置 provider 的模型
如果你在第 8 节使用了自定义 provider ID,请把下面命令中的名称替换为实际 ID。
如果配置了 Responses provider,请删除最后一行开头的
# 后单独执行。
这些命令会列出你写入配置文件的模型。这里列出模型只代表配置已登记,不代表每个请求都成功,还要执行第 10 节的实际调用。
**下一步:**使用第 10 节的
opencode run 发送第一条消息。
10. 在 OpenCode 中实际调用
首次验证建议使用独立临时目录,避免 OpenCode 读取当前项目的代码、指令文件或会话上下文。在 Terminal 执行:
后面的首次测试命令都使用
--dir "$TEST_DIR"。这只改变测试工作目录,不会改变 OpenCode 的全局 provider 配置。
10.1 调用 OpenAI Chat provider
如果你使用了自定义 provider ID,请把命令中的
my-relay 替换为实际 ID。
下面使用
openai/gpt-5.5 作为示例。如果你的 API Key 的 OpenAI 目录没有这个 ID,请替换成自己目录中存在、并在第 7 节验证成功的 OpenAI Chat 模型;provider 写法不变。
成功时 JSON 中应有模型输出文本。
如果需要测试 DeepSeek,并且自己的目录中存在该模型,先把它加入
my-relay.models,再使用同样的 provider 写法:
10.2 调用 OpenAI Responses provider(按需)
只有已经执行第 7.2 节和第 8.4 节时,才运行此命令。把示例 ID 替换成你在
/responses 下得到最终文字的模型 ID。
如果这条命令成功,说明 OpenCode 已用
@ai-sdk/openai 通过 /responses 调用模型。若 curl 成功而此处失败,请回到第 12.2 节确认没有误用 Chat provider。
10.3 调用 Anthropic provider
如果你使用了自定义 provider ID,请把命令中的
my-relay-anthropic 替换为实际 ID。
下面使用
anthropic/claude-opus-5 作为示例。如果你的 API Key 没有该 Claude 权限,请替换成自己 Anthropic 目录中存在、并在第 7 节验证成功的 Claude ID;按照本文已经验证的路径,继续使用 my-relay-anthropic。
如果自己的 Anthropic 目录中有 Sonnet 或 Haiku,先把对应 ID 加入
my-relay-anthropic.models,再分别测试:
10.4 默认模型
配置文件中的:
表示未指定
--model 时使用 GPT-5.5。如果希望默认使用 Claude,改成:
修改后重新执行
opencode debug config,再重新运行命令。
10.5 配置完成后的效果和判断标准
完成配置后,你至少应看到一个自己有权限的模型返回最终文本。如果 API Key 同时有 OpenAI 和 Anthropic 模型权限,再分别检查下面两类结果:
如果两类调用都成功,说明:
- OpenCode 能读取配置文件;
- API Key 已通过环境变量传入;
- OpenAI Compatible Chat 路由可用;
- Anthropic Messages 路由可用;
- 至少一个 OpenAI 模型和一个 Claude 模型完成了端到端调用。
如果 API Key 没有 Claude 权限,只检查 OpenAI Chat;如果没有 OpenAI 模型,则只检查 Anthropic provider。不要为了满足示例而添加自己目录中不存在的模型。
这不说明所有模型都可用,也不说明所有高级能力都可用。其他模型必须按照第 11 节的厂商和协议规则选择 provider,并按第 7 节和本节命令单独检查。
**下一步:**按第 11 节的厂商和协议规则选择模型,不要只根据模型名称猜测协议。
11. 按厂商和协议选择模型
模型 ID 由中转站返回,厂商名称或 ID 前缀不能单独决定请求协议。配置时先确认模型属于哪类厂商,再根据该模型在你的目录和测试结果选择 provider。
下面的说明用于帮助你完成配置,不是固定模型清单。模型数量、版本和权限可能随 API Key、套餐和上游路由变化。
11.1 目录和请求结果怎么理解
| 状态 | 含义 | 下一步 |
|---|---|---|
| ✅ 成功 | HTTP 200,并且响应中有最终模型文本 | 可以在这个协议下配置 |
| ❌ 无上游 | HTTP 400,返回 | 检查模型 ID、协议、权限和路由 |
| ⚠️ 上游失败 | HTTP 502,返回 或 | 稍后重试,仍失败时联系中转站 |
| ⏳ 客户端等待 | OpenCode 持续等待或重试,没有返回最终模型文本 | 先用 curl 复现,再检查 provider |
| — 不在目录 | 当前认证方式对应的 中没有该模型 | 不要在这个协议下配置 |
“成功”必须同时满足 HTTP 200 和有最终文本。HTTP 200 但只有思考块、没有最终文本时,仍应继续检查输出预算和响应解析。
11.2 厂商类型与协议选择
| 厂商或模型类型 | OpenAI Chat | OpenAI Responses | Anthropic Messages | OpenCode provider | 配置原则 |
|---|---|---|---|---|---|
| OpenAI、Codex 等 OpenAI 系列 | 通常使用 | 只有该模型和网关明确提供时使用 | 通常不使用 | Chat 用 ;Responses 用 | 先按实际成功端点选择,不要把 OpenAI 模型放入 Anthropic provider |
| Anthropic Claude 系列 | 只有网关明确提供兼容路由且实测成功时使用 | 需要单独测试 | 本文示例网关的优先且已验证路径 | | 先测试 Anthropic Messages;ID 中的 不会自动切换协议 |
| DeepSeek 系列 | 可能使用 | 按模型和网关路由确认 | 可能使用 | 按实际成功协议选择 | Chat 成功不代表 Responses 成功;如果两个协议都成功,可以分别配置 |
| Qwen 系列 | 可能使用 | 按模型和网关路由确认 | 可能使用 | 按实际成功协议选择 | 以自己的 和最小请求结果为准 |
| 其他厂商或自定义模型 | 不能推断 | 不能推断 | 不能推断 | 按协议单独配置 | 不要根据厂商名称或模型前缀猜测协议 |
这里的“通常”表示常见适配方式,不是自动路由规则。每个模型仍需以自己的目录、协议请求和 OpenCode 调用结果为准。
11.3 OpenCode 配置写法
模型引用始终使用下面的格式:
常见写法:
最后两个示例只有在 DeepSeek 分别通过 OpenAI Chat 和 Anthropic Messages 成功时才同时成立。以下写法不会自动改变协议:
11.4 选择模型的实际步骤
对每个准备使用的模型,按以下顺序操作:
- 确认模型 ID 出现在对应认证方式的
中;/models - 用第 7 节的 OpenAI Chat、Responses 或 Anthropic Messages 请求测试;
- 只有 HTTP 200 且有最终文本时,才把模型放入对应 provider;
- 使用第 10 节的
进行实际调用;opencode run - OpenCode 失败时,先用同一模型、同一协议的 curl 对照,判断是网关问题还是客户端配置问题。
11.5 Claude 模型 ID 的写法
Claude 版本号和标点是路由键的一部分,必须原样复制:
下面只展示写法示例,不代表 Claude 只有这些版本。请以自己的 Anthropic
/models 返回值为准。
错误的连字符版本会返回
No upstream candidates,不是 OpenCode 的 Claude 功能缺失。
11.6 OpenCode 能力边界
本文配置覆盖三种请求方式,其中 Responses 是按需配置:
| 能力 | 配置方式 | 说明 |
|---|---|---|
| OpenAI Compatible Chat | + | 请求 |
| OpenAI Responses | + | 请求 ,仅在第 7.2 节和第 8.4 节均完成后使用 |
| Anthropic Messages | + | 请求 ,Claude 使用此方式 |
模型能否调用,应该这样理解:
- “目录中出现”表示 API Key 能看到模型 ID;
- “协议调用成功”表示该模型在某一个协议下返回最终文本;
- “OpenCode 调用成功”表示对应 provider、模型 ID 和客户端参数组合可以工作;
- 以上结论只适用于对应协议,不会自动推广到其他协议;
- 文本调用成功,不代表工具调用、流式、多模态、结构化输出、缓存、长上下文或思考参数都可用。
因此,对本文示例网关,Claude 优先使用
my-relay-anthropic;配置 OpenAI 系列时,Chat 用 my-relay、Responses 用 my-relay-responses;DeepSeek、Qwen 或其他模型则根据第 11.2 节和实际测试结果选择 provider。未来如果网关为 Claude 增加其他协议路由,也必须重新完成目录、curl 和 OpenCode 三层验证。
**下一步:**需要进一步了解协议字段时,阅读第 12 节;遇到错误时进入第 13 节。
12. OpenCode 的请求协议限制
12.1 三种协议的硬性差异
协议不能只修改 URL 后继续沿用另一种请求体。客户端必须同时匹配端点、认证头、请求结构和响应解析方式。
| 项目 | OpenAI Chat Completions | OpenAI Responses | Anthropic Messages |
|---|---|---|---|
| 端点 | | | |
| 认证头 | | | |
| 必要版本头 | 无 | 无 | |
| 输入字段 | 、 | 、 | 、,系统提示通常放顶层 |
| 常见最终文本 | | 或 | 中 的 |
| 本文 OpenCode provider | | ,按第 8.4 节配置 | 使用 Messages |
必须遵守:
中的anthropic/claude-opus-5
只是模型 ID 的一部分,不会自动选择 Anthropic runtime;anthropic/
仍走 OpenAI Chat;如果该模型没有通过 Chat 验证,不应使用此写法;my-relay/anthropic/claude-opus-5
会走本文已经验证的 Anthropic Messages 路径;my-relay-anthropic/anthropic/claude-opus-5
和Authorization: Bearer
会得到不同模型视图,不能只查询一次x-api-key + anthropic-version
;/models- Chat 成功不代表 Responses 成功;同一个模型需要分别测试;
- Anthropic Messages 成功不代表 OpenAI Chat 成功;Claude 通常应使用 Anthropic provider;
- AI Gateway 不保证自动把 OpenAI
转成 Anthropictool_calls
,也不保证反向转换。tool_use
12.2 Responses 必须使用独立 provider
my-relay 使用的是:
它不会因为某个模型在
/v1/responses 成功,就自动改变为 Responses。若需要使用 Responses,必须先完成第 7.2 节的标准 curl,再按第 8.4 节配置 my-relay-responses 和 @ai-sdk/openai。不能把现有 my-relay 当作 Responses provider。
12.3 OpenCode 不自动回退
一次调用选定 provider 后,请求协议固定:
需要切换协议时,必须显式选择另一个 provider;需要切换模型时,必须显式填写另一个精确 ID。
12.4 SDK 可能改变请求参数
OpenCode 通过 AI SDK runtime 组装请求。即使裸 curl 成功,客户端仍可能因为自动添加思考、工具、结构化输出或流式相关字段而出现差异。
本文只要求最小文本请求成功,不等于以下能力都已确认:
- streaming 流式输出;
- tool calling / function calling;
- JSON schema 或严格结构化输出;
- 图像、文件和多模态输入;
- prompt caching;
- 长上下文接近上限时的行为;
- 模型特定的思考预算字段。
例如某些客户端给请求加入不被中转站接受的
thinking_budget,可能返回参数校验错误。遇到此类问题,先用第 7 节的最小 curl 复现,再逐个减少客户端高级参数。
12.5 配置上限不是服务端承诺
示例中的:
只是告诉 OpenCode 如何估算上下文和输出预算。它不能扩大模型实际能力、账号额度或中转站限制,也不能保证所有模型都支持相同的工具、图像或思考能力。
**下一步:**如果请求失败,按第 13 节从网络、认证、协议、模型和 provider 逐层排查。
13. 常见错误与定位顺序
13.1 先看错误属于哪一层
建议按以下顺序定位:
13.2 错误对照表
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
、连接超时 | DNS、网络、代理或 VPN | 先访问 Base URL,检查公司网络和 VPN;这不是模型路由结论 |
HTTP 或 | API Key 错误、过期或无权限 | 重新生成 Key,确认当前 Terminal 使用的是同一 Key,不要把 Key 发出来 |
| 模型 ID 不存在、协议不匹配、账号无该上游权限 | 重新执行对应协议的 ,核对 provider 和精确 ID |
| ID 拼写或点号/连字符错误 | 复制实时目录的完整 ID;Claude 使用 、,不要改成 、 |
HTTP 、 或 | 上游暂时故障、网关没有候选或模型未路由 | 先用另一个已知成功模型重试,再将错误时间和请求 ID 提供给中转站 |
| OpenAI Chat 成功、Responses 失败 | 两个端点的上游路由不同 | 不要在 OpenCode 中把 Chat provider 当 Responses provider;单独验证和配置 |
| Anthropic 成功、OpenAI 失败 | 当前模型只开放或只验证了 Anthropic 路由 | 使用 ;不要在 Chat 未验证时使用 |
配置报 | provider 被写成字符串或格式混用 | 检查 是对象;OpenCode 使用单数 |
| OpenCode 列表有模型但调用失败 | 列表只是注册信息,或 provider/runtime 不匹配 | 先做标准 curl,再用相同 provider 做最小 OpenCode 调用 |
| HTTP 200 但看不到最终文本 | 输出预算过小、只返回思考块或解析字段不对 | 先提高到 ,必要时提高到 ;仍无最终文本时不能标记为可用 |
| 多个 OpenCode 进程同时访问本地状态数据库 | 等待正在运行的 OpenCode 命令结束,再串行重试;这不是网关或模型错误 |
13.3 No upstream candidates
的判断方法
No upstream candidates按以下顺序执行:
然后分别用第 7 节的请求测试同一个模型:
如果正确的模型 ID 在正确协议下仍然失败,才需要让中转站检查上游候选、账号权限和路由配置。不要通过不断修改 provider 名称或在模型 ID 中添加后缀来“碰运气”。
13.4 如何区分 VPN 问题和模型问题
**下一步:**确认问题层级后,阅读第 14 节了解使用边界和提交问题所需信息。
14. 如何判断产品支持范围
模型是否能在 OpenCode 中使用,不只取决于模型名称,还取决于 API Key 权限、请求协议、provider 配置和上游路由。遇到不同模型时,可以用下面的方式判断:
14.1 四种结果分别代表什么
| 看到的结果 | 表示什么 | 下一步 |
|---|---|---|
中没有模型 | 当前 API Key 或协议视图没有提供该模型 | 检查认证头、权限和模型 ID,不要强行加入配置 |
中有模型 | 当前 API Key 能看到该模型 ID | 继续执行对应协议的 curl |
| curl 返回 HTTP 200 且有最终文本 | 该模型在这个协议下可以进行最小文本调用 | 使用同一协议对应的 OpenCode provider |
| curl 成功但 OpenCode 失败 | 客户端 provider、SDK 参数或模型登记方式不匹配 | 对照第 12 节检查 provider 和请求参数 |
14.2 使用产品时需要遵守的边界
- Base URL 必须使用中转站提供的地址,并确认是否已经包含
;/v1 - OpenAI 和 Anthropic 的认证头不同,不能混用;
代表 OpenAI Compatible Chat,my-relay
代表 OpenAI Responses,my-relay-responses
代表 Anthropic Messages;my-relay-anthropic- 本文示例网关的 Claude 优先使用 Anthropic Messages;模型 ID 中出现
不会自动切换协议;anthropic/ - Responses 必须按第 8.4 节配置独立 provider,不能把 Chat provider 当成 Responses provider;
- 模型在某个协议下成功,不代表在其他协议下也成功;
- 最小文本调用成功,不代表工具、流式、多模态、结构化输出、缓存、长上下文或思考参数都可用;
- 模型名称、版本号和标点必须与
返回值完全一致。/models
14.3 提交问题时应提供什么
如果按照本文仍然失败,无需提供 API Key。请提供以下脱敏信息:
- OpenCode 版本:
;opencode --version - 使用的 provider ID:例如
或my-relay
;my-relay-anthropic - 模型 ID;
- 使用的协议:OpenAI Chat、Responses 或 Anthropic Messages;
- HTTP 状态码;
- 请求时间和 request ID;
- 脱敏后的错误摘要;
是否通过。opencode debug config
不要直接粘贴完整的
opencode run --format json 错误输出。除完整的 Authorization、x-api-key、Cookie、请求体和真实令牌外,还应删除或替换以下内容:
、virtualApiKeyAlias
等租户信息;tenantId- 上游供应商名称、上游 Base URL 和账号别名;
、内部路由编号和完整重试历史;endpoint_id- 完整
,其中可能再次嵌套上述信息。responseBody
request ID 通常可以保留,用于支持人员查询服务端日志。支持人员会根据版本、时间、模型、协议、HTTP 状态和 request ID 判断网络、权限或上游路由问题。
**下一步:**完成第 15 节安全检查,再用第 16 节清单逐项确认。
15. 安全与日常运维
15.1 API Key 安全
- 不要把 Key 写入
;opencode.json - 不要把 Key 写入命令参数、聊天记录、工单、截图或 Git;
- 不要在排查时执行
、env
或set
;echo "$CLICKZETTA_API_KEY" - 分享日志前,删除
、Authorization
、Cookie、租户信息、上游地址、内部端点编号、完整重试历史和请求体中的敏感字段;x-api-key - 不要直接分享
的完整错误事件,先按第 14.3 节整理为脱敏摘要;opencode run --format json - 怀疑泄露时立即在中转站后台撤销并重新生成 Key。
**下一步:**完成第 16 节的最终成功检查。
15.2 配置备份和恢复
修改前备份:
恢复时先确认目标文件路径,再覆盖当前配置。恢复后必须重新执行:
15.3 什么时候需要重新验证
以下情况发生后,应重新执行
/models、curl 和 OpenCode 最小文本测试:
- 中转站更换 Base URL 或网关版本;
- API Key 权限、套餐或上游账号变化;
- 模型版本号或模型 ID 变化;
- OpenCode 或 AI SDK runtime 升级;
- 出现持续的
、502
或输出格式异常。No upstream candidates
16. 最终成功检查表
逐项确认:
-
能返回版本;opencode --version -
已加载,但没有写进配置文件;CLICKZETTA_API_KEY -
只包含一个RELAY_BASE_URL
;/v1 - 已查询自己的 OpenAI 和 Anthropic
,没有盲目复制本文示例模型;/models - OpenAI
已按自己的 API Key 确认 OpenAI/DeepSeek/Qwen 视图;/models - Anthropic
已按自己的 API Key 确认 Qwen、DeepSeek 和 Claude 权限范围;/models -
使用my-relay
;@ai-sdk/openai-compatible - 如使用 Responses,
使用my-relay-responses
;@ai-sdk/openai -
使用my-relay-anthropic
;@ai-sdk/anthropic -
通过;jq empty -
通过;opencode debug config - 每个已配置 provider 都能通过
列出模型;opencode models <provider-id> - 首次实际调用使用了独立临时目录,没有在业务项目目录中直接测试;
- 至少一个自己目录中的 OpenAI Chat 模型实际调用成功;
- 如使用 Responses,至少一个 Responses 模型通过
实际调用成功;my-relay-responses - 如果 API Key 有 Claude 权限,至少一个 Claude 模型通过
实际调用成功;my-relay-anthropic - 每个准备使用的模型都在自己的对应协议目录中,并完成了最小文本请求;
- Claude 使用点号版本 ID,而不是连字符版本 ID;
- 没有把 OpenCode 的 Chat provider 当成 Responses provider;
- 最小文本测试成功,没有把未确认的工具、流式、多模态能力当成已支持。
17. 一键复查命令
下面命令不会打印 API Key,可在排查时依次执行:
最小实际调用:
下面命令使用示例模型。如果自己的实时目录没有对应 ID,请替换为同一协议下已经验证成功的模型;不要因为模型 ID 不同,就修改 provider runtime。第三条仅在你已配置并验证 Responses provider 时执行。
如果已配置的模型都返回实际文本,说明 OpenCode 已通过相应协议接入中转站。其他模型仍应按照第 11 节的厂商和协议规则选择 provider。
18. 结论
OpenCode 接入中转站的核心不是“把 Base URL 填进去”,而是同时满足以下关系:
配置时可以先记住三条:
Claude 一般使用 Anthropic Messages;OpenAI 系列使用 Chat 或 Responses 时分别使用对应 runtime;DeepSeek、Qwen 和其他厂商模型需要根据自己的目录和协议测试结果选择 provider。任何新模型或新协议都应先经过
/models、标准 curl、OpenCode 实际调用三层检查,再投入使用。
19. 相关资料
- OpenCode Providers 官方文档:自定义 OpenAI Compatible provider、Anthropic provider、
和模型配置。baseURL - OpenCode Config 官方文档:配置文件、默认模型和 provider 配置项。
- OpenCode 官方下载页面:安装脚本、npm、Homebrew 等安装方式。
