本地 AI 代理系统真正进入长期使用阶段后,最重要的问题不再只是“它能不能完成任务”,而是“它以后会不会按照稳定、可预期、边界清楚的方式完成任务”。

一次迁移、一次修复、一次浏览器调用、一次误操作事故,如果只停留在当前对话里,很快就会消失。下一次再遇到类似场景,代理可能重新犯同样的错误。

因此,迁移完成后的一个重要收尾工作,是把经验写入长期规则文件。

在这个过程中,TOOLS.md 成为最关键的文件之一。

为什么需要长期规则

AI 代理和普通脚本不同。

普通脚本只会执行写死的逻辑。AI 代理则会根据自然语言指令、上下文、工具可用性和自己的推断来决定下一步操作。

这带来灵活性,也带来风险。

如果只告诉代理:

需要浏览器时,连接桌面机上的 Brave。

它可能会自己推断出很多没有被允许的做法:

- 创建 systemd 服务
- 设置开机自启
- 写 wrapper 脚本
- 打开防火墙端口
- 使用 headless 替代可见窗口
- 为了释放端口 kill 浏览器
- 为了恢复干净状态清理进程

这些推断未必是恶意的,但可能与实际使用场景冲突。

因此,长期规则的作用不是单纯记录“怎么做”,还要记录:

- 什么情况下才做
- 应该按什么顺序做
- 失败时怎么报告
- 绝对不能做什么
- 哪些资源属于代理
- 哪些资源不属于代理
- 自然语言指令应该如何解释

对长期运行的 AI 代理来说,负面边界和正向流程同样重要。

日期记忆不适合保存持续规则

很多代理工作区会有按日期排列的记忆文件,例如:

memory/2026-06-27.md
memory/2026-06-28.md

这类文件适合记录当天发生了什么:

- 今天修复了某个问题
- 今天迁移了某个目录
- 今天确认了某个状态
- 今天做了一次审计

但它们不适合作为长期规则的唯一来源。

原因是日期文件本质上是事件记录,而不是行为规范。代理以后要决定如何调用工具时,不一定会优先读取某一天的历史记录。

例如:

2026-06-27:修复 Mars 浏览器/CDP 规则

这条记录能说明事情发生过,但不能保证代理以后每次用浏览器都遵守这些规则。

因此,持续规则应该写入专门的规则文件。

为什么浏览器规则应该写入 TOOLS.md

在 OpenClaw 工作区中,不同 Markdown 文件承担不同职责。

抽象上可以这样划分:

IDENTITY.md:
- 代理身份
- 基本定位

USER.md:
- 用户偏好
- 用户长期信息

SOUL.md:
- 风格
- 长期价值取向
- 交互气质

HEARTBEAT.md:
- 当前运行状态
- 健康检查
- 活跃状态

MEMORY.md:
- 记忆说明
- 记忆索引
- 长期记忆组织方式

AGENTS.md:
- 多代理协作
- 角色分工

TOOLS.md:
- 工具调用规则
- 外部能力使用方式
- 命令边界
- 资源权限

远程浏览器/CDP 能力本质上是一个工具。它不是用户偏好,也不是人格设定,也不是普通历史记忆。

它包含:

- 外部主机
- SSH 连接方式
- 浏览器 profile
- CDP endpoint
- tunnel 端口
- 启动流程
- 关闭规则
- 禁止操作

所以它应该写入 TOOLS.md

这能让代理在以后调用浏览器时,把它当作一个受约束的工具,而不是凭当前对话临时推断。

工具规则不只是命令

一个常见误区是把工具规则写成几条命令。

例如:

ssh 到桌面机
启动 Brave
建立 tunnel
访问 CDP endpoint

这还不够。

真正可长期使用的工具规则应该包含五个层次:

1. 资源定义
2. 使用前检查
3. 正常启动流程
4. 失败处理方式
5. 禁止操作边界

以远程浏览器为例,资源定义应包括:

- 桌面机地址
- SSH 用户
- Brave 程序路径
- 专用 user-data-dir
- 远程 CDP 端口
- 本地 tunnel 端口
- OpenClaw 使用的 endpoint

使用前检查应包括:

- 先确认桌面机是否在线
- SSH 是否可连接
- 如果无法连接,直接报告无法使用浏览器

正常启动流程应包括:

- 从真实图形会话读取 DISPLAY
- 读取 XAUTHORITY
- 读取 DBUS_SESSION_BUS_ADDRESS
- 使用专用 profile 启动 Brave
- 确认远程 /json/version 可用
- 建立 SSH tunnel
- 确认本地 endpoint 可用

失败处理方式应包括:

