0%

OpenClaw 接入 OpenCode Go 模型实战:从踩坑到最佳实践

OpenClaw 接入 OpenCode Go 模型实战:从踩坑到最佳实践

摘要:OpenCode Go 是一个低价的开放编码模型订阅($5 首月,之后 $10/月),一份 key 就能用上 GLM-5.2、Kimi、MiniMax、DeepSeek、Qwen 等一票模型。把它接入 OpenClaw 看起来只是填几行 JSON,但实际配置时我连续踩了好几个坑——provider 拼接、代理注入、systemd 环境隔离,层层叠加,排查了一整个上午。本文把整个过程沉淀成一份可直接照抄的最佳实践,顺便记录排查思路,方便后来人少走弯路。

关键词:OpenClaw、OpenCode Go、模型配置、GLM-5.2、MiniMax M3、代理配置、systemd、fallback 容灾


一、两条 API 线:别用错协议

OpenCode Go 的模型分属两种 API 协议,必须配成两个独立 provider,不能混在一起:

  • OpenAI 兼容线openai-completions):GLM、Kimi、DeepSeek、MiMo 系列,端点是 /v1/chat/completions
  • Anthropic 兼容线anthropic-messages):MiniMax、Qwen 系列,端点是 /v1/messages

哪个模型走哪条线,以官方 /v1/models 返回和 Endpoints 文档为准,不要凭名字猜。

二、最关键的坑:baseUrl 与自动拼接

这是全程最隐蔽、也最浪费时间的一个点。

OpenClaw 会在 baseUrl 后面自动追加端点后缀,而且两条线追加的后缀不一样:

  • openai-completions 追加 chat/completions
  • anthropic-messages 追加 v1/messages

所以 baseUrl 要写成”拼接后正好是完整 URL”的形式。最终验证过能用的写法是:

1
2
3
4
5
"opencode-go": {
"api": "openai-completions",
"baseUrl": "https://opencode.ai/zen/go/v1/",
"apiKey": "${OPENCODE_API_KEY}"
}
1
2
3
4
5
"opencode-go-anthropic": {
"api": "anthropic-messages",
"baseUrl": "https://opencode.ai/zen/go/",
"apiKey": "${OPENCODE_API_KEY}"
}

注意两个 baseUrl 不一样

  • OpenAI 线:.../zen/go/v1/ + chat/completions = .../zen/go/v1/chat/completions
  • Anthropic 线:.../zen/go/ + v1/messages = .../zen/go/v1/messages

如果照搬官方 Endpoints 文档里给的完整 URL(比如把 anthropic 线的 baseUrl 写成 .../v1/messages),OpenClaw 会再补一次,拼成 .../v1/messages/v1/messages,请求落空,等满 120 秒超时后才 fallback。

判断对错的唯一标准:看日志里的实际请求 URL。出问题时日志会打印类似:

1
[fetch-timeout] url=https://opencode.ai/zen/go/v1/messages/v1/messages

一眼就能看出 /v1/messages 重复了。URL 干净单次,就是对的。

三、模型 ID 以 /v1/models 为准

配置里写的模型 ID 必须和服务端完全一致,否则触发时 404。最稳的做法是直接拉官方列表核对:

1
2
curl -s -x http://127.0.0.1:7890 https://opencode.ai/zen/go/v1/models \
-H "x-api-key: ${OPENCODE_API_KEY}" | jq -r '.data[].id' | sort

一个典型的坑:Kimi 的实际 ID 是 kimi-k2.7-code不是 kimi-k2.7。差一个后缀就调不通。

四、按”费用 + 能力”分级配模型

OpenCode Go 的额度是按美元计($12/5小时、$30/周、$60/月),所以越便宜的模型能跑越多请求。配置时把模型分三档:

主力(日常高频):选性价比最高的。MiniMax M3 是不错的选择——价格低(输入 $0.30 / 输出 $1.20 每百万 token),又是 Anthropic 协议原生,工具调用稳定。

攻坚(难任务手动切):复杂推理、重构时手动指定高能力模型,如 GLM-5.2 或 DeepSeek V4 Pro。单次贵但用得少。DeepSeek 系列的缓存读价格($0.0145)极低,对重复上下文的 agentic 负载尤其划算。

