乐于分享
好东西不私藏

OpenClaw 缺陷修复和配置最佳实践:先让 Codex / Claude Code 读完,再动手

OpenClaw 缺陷修复和配置最佳实践:先让 Codex / Claude Code 读完,再动手

OpenClaw 这类项目,最容易让人犯的错,不是不会配,而是太想赶紧配。

因为它看起来太像一个“只要改几行 JSON 就能搞定”的系统了:配置文件在本地,文档也在,命令行也齐全,改动路径似乎一目了然。于是很多人一遇到问题,第一反应就是打开 openclaw.json,凭经验改两行,再重启试试。

我现在越来越确定,这正是 OpenClaw 最该警惕的地方。

OpenClaw 的缺陷修复和配置优化,真正的最佳实践,不是人工靠印象去改,而是先让 Codex 或 Claude Code 把代码、文档和当前配置通读一遍,再自动生成修复方案和配置 patch。这样做最大的价值,不是省事,而是幻觉少,每一步改动都有依据。

这件事听上去像方法论,实际上它直接决定了你到底是在修系统,还是在碰运气。

最大的问题,不是配置复杂,而是太容易靠猜

很多人以为 OpenClaw 的难点在“配置项太多”。我反而觉得,真正的问题是它太容易让人产生一种错觉:这些配置我大概看一眼就能改。

但 OpenClaw 不是一个静态表单。它背后有文档、默认值、校验逻辑、覆盖顺序、运行时实现、消息通道、ACP 会话、重启路径。你看到的是一个 JSON 文件,实际面对的是一整条链。

也正因为如此,靠经验改配置,最容易掉进三种坑里。

第一种,是文档里有这个字段,但当前版本代码根本没按你理解的方式消费它。第二种,是字段本身没改错,但你忽略了 bindings[]、agent runtime 和全局默认值之间的覆盖关系。第三种,是配置本身没问题,最后却被错误的重启方式把消息通道和上下文一起打断。

所以我现在的看法很明确:修 OpenClaw,最危险的不是不会,而是“好像会”。

更稳的修法,不是先改,而是先读

真正有效的做法,其实非常朴素。

不是先打开配置文件,而是先让 Codex 或 Claude Code 去做一件人最容易偷懒的事:把代码、文档、当前配置和实际行为对起来。

这套工作流并不复杂:

先读项目代码。
再读对应文档。
再看当前 openclaw.json
然后判断问题究竟属于配置、实现、文档,还是运行时行为。
最后再生成 patch 或修复建议。

差别就在这里。

当 Agent 按这个顺序工作时,它给出的建议就不再是“我猜你应该这样配”,而是“当前代码怎么读这个字段,文档怎么描述这件事,你本机配置现在是什么状态,所以应该改这里”。

这就是为什么我会把 Codex / Claude Code 放在 OpenClaw 修复流程的前面,而不是后面。

它们最有价值的地方,不是替你写一段漂亮 patch,而是先替你建立证据链。

所谓“幻觉少”,本质上是证据约束更多

很多人说 Agent 好不好用,习惯用“幻觉多不多”来判断。但如果只停在这个层面,讨论其实很虚。

我更愿意把它说得更直接一点:幻觉少,不是因为模型突然变得更诚实了,而是因为你给它的工作方式,逼它先去碰事实。

当 Codex 或 Claude Code 同时读到三样东西时,它的自由发挥空间会明显缩小:

  • • OpenClaw 当前代码实现
  • • OpenClaw 对应文档
  • • 你本机的真实配置

这三样东西一起摆在面前,很多“想当然”的判断就会自动失效。

比如,文档写 Telegram topic 可以绑定持久化 ACP 会话;当前配置里也确实存在 Telegram topic 到 codex 的 route 和 acp 绑定;而工具文档又明确给出了 config.patchconfig.applyrestart 的正式行为路径。那这时候再去讨论“是不是可以这样改”,就不是拍脑袋,而是在已有事实之上推进。

所以这套方法的核心,不是让 Agent 取代你判断,而是让它先帮你把判断所需要的证据收齐。

为什么我会特别强调固定 workspace

如果说“先读再改”是原则,那 workspace 就是这个原则能不能落地的关键细节。

因为你让 Agent 读什么,它就会在什么范围内建立认知。

如果 workspace 指向一个大而杂的总目录,OpenClaw 在 Agent 眼里就只是一堆项目中的一个。它当然也能回答问题,但注意力很容易分散,回答也容易沾上一种泛化味:像是在讲原理,实际上没完全贴着当前项目走。

所以我现在更倾向于把处理 OpenClaw 的 agent workspace 直接固定到:

/usr/local/lib/node_modules/openclaw/

这样一来,Codex 或 Claude Code 进入上下文后,面对的就是 OpenClaw 自己的代码、文档、构建产物和规则文件。它不是“顺便看一下 OpenClaw”,而是在一个只服务 OpenClaw 的工作台里工作。

这会显著降低一种很常见的风险:说得头头是道,但其实没认真看你当前这一份实现。

Telegram topic 的价值,不是方便,而是稳定

