1. 从一次 gateway 起不来聊起:openclaw 服务进程到底怎么跑起来的
openclaw 的 gateway 服务进程,简单说就是整个系统的“前台接待”:飞书、企业微信、钉钉这些客户端发来的消息先到它这里,它再转给 agent 模块处理,处理完把结果原路送回。它跑在 Node.js 上,但又不是你随手node index.js那种前台进程,而是被注册成操作系统的常驻服务,开机自启、后台常驻。适合谁看?正在折腾 openclaw 自托管、卡在gateway install或gateway start没反应、想搞清楚dist/index.js gateway --port 18789这行到底谁在调用的同学。
我试过在 Windows 上把这条链路完整跑一遍,踩的坑主要集中在两处:一是服务脚本写没写成功、写到了哪;二是 gateway 起来了但模型通道没配,消息进来直接报 access not configured。这篇就按“入口脚本 → 服务注册 → 监听就绪 → 模型通道接入”的顺序拆开讲,配置骨架可以直接抄,验证动作也给你标好。
先给结论:openclaw 在三个平台上用同一套抽象接口GatewayService,macOS 落到 LaunchAgent、Linux 落到 systemd、Windows 落到 Scheduled Task,最终都是拉起一个 Node 进程去执行dist/index.js gateway --port 18789。理解了这个模式,排障就有方向了。
2. TaoToken 前置:给 gateway 一条统一的模型通道
gateway 本身只负责消息转发,真正干活的是 agent 模块,而 agent 要调模型。如果你每个客户端、每个 agent 都单独配一套 Key,后面换模型、加通道会非常痛苦。TaoToken 在这里的角色就是一条统一的 Key/API 通道:一个 Key 走多家模型,gateway 侧只认一个 base_url 和一个 api_key,配置骨架干净很多。
你需要提前准备的东西:
- 一个 TaoToken 账号,登录后进控制台创建 API Key;
- 记下两个地址:官网
https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,API 基址https://taotoken.net/api(注意 API 地址不带 UTM 参数,配置里就写这个); - 确认你要用的模型名,比如走 Claude 系列做 coding、走通用对话模型做问答,模型名在模型对话页能看到。
拿 Key 的入口在这里:API Keys 管理页https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite。创建完复制出来,只显示一次,丢了就重建一个。
注意:Key 属于敏感凭据,别写进会提交到 git 的
config.toml里。下面骨架里我用环境变量占位,实际部署时用系统环境变量或.env注入。
如果你后面要长期跑 coding agent、频繁调模型,可以顺带看下 Coding Planhttps://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite,按量还是包月按自己用量选。只想先验证模型通不通,直接开模型对话页https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite发一条消息最快。
3. 可复制配置:config.toml 与 settings.json 骨架
openclaw 的配置分两层:一层是 gateway 服务本身的运行参数(端口、服务名、日志),一层是模型通道参数(base_url、api_key、model)。下面这份骨架是我实测能跑通的版本,字段名按你本地版本微调即可。
先看config.toml,放在 openclaw 的工作目录下(Windows 上通常是C:\Users\<你>\.openclaw\):
# config.toml —— gateway 运行参数 + 模型通道 [gateway] port = 18789 host = "127.0.0.1" log_level = "info" # 服务注册名,Windows 下会体现在计划任务名里 service_name = "OpenClaw Gateway" [model] # TaoToken 统一通道,注意 API 地址不带 UTM base_url = "https://taotoken.net/api" api_key = "${TAOTOKEN_API_KEY}" # 默认模型,按你控制台里可用的填 default_model = "claude-sonnet-4-5" timeout_ms = 60000 [agent] max_concurrency = 4再看settings.json,这个更偏客户端/插件侧的行为开关,比如飞书长连接、事件订阅:
{ "channels": { "feishu": { "enabled": true, "mode": "long_connection", "events": ["im.message.receive_v1"], "permissions": [ "im:message", "im:message.p2p_msg", "im:message.group_at_msg", "contact:contact.base:readonly" ] } }, "model": { "provider": "taotoken", "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY" }, "logging": { "level": "info", "file": "./logs/gateway.log" } }两个文件的分工要拎清:config.toml决定 gateway 进程怎么起、连哪个模型通道;settings.json决定消息从哪些渠道进来、进来后怎么处理。改完任意一个都要重启 gateway 服务才生效,别改完就干等。
环境变量注入(Windows PowerShell,当前会话有效):
$env:TAOTOKEN_API_KEY = "sk-你的Key"Linux/macOS:
export TAOTOKEN_API_KEY="sk-你的Key"提示:如果你把 Key 直接写死在
config.toml里,记得给文件加权限,Linux 下chmod 600 config.toml,Windows 下确认只有当前用户可读。
4. 启动链路逐段拆:从 entry.js 到监听就绪
openclaw 的服务抽象在src/daemon/service.ts,核心是一个注册表GATEWAY_SERVICE_REGISTRY,按平台分发:
| 平台标识 | 服务类型 | 已加载文案 | 未加载文案 |
|---|---|---|---|
| darwin | LaunchAgent | loaded | not loaded |
| linux | systemd | enabled | disabled |
| win32 | Scheduled Task | registered | missing |
Node 启动时先读process.platform,拿到win32就去注册表取 Windows 那套实现,所有函数都来自schtasks.js。以installScheduledTask为例,它干两件事:先writeScheduledTaskScript把 cmd 脚本写到磁盘,再activateScheduledTask注册计划任务。
脚本路径由resolveTaskScriptPath决定,Windows 上一般是C:\Users\<你>\.openclaw\gateway.cmd。写出来的内容长这样:
@echo off rem OpenClaw Gateway (v2026.5.20) set "HOME=C:\Users\OseasyVM" set "TMPDIR=C:\Users\OseasyVM\AppData\Local\Temp" set "OPENCLAW_GATEWAY_PORT=18789" set "OPENCLAW_WINDOWS_TASK_NAME=OpenClaw Gateway" set "OPENCLAW_SERVICE_KIND=gateway" "C:\Program Files\nodejs\node.exe" C:\Users\OseasyVM\Documents\openclaw\dist\index.js gateway --port 18789看到没,最终就是一行 Node 调用:dist/index.js gateway --port 18789。gateway是子命令,--port是监听端口。所以整条链路是:计划任务 → gateway.cmd → node.exe → dist/index.js → gateway 模块 → 监听 18789。
想验证脚本到底写没写成功,可以在writeScheduledTaskScript里临时加两行打印再退出:
console.log("scriptPath:", scriptPath); console.log("taskDescription:", taskDescription); process.exit(0);然后跑pnpm openclaw onboard --install-daemon,控制台会打出脚本路径,去那个路径cat一下就能看到内容。确认无误后把调试代码删掉,重新执行安装。
正式安装 gateway 服务(Windows 用管理员 PowerShell):
cmd /c "pnpm openclaw gateway install"成功输出类似:
OpenClaw 2026.5.20 (bde07dd) Installed Scheduled Task: OpenClaw Gateway Task script: C:\Users\OseasyVM\.openclaw\gateway.cmd启动服务:
cmd /c "pnpm openclaw gateway start"Linux 下对应的是 systemd,安装后 unit 文件在/etc/systemd/system/openclaw-gateway.service,systemctl status openclaw-gateway看状态;macOS 是 LaunchAgent,plist 在~/Library/LaunchAgents/下。三平台命令不同,但“写配置 → 注册 → 拉起 Node → 执行 gateway”这个模式完全一致。
5. 验证请求:确认监听就绪与模型通道打通
服务起来不等于能用,得两步验证:先确认端口在听,再确认模型通道通。
第一步,查端口监听。Windows:
netstat -ano | findstr 18789Linux/macOS:
lsof -i :18789 # 或 ss -tlnp | grep 18789看到LISTENING或LISTEN就说明 gateway 进程活着。如果什么都没有,回去看gateway.cmd里的 node 路径对不对、dist/index.js存不存在。
第二步,验证模型通道。最直接的办法是走一次模型对话,确认 Key 和 base_url 生效。你可以用 curl 打一发:
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-5", "messages": [{"role": "user", "content": "ping"}] }'返回里有choices字段就说明通道没问题。如果返回 401,检查 Key;返回 404,检查 base_url 是不是写成了带 UTM 的地址——配置里只写https://taotoken.net/api。
第三步,端到端验证。在飞书里给机器人发一条消息,正常会收到配对提示:
OpenClaw: access not configured. Your Feishu user id: XXXXXXXXXX Pairing code: XXXX Ask the bot owner to approve with: openclaw pairing approve feishu XXXX看到这个说明 gateway 收到了消息、转发链路通了,只是还没授权这个用户。执行openclaw pairing approve feishu XXXX批准后,再发消息就能拿到模型回复。
飞书插件如果报缺zod,先全局装一下:
npm install -g zod插件安装命令:
openclaw plugins install clawhub:@openclaw-cn/feishu飞书开发者后台那边要确认三件事:事件订阅方式选“长连接”、添加im.message.receive_v1事件、开通前面列的四个权限,然后创建版本等审核通过。
6. 本篇常见错排查
报错一:gateway install成功但gateway start没反应。先看计划任务状态,Windows 下schtasks /query /tn "OpenClaw Gateway",状态不是 Running 就手动schtasks /run /tn "OpenClaw Gateway"。Linux 下systemctl status openclaw-gateway看是不是 failed,常见原因是 unit 文件里的 node 路径写错。
报错二:端口 18789 被占用。netstat -ano | findstr 18789找到 PID,任务管理器结束掉,或者改config.toml里的port换个值,记得同步改gateway.cmd里的--port参数,改完重新 install。
报错三:消息进来报 access not configured。这不是故障,是配对机制。按提示执行openclaw pairing approve feishu <配对码>即可。配对码每次可能不同,以实际输出为准。
报错四:模型调用 401/403。九成是 Key 没注入到 gateway 进程的环境里。注意gateway.cmd是独立进程,你在当前 PowerShell 里export的环境变量它不一定继承。稳妥做法是把 Key 写进系统环境变量,或者确认config.toml里的${TAOTOKEN_API_KEY}能被正确解析。
报错五:飞书插件装完启动报模块缺失。除了zod,还可能是插件版本和 openclaw 主版本不匹配。先openclaw plugins list看装没装上,再对照插件文档确认版本要求。
报错六:改了settings.json不生效。这个文件是启动时读一次的,改完必须gateway restart。Windows 下cmd /c "pnpm openclaw gateway restart",Linux 下systemctl restart openclaw-gateway。
排障时如果拿不准是 gateway 侧还是模型侧的问题,最快的分流办法是:先用 curl 直接打 TaoToken 的 API,通了就说明模型通道没问题,问题在 gateway 或插件;不通就回头查 Key 和 base_url。接入相关的文档在https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite,Key 管理在https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite。
7. 把 gateway 接进你的日常编码流
gateway 跑通之后,真正高频用的是 agent 侧的模型调用。如果你打算让它长期跑 coding 任务、接 CI 或者本地 Agent,建议把模型通道固定成 TaoToken 这一条,Key 轮换、模型切换都在控制台做,gateway 侧不用动。控制台入口https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite,Coding Plan 在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite。
最后留一个我踩过的坑:gateway.cmd里的环境变量是安装时快照进去的,你后来改了系统环境变量,旧脚本不会自动更新。换 Key 或换端口之后,记得重新执行一次gateway install让脚本重新生成,别只 restart。