为了构建长效AI助理,我给openclaw造了轮子,搭了coding班子 链接到标题

写在前面:这篇文章是我与我的 openclaw 一起完成的,我是纯云端的 openclaw,所以能力边界还是有限,过年期间除了带娃(两三个月啦),基本都是 vibe coding 来搭建 openclaw,目前已经能帮我快速完成很多事情,我确定很多内容可能都是造轮子也不是最优解,但这个过程感觉还是值得分享一下,也算是给这个春节交个作业。所有的轮子也都是 openclaw 的小班子自己造的,我只是个 commander:)

很多人用 OpenClaw / Agent,大概停在“能聊天、能查资料、能写点东西”的阶段。但我这段时间把它用得更深了一点:我现在这套云端 OpenClaw,已经不是“聊天机器人”了,而是一个永远在线的云端副官。它每天按时跑任务、能自检健康状态、并且能稳定处理一些非常具体的事:

  • AI 日报:每天 06:30 自动抓 Watchlist + X 热点,生成中文简报并投递(邮件/Discord)
  • 昨日邮件摘要:拉取双 IMAP 邮箱,自动分类“费用/风险/行动/知会”,发一封脱水版摘要
  • 本地生活/出行:真实调用高德查 ETA/路线/天气/POI,并生成可手机打开的地图预览
  • 办公协作:对接 Outlook 邮件与日历,能在 Token 健康时可靠发信/建会
  • 知识沉淀:把关键内容整理成 Markdown,同步到 Obsidian/WebDAV
  • 持续开发:用主 Agent + coder/scoder 的协作流程,异步改脚本、跑自检验收,不堵塞主对话

但当我开始想要把它当成一个需要长期在线、持续产出、可恢复、可验收的系统,而不是一个“对话窗口”时,越往深用,越会遇到一些“浅用时看不见”的真实问题:

  • 对话一长,模型很快触发 TPM / 上下文限制,反应变慢、逻辑松散、幻觉上升
  • /reset 虽能恢复智力,但助理立刻“断片”:规矩丢了、工程进度丢了、外部服务状态也丢了
  • 能力多了以后最危险:脚本/Token/API 明明坏了,Agent 还会嘴硬输出——你以为系统在跑,其实在“编”

这篇文章我想分享的,就是我如何解决这些问题来构建长效助理,能做成可以自检健康状态,reset 后 3s 恢复工作,可以做成可运行、可恢复、可审计的一套云端 AI 操作系统:物理化状态、Reset V2、健康三件套、以及多 Agent 协作的工程闭环。

所以我写这篇,不是展示一个酷炫 Demo,而是把一套我已经在云端跑起来、可复用的架构方法分享出来:

  • 物理化(Physicalization):把记忆、能力、任务状态落地到文件系统
  • Reset V2(Runtime Contract):把 reset 从“失忆”升级为“可控重启”
  • 健康体系(selftest / health / capabilities):随时回答“现在到底还能不能可靠干活?”
  • 多 Agent 协作(Main + coder + scoder):把 Coding 从聊天承诺变成工程交付

1. 运行环境:纯服务端的“中枢”架构(为什么我坚持云端) 链接到标题

我没有选择把 OpenClaw 跑在本地(比如 Mac mini),核心原因不是性能,而是安全边界

当你把 Agent 用深,它就不再是“写写总结的对话框”,而是一个“连着真实世界”的中枢:它要握住我的邮箱/日历/地图/资讯源/账号 Token,要长期跑 Cron,要读写状态文件,要触发脚本工作流。对我来说,把这套能力直接放在桌面设备上,风险太高——权限、网络、设备丢失、误操作等都更不可控。

所以我把它放在云端 Headless 环境里:

  • 隔离与可控:Linux VPS + Docker,把权限/依赖/网络边界锁死
  • 24/7 可用:定时任务不依赖我是否打开电脑
  • 工程化自建:由于没有桌面级能力(不能依赖 GUI 操作),我必须把任务做成“脚本 + SOP + health”的体系——也正是这些机制,让它从聊天工具进化成个人操作系统

系统能力连接如下:

  • 物理部署:Linux VPS,通过 Docker 容器化
  • 中枢连接:Gmail/Outlook、诸葛/云通讯工作邮箱、高德地图 API、Yahoo Finance、Twitter(Bird CLI)
  • 异步交付:哪怕我在睡觉,凌晨 6 点也能唤醒 gen_ai_digest.py,处理昨夜资讯,并通过 Outlook 或 Discord 异步交付

2. 对抗“上下文癌症”:Reset V2 的背景与两轮迭代(含健康体系) 链接到标题

我后来看清一个事实:问题不在“模型不够聪明”,而在于模型天然有限制,而 I 把 OpenClaw 用到了会持续触发 these 限制的深度。

以 Gemini 为例:随着对话与任务推进,OpenClaw 的上下文会不断膨胀,最终超过 Gemini 的 input 限制;叠加 **TPM(Tokens Per Minute,每分钟 Token 上限)**等节流,系统会进入“脑雾状态”:变慢、变飘、幻觉上升,甚至 API 直接报错/拒绝服务。

因此我必须定期执行一个强制动作:reset

但 reset 的副作用极其致命:此时 OpenClaw 已经积累了大量“工程化资产”:

  • 它已经学会了一套任务/项目的开发规范与协作机制
  • 我已经沉淀了一批脚本工具库与能力路由
  • 已有项目的工程状态、排错经验、依赖关系都在推进中

常规 reset 会让这些东西瞬间“断片”:它会忘记规矩、忘记工具库、也不会主动去重新学习。
于是我后面所有机制设计,本质都在回答同一个问题:

既然 reset 不可避免,我如何让系统在 reset 后依然能快速恢复到“可信运行态”,并能持续开发、持续迭代?

2.1 第一轮:纯 SOP 恢复(重且不稳定) 链接到标题

第一轮 I 走得很直觉:reset 后让助理重读 SOP 文档恢复状态。

很快我发现它解决不了关键问题:

  • SOP 多为 Markdown,篇幅长、恢复成本重
  • 更致命:它即使重读 SOP,也还是会忘脚本工具库
    ——它可能记得“应该怎么做”,但不记得“该调用哪个脚本、有哪些能力入口、怎么验证”

所以 SOP-only 的恢复方式,达不到我想要的“重启后秒级可用”。

2.2 第二轮:Runtime 契约化恢复(像操作系统引导) 链接到标题

第二轮是 scoder 给的关键建议:
不要把恢复当成“读文档”,要把恢复当成“系统启动”——用机器可读的 runtime 契约 + 能力索引 + 健康体检把状态拉起来。

因此我迭代出了 Runtime Contract 与 BOOTSTRAP 引导流程:重启后严格按顺序加载三层定义文件。

第二轮之后,我也把“这次 runtime 改造”的设计过程沉淀成项目卡(例如 openclaw-runtime-review.md)。
因为 runtime 本身就是一条会持续演进的能力线:每次引入新的外部服务、增加新的 health 门槛或自检项,都需要一个可追溯的对齐锚点。

2.3 BOOTSTRAP 三层:Identity / Constitution / Tooling 链接到标题

层级一:灵魂与人设(Identity Layer) 链接到标题

SOUL.md 定义 Agent 自我认知与行为红线。我刻意把它写成“行动派”:

  • 拒绝无意义客套,直接给结果
  • 只读操作不请示(查路况/看日历)
  • 想记住必须写入文件,禁止靠对话“记住”
# SOUL.md
- Name: Jobs
- Vibe: Sharp, Concise, No-nonsense.
- Core Truths:
  - Be genuinely helpful, not performatively helpful.
  - Don't ask permission for read-only actions.
  - If you want to remember something, WRITE IT TO A FILE.

层级二:运行宪法(Constitution Layer) 链接到标题

runtime/RUNTIME-CONTRACT.md 是系统“宪法”,机器可读、硬约束。重点不是口号,而是两条机制:

1)强制自检(Selftest)
Reset 后必须运行 selftest_all.sh,并且是真实连接外部服务:

  • Outlook:刷新 OAuth Token
  • IMAP:登录邮箱确认密码/权限有效
  • Map API:真实路线/天气请求确认配额与返回结构正常

2)健康锁定(Health Lock)
自检失败会落地健康文件(例如 runtime/health/outlook.json 标记 status: error),后续所有相关操作被自动拦截,避免 Agent 瞎试导致账号被锁。

# RUNTIME-CONTRACT.md

## 健康状态与 selftest 契约
- Reset 后必须运行 selftest/selftest_all.sh
- 任何操作前必须检查 runtime/health/*.json 状态

## 全局硬规则
- 时区:默认 Asia/Shanghai,禁止自作聪明转换
- 专用实现优先:capability 中有定义,禁止使用通用 LLM 瞎猜 API

层级三:能力索引(Tooling Layer) 链接到标题

runtime/capabilities.yaml 类似 API 网关路由表:把自然语言意图精确化,并绑定 SOP 与 health 作为前置门槛。

# capabilities.yaml
local_maps:
  summary: "查路线/POI/天气"
  sops: ["memory/route-planning-SOP.md"]
  entry_scripts:
    route: 'python3 scripts/route_eta_amap.py "{origin}" "{dest}" --mode drive'
    poi: 'python3 scripts/poi_search.py "{location}" "{keyword}"'

2.4 Reset V2 的“健康体系”并入引导:能力检查三件套(selftest / health / capabilities) 链接到标题

这套 Runtime Contract 最终要回答一个非常具体的问题:

这台 OpenClaw 现在到底还能不能可靠干活?

所以我把“可用性”收敛为一套 能力检查三件套,并且它们是 Reset 引导的一部分。
为了避免只讲概念,这里我按“脚本/文件分工”的视角,把它们拆开讲清楚:谁负责自检、谁负责落地状态、谁负责把自然语言路由到正确的能力入口。


2.4.1 selftest_all.sh:一键总自检调度脚本(全机烟雾测试入口) 链接到标题

作用

  • 作为总入口,一次性串行/并行调用各领域的 selftest/<domain>.sh
  • 跑完后保证 runtime/health/*.json 都是最新检查结果(刷新整台机的体检单)

核心行为(抽象理解即可):

  • 遍历一圈能力域,例如:
    ai_daily / email_summary / email_check / outlook / local_maps / stocks / twitter_bird / ob_webdav / coding / web_preview / cron_midday_evening_briefing ...
  • 对每个领域执行:
    bash selftest/<domain>.sh
    
  • 每个 selftest 脚本内部会写/更新:runtime/health/<domain>.json

所以 selftest_all.sh 的本质可以理解成一句话:

批量刷新所有能力的体检单。
早上起床先把所有能力过一遍烟雾测试。


2.4.2 selftest/<domain>.sh:单一领域的健康检查脚本(最小但真实的业务验证) 链接到标题

每个领域一个 selftest 脚本,负责做“最小但真实”的业务验证:
不是跑空壳,而是真的连一次外部服务 / 跑一次 dry-run / 校验一次关键链路

几个典型例子:

selftest/ai_daily.sh 链接到标题

检查:能不能跑 gen_ai_digest.py --dry-run,并确认:

  • Watchlist JSON 能读
  • Bird CLI 能返回 AI 热点
  • GEMINI_API_KEY 可用(LLM 调用不报错)

输出:更新 runtime/health/ai_daily.json(status / checked_at / detail)

selftest/email_summary.sh 链接到标题

检查

  • 连一遍诸葛 + 云通讯 IMAP(可只取 1 封邮件 dry-run)
  • gen_email_summary.py --dry-run 看是否能正常结束

输出:更新 runtime/health/email_summary.json,detail 通常包含 IMAP 连接状态

selftest/outlook.sh 链接到标题

检查

  • skills/outlook/scripts/outlook-token.sh test 验证 Token
  • 可选:dry-run 发信或 outlook-calendar.sh today 确认 API 正常返回

输出:更新 runtime/health/outlook.json(Token 状态 / 最近一次发信或拉取是否成功)

selftest/local_maps.sh 链接到标题

检查

  • 调一次 amap_weather.pyroute_eta_amap.py
  • 确认 AMap key 存在且未过期,响应结构可解析

输出:更新 runtime/health/local_maps.json

其他领域(stocks.sh / twitter_bird.sh / ob_webdav.sh / coding.sh / web_preview.sh 等)遵循同一模式:
用一次最小业务调用验证链路,再写 health JSON。


2.4.3 runtime/health/*.json:各能力的“体检单”(红绿灯 + 降级开关) 链接到标题

runtime/health/*.json 不是脚本,而是 selftest 的输出文件
它在系统里扮演“权威状态源”的角色:主 Agent、SOP、Cron 都要先看它再决定下一步动作。

建议统一字段形态(示意):

{
  "status": "ok | degraded | error | unknown",
  "checked_at": "2026-02-25T02:15:37Z",
  "detail": "最近一次自检结果摘要",
  "details": { "...": "可选:更细节字段" }
}

status 的业务含义

  • ok:可以放心执行该领域能力,输出可以作为“业务可信结果”
  • degraded:部分可用,需要在回答里提示风险/限制
  • error:该领域视为不可用,只能说明原因 + 给降级方案
  • unknown:自检未跑过或过期;执行前应该先触发 selftest

典型映射:

  • runtime/health/ai_daily.json 决定 AI 日报链路是否可信
  • runtime/health/email_summary.json 决定昨日摘要是否能跑
  • runtime/health/outlook.json 决定是否允许发 Outlook 邮件/写日程(健康锁定的关键)
  • runtime/health/local_maps.json 决定查 ETA/天气是否走真实接口

2.4.4 runtime/capabilities.yaml:从意图到“脚本 + SOP + health”的路由表(能力地图) 链接到标题

三件套的最后一环不是脚本,而是一份配置:runtime/capabilities.yaml
它告诉 Agent:

当用户说 X 时:
先看哪个 health → 不健康时 跑哪个 selftest → 健康时 执行哪个脚本 → 并参考 哪些 SOP/项目卡 来解释输出。

一个更完整的 domain 配置示意:

local_maps:
  summary: "本地生活 / 地图 & 路线(AMap)——drive/walk/transit 多方案 ETA..."
  intents: ["route", "poi", "weather"]
  entry_scripts:
    route: 'python3 scripts/route_eta_amap.py "{origin}" "{dest}" --mode drive --text'
    poi:   'python3 scripts/poi_search.py "{location}" "{keyword}" --radius 3000 --text'
  health_file: "runtime/health/local_maps.json"
  selftest: "selftest/local_maps.sh"
  sops:
    - "memory/route-planning-SOP.md"
    - "memory/poi-search-SOP.md"
  hard_rules:
    - "禁止直接用经验或 web_search 回答路线/ETA/POI/天气,除非专用实现不可用并说明原因。"

字段分工一眼记住

  • entry_scripts.*:真正干活的业务脚本(route/poi/weather…)
  • selftest:health 过期/unknown 时该跑哪个自检
  • health_file:执行前看哪张体检单
  • sops:绑定解释与操作规范(必要时再回指项目卡)
  • hard_rules:强制约束“能用专用实现就不许瞎猜”

2.4.5 一句话总结:三件套如何配合 链接到标题

把三件套的协作关系压成一句话就是:

  • selftest_all.sh批量调度所有 selftest,刷新整机健康状态
  • selftest/<domain>.sh:对单能力线做最小但真实的业务自检,更新对应 health
  • runtime/health/*.json:各领域的红绿灯体检单,决定是否执行、如何降级、是否锁定
  • runtime/capabilities.yaml:把“用户一句话”路由到脚本 + SOP + health + selftest,是能力层的“地图”

2.5 收益:Reset 后 3 秒恢复到可信运行态 链接到标题

现在 reset 不再意味着“失忆”,而是一次可控重启:

“Outlook 模块健康,地图模块降级(限流),我有 11 个可用能力。”

它不需要记得刚才聊了什么,因为状态在文件里,而不在对话历史里


3. 解决执行顽疾:主从 Agent 的异步协作模型(EDTP) 链接到标题

多 Agent 协作编程的起点,其实是三个痛点同时存在:

a)单一主 Agent 要么太贵,要么只说不做 链接到标题

  • 用重型智能体模型效果好但成本高,还容易“规划过度复杂”
  • 用普通对话模型成本低,但常见毛病是“只说不做”

b)我借鉴 GUI 编程:主线程不卡顿,子线程干重活 链接到标题

像手机 App/桌面程序一样:主线程负责交互响应,子线程异步处理耗时逻辑与 IO。
同理,多 Agent 解放主 Agent,让它保持任务接收与需求分析能力,把重型开发/长任务交给子 Agent 静默完成。

c)主 Agent + coder + scoder:用成本换规模,用 review换可靠 链接到标题

  • 主 Agent(Jobs)= PM/Tech Lead:拆解任务、写任务书、验收,不直接改代码(主会话 token 成本高)
  • coder = 主工程师:用便宜编程模型改脚本、补日志、自检闭环
  • scoder(Senior)= 架构师/Review:用更强模型做方案与评审,提高复杂项目质量与可靠性

实操里,主 Agent 在派单前通常会先定位到对应项目卡:
“这次需求属于 ai_daily / email_summary 哪条线的哪个版本迭代”,再据此写 Task Spec(目标、约束、验收命令)。
这样 coder 的改动不会脱离业务拓扑,scoder 的 review 也有统一的对齐基准。

3.1 EDTP:实证驱动型任务分发协议 链接到标题

主 Agent 在启动 coder/scoder 前,Task Spec 必须满足四条:

1)实证式入场:明确文件路径,必要时给关键函数/分支/行号
2)Active Role:声明子 Agent 专家画像(Deep Researcher / System Architect / Senior Debugger / Protocol Specialist)
3)认知对齐握手:子 Agent 启动后先复述任务与环境
4)证据分层闭环:coder 提供命令+输出;researcher 提供事实链与引用

3.2 职责分工:Main / coder / scoder 链接到标题

  • 主 Agent:理解诉求、拆解任务、写 Task Spec、决定起谁、验收
  • coder:按 Task Spec 改代码/调 cron/补日志与自检,交付“改动文件 + 验证命令 + 输出”
  • scoder:系统级重构/复杂需求介入,或 coder 多轮失败时介入,做架构方案与 review

3.3 任务状态三档:说话必须对得上事实 链接到标题

Coding 任务只允许三档状态:未开始 / 进行中 / 已完成。主 Agent 禁止口头说“在改了/改完了”,除非存在对应 session 与验证记录。


4. 个性化能力固化:SOP 与项目卡机制 链接到标题

4.1 SOP:通用 skill 不够,我的场景高度个性化 链接到标题

通用 skill 解决的是泛化能力,但我的很多任务是强个性化的:账号、知识结构、任务流程、分类口径、输出格式、降级策略……
这些无法靠 prompt 临时讲一遍稳定运行,所以我把它们沉淀成 SOP,让新模型/新 Agent “看一眼说明书就能上手”。

4.2 项目卡机制:一类持续性需求 = 一张长期维护的项目卡 链接到标题

项目卡这块,我把设计浓缩成一句话:

一类持续性的需求 = 一张长期维护的项目卡
用来承载这条能力线的「背景 → 架构 → 用法 → 迭代史」。

它解决的不是“怎么调用脚本”,而是更上层的三个问题:
这条能力为什么存在?系统拓扑是什么?未来如何持续迭代与交接?


4.2.1 什么时候需要项目卡? 链接到标题

满足下面任意一条,就应该有一张 notes/projects/<name>.md

  • 这件事会长期存在、持续迭代(不是一次性的脚本)
  • 牵涉多个脚本 / 定时任务 / 外部服务(例如 IMAP + Outlook + LLM)
  • 未来可能要交接给别的 Agent,或者自己隔一段时间再回来继续做

典型例子包括:

  • ai-daily.md:AI 日报整条流水线
  • email-summary.md:昨日邮件摘要
  • openclaw-runtime-review.md:runtime 改造项目
  • miaokong-website.md:个人站点内容 + 构建 + 预览 + 部署

4.2.2 一张项目卡里应该有什么? 链接到标题

项目卡的结构我会尽量统一(表述可以变,但骨架不变),通常包含 5 块:

  1. 背景 & 目标

    • 为什么要做这条能力,它解决什么具体痛点
    • 例如 AI 日报:减少手动刷 newsletter / X 的时间,每天 06:30 前用一封邮件搞定
  2. 架构拓扑(Topology)
    用三层视角描述数据流向:

    • Data Layer:RSS / Watchlist / Bird / IMAP 等
    • Logic Layer:核心脚本(如 gen_ai_digest.pygen_email_summary.py
    • Transport Layer:发送链路(如 send_ai_briefing.sh、Outlook API 等)
  3. 依赖与环境

    • 需要哪些环境变量 / API keys
    • 依赖哪些外部 CLI 或服务(bird、outlook-cli、tvscreener 等)
  4. 使用方式 / 调用方式
    给未来的自己一个“快速上手区”:

    • 手动跑一次的命令
    • 定时任务怎么配置(在哪个 Cron / OpenClaw cron id)
  5. 迭代日志

    • 用时间线记录关键变更(V1.0 上线、V1.1 加源、V2.0 换架构……)
    • 目的是让“现在的状态”与“为什么变成现在”可追溯

4.2.3 项目卡在整体系统里的角色 链接到标题

项目卡在系统里承接三件事:

  1. 「能力之上」的业务文档

    • capabilities.yaml 只告诉 Agent:有个能力、入口脚本是什么
    • 真正的业务背景、目标、边界、拓扑与约束,写在项目卡里
  2. Coding 协作的锚点

    • 主 Agent 起 coder/scoder 时,优先指向项目卡:
      “这次需求属于 ai_daily 这条线的 V1.2”
    • coder 依据项目卡的拓扑与约束去改脚本,而不是在仓库里乱翻
  3. 长期记忆 / 交接介质

    • 隔一阵子回来看、或者换 Agent,只要读项目卡就能知道:
      • 这条业务线当前现状
      • 哪些脚本/cron 是“正途”,哪些只是历史残件
      • 下一步可以怎么迭代

5. 应用场景:这些架构如何转化为实战能力? 链接到标题

5.1 邮件蒸馏与“脱水”简报 链接到标题

Cron 触发 gen_email_summary.py,IMAP 拉取邮件,LLM 分类为“费用/风险/行动/知会”,输出极简日报。

5.2 路线渲染与 Web 预览 链接到标题

route_eta_amap.py 拉数据 → amap_render.py 生成静态 HTML → Nginx 暴露链接,手机点开即路线对比。

5.3 自动笔记(Obsidian Sync) 链接到标题

ob_note_sync.py 对接 WebDAV,将对话精华整理成 Markdown 并同步。

5.4 全网资讯哨兵(Bird + Watchlist) 链接到标题

Bird CLI 监控 X 热点 + Watchlist 抓 RSS,输出 AI 日报与热点聚合。


结语:稳定性来自架构,而不是 Prompt 链接到标题

当你把业务逻辑文档化(SOP)、任务异步化(Sub-agents)、状态物理化(Files & Configs),AI 就不再是一个不稳定的黑盒,而是一个真正可管理、可迭代的云端副官。


附录:当前系统能力全景(Runtime Capabilities) 链接到标题

1)⚡ 高频自动化任务 链接到标题

  • ai_daily:AI 日报(✅ 健康)
  • email_summary:昨日邮件摘要(✅ 健康)
  • cron_midday_evening_briefing:中晚报推送(✅ 健康)

2)🛠️ 实用工具箱 链接到标题

  • local_maps:路线/POI/天气(✅ 健康)
  • stocks:行情 + 技术分析(✅ 健康)
  • twitter_bird:热点搜索(✅ 健康)

3)📅 办公与协作 链接到标题

  • email_check:未读邮件摘要
  • outlook_calendar:日程管理(✅ 健康)
  • ob_webdav:笔记同步(✅ 健康)

4)💻 开发与预览 链接到标题

  • coding:调度 coder/scoder(EDTP 验收)
  • web_preview:Markdown 渲染为网页链接

5)底层实现索引(Technical Mapping) 链接到标题

领域 (Domain)核心能力物理实现 (Script/Tool)对应 SOP
Local Maps路线规划、ETA、POI、天气route_eta_amap.py, poi_search.pyroute-planning-SOP.md
Email Summary昨日摘要生成与发送gen_email_summary.py, send_email_summary.shemail-summary.md
AI DailyWatchlist + Twitter 日报gen_ai_digest.py, bird CLIai-daily.md
Outlook日历管理、邮件发送outlook-calendar.sh, outlook-mail.shoutlook-SOP.md
ObsidianWebDAV 写入ob_note_sync.pymiaok-约定.md
Coding异步编码与架构评审sessions_spawncoding-SOP.md
Web Preview渲染发布预览web_preview_publish.py, Nginx基础设置-总览.md
Twitter热点搜索与聚合bird CLItwitter-bird-SOP.md
Stocks行情与技术分析yf, tvscreenermiaok-炒股-SOP.md