- 人工智能
- AI Agent
- 即时通讯
- 后端
- 本地部署
- 语音
【免费下载链接】openclaw-cn
中文社区版OpenClaw,同原版保持定期更新,已内置钉钉、企业微信、飞书、QQ、微信以及国内网络环境优化。你的专属个人AI助手。支持所有操作系统和平台。🦞
导读
本文围绕 OpenClaw(openclaw-cn 中文社区版)在 macOS 上的网关托管方案展开:macOS 桌面应用(Clawdbot.app)不再内嵌 Node/Bun 运行时与网关进程,而是依赖一个独立的全局 CLI,并通过launchd LaunchAgent以守护进程方式常驻运行本地网关。读完本文,你将掌握在 Mac 上安装全局 CLI、理解 LaunchAgent 的安装/启用/停用机制、处理应用与网关的版本兼容校验,以及用一条命令完成网关启动与健康探测的完整流程。
原文档位置:docs/platforms/mac/bundled-gateway.md。
macOS 网关托管架构:从内嵌到外部化
原文档明确了 Clawdbot.app 的重大架构变化:
- 不再捆绑 Node/Bun 运行时,也不再把 Gateway 作为应用子进程(child process)拉起;
- macOS 应用期望一个外部安装的
clawdbotCLI; - 应用通过管理一个按用户(per-user)的 launchd 服务来保持网关常驻;
- 如果配置端口上已经有网关在运行,应用会直接附加(attach)到现有实例,而不是重复启动。
这一设计可以从 macOS 应用源码中得到印证。在 GatewayProcessManager.swift 中,启动流程被明确为"先尝试附加、再启用 launchd"两阶段:
// 1. 先尝试连接已经运行的网关,避免重复拉起 if await self.attachExistingGatewayIfAvailable() { return } // 2. 没有可用的现有实例,才启用 launchd 托管 await self.enableLaunchdGateway()在远程模式(Remote mode)下,应用甚至完全跳过本地网关的拉起逻辑——setActive会直接置为停止并记录日志"remote mode active; skipping local gateway"(见 GatewayProcessManager.swift)。也就是说,本篇文章讨论的 launchd 托管方案只适用于本地模式(Local mode)。
说明:本仓库(openclaw-cn)的 npm 包名与命令名与原版略有差异——package.json 中定义了
clawdbot-cn、openclaw、openclaw-cn三个 bin 别名。安装指南见仓库根目录的 README.md。
安装全局 CLI(本地模式的前提)
环境要求与安装命令
macOS 本地模式必须先在 Mac 上装好 Node.js 22+,随后全局安装clawdbotCLI:
npm install -g clawdbot@<version>在本仓库的实际安装命令为:
npm install -g openclaw-cn@latest # 或 pnpm add -g openclaw-cn@latest版本号<version>应替换为与 macOS 应用版本匹配的具体版本,详见下文"版本兼容校验"一节。
应用内的 Install CLI 流程
macOS 应用内置了Install CLI按钮,触发相同的安装流程。从 CLIInstallPrompter.swift 可以看到,应用会弹出提示框("Local mode needs the CLI so launchd can run the gateway"),提供Install CLI/Not now/Open Settings三个选项。安装器在 GatewayEnvironment.swift 中按 npm → pnpm → bun 的顺序解析包管理器,实际执行npm install -g clawdbot@<target>(或对应 pnpm/bun 等价命令)。
需要注意原文档的明确提示:bun 不推荐用于 Gateway 运行时。从源码侧看,守护进程运行时的合法值是node与bun,但默认值固定为node,且在 daemon-runtime.ts 的选项说明中标注了 Bun 的隐患:"Bun can corrupt memory on reconnect"(WhatsApp + Telegram 渠道必需 Node)。因此在 Mac 上请优先使用 npm/pnpm 安装,并保持 Node 22+ 环境。
Launchd:把 Gateway 托管为 LaunchAgent
Label 与 plist 位置
原文档给出了两条关键路径信息:
- Label:
com.openclaw.gateway(或配置了 profile 时为com.openclaw.<profile>) - plist 路径(按用户):
~/Library/LaunchAgents/com.openclaw.gateway.plist(或com.openclaw.<profile>.plist)
在本仓库实现中,默认 Label 定义在 src/daemon/constants.ts 为com.clawdbot.gateway,profile 化逻辑见 resolveGatewayLaunchAgentLabel:未指定 profile(或 profile 为 default)时使用默认 Label,否则生成com.clawdbot.<profile>。macOS 应用侧也保持了同一约定,Constants.swift 中的gatewayLaunchdLabel = "com.clawdbot.gateway"与 GatewayLaunchAgentManager.swift 中拼装的 plist URL(~/Library/LaunchAgents/<label>.plist)完全对应。原文档中的com.openclaw.*是上游命名,以你实际安装版本生成的 Label 为准。
plist 关键字段
CLI 安装守护进程时,plist 由 src/daemon/launchd-plist.ts 生成,核心字段包括:
RunAtLoad = true:用户登录加载时即启动网关;KeepAlive = true:进程退出后由 launchd 自动拉起,这正是"App 退出后网关仍在运行"的机制来源;ProgramArguments:<node路径> <dist入口> gateway --port <port>(resolveGatewayProgramArguments 负责拼装,Node 运行时下固定带--port);StandardOutPath/StandardErrorPath:launchd 的标准输出/错误重定向文件;EnvironmentVariables:注入网关运行所需的环境变量。
CLI 侧同样有一份守护进程审计逻辑,校验 plist 是否包含RunAtLoad=true与KeepAlive=true(见 src/daemon/service-audit.ts),侧面印证这两个字段对该托管方案至关重要。
环境变量注入
buildServiceEnvironment 展示了 launchd 服务注入的关键环境变量,包括:
| 变量 | 含义 |
|---|---|
HOME | 用户主目录 |
PATH | 最小化 PATH(含/opt/homebrew/bin、/usr/local/bin等) |
OPENCLAW_PROFILE | 当前 profile |
OPENCLAW_GATEWAY_PORT | 网关端口 |
OPENCLAW_GATEWAY_TOKEN | 网关令牌(token 认证模式) |
OPENCLAW_LAUNCHD_LABEL | 当前 LaunchAgent Label |
OPENCLAW_SERVICE_MARKER/OPENCLAW_SERVICE_KIND | 服务标识与类型(openclaw/gateway) |
OPENCLAW_SERVICE_VERSION | 服务版本 |
其中 token 的写入逻辑值得注意:CLI 在自动生成令牌后,会尽量持久化到配置文件(因为launchd 不会继承 shell 环境变量),并同时嵌入 plist 的EnvironmentVariables作为兜底(见 src/cli/daemon-cli/install.ts)。
管理方式与行为细节
原文档对管理权责与行为做了明确说明:
- Manager:本地模式下,macOS 应用拥有 LaunchAgent 的安装/更新权限;CLI 也可通过
clawdbot gateway install安装。 - "Clawdbot Active" 开关:负责启用/禁用 LaunchAgent。在 GatewayLaunchAgentManager.swift 中可以看到,启用时执行
install --force --port <port> --runtime node,停用时执行uninstall,且远程模式下跳过一切 launchd 变更。 - 退出不停止:应用退出不会停止网关(launchd 的
KeepAlive=true保证常驻)。应用侧 stop() 只负责在用户主动关闭时执行卸载,并不会在普通退出时干扰 launchd 托管的实例。 - 附加优先:若配置端口上已有网关,应用直接附加(attach)而非新建。附加流程在 attachExistingGatewayIfAvailable:先探测端口上是否存在监听者,再调用
healthRPC(超时 2 秒、最多重试 3 次),成功后状态显示为 "Using existing gateway";若端口被占用但健康探测失败,则会给出针对性的失败原因(认证失败、协议不匹配、端口被其他进程占用等)。
CLI 侧的守护进程管理命令(install/uninstall/start/stop/restart/status)注册在 src/cli/gateway-cli/register.ts,install支持--port、--runtime node|bun、--token、--force、--json等选项;macOS 上平台适配经由 resolveGatewayService 映射到 LaunchAgent 实现。
版本兼容校验
macOS 应用会拿网关版本与自身版本做比对,版本不兼容时提示更新全局 CLI,使其与应用版本一致。源码实现位于 GatewayEnvironment.swift:
- 应用期望版本来自
CFBundleShortVersionString(expectedGatewayVersionString); - 实际安装版本通过运行
clawdbot --version读取(readGatewayVersion),本地项目入口存在时也可回退读取package.json的 version 字段; - 兼容规则为主版本号一致且不低于应用版本(
self.major == required.major && self >= required); - 一旦判定不兼容,check() 会返回
incompatible(found:required:)状态,提示 "install or update the global package"。
因此,当你看到应用提示网关版本不兼容时,直接按上文"安装全局 CLI"一节把全局包更新到与应用相同的版本即可。
冒烟检查:启动网关并验证健康状态
原文档给出了完整的两段式冒烟检查命令,可直接照用:
clawdbot --version OPENCLAW_SKIP_CHANNELS=1 \ OPENCLAW_SKIP_CANVAS_HOST=1 \ clawdbot gateway --port 18999 --bind loopback随后验证健康状态:
clawdbot gateway call health --url ws://127.0.0.1:18999 --timeout 3000环境变量与参数的含义
OPENCLAW_SKIP_CHANNELS=1:跳过渠道(channels)启动。源码中网关启动时会检查该变量并跳过渠道初始化(见 src/gateway/server-startup.ts),适合只想验证网关本体、不接入任何消息渠道的冒烟场景。OPENCLAW_SKIP_CANVAS_HOST=1:跳过 Canvas Host。实现于 src/canvas-host/server.ts,与上一条同理,用于最小化启动面。--port 18999:指定临时端口,避免与默认端口冲突。默认端口在本仓库中为18789(应用侧 fallback 见 GatewayEnvironment.swift)。端口取值也可来自CLAWDBOT_GATEWAY_PORT环境变量或配置中的gateway.port。--bind loopback:仅绑定回环地址,不对外暴露。合法值为loopback/lan/tailnet/auto/custom(校验见 src/cli/gateway-cli/run.ts)。
health 调用的底层实现
clawdbot gateway call health最终通过 WebSocket 调用网关的health方法。call.ts 定义了--url、--token、--password、--timeout <ms>、--expect-final、--json等选项,默认超时 10 秒(冒烟命令显式指定 3000ms 以快速失败)。子命令注册见 src/cli/gateway-cli/register.ts,成功后输出Gateway Health: OK及耗时信息。
日志与故障排查
日志位置
- launchd 的 stdout/stderr 统一重定向到:
/tmp/clawdbot/clawdbot-gateway.log。 - macOS 应用侧 LogLocator.swift 也返回同一路径(
launchdGatewayLogPath),应用内的"Gateway Log"面板读取的正是这个文件。 - 若想覆盖日志目录,可设置环境变量
CLAWDBOT_LOG_DIR(见 LogLocator.swift)。注意 launchd 托管模式下环境来自 plist 注入,改动环境变量后需重新gateway install --force才会生效。
常见问题定位思路
- 应用提示 CLI 未安装 / Local mode needs the CLI:检查
node --version是否 ≥ 22,然后通过应用内Install CLI或手动npm install -g openclaw-cn@latest完成安装。 - 提示版本不兼容:按"版本兼容校验"一节,更新全局 CLI 至与应用一致的版本。
- 端口被占用但附加失败:健康探测失败原因会明确区分"认证失败(auth)""协议不匹配(protocol mismatch)""端口被其他进程占用(invalid response)"三类,按提示核对
gateway.auth.token或改用--force清理端口占用。 - 不想让应用自动写 LaunchAgent:应用支持在用户主目录放置标记文件
~/.clawdbot/disable-launchagent以禁用自动安装/启用(见 GatewayLaunchAgentManager.swift),此时需手动用clawdbot gateway install管理服务。
小结
macOS 上的 OpenClaw 网关托管遵循"外部 CLI + launchd LaunchAgent"的清晰分工:CLI 提供运行时与安装能力,launchd 保证常驻与崩溃恢复,应用只负责按需安装、启停和附加已有实例。理解 Label、plist 字段、环境变量注入与版本兼容规则之后,无论是日常使用还是排查本地模式故障,都能快速定位问题所在。
相关参考:
- docs/platforms/mac/bundled-gateway.md
- src/daemon/launchd-plist.ts
- src/daemon/service-env.ts
- apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift
- apps/macos/Sources/Clawdbot/GatewayProcessManager.swift
- apps/macos/Sources/Clawdbot/GatewayEnvironment.swift
- 人工智能
- AI Agent
- 即时通讯
- 后端
- 本地部署
- 语音
【免费下载链接】openclaw-cn
中文社区版OpenClaw,同原版保持定期更新,已内置钉钉、企业微信、飞书、QQ、微信以及国内网络环境优化。你的专属个人AI助手。支持所有操作系统和平台。🦞
相关推荐
openclaw-cn 网关服务操作手册:本地运行、远程访问与 launchd/systemd 监管实战指南
openclaw cn 网关服务操作手册:本地运行、远程访问与 launchd/systemd 监管实战指南 网关(Gateway)是 openclaw cn
人工智能AI Agent即时通讯后端本地部署语音OpenClaw 自托管 AI 网关完整实战指南:安装、模型接入、多通道配置与故障排查
OpenClaw 自托管 AI 网关完整实战指南:安装、模型接入、多通道配置与故障排查 导读 本文围绕 OpenClaw —— 一个 MIT 许可、可自托管的
人工智能MCP 服务AI Agent开发工具OpenClaw `openclaw uninstall` 完全指南:安全卸载网关服务与本地数据
OpenClaw openclaw uninstall 完全指南:安全卸载网关服务与本地数据 openclaw uninstall 是 OpenClaw CLI
人工智能大模型LLM 网关AI Agent即时通讯
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考