这是 OpenClaw 部署系列的第二篇。上一篇我记录了从零开始安装、配置局域网访问的全过程。本以为大功告成,结果模型调用始终返回 404。折腾了一整天,最后发现只是少了一个
/v1。这篇文章记录这个“致命细节”的发现过程,以及最终的正确配置。
📌 前情回顾
上一篇文章里,我成功地在 Ubuntu 虚拟机里装好了 OpenClaw,配置好了网关,甚至能从局域网访问 Web 界面。但卡在了最后一步:模型调用返回 404。
现象是这样的:
- 在 Ubuntu 里直接 curl Ollama 的 OpenAI 兼容端点:✅ 成功返回 JSON
- 在 OpenClaw 的 TUI 里发消息:❌ 一直报
HTTP 404: 404 page not found
日志里反复出现这行:
[agent/embedded] embedded run agent end: ... error=HTTP 404: 404 page not found
明明 curl 能通,OpenClaw 却调不通,说明问题出在配置细节上。
🔍 排查过程
第一步:确认 Ollama 的 OpenAI 兼容模式是否开启
我在 Windows 上用 Docker 启动 Ollama 时,已经加了环境变量:
docker run -d --gpus all `
-v ollama:/root/.ollama `
-p 11434:11434 `
-e OLLAMA_HOST=0.0.0.0 `
-e OLLAMA_OPENAI_COMPAT=1 ` # ← 这个就是关键
--name ollama `
ollama/ollama
用 curl 验证:
curl http://192.168.175.1:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "qwen2.5:7b", "messages": [{"role": "user", "content": "hi"}]}'
返回了正常的 JSON 响应,说明 Ollama 端没问题。
第二步:检查 OpenClaw 配置
一开始我是这样配的(网上很多教程也是这么写的):
"ollama": {
"baseUrl": "http://192.168.175.1:11434", // ← 没有 /v1
"api": "openai-completions",
"models": [...]
}
直觉告诉我,OpenClaw 应该会自动拼接 /v1 吧?毕竟 api 都写的是 openai-completions。
但事实是:它不会。
第三步:用 curl 模拟 OpenClaw 的请求
为了确认 OpenClaw 到底在请求什么,我试着直接调用 OpenClaw 的网关 API:
curl -X POST http://127.0.0.1:18789/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "ollama/qwen2.5:7b",
"messages": [{"role": "user", "content": "hi"}]
}'
也返回 404。说明 OpenClaw 的 API 路径根本不是 /v1/chat/completions,这个路径是给模型用的,不是给网关用的。测试方向错了。
第四步:查看网关日志,看真实请求
开启 debug 日志:
export OPENCLAW_LOG_LEVEL=debug
systemctl --user restart openclaw-gateway.service
然后在 TUI 发消息,看日志。虽然没有直接打印 URL,但结合错误信息,我推测 OpenClaw 是在 baseUrl 后面直接拼接了 OpenAI 的 API 路径。
也就是说:
- 如果
baseUrl是http://192.168.175.1:11434 - OpenClaw 实际请求的是
http://192.168.175.1:11434/chat/completions(没有/v1) - 而 Ollama 的 OpenAI 兼容端点在
/v1/chat/completions
所以 404 的根本原因:路径对不上。
第五步:验证猜想
我直接把 baseUrl 改成包含 /v1:
"ollama": {
"baseUrl": "http://192.168.175.1:11434/v1",
"api": "openai-completions",
...
}
重启网关,再发消息——通了!
✅ 最终正确配置
{
"models": {
"providers": {
"ollama": {
"baseUrl": "http://192.168.175.1:11434/v1", // ← 必须包含 /v1
"api": "openai-completions",
"models": [
{
"id": "qwen2.5:7b",
"name": "qwen2.5:7b",
"contextWindow": 32000,
"maxTokens": 8000
}
]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "ollama/qwen2.5:7b"
}
}
}
}
💡 关键总结
| 组件 | 关键点 |
|---|---|
| Ollama 启动 | 必须加 -e OLLAMA_OPENAI_COMPAT=1 |
| OpenClaw 配置 | baseUrl 必须包含 /v1 |
| 验证方式 | 直接 curl http://IP:11434/v1/chat/completions |
| 调试手段 | journalctl --user -u openclaw-gateway.service -f |
🎯 为什么第一篇没写对?
上一篇我写“baseUrl 不要加 /v1,OpenClaw 会自动拼接”——这个结论是错误的。感谢读者 @[你的用户名] 的反馈和验证,让我意识到这个细节的差异。
可能的原因:
- OpenClaw 版本差异(我用的 2026.3.13 不会自动补全
/v1) - Ollama 版本差异(某些版本可能支持路径重定向)
- 不同
api类型的行为不同
建议:统一在 baseUrl 中显式包含 /v1,这样最保险。
🚀 最终效果
现在,在 TUI 或 Web 界面里,我可以丝滑地和本地千问模型对话了:
> 你好,请介绍一下自己
你好!我是 Qwen,一个由阿里云开发的大型语言模型...
CPU 占用不高,GPU 跑起来温度稳定,响应速度很快。Windows 上的 Docker 容器 + Ubuntu 虚拟机里的 OpenClaw,整套架构跑通了。
📚 相关资源
- OpenClaw 官方文档:docs.openclaw.ai
- Ollama GitHub:github.com/ollama/olla…
- 上一篇博客:[OpenClaw 部署指南:从零开始配置本地 AI 智能体]
希望这篇文章能帮你少踩一个坑。如果你也在折腾 OpenClaw,欢迎交流!