1. 为什么要把 openclaw 的 endpoint 从本地 Ollama 切到统一通道
openclaw 是一个自托管网关,跑在你自己的机器或服务器上,把聊天应用和 AI 编程智能体连起来。用 docker-compose 部署它本身不复杂,真正让人头疼的是模型接入这一层:默认配置里baseUrl指向的是内网 Ollama 地址,比如http://192.168.100.20:11434,模型列表也是一个个手写进去的。单机自用没问题,但只要你想同时用几个不同厂商的模型,Key 就会散落在openclaw.json、.env、各种脚本里,换一台机器就得重新对一遍。
我这次要解决的就是这个分散问题:把 openclaw 的 endpoint 统一改到 TaoToken 的 API 通道,让 openclaw 只认一个 Base URL、一个 Key,模型 ID 按需切换。TaoToken 在这里扮演的是统一 API 入口,openclaw 侧仍然是标准的 OpenAI 兼容调用方式,配置项不用大改,改的是baseUrl、apiKey和models里的 provider 定义。
适合谁看:已经用 docker-compose 把 openclaw 跑起来、现在想接统一模型通道的开发者;或者正准备部署 openclaw、想一步到位不接本地 Ollama 的人。下面会给可复制的docker-compose.yml环境变量片段、openclaw.json的 endpoint 配置项,以及一次 curl 验证,确认请求确实走了 TaoToken。
先说清楚一个概念,避免后面混淆。openclaw 的模型配置在openclaw.json的models.providers下面,每个 provider 有baseUrl、apiKey、api、models四个关键字段。我们要做的就是把原来ollama这个 provider 换成指向 TaoToken 的 provider,api字段用 OpenAI 兼容格式,baseUrl填 TaoToken 的 API 地址。docker-compose 层面则通过环境变量把 Key 注入容器,避免明文写死在编排文件里。
这里有个容易踩的点:openclaw 容器内的openclaw.json路径是/home/node/.openclaw/openclaw.json,而宿主机上你放在/opt/openclaw/openclaw.json,两者靠docker cp或 volume 映射同步。改配置时一定要确认改的是容器实际读取的那份,否则你会遇到「明明改了却没生效」的情况。我建议直接用 volume 把宿主机目录挂进去,改完 restart 即可,省掉反复docker cp。
另外,TaoToken 的 API 地址是https://taotoken.net/api,这个地址不加任何多余路径,openclaw 侧拼接/v1/chat/completions时由它自己处理。Key 在控制台的 API Keys 页面生成,格式是sk-开头的一串。模型 ID 用你在模型对话页面能看到的名字,比如常见的对话模型 ID 直接填进去即可。下面进入具体配置。
2. TaoToken 前置准备:Key、Base URL 与模型 ID 三件套
在动 openclaw 之前,先把 TaoToken 侧的三件套拿到手,不然后面配置会卡住。这三件套是:Base URL、API Key、Model ID。任何 OpenAI 兼容客户端接入,缺一个都跑不通,openclaw 也不例外。
Base URL 固定是https://taotoken.net/api。注意不要自己加/v1,也不要加/chat/completions,openclaw 的 provider 配置里api字段会决定它怎么拼路径。如果你手动把完整路径写进baseUrl,大概率会拼出/api/v1/v1/chat/completions这种重复路径,然后收到 404。这个坑我在别的工具上踩过,openclaw 同理。
API Key 到控制台的 API Keys 页面创建。创建时给它起个能认出来的名字,比如openclaw-gateway,方便以后按用途吊销。生成后那串sk-开头的字符串只显示一次,复制下来存好。如果你打算用环境变量注入 docker-compose,就把它写进.env文件,别直接提交到 git。
Model ID 在模型对话页面能看到当前可用的模型列表。openclaw 的models数组里每个条目有id和name,id必须和 TaoToken 侧接受的模型名一致,否则会返回模型不存在的错误。你可以先挑一个通用对话模型做验证,跑通后再往数组里加更多。
三件套齐了之后,建议先在宿主机上用 curl 直接打一次 TaoToken,确认 Key 和网络都没问题,再去改 openclaw。这样能把「TaoToken 侧的问题」和「openclaw 配置的问题」分开,排障时省一半时间。curl 命令如下,把$TAOTOKEN_KEY换成你的真实 Key:
curl -sS https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "你的模型ID", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 16 }'如果返回里能看到choices数组和一段回复内容,说明三件套没问题,可以进入 openclaw 配置。如果返回 401,检查 Key 是否复制完整、有没有多余空格;如果返回 404,检查 Base URL 是不是多写了路径;如果返回模型不存在,检查 Model ID 拼写。这一步过了,后面 openclaw 里再出问题,基本就是配置格式的事。
还有一点,openclaw 容器访问外网需要 DNS 正常。如果你在容器里 curl 不通 TaoToken,但在宿主机能通,多半是容器 DNS 或网络模式的问题。docker-compose 默认 bridge 网络一般没问题,但如果你之前给容器配了自定义网络或 hosts,需要确认taotoken.net能解析。这个放到排障章节细说。
3. 可复制配置:docker-compose 环境变量与 openclaw.json endpoint 改写
这一节是核心,直接给可复制的片段。分两部分:docker-compose 的环境变量注入,以及openclaw.json里 provider 的改写。我建议用 volume 挂载配置目录,而不是docker cp,这样改完 restart 就生效。
先看 docker-compose。在原来openclaw-gateway服务基础上,加一个env_file或environment,把 TaoToken 的 Key 和 Base URL 传进去。同时把宿主机配置目录挂到容器的/home/node/.openclaw,这样openclaw.json直接改宿主机文件即可:
version: "3.8" services: openclaw-gateway: image: ghcr.io/openclaw/openclaw:latest container_name: openclaw hostname: openclaw restart: always volumes: - /opt/openclaw/.openclaw:/home/node/.openclaw environment: - TZ=Asia/Shanghai - TAOTOKEN_BASE_URL=https://taotoken.net/api - TAOTOKEN_API_KEY=${TAOTOKEN_API_KEY} ports: - "18789:18789" mem_limit: 2g logging: driver: json-file options: max-size: "10m" max-file: "3"同目录下建一个.env,写入你的 Key,权限设成 600:
TAOTOKEN_API_KEY=sk-你的真实Key注意openclaw.json里能不能直接引用${TAOTOKEN_API_KEY}取决于 openclaw 版本对配置内插值的支持。稳妥做法是:要么在openclaw.json里直接写 Key(不推荐,但简单),要么用启动脚本把环境变量渲染进配置。我下面给的openclaw.json片段用直接写 Key 的方式,你替换成自己的即可;如果你要环境变量注入,就在容器启动前用envsubst生成配置。
接下来是openclaw.json的关键改写。把原来models.providers.ollama整段替换成指向 TaoToken 的 provider。api字段用openai(OpenAI 兼容),baseUrl填 TaoToken 地址,apiKey填你的 Key,models数组里放你要用的模型 ID:
{ "models": { "mode": "merge", "providers": { "taotoken": { "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的真实Key", "api": "openai", "models": [ { "id": "你的模型ID", "name": "你的模型ID", "reasoning": false, "input": ["text"], "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }, "contextWindow": 128000, "maxTokens": 8192 } ] } } } }然后把agents.defaults.model.primary从原来的ollama/qwen3:8b改成taotoken/你的模型ID,agents.defaults.models里的键也同步改成taotoken/...。这一步不改的话,openclaw 启动后仍然会去找ollamaprovider,报 provider 不存在。
改完配置,重启容器:
cd /opt/openclaw && docker-compose restart重启后进容器确认配置读到了:
docker exec -it openclaw cat /home/node/.openclaw/openclaw.json | head -40看到taotokenprovider 和你的模型 ID 就对了。如果还是旧的ollama,说明 volume 没挂对,或者你改的是宿主机另一份文件。这一步确认完,再进验证环节。
4. 验证请求:curl 打 openclaw 网关,确认流量走 TaoToken
配置改完不代表通了,得实际发一次请求,看 openclaw 网关有没有把流量转发到 TaoToken。验证分两层:先直接打 openclaw 的网关端口,再通过 openclaw 的对话入口发一条消息,观察返回。
第一层,确认 openclaw 网关在监听。宿主机上执行:
curl -sS http://127.0.0.1:18789/health如果返回健康状态或 200,说明网关进程正常。如果连接被拒,检查docker-compose ps里容器是否 Up,端口 18789 是否映射成功。
第二层,通过 openclaw 的 API 或控制台发一条对话。openclaw 的 gateway 端口是 18789,控制台默认开启。你可以用 curl 直接打它的对话接口(具体路径以你版本为准,常见是/v1/chat/completions或 openclaw 自己的/api/...),带上 gateway 的 token:
curl -sS http://127.0.0.1:18789/v1/chat/completions \ -H "Authorization: Bearer 85ee32ad9b5076be296ace3d9eb334efd00cc70eeee2d711c" \ -H "Content-Type: application/json" \ -d '{ "model": "taotoken/你的模型ID", "messages": [{"role": "user", "content": "你好,报一下你的模型名"}], "max_tokens": 32 }'如果返回里有正常的choices和回复内容,说明 openclaw 已经把请求转发到 TaoToken 并拿到了结果。这时候你可以在 TaoToken 控制台的用量或日志页面看到这次调用记录,进一步确认流量确实走了统一通道。
如果返回 401,先分清是 openclaw 网关的 token 错了,还是 TaoToken 的 Key 错了。openclaw 网关 token 在openclaw.json的gateway.auth.token字段,TaoToken Key 在models.providers.taotoken.apiKey。两个都检查一遍。如果返回local proxy failed或连接超时,多半是容器内访问 TaoToken 的网络问题,进容器 curl 一次 TaoToken 确认。
还有一种情况:返回里choices为空或报reading choices相关错误。这通常是上游返回格式和 openclaw 预期不一致,或者模型 ID 不被 TaoToken 接受。先确认 Model ID 拼写,再用第 2 节的 curl 直接打 TaoToken 对比返回结构。两边返回结构一致,openclaw 侧就不该报解析错。
验证通过后,建议把这次成功的 curl 命令存成一个脚本,以后换机器或改配置后跑一遍,几十秒就能确认链路没断。这比每次开控制台点半天快得多。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一节按真实报错来对。你在 openclaw 接 TaoToken 的过程中,大概率会遇到下面几类,我按现象、原因、处理顺序列出来。
401 Unauthorized。两种可能:openclaw 网关 token 错,或 TaoToken Key 错。先看报错发生在哪一层——如果是打127.0.0.1:18789就 401,是网关 token 问题,检查gateway.auth.token和你请求头里的 Bearer 是否一致。如果是 openclaw 转发到 TaoToken 后返回 401,是 TaoToken Key 问题,检查models.providers.taotoken.apiKey是否完整、有没有被.env覆盖成空值。用docker exec进容器打印配置里的 Key 前几位对比。
local proxy failed。这个报错通常出现在 openclaw 尝试连接上游但网络不通时。进容器执行curl -sS https://taotoken.net/api/v1/models -H "Authorization: Bearer $TAOTOKEN_API_KEY",如果容器内不通而宿主机通,检查容器 DNS 和网络模式。docker-compose 默认 bridge 一般能出网,但如果你之前配过network_mode: host或自定义 DNS,需要确认taotoken.net能解析。另外确认容器时间正确,TLS 握手对时间敏感。
reading choices 相关错误。这表示 openclaw 拿到了上游响应,但解析choices字段失败。常见原因是上游返回了非预期结构,比如错误对象被当成正常响应。先用第 2 节的 curl 直接打 TaoToken,看返回 JSON 里有没有choices。如果直接打有、经 openclaw 没有,检查 openclaw 的 providerapi字段是不是写成了ollama而不是openai。api字段决定解析方式,写错就会解析失败。
OAuth 相关报错。如果你在 openclaw 里配了需要 OAuth 的 provider,或者auth.profiles里残留了旧的ollama:default配置,可能触发 OAuth 流程报错。处理方式是清掉auth.profiles里不再使用的条目,只保留 TaoToken 相关的。openclaw 的 auth profile 和 models provider 是两套东西,别混在一起。
配置改了不生效。最常见的原因是 volume 没挂对,或者你改的是宿主机文件但容器读的是镜像内旧文件。用docker exec -it openclaw cat /home/node/.openclaw/openclaw.json确认容器内实际内容。如果和宿主机不一致,检查docker-compose.yml的 volumes 路径,宿主机路径必须是绝对路径,且目录存在。
模型 ID 不存在。TaoToken 返回模型不存在时,openclaw 侧可能包装成别的错误。回到模型对话页面核对可用模型 ID,注意大小写和连字符。models数组里的id和name都填同一个正确值,避免 openclaw 内部按 name 查找时找不到。
排查顺序建议:先宿主机 curl TaoToken,再容器内 curl TaoToken,再 curl openclaw 网关,最后看 openclaw 日志docker logs openclaw --tail 100。一层层缩小范围,比一上来就翻配置快。
6. 长期使用建议与接入入口
跑通之后,日常维护其实很轻。我的做法是把openclaw.json和.env都纳入版本管理(Key 用占位符,真实 Key 只放本地),换机器时 clone 下来改一下.env就能起。模型列表按需增减,TaoToken 侧新增模型后,在models.providers.taotoken.models数组里加一条即可,不用动 docker-compose。
如果你后面要接更多工具,比如 Claude Code 或别的编码助手,思路是一样的:Base URL 用https://taotoken.net/api,Key 用同一个,Model ID 按工具要求填。统一通道的好处就是 Key 和地址只维护一份,工具换了一茬,接入层不用重来。
需要生成 Key 或管理已有 Key,去控制台的 API Keys 页面:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=openclaw_docker_compose&utm_campaign=rewrite
想先确认模型 ID 和返回格式,用模型对话页面直接试:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=openclaw_docker_compose&utm_campaign=rewrite
接入参数和路径细节看文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=openclaw_docker_compose&utm_campaign=rewrite
如果你打算把 openclaw 长期挂在服务器上跑编码或 Agent 任务,Coding Plan 比按量更省心:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=openclaw_docker_compose&utm_campaign=rewrite
最后留一个我自己的习惯:每次改完openclaw.json,先docker-compose restart,再跑一遍第 4 节那条 curl,看到choices里有内容才算改完。这个动作花不到一分钟,但能挡住九成的「改了没生效」。