- 可见窗口启动失败时,不自动切 headless
- 端口被占用时,不自动 kill
- 无法确认进程归属时,不关闭任何浏览器
- 外部主机离线时,不继续执行浏览器任务

禁止操作边界应包括:

- 不创建 systemd 服务
- 不设置开机自启
- 不创建额外 wrapper 脚本
- 不暴露 CDP 到局域网
- 不管理普通浏览器
- 不执行模糊 kill

这种规则比单纯命令更可靠。

把“默认不做什么”写清楚

AI 代理在执行任务时,常常会为了完成目标而主动补全步骤。

例如,浏览器打不开时,它可能推断:

也许需要改用 headless。
也许需要杀掉旧浏览器。
也许需要释放端口。
也许需要创建常驻服务。
也许需要清理旧状态。

这些推断在某些服务器任务中可能合理,但在个人桌面环境里可能非常危险。

因此,规则中必须写明“默认不做什么”。

例如:

默认不使用 headless。
默认不关闭浏览器。
默认不 kill 进程。
默认不清理端口。
默认不创建服务。
默认不追求干净状态。
默认不影响用户正在使用的桌面程序。

这类规则可以阻止代理在任务失败时擅自扩大操作范围。

尤其是在浏览器事故后,“默认不 kill”比“谨慎 kill”更安全。

自然语言语义也要固定

工具规则不只约束命令,也约束语言理解。

在浏览器任务中,“浏览器”这个词本身就可能产生歧义:

普通理解:
- 用户当前使用的浏览器

代理任务语境:
- OpenClaw 专用 CDP 浏览器

如果不写清楚,用户一句“关闭浏览器”,代理可能错误理解成关闭桌面上所有 Brave 窗口。

因此,规则中应明确:

在 Mars 浏览器任务语境中:
“浏览器”默认只指 OpenClaw 专用 Mars CDP Brave。
不指用户普通 Brave。
不指所有 Brave。
不指桌面上所有浏览器窗口。

这类语义规则非常重要,因为 AI 代理不是机械执行 API,而是在理解自然语言。

当自然语言存在歧义时,长期规则必须给出默认解释。

资源边界必须具体到路径

抽象说“不要影响普通浏览器”不够。

代理需要知道什么属于它、什么不属于它。

因此,规则必须具体到路径和条件。

例如:

属于 OpenClaw 的浏览器资源:
- 专用 CDP profile
- 通过该 profile 启动的 Brave
- 明确带有指定 remote-debugging-port 的进程

不属于 OpenClaw 的资源:
- 普通 Brave profile
- 普通 Brave 窗口
- 普通 Brave 标签页
- 普通 Brave 会话
- 未明确使用专用 profile 的 Brave 进程

判断进程归属时,也必须写成硬条件:

命令行必须包含专用 user-data-dir
命令行必须包含 remote-debugging-port

不能用这些条件:

- 程序名是 brave
- 路径里有 /opt/brave-bin/brave
- 进程里出现 Chrome
- 端口是 9222
- 看起来像浏览器进程

因为普通浏览器和专用浏览器使用同一个程序本体。唯一可靠边界是专用 profile。

失败时应该报告,而不是修补

长期规则还应该定义失败处理方式。

对 AI 代理来说,一个常见问题是:失败后过度修补。

例如:

可见窗口启动失败 -> 自动改 headless
端口占用 -> 自动 kill
SSH tunnel 失败 -> 自动创建服务
浏览器退出 -> 自动设置 Restart=always

这些做法可能让当前任务继续推进,但会破坏系统边界。

更好的规则是:

如果失败原因涉及权限、图形会话、端口占用、进程归属不明,优先报告,不自动修补。

这种设计承认代理不是系统主人。它可以协助执行任务,但不能为了完成任务而改变系统长期行为。

把事故变成规则

一次误操作如果只停留在“以后小心”,价值有限。

更好的做法是把事故转化成规则。

例如,浏览器误杀事故后,规则需要从:

使用专用 profile 启动 Brave。

升级为:

禁止 pkill brave。
禁止 killall brave。
禁止按 /opt/brave-bin/brave 杀进程。
禁止关闭普通 Brave。
只能识别专用 profile 的进程。
关闭前必须列出候选 PID 和完整命令行。
找不到专用进程就不关闭任何浏览器。

这就是从经验到制度的转化。

AI 代理的可靠性不是通过一次提醒提高,而是通过把提醒写入长期规则提高。

规则要写成代理能执行的形式

规则不能写得太抽象。

例如:

小心不要影响普通浏览器。

这句话对人有用,但对代理不够具体。

更好的写法是:

绝对禁止执行:
- pkill brave
- pkill -f brave
- pkill -f /opt/brave-bin/brave
- killall brave
- ps ... grep brave ... xargs kill

关闭前必须列出候选 PID 和完整命令行。
候选 PID 必须同时满足:
- 命令行包含专用 user-data-dir
- 命令行包含 remote-debugging-port

可执行规则应该有明确条件、明确禁止项和明确失败行为。

也就是说,规则应尽量从“提醒”变成“判断逻辑”。

工具规则也需要持续修订

长期规则不是一次写完就永远不变。

在本次迁移和收尾过程中,浏览器规则经历了多次加固:

第一版:
- 记录 SSH 启动 Mars Brave
- 记录 CDP endpoint
- 记录 tunnel

第二版:
- 不创建 systemd
- 不开机自启
- 不写 wrapper 脚本
- 不暴露 CDP

第三版:
- 可见窗口优先
- 不自动 headless
- 读取真实图形会话环境

第四版:
- 禁止影响普通 Brave
- 禁止模糊 kill
- 只识别专用 profile

第五版:
- “浏览器”默认只指专用浏览器
- 关闭浏览器也只能关闭专用 profile
- 无法确认归属就不关闭

这种迭代是正常的。

真正危险的是规则没有更新,导致代理下次仍按旧理解行动。

MEMORY.md 和 TOOLS.md 的关系

TOOLS.md 保存具体工具规则,但不一定适合保存所有历史背景。

如果要记录“为什么会有这条规则”,可以在记忆文件或总结中保留简短背景:

曾经发生过远程浏览器误杀普通 Brave 的事故,因此 TOOLS.md 中对 Mars Brave CDP 工具设置了严格边界。

但具体执行规则仍然应该放在 TOOLS.md

可以理解为:

MEMORY.md / memory/*.md:
- 记录发生过什么
- 记录为什么形成某条规则

TOOLS.md:
- 记录以后具体怎么做
- 记录哪些命令可以用
- 记录哪些操作禁止

这种分工能避免日期记忆越来越长,也避免工具规则散落在历史记录中。

规则文件不是给人看的备忘录,而是代理的操作边界

TOOLS.md 表面上是一个 Markdown 文件,但在 AI 代理系统中,它更像是操作边界文档。

它回答的是:

这个代理在调用外部工具时,能做什么?
不能做什么?
出错时该怎么停下来?
哪些资源属于它?
哪些资源不属于它?

对本地 AI 代理来说,这比普通日志重要得多。

日志记录过去。

规则约束未来。

给代理写规则时的通用模板

把经验写成长期规则时,可以使用一个通用模板:

工具名称:
- 这个工具是什么

资源范围:
- 它可以访问哪些主机、目录、端口、profile

使用前检查:
- 使用前必须确认什么

标准流程:
- 正常情况下按什么顺序操作

失败处理:
- 哪些失败应该报告
- 哪些失败不能自动修复

禁止操作:
- 明确列出不能执行的命令或行为

语义规则:
- 用户简短表达时应该如何解释

关闭/清理规则:
- 是否允许关闭
- 关闭什么
- 不能关闭什么

验收标准:
- 怎么确认操作成功

这个模板不仅适用于浏览器,也适用于其他工具能力,例如:

- 文件同步
- 数据库操作
- 系统服务管理
- 消息通道
- Webhook
- 远程主机调用
- 大型项目目录访问

每一个高风险工具都应该有自己的边界。

小结

本地 AI 代理要长期可靠运行,不能只依赖当前对话中的临时理解。

迁移、修复、事故和清理过程中产生的经验,必须被写入长期规则。

这次最重要的规则沉淀包括:

- Mars 浏览器/CDP 是工具能力,规则写入 TOOLS.md
- 日期文件只记录事件,不作为唯一长期规则来源
- 浏览器任务必须先检测远程主机在线
- CDP 不暴露到局域网
- 不创建 systemd
- 不开机自启
- 不写额外 wrapper 脚本
- 可见窗口优先,不自动 headless
- 普通 Brave 不属于 OpenClaw
- 禁止模糊 kill
- “关闭浏览器”默认只关闭专用浏览器
- 无法确认归属就不关闭

这些规则的意义不是让代理变得保守,而是让它变得可控。

AI 代理真正可靠的关键,不是它每一次都能临场猜对,而是它在关键边界上没有自由发挥的空间。

对于本地基础设施型代理来说,TOOLS.md 这样的长期工具规则文件,就是把一次次经验变成稳定行为的地方。

Leave a Reply

Your email address will not be published. Required fields are marked *