兜底(fallback):fallback 的目的是”别断”,不是”更强”。所以选最便宜的保证有响应,如 DeepSeek V4 Flash(输入 $0.14 / 输出 $0.28)。

fallback 链的设计原则:跨线容灾 + 便宜保底

一条好的 fallback 链应该遵循”主模型 → 同线备份 → 切到另一条 API 线 → 最便宜模型保底”:

1
2
3
4
5
6
7
8
"model": {
"primary": "opencode-go-anthropic/minimax-m3",
"fallbacks": [
"opencode-go-anthropic/minimax-m2.7",
"opencode-go/glm-5.2",
"opencode-go/deepseek-v4-flash"
]
}

关键在第二跳切换 API 线:主模型走 Anthropic 线,fallback 跳到 OpenAI 线。这样即使整条 Anthropic 端点出问题,也能切到 OpenAI 线,不会一起死。

反面教材:把 fallback 全指向同一个已过期/不可用的 provider。一旦主模型抖动,就会沿着死链一个个超时重试,每个卡几秒甚至 120 秒,用户那头长时间无响应。这是排查时遇到的真实场景——fallback 全是过期的订阅,日志里刷了一屏的鉴权失败。

按 agent 性质分配 primary

不同 agent 的任务性质不同,primary 也该区别对待:

  • 通用助手 / IM 对接 → MiniMax M3(便宜、对话与工具调用均衡)
  • 运维 / 执行类 → DeepSeek V4 Pro(推理强、容错要求高)
  • 写作类 → GLM-5.2(中文写作能力强)
  • 纯代码 → Kimi K2.7 Code(代码专用模型)

能力分级只是基于模型家族定位和价格信号的经验估计,确切效果建议按自己的任务实测一段时间,再结合控制台账单微调。

五、代理与环境变量:systemd 隔离的大坑

这是第二个吃了大亏的地方。现象是:在 shell 里 curl 测试一切正常,但 OpenClaw 服务里就是超时

根因有两层:

1. OpenClaw 走出站代理,curl 直连

国内访问 opencode.ai 这类海外服务通常要走代理。你的交互式 shell 里有代理环境变量(http_proxy 等),所以 curl 能通;但 OpenClaw 进程不一定继承了这些变量,于是直连海外、连不上、超时。

验证方法——对比 shell 和进程各自的代理变量:

1
2
3
4
5
# 你的 shell
env | grep -i proxy

# OpenClaw 进程(PID 换成实际值)
cat /proc/<PID>/environ | tr '\0' '\n' | grep -i proxy

如果 shell 有、进程没有,根因就在这里。

2. systemd user service 不继承登录环境

如果 OpenClaw 是用 systemd user service 启动的(systemctl --user),它默认不继承你登录 shell 的环境变量。这同时解释了为什么代理变量和 API key 都”丢了”——它们都在 shell 里,但进程里没有。

3. socks5 的额外陷阱

很多人用 Clash,代理写成 socks5://127.0.0.1:7890。但 Node 的原生 fetch(undici)默认不支持 socks5,只认 http/https 代理。好在 Clash 的混合端口(常见 7890)同时支持 http,所以给 OpenClaw 配 http 代理即可:

1
2
curl -x http://127.0.0.1:7890 https://opencode.ai/zen/go/v1/models \
-H "x-api-key: ${OPENCODE_API_KEY}"

这条通了,就用 http:// 前缀的代理喂给服务。

正确的注入方式

用 systemd 的 EnvironmentFile 统一管理代理和 key,既能注入进程,又把敏感信息从主配置里隔离出来:

1
2
3
4
5
6
7
8
# 创建独立 env 文件,600 权限只有自己能读
cat > ~/.openclaw/.env <<'EOF'
OPENCODE_API_KEY=your-key-here
https_proxy=http://127.0.0.1:7890
http_proxy=http://127.0.0.1:7890
no_proxy=localhost,127.0.0.1,.aliyuncs.com,.volces.com,dashscope.aliyuncs.com
EOF
chmod 600 ~/.openclaw/.env

EnvironmentFile 用纯 KEY=value 格式,不要加 export,不要加引号。

然后让 service 引用它:

1
systemctl --user edit openclaw-gateway.service
1
2
[Service]
EnvironmentFile=/home/johnzok/.openclaw/.env
1
2
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service

别忘了 no_proxy

