乐于分享
好东西不私藏

Claude code修复openclaw

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,其他版本配置格式可能不同。