我现在也越来越看重 Telegram topic,但理由不是“远程聊天更方便”。

真正的价值在于,它给 OpenClaw 的修复工作提供了一个稳定、独立、不会轻易串味的上下文。

我的理解是,OpenClaw 这种系统很怕“所有事都在一个总对话里做”。你一会儿聊别的项目,一会儿问配置,一会儿看 bug,一会儿又让 Agent 去干别的事,最后上下文会越来越散。到最后不是模型不行,而是工作面本身已经糊了。

把 OpenClaw 的问题单独放在一个 Telegram topic 里,本质上是在给这个系统留一个长期维修间。这个 topic 里只做两件事:看缺陷,改配置。

当前文档明确支持 Telegram forum topic 绑定持久化 ACP 会话,而本机配置里也已经在用这种结构。这件事的意义,不是“能在 Telegram 里跑 Agent”,而是你终于可以把修复链条固定下来,不再每次都重新搭场景。

实操一:agents.md 怎么配,才能让 Agent 真正先读再改

如果你想把这套方法固定下来,最值得补的一份文件其实不是脚本,而是项目根目录的 agents.md

这份文件的作用,不是介绍项目,而是明确规定 Agent 的工作纪律。它应该直接写在 OpenClaw 项目根目录下,也就是:

/usr/local/lib/node_modules/openclaw/agents.md

这里放的是我现在在用的脱敏版思路,用户名、目录等敏感信息都已经替换成占位符:

# agents.md

## 适用范围


适用于当前 OpenClaw 项目根目录及其子目录。

默认约定:
-
 项目代码目录:`/usr/local/lib/node_modules/openclaw`
-
 文档目录:`/usr/local/lib/node_modules/openclaw/docs`
-
 运行时配置文件:`~/.openclaw/openclaw.json`

## 目标


1.
 阅读 OpenClaw 代码和文档,解释或修改 `openclaw.json`
2.
 定位 OpenClaw 缺陷,给出可核查、可复现、可落地的结论

## 核心规则


-
 不猜。配置含义、默认行为、问题原因都必须有代码、文档、配置或运行现象作为依据
-
 先读再答。涉及能力、配置、故障、兼容性时,先查源码和文档
-
 必须给出处。优先引用具体文件、模块或文档位置
-
 代码与文档冲突时,以当前代码实现为准,并明确指出差异
-
 推断必须标明是推断,并说明依据;没有依据就不要下结论

## 推荐工作流


1.
 先判断问题属于配置、实现、文档还是运行时行为
2.
 查找对应源码、文档和配置位置
3.
 交叉验证:
   -
 配置问题:文档 + 配置读取/默认值/校验代码 + 当前 `openclaw.json`
   -
 故障问题:报错/日志 + 调用链 + 条件分支 + 诊断文档
4.
 先给结论,再给证据链
5.
 证据不足时明确说明缺口,不要猜测补全

这份文件看起来不复杂,但很关键。因为它直接约束了 Agent 的回答方式:不是先给建议,再补理由,而是先找依据,再输出结论。

这才是“幻觉少”的真正起点。

实操二:openclaw.json 应该怎么组织,才能形成独立调试上下文

如果你希望 Telegram 某个特定 topic 专门承担 OpenClaw 的缺陷修复和配置调优,那么 openclaw.json 里至少要把三件事绑定在一起:

  • • 这个 topic 路由到哪个 agent
  • • 这个 agent 是不是 ACP 持久会话
  • • 这个会话的工作目录是不是 OpenClaw 项目根目录

当前本机配置里,已经有一组实际在跑的结构:Telegram 某个 topic 绑定到 codexacp.mode 是 persistentacp.cwd 直接指向 /usr/local/lib/node_modules/openclaw/。为了避免暴露真实群组 ID、topic ID、token 和账号信息,我这里贴一个脱敏后的参考片段:

{
  "agents"
: {
    "list"
: [
      {

        "id"
: "codex",
        "name"
: "codex",
        "workspace"
: "<WORKSPACE_ROOT>",
        "runtime"
: {
          "type"
: "acp",
          "acp"
: {
            "agent"
: "codex",
            "backend"
: "acpx",
            "mode"
: "persistent",
            "cwd"
: "/usr/local/lib/node_modules/openclaw"
          }

        }

      }
,
      {

        "id"
: "claude",
        "name"
: "claude",
        "workspace"
: "<WORKSPACE_ROOT>",
        "runtime"
: {
          "type"
: "acp",
          "acp"
: {
            "agent"
: "claude",
            "backend"
: "acpx",
            "mode"
: "persistent",
            "cwd"
: "/usr/local/lib/node_modules/openclaw"
          }

        }

      }

    ]

  }
,
  "bindings"
: [
    {

      "type"
: "route",
      "agentId"
: "codex",
      "match"
: {
        "channel"
: "telegram",
        "accountId"
: "default",
        "peer"
: {
          "kind"
: "group",
          "id"
: "<GROUP_ID>:topic:<TOPIC_ID>"
        }

      }

    }
,
    {

      "type"
: "acp",
      "agentId"
: "codex",
      "match"
: {
        "channel"
: "telegram",
        "accountId"
: "default",
        "peer"
: {
          "kind"
: "group",
          "id"
: "<GROUP_ID>:topic:<TOPIC_ID>"
        }

      }
,
      "acp"
: {
        "mode"
: "persistent",
        "cwd"
: "/usr/local/lib/node_modules/openclaw",
        "backend"
: "acpx"
      }

    }

  ]
,
  "channels"
: {
    "telegram"
: {
      "enabled"
:true,
      "threadBindings"
: {
        "spawnAcpSessions"
:true
      }

    }

  }

}