如果同时还配了国内的 provider(火山引擎、阿里云百炼等),一定要把它们的域名加进 no_proxy,否则这些请求会绕代理出海再回来,变慢甚至失败。

API key 安全

配置文件里始终用 ${OPENCODE_API_KEY} 占位符,真实 key 只放在 600 权限的 env 文件里。这样主配置可以安全备份、分享、排查,不会泄露 key。如果排查过程中 key 不慎暴露,第一时间去控制台吊销重置。

六、排查方法论:逐环节验证

整个链路涉及多个环节,任何一环断了都会”没响应”。有效的排查思路是自底向上逐环节验证,而不是盲改配置:

  1. API key 有效吗? → 直接 curl 测端点
  2. 走哪种鉴权? → OpenAI 线用 Authorization: Bearer,Anthropic 线用 x-api-key,别用混了
  3. 端点本身通吗? → 分别 curl /v1/chat/completions/v1/messages
  4. 进程里有 key 和代理吗? → 查 /proc/<PID>/environ
  5. URL 拼对了吗? → 看日志里的实际请求 URL
  6. fallback 链健康吗? → 确认没有指向失效 provider

每验证一环,就排除一个可能性。这个问题最终定位到的是两个独立问题叠加(baseUrl 拼接 + 代理未注入),正因为是叠加,才特别容易误判——修好一个还不通,容易以为方向错了。逐环节验证能避免这种迷惑。

七、完整配置参考

两个 provider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"opencode-go": {
"api": "openai-completions",
"baseUrl": "https://opencode.ai/zen/go/v1/",
"apiKey": "${OPENCODE_API_KEY}",
"models": [
{ "id": "glm-5.2", "name": "GLM 5.2", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "glm-5.1", "name": "GLM 5.1", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "kimi-k2.7-code", "name": "Kimi K2.7 Code", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "kimi-k2.6", "name": "Kimi K2.6", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "deepseek-v4-pro", "name": "DeepSeek V4 Pro", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "deepseek-v4-flash", "name": "DeepSeek V4 Flash", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "mimo-v2.5", "name": "MiMo V2.5", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "mimo-v2.5-pro", "name": "MiMo V2.5 Pro", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] }
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
"opencode-go-anthropic": {
"api": "anthropic-messages",
"baseUrl": "https://opencode.ai/zen/go/",
"apiKey": "${OPENCODE_API_KEY}",
"models": [
{ "id": "minimax-m3", "name": "MiniMax M3", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "minimax-m2.7", "name": "MiniMax M2.7", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "minimax-m2.5", "name": "MiniMax M2.5", "reasoning": true, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "qwen3.7-max", "name": "Qwen 3.7 Max", "reasoning": false, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "qwen3.7-plus", "name": "Qwen 3.7 Plus", "reasoning": false, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] },
{ "id": "qwen3.6-plus", "name": "Qwen 3.6 Plus", "reasoning": false, "contextWindow": 512000, "maxTokens": 65536, "input": ["text", "image"] }
]
}

agent 模型分级示例:

1
2
3
4
5
6
7
8
"model": {
"primary": "opencode-go-anthropic/minimax-m3",
"fallbacks": [
"opencode-go-anthropic/minimax-m2.7",
"opencode-go/glm-5.2",
"opencode-go/deepseek-v4-flash"
]
}

小结

接入 OpenCode Go 本身不难,真正的坑集中在三处:

  1. baseUrl 要配合 OpenClaw 的自动拼接,两条 API 线追加的后缀不同,以日志里的实际 URL 为准
  2. systemd user service 不继承 shell 环境,代理和 key 都要显式注入(用 EnvironmentFile 最干净),且 socks5 要换成 http 代理
  3. fallback 链要跨线容灾 + 便宜保底,别让失效 provider 拖垮整条链

把这三点配对,加上”逐环节验证”的排查习惯,就能稳定地把这套低价模型订阅跑起来。


本文涉及 OpenClaw 的安装、配置与多 Agent 协作实践。 如果你在企业 AI 落地过程中遇到类似的模型选型、Agent 配置或部署运维问题,欢迎查看我的企业 AI Agent 咨询服务,或了解 PR 审查官——多 Agent 协作的 GitHub PR 自动审查方案。也可前往关于我页面获取联系方式,交流探讨。