Claude code修复openclaw
手搓部署OpenClaw死活用不了,放了两个月,用Claude code完美修复
症状:网页对话「三颗闪烁,永远无回复」— 一次完整的 API 配置排错实录
折腾了两小时,踩了五个坑,终于把 OpenClaw 的中文社区版跑通了。全程记录如下。
一、症状
OpenClaw(openclaw-cn)服务正常启动,浏览器访问 http://127.0.0.1:18789 也能加载出控制台页面。进入聊天界面后:
·能发送消息 ✅
·永远收不到回复 ❌
·输入框上方三颗点一直闪烁(loading 动画)
按 F12 打开开发者工具,Console 里有一个 CSP 报错(Google Fonts 被拦截),但这是无害的,和聊天功能无关。Network → WS 面板显示 WebSocket 连接正常,心跳包也在收发。
也就是说,前端和网关之间的通信没断,但 AI 回复永远不到。
二、第一轮排查:怀疑 API Key
OpenClaw 是开源的 AI 网关,它本身不跑模型,而是把请求转发到各家大模型厂商的 API。最先想到的自然是——是不是 Key 配错了。
查看 CC模型管理器的 config.json,配置了两套 DeepSeek:
|
用途 |
端点 |
Key |
|
Claude Code(主) |
api.deepseek.com/anthropic |
sk-122e…44b3 |
|
Codex |
api.deepseek.com/v1 |
sk-3539…f9f0 |
用 curl 直接打这两个 Key:
# Anthropic 兼容端点
curl -X POST “https://api.deepseek.com/anthropic/v1/messages” \
-H“x-api-key: sk-122e…44b3” \
-d‘{“model”:”deepseek-v4-pro”,”max_tokens”:50,”messages”:[{“role”:”user”,”content”:”say hello”}]}’
# OpenAI 兼容端点
curl -X POST “https://api.deepseek.com/v1/chat/completions” \
-H“Authorization: Bearer sk-3539…f9f0” \
-d‘{“model”:”deepseek-v4-pro”,”max_tokens”:50,”messages”:[{“role”:”user”,”content”:”say hello”}]}’
两个都返回了正常回复 💬。Key 没问题。
三、第二轮排查:发现真正的配置入口
CC模型管理器的 config.json 管的是 Claude Code,跟 OpenClaw 没有半毛钱关系。
OpenClaw 有自己独立的配置体系,位于 ~/.openclaw/:
~/.openclaw/
├── openclaw.json# 全局配置
├── agents/
│└── main/
│├── agent/
││├── auth-profiles.json# Agent 级别的认证配置
││└── models.json# 模型定义
│└── sessions/
│└── sessions.json# 会话状态
打开 openclaw.json,发现默认配置的是 MiniMax:
{
“auth”:{
“profiles”:{ “minimax:default”: { “provider”: “minimax”, “mode”: “api_key” } },
“order”:{ “minimax”: [“sk-api–OgFr9cKOKC****2Ra5t0sLDCr-…”] }
},
“models”:{
“providers”:{
“minimax”:{ “baseUrl”: “https://api.minimax.chat/v1”, “api”: “openai-completions”, … }
}
},
“agents”:{
“defaults”:{ “model”: { “primary”: “minimax/MiniMax-M2.5” } }
}
}
测试 MiniMax Key:
curl -X POST “https://api.minimax.chat/v1/chat/completions” \
-H“Authorization: Bearer sk-api–OgFr9cK…” \
-d‘{“model”:”MiniMax-M2.5″,”max_tokens”:50,”messages”:[{“role”:”user”,”content”:”say hi”}]}’
返回:
{“type”:”error”,”error”:{“type”:”insufficient_balance_error”,”message”:”insufficient balance (1008)”}}
破案了——MiniMax 余额不足。 这就是为什么发消息永远收不到回复。
四、第三轮排查:切到 DeepSeek,还是不行
既然 MiniMax 欠费,那就切成 DeepSeek。把 openclaw.json 里的 provider、model、auth 全改成 DeepSeek。
重启网关,访问页面,发送消息——还是三颗点。
打开 F12 Console,这次看到了真正的错误:
disconnected (1008): unauthorized: gateway token missing
OpenClaw 的网关配置了 Token 认证。需要用带 Token 的 URL 访问:
http://127.0.0.1:18789/?token=d3db369ee0ab8fa0762*******0b3b2d3886980d04
Token 认证通过后,再进聊天页面,依然是三颗点。
五、第四轮排查:终极大 Boss
这次仔细看了网关的 verbose 日志,一行关键错误藏在里面:
Embedded agent failed before reply:
No API key found for provider “deepseek”.
Auth store: ~\.openclaw\agents\main\agent\auth-profiles.json
明明 auth-profiles.json 里写了 Key,为什么说找不到?
直接去看 OpenClaw 源码 dist/agents/auth-profiles/oauth.js,找到了 resolveApiKeyForProfile 函数:
export async function resolveApiKeyForProfile(params) {
constcred = store.profiles[profileId];
//…
if(cred.type === “api_key”) {
constkey = cred.key?.trim();
if(!key) return null;
return{ apiKey: key, provider: cred.provider };
}
//…
}
关键判断是 cred.type === “api_key”。
再回头看我的 auth-profiles.json:
{
“profiles”:{
“deepseek:default”:{
“mode”:“api_key”,// ← 这里写的是 mode!
“provider”:“deepseek”,
“key”:“sk-122e…”
}
}
}
字段名应该是 `type`,我写成了 `mode`。
为什么我会写 `mode`?因为全局配置 `openclaw.json` 里用的是 `mode`。但 Agent 级别的 auth-profiles.json 用的是 `type`。两个配置文件格式不一致,是 OpenClaw 的设计问题,但也确实是个容易踩的坑。
还有一个坑:order 字段。全局配置的 auth.order 存的是裸 Key 数组,Agent 级别的 order 存的应该是 Profile ID 数组。
|
配置层级 |
order 内容 |
|
openclaw.json |
[“sk-xxx…”](裸 Key) |
|
auth-profiles.json |
[“deepseek:default”](Profile ID) |
六、完整修复
最终正确的 auth-profiles.json:
{
“version”:1,
“profiles”:{
“deepseek:default”:{
“type”:“api_key”,
“provider”:“deepseek”,
“key”:“sk-*2ec*****93aa*****16****4***”
}
},
“order”:{
“deepseek”:[
“deepseek:default”
]
},
“lastGood”:{
“deepseek”:“deepseek:default”
},
“usageStats”:{}
}
同时更新全局 openclaw.json:
{
“auth”:{
“profiles”:{ “deepseek:default”: { “provider”: “deepseek”, “mode”: “api_key” } },
“order”:{ “deepseek”: [“sk-*2ec*****93aa*****16****4***”] }
},
“models”:{
“providers”:{
“deepseek”:{
“baseUrl”:“https://api.deepseek.com/v1”,
“api”:“openai-completions”,
“models”:[{ “id”: “deepseek-chat”, “reasoning”: false, … }]
}
}
},
“agents”:{
“defaults”:{ “model”: { “primary”: “deepseek/deepseek-chat” } }
}
}
清空旧会话,重启网关,终于正常回复了 🎉。
七、总结
一个看似「发消息没回复」的简单问题,背后踩了五个坑:
|
序号 |
坑 |
教训 |
|
1 |
搞混 CC模型管理器配置和 OpenClaw 配置 |
先搞清楚谁是真正的配置入口 |
|
2 |
MiniMax 余额不足被静默忽略 |
直接 curl 测试 API 可以快速排除 |
|
3 |
网关 Token 认证拦截 WebSocket |
看 F12 Console 的 WebSocket 错误码 |
|
4 |
type 和 mode 两个配置文件用不同字段名 |
读源码是终极手段 |
|
5 |
order 在两层配置中语义不同 |
不要想当然地复制粘贴 |
排错心法:逐层验证。
API Key → curl 打一下 / 网关进程 → –verbose 看日志 / 代码逻辑 → 直接读 dist/*.js。每一步都在缩小问题范围,而不是瞎猜。
本文适用于 `openclaw-cn` v0.1.7,其他版本配置格式可能不同。
夜雨聆风