这段配置最重要的不是字段多,而是它把“入口、会话、工作目录”锁在了一起。以后你在这个 topic 里说“先看代码,再改配置”,Agent 进入的就是 OpenClaw 自己,而不是别的项目。

如果你更偏向 Claude Code,也可以把同样的结构绑定给 claude。原则不变,区别只在具体 harness。

实操三:自动修复 openclaw.json,重点不是自动,而是最小 patch

我现在其实不太喜欢“自动配置”这种说法,因为它很容易让人误以为重点是省事。

对 OpenClaw 来说,真正重要的不是自动,而是最小、可证实、可回退。

如果一个 Agent 没看代码、没看文档、没看当前配置,就直接去改 openclaw.json,那所谓自动化只是把错误放大而已。

但如果它已经把前面的证据链走完了,情况就完全不同了。它此时输出的 patch,不再是“帮你试一把”,而是“根据当前实现和当前配置,建议做这一处最小改动”。

在我看来,一个合格的修复请求,至少应该让 Agent 完成下面这几步:

  1. 1. 指出当前问题属于配置、实现还是运行时行为
  2. 2. 给出对应的代码或文档依据
  3. 3. 说明准备修改 openclaw.json 的哪个字段
  4. 4. 说明为什么改这个字段,而不是改别的字段
  5. 5. 输出最小 patch,而不是整份重写
  6. 6. 改完后说明如何生效和如何验证

也就是说,你不是让 Agent 替你“写配置”,而是让它替你“生成可解释的配置变更”。

实操四:重启规则,必须从操作习惯升级成执行策略

很多配置不是改坏的,而是重启重坏的。

这句话在 OpenClaw 上尤其成立。

因为 OpenClaw 的很多使用场景并不是本地单机命令执行完就结束了,它还牵涉消息通道、ACP 会话、上下文绑定、配置生效和后续验证。这个时候,重启方式本身就成了修复链条的一部分。

你给我的那份重启规则文稿,我认为非常关键。它真正有价值的地方,不是提醒你“少乱来”,而是把一件常常被临时处理的事,明确成了长期策略:来自消息通道的重启请求,默认走进程内重启,而不是直接做服务级重启。

OpenClaw 的工具文档也能对上这一点:restart 本质上是给 Gateway 发 SIGUSR1,而 config.applyconfig.patch 本身就承担了写配置、重启和唤醒的职责。

所以对我来说,这条规则不该只是记在文档里,而应该写进记忆里。因为它已经不是某次排障的经验,而是以后每次调 OpenClaw 都应该默认调用的执行策略。

这里我把可直接复用的重启原则也压缩成一版,方便你贴进记忆或规则文件:

重启 OpenClaw 的默认规则:

1. 任何来自聊天通道的“重启 OpenClaw / 重启网关 / 应用配置并重启”请求,默认只能走进程内重启。
2. 优先使用 config.patch、config.apply、/restart 或 gateway 内部 restart 路径。
3. 严禁默认把聊天中的重启请求转换为 openclaw gateway restart、stop、start,或 launchctl bootout、bootstrap、kickstart。
4. 只有在明确确认服务损坏、LaunchAgent 未加载、或 SIGUSR1 重启失败时,才进入修复流程。
5. 进入修复流程时,先 doctor --fix,再查 gateway status,仍未恢复时才考虑服务级重启。
6. 默认目标是零卸载、零 bootout、最小中断。

这段规则的意义,不在于“看起来规范”,而在于它能保住你最宝贵的东西:消息通道和连续上下文。

最终体验,应该是“基于证据的自动修复”

如果把这套方法真正跑顺,最终体验应该很清楚。

你在一个固定的 Telegram topic 里,调用 Codex 或 Claude Code 处理 OpenClaw 本身。Agent 进入之后,不是直接改配置,而是先读项目代码、文档、规则文件和当前配置;确认问题归属之后,再生成最小 patch;配置生效时走正确路径;重启之后继续在同一个上下文里验证结果。

这套流程最打动我的地方,不是它足够自动,而是它足够克制。

它不假装自己什么都知道,不靠术语堆出一种“好像已经定位”的感觉,也不把修改动作变成试错游戏。它做的事情很简单:先把代码和文档读透,再动手。

我现在对 OpenClaw 缺陷修复和配置最佳实践的看法,基本可以压缩成一句话:

不要让 Agent 替你猜配置,要让 Agent 替你先读代码。

只有这样,自动修复才不是一种更快的冒险,而是一种更稳的工程方法。