2026-02-11 · 架构
32
架构 · 2026-02-11

OpenClaw 自动化 Agent 运维实战:从 Cron 报错到系统性治理

你有没有遇到过这种情况:部署好的自动化任务跑了几天一切正常,突然某天一查日志,满屏红色——连续报错三次,但你毫不知情。

我遇到了。在远端服务器上跑的 OpenClaw Agent,两个 Cron 任务分别报了不同的错,一个说”投递目标丢了”,另一个说”不支持 whatsapp”。服务器上压根没配 whatsapp。

架构先交代清楚

我的方案是远端服务器跑 OpenClaw Agent,通过 CLIProxyAPI(下面简称 cliproxy)做中转代理,打通多个大模型 API。

整体分三层:

本地 Mac                              远端服务器
─────────────                        ──────────────────
cliproxyapi.conf  ──sync──▶  config.yaml
                                     CLIProxyAPI (port 8317)
                                         ↓
                                     OpenClaw Agent
                                       ↓ 选择 provider/model
                                     cliproxy/主力模型(首选)
                                     代理通道/claude-*(备选)
                                     glm-provider/glm-*(兜底)

配置管理有个铁律:本地配置是单一真相源。所有改动在本地做,同步到远端,不手动碰远端文件。Cron 定时任务执行完后,结果自动投递到 Discord 频道。

三个报错,三种死法

那天 SSH 到远端检查状态,openclaw cron list --json 一跑,两个任务的 lastStatus 都是 error

第一个:cron delivery target is missing

这是一个 SEO 心跳任务,每 30 分钟跑一次,已经连续失败 3 次了。

看它的 delivery 配置:

{
  "mode": "announce",
  "channel": "discord"
}

少了个 to 字段。告诉了系统”我要往 Discord 发”,但没说往哪个频道发。

第二个:Unsupported channel: whatsapp

一个定时发帖任务,delivery 配置更离谱:

{
  "mode": "announce"
}

只说”我要广播”,没说往哪广播、用什么渠道。OpenClaw 内部回退到了某个默认渠道——whatsapp。但我的服务器上根本没配 whatsapp,所以直接炸了。

第三个:/restart is disabled

想在 Discord 里发个 /restart 重启 Agent,被告知命令没开。不算严重,但也是个漏配。

把这三个和唯一正常的任务放一起对比:

✗ { mode: "announce", channel: "discord" }            ← 缺 to
✗ { mode: "announce" }                                 ← 缺 channel + to
✓ { mode: "announce", channel: "discord", to: "..." }  ← 完整

差别很直观。

真正让人难受的地方

三个配置问题,修起来不难。让人难受的是另一件事。

OpenClaw 的 cron add 命令,在 --announce 模式下,不强制要求 --to 参数。你可以创建一个 delivery 配置不完整的任务,创建时不报错,运行时才炸。

用一个类比:这相当于编译器允许你写出有语法错误的代码,编译时说”成功”,运行时 segfault。

这种 fail-late 设计在自动化系统里特别危险。定时任务不像手动命令——手动跑你能立刻看到报错。Cron 任务可能凌晨三点触发,失败三次你都不知道,直到隔天上去查日志。

修复过程

诊断思路很简单:

  1. SSH 到远端,先确认 cliproxy 服务本身正常(systemctl --user status
  2. openclaw cron list --json 拿到所有任务的完整 JSON
  3. 对比出错任务和正常任务的 delivery 字段
  4. cron/jobs.json 确认持久化数据和运行时状态一致

修复用了三条命令。

SEO 心跳任务——补上 agent ID、目标频道和渠道:

openclaw cron edit <job-id> \
  --agent main \
  --to <channel_id> \
  --channel discord

发帖任务——补渠道和目标(这个任务当前是 disabled,但配置先修好):

openclaw cron edit <job-id> \
  --channel discord \
  --to <channel_id>

启用 /restart 命令:

openclaw config set commands.restart true --json

改完重启 Gateway 让配置生效,然后手动触发心跳任务验证:

openclaw cron run <job-id> --timeout 90000
# => { "ok": true, "ran": true }

lastStatuserror 变成 okconsecutiveErrors 归零。

顺带整理的踩坑清单

这次修的是 Cron delivery 配置,但整个 OpenClaw + cliproxy 体系里踩过的坑远不止这些。挑几个有代表性的。

Provider 注册有两道门

OpenClaw 对模型的管控分两层:

只注册不放行,会报 Model "xxx" is not allowed。两道门都过了才能用。

agent 级配置不能注册新 provider

agent 目录下的 models.json 只能给已有 provider 追加模型,不能注册新 provider。新 provider 必须在全局 openclaw.json 里声明。这个坑让我 debug 了很久——curl 直接请求 cliproxy 返回 200,但 Agent 死活走 GLM 兜底。最后发现 cliproxy 这个 provider 只在 agent 级定义了,全局配置里没有。

HTTP 200 也可能是错

有些 API 站点后端用了特殊平台,认证失效时返回 HTTP 200,但 body 里塞了错误信息。cliproxy 只看 status code,200 就当成功透传。排查只能从请求日志里倒推——追踪请求 ID,反查 API key 后缀,定位到具体站点。

改了配置必须重启 Gateway

OpenClaw Gateway 是常驻进程,启动时读配置并缓存。改了 openclaw.json 不重启 Gateway,运行时用的还是旧配置。踩过一次之后,所有管理脚本里都加了自动重启。

delivery 三要素

Cron 任务的投递配置,三个字段缺一不可:

{
  "mode": "announce",
  "channel": "discord",
  "to": "<channel_id>"
}

mode 决定投递行为,channel 决定走哪个渠道,to 决定投给谁。这三个字段应该是一个原子结构——要么全有,要么创建时就拒绝。不该存在”有 channel 没 to”这种中间态。

入口校验的价值

回到让我难受的那个点:fail-late。

运行时报错是成本最高的反馈方式。你要等到任务触发、执行、失败,然后隔天甚至隔周上去查日志才发现问题。入口校验是成本最低的反馈方式——cron add 的时候就告诉你”缺了 –to 参数”,当场改掉。

改不了 OpenClaw 的源码,但可以在自己的自动化脚本里加一层。我现在的做法是所有 cron addcron edit 操作都经过一个 wrapper 脚本,脚本里检查 --announce 模式是否同时带了 --to--channel,缺了就拒绝执行。

把校验前置,把错误消灭在它被创建之前。这比事后修复省心得多。

下次你看到一个系统允许创建”注定会失败”的配置,想想能不能在上游堵住那个口。

目录 最新
← 左侧翻上一屏 · 右侧翻下一屏 · 中间唤出菜单