本地 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 这样的长期工具规则文件,就是把一次次经验变成稳定行为的地方。