龙虾调教(二):让 OpenClaw 帮你把重复工作变成 SOP
贵的大模型 Token 最大的价值不是帮你做一次,而是帮你把”做一次”变成”永远不用亲自做”。 在 Claude Code 和 Cursor 里花掉的那些 token,真正的价值不在于那一次的输出,而在于是否把那次经验提炼成了下次不需要再解释的指令。
但要做到这一点,光靠口头说”以后帮我这样做”根本不够。每次 session 结束,AI 就忘了。下次新开一个对话,你还是要重新描述背景、重新定义偏好、重新告诉它输出格式是什么。
这篇文章记录我如何在 OpenClaw 里构建一套 workflow 系统,把这个问题彻底解决。目标只有一个:让 AI 助手读完几个文件,就能从零开始独立执行任何重复性工作,不需要我过多解释。
问题出在哪
AI 助手本质上是无状态的。每个 session 是独立的,没有跨 session 的共享记忆。即使在同一个 session 里,对话过长时系统会自动压缩(Compaction),丢弃早期内容。
这意味着:你做过的每一个”这件事以后这样处理”的约定,在 session 结束后都会消失。下次再说,还是要从头来。
解决这个问题的办法只有一个:把约定从对话里拉出来,写进文件。文件才能跨 session 持久,对话不行。
整体架构
Workflow 系统由三个层次构成:
AGENTS.md(行为规范层) — AI 每次启动都会读这个文件,里面定义了”如何处理 workflow”的元规则:碰到任务时先去匹配触发词,找到了就按 SOP 执行,找不到才自由发挥。
WORKFLOW.md(索引层) — 所有已有工作流的目录表,包含触发词、文件路径、状态、TTL 和一行简述。AI 匹配触发词时读这个。
workflow/NN-slug.md(执行层) — 每个工作流一个 Playbook 文件,包含这件事从头到尾怎么做的完整指令。
workspace/
├── AGENTS.md # 元规则:如何调度和执行 workflow
├── WORKFLOW.md # 索引:触发词 → 文件映射
└── workflow/
├── 00-create-workflow.md # 元工作流:如何新建工作流
├── 01-stock-review.md # A股每日复盘
├── 02-research-obsidian.md # 调研 → Obsidian 归档
└── 03-hiring.md # 招聘进度管理
第一层:AGENTS.md 的 workflow 规则
AGENTS.md 是整个系统的”操作系统”,AI 每次启动都会读它。其中 workflow 相关的部分是这样写的:
## Workflow Playbooks
工作流 SOP 存放在 `workflow/` 目录,`WORKFLOW.md` 是索引(session 启动时已加载)。
### 执行规则
收到任务时,先检查 WORKFLOW.md 是否有匹配的触发词:
- **命中** → read 对应 playbook 文件,按 SOP 执行
- **未命中** → 自由推断
执行逻辑(按 status + 保鲜期):
├─ status = draft → 提醒用户这是未验证工作流,谨慎执行
├─ status = deprecated → 拒绝执行,告知已废弃
└─ status = active
├─ last_verified 距今 < ttl → 直接执行(无脑模式)
└─ last_verified 距今 ≥ ttl → 边执行边验证
├─ 每步评估有无更好方案
├─ 有改进点 → 执行完后等用户确认,再更新 playbook
└─ 无改进点 → 仅更新 last_verified
### 执行记录
每次执行 workflow 后:
1. 在当天日记(memory/YYYY-MM-DD.md)追加执行记录
2. 更新 workflow 文件的 last_run 字段
### 每日反思新增 Workflow 报告(23:45 cron)
扫描当天执行过的 workflow,在反思推送中增加:
| 工作流 | 执行结果 | 偏差 | 改进建议 |
|--------|---------|------|---------|
| ... | ✅/⚠️ | ... | ... |
用户确认后,AI 再回写 playbook。不单方面修改 active workflow 的 SOP。
这段配置做了几件事:
- 把触发逻辑写死 — AI 不需要记住”要去看 workflow”,因为每次启动都会重读 AGENTS.md,这个规则就在里面
- 状态机制由 AGENTS.md 定义 — 什么状态下怎么执行,统一在这里描述,Playbook 里不重复
- 改 SOP 需要人确认 — AI 发现改进点后提出来,但不单方面修改 active 状态的 SOP,人在回路里
第二层:WORKFLOW.md 索引
# WORKFLOW.md — 工作流索引
_Last updated: 2026-03-16_
> 收到任务时先匹配触发词;命中则 read 对应文件按 SOP 执行;未命中则自由推断。
## 工作流列表
| # | 工作流 | 触发词 | 文件 | Status | TTL | 简述 |
|---|--------|--------|------|--------|-----|------|
| 00 | 创建工作流 | 新建工作流、创建 workflow、建个 SOP | workflow/00-create-workflow.md | active | 180d | 标准化新建任何 workflow 的元流程 |
| 01 | A股复盘 | 复盘、今日股票、市场分析、跑复盘 | workflow/01-stock-review.md | active | 30d | 运行复盘脚本,输出到 Obsidian,推送摘要 |
| 02 | 调研归档 | 调研、帮我研究、学习X、整理资料 | workflow/02-research-obsidian.md | active | 90d | 研究主题写入 Obsidian DigitalGarden |
| 03 | 招聘管理 | 面试、候选人、录用、安排面试 | workflow/03-hiring.md | active | 90d | Linear Interview 项目管理,日历扫描 |
## 执行规则(速查)
- **draft** → 提醒用户未验证,谨慎执行
- **active + 在保鲜期内** → 直接执行
- **active + 超过 TTL** → 边执行边验证,完成后更新 last_verified
- **deprecated** → 拒绝执行,告知已废弃
- **skill 缺失** → 告知,建议安装或新建,不主动安装
索引的作用是让 AI 用 O(1) 的成本找到对应 Playbook,而不是每次去 workflow/ 目录里扫所有文件。触发词要够具体,避免误触发。
第三层:Playbook 文件
Frontmatter 规范
每个 Playbook 文件都有 YAML frontmatter,记录这个工作流的元信息:
---
title: "招聘管理"
created: 2026-03-15
last_run: ~
last_verified: 2026-03-15
ttl: 90d
status: active
skills: [linear-cli]
tags: [hiring, interview, linear]
---
这几个字段里,ttl 和 last_verified 最重要,它们共同控制 TTL 机制(下文详细解释)。skills 字段让 AI 在执行前知道需要哪些工具,缺少时提前告知而不是执行到一半报错。
Playbook 内容结构
一个完整的 Playbook 包含以下章节:
触发条件 → 什么话会触发这个工作流(和 WORKFLOW.md 的触发词对应)
前置检查 → 执行前需要确认的条件和参数
执行步骤 → Step by step,含具体命令、代码片段、判断逻辑
权限边界 → AI 可以自主决定什么,什么情况必须来问用户
输出/交付物 → 产物是什么,放哪里,通知谁
异常处理 → 常见失败场景和处理方式
背景 → 这个工作流怎么来的(方便日后回头改)
权限边界这段尤为重要。 明确写出”AI 可以自主决定什么”和”必须询问用户的情况”,让助手有清晰的自主边界,而不是每次都来打扰你确认。
以招聘管理 Playbook 为例,权限边界部分是这样写的:
AI 可以自主决定:
- 日历扫描方式(SQLite 直读,禁止 AppleScript——这是踩坑后的约束,不写进来新助手不会知道)
- 面试事件与 Linear issue 的匹配逻辑
- issue 的 priority 根据状态自动判断
必须询问用户的情况:
- 候选人面试结果(通过/淘汰)
- 是否发 Offer
隐性知识显式化
Playbook 里最有价值的内容,往往不是步骤本身,而是步骤背后的约束和踩坑记录——这些是口头传递最容易丢失的东西。
招聘管理 Playbook 里有这样一段:
# ⚠️ 读取日历禁止 AppleScript(会在 sandbox 环境无限 hang)
# 直接读 SQLite:
EPOCH = datetime.datetime(2001, 1, 1)
DB = "/path/to/Calendar.sqlitedb"
# start_date 存储为 UTC,需要 +8h 转 CST
start_cst = EPOCH + datetime.timedelta(seconds=sd) + datetime.timedelta(hours=8)
Linear 的 State ID 也直接硬写进来:
Todo: 624bb002-4790-4e13-86fa-418c64094ba0
In Progress: c8d48dc1-625c-42cc-9c14-27d02ae583d9
...
这些不写下来,一个新助手每次执行都得重新摸索,或者默默踩同一个坑。
TTL 机制:为什么工作流需要”保质期”
这是整个系统里最容易被忽视、但实际上最重要的设计之一。
问题:SOP 会过期
工具版本会变,外部平台的 API 会改,个人偏好也会随时间演化。一个半年前写的 Playbook,今天执行时可能有更好的方案,甚至某些步骤已经完全失效了——但如果没有机制强制检查,AI 会一直按老版本执行,你也不会意识到。
解决方案:TTL + last_verified
每个 Playbook 有两个字段:
ttl:这个工作流的有效期(如30d、90d、180d)last_verified:最后一次验证它仍然有效的日期
两者组合计算”保鲜期截止日”:last_verified + ttl
AI 在执行时检查这个截止日:
active + last_verified + ttl > 今天
→ 直接执行,无脑模式,不质疑步骤
active + last_verified + ttl ≤ 今天(过期)
→ 边执行边验证
→ 每步评估:有没有更好的方案?
→ 执行完:若有改进点 → 提出来,等用户确认后回写
→ 若无改进点 → 只更新 last_verified,下次继续正常跑
这个设计的妙处在于:TTL 到期不是”停止执行”,而是”开启审视模式”。 工作流依然会跑,只是 AI 在执行的同时保持批判性眼光,发现问题就提出来。
TTL 长度怎么定
| 工作流类型 | 建议 TTL | 原因 |
|---|---|---|
| 依赖 CLI 工具的工作流 | 30d | CLI 版本迭代快,接口可能变 |
| 依赖外部平台(API、网页) | 14d | 平台改版、API 变更频繁 |
| 纯流程类(招聘、调研) | 90d | 流程本身相对稳定 |
| 元工作流(如”如何新建工作流”) | 180d | 架构级决策,不常变 |
元工作流:用工作流管理工作流
这是系统里我最喜欢的部分:00-create-workflow.md 是一个用于创建新工作流的工作流。
它解决了一个自然而然的问题:既然”新建工作流”本身也是一件重复性的工作,为什么不把它本身也 SOP 化?
完整文件如下:
---
title: "创建工作流"
created: 2026-03-15
last_verified: 2026-03-15
ttl: 180d
status: active
skills: []
---
# 创建工作流 Playbook
## 触发条件
说:新建工作流、创建 workflow、建个 SOP、帮我把 X 做成工作流
## 前置检查
- [ ] 确认新工作流的名称和用途
- [ ] 确认触发词(2-4 个关键词)
- [ ] 确认所需 skills
- [ ] 确认 TTL(参考类型建议表)
## 执行步骤
### Step 1 — 确定编号
查看 workflow/ 目录,取当前最大数字前缀 +1 作为新文件编号。
### Step 2 — 创建 Playbook 文件
文件名格式:workflow/NN-slug.md(slug 用英文小写 + 连字符)
Frontmatter 模板:
---
title: "工作流名称"
created: YYYY-MM-DD
last_run: ~
last_verified: YYYY-MM-DD
ttl: 30d
status: draft
skills: []
tags: []
---
新建时默认 status: draft,首次执行验证后改 active。
### Step 3 — 填写 Playbook 内容
必须包含以下章节:
- 触发条件
- 前置检查(含参数/条件)
- 执行步骤(Step by step,含具体命令)
- 权限边界(AI 可以自主决定什么,什么必须询问)
- 输出/交付物
- 异常处理
### Step 4 — 更新 WORKFLOW.md 索引
在表格追加一行:
| NN | 工作流名 | 触发词 | workflow/NN-slug.md | draft | TTL | 简述 |
### Step 5 — 通知用户
新工作流已创建,状态 draft,首次执行后可升 active。
## 主动识别机会
发现某件事反复出现 ≥ 3 次且没有对应 workflow 时,主动建议:
> "我注意到 [X] 已经出现了几次,要不要建个工作流?"
## TTL 建议表
| 类型 | 建议 TTL |
|------|---------|
| 依赖 CLI/API 工具 | 30d |
| 依赖外部平台 | 14d |
| 纯流程(招聘、调研) | 90d |
| 元工作流 | 180d |
## workflow vs skill 边界
| 特征 | 建议 |
|------|------|
| 私有、个性化、专属配置(特定 ID、路径、偏好) | workflow/ |
| 通用、可复用、可分享给其他人 | skill(可发布到 ClawHub) |
| 依赖通用工具 + 个人 SOP | workflow/ 引用 skill |
有了这个,每次需要新建工作流时,AI 会按照统一的规范来创建,而不是每次风格不一。更有意思的是:AI 会主动发现”这件事出现了 ≥ 3 次,要不要建个工作流”——把发现机会的责任也交给了系统本身。
Workflow 与 Skill 的关系
这是经常让人困惑的地方,值得专门说清楚。
Skill 是 OpenClaw 的能力扩展单元。每个 skill 是一个目录,包含 SKILL.md(使用说明)和 scripts/(实际执行脚本)。Skill 是通用的、可分享的,OpenClaw 官方有 50 多个内置 skill,社区也可以发布到 ClawHub。
Workflow 是私有的、高度个性化的 SOP。它依赖 skill 提供的工具能力,但包含了大量无法通用化的个人配置:特定的 project ID、个人的选股方法论、团队特有的面试流程、踩过的坑、个人偏好……
关系可以这样理解:
skill = 工具(锤子、扳手)
workflow = 操作手册(这个项目的维修流程,用哪个工具,踩过什么坑)
举个具体例子——招聘管理工作流:
- 它依赖
linear-cliskill(提供 Linear API 调用能力) - 但 workflow 里包含了具体的 Project ID、Team ID、State UUID、日历读取的 SQLite 路径,以及”禁止 AppleScript”这个特定于我的 Mac 环境的约束
- 这些东西打包进 skill 没有意义,发布出去别人也用不了
边界判断只需要回答一个问题:这个东西能不能给完全不了解我的其他人直接用?
- 能 → skill
- 不能(因为包含个人配置、个人偏好、个人环境) → workflow
另一种典型模式是 workflow 引用 skill:
调研归档工作流 (02-research-obsidian.md) 的 frontmatter 写了 skills: [obsidian, perplexity]——它需要 obsidian skill(提供 vault 操作)和 perplexity skill(提供 AI 搜索能力),但调研的具体步骤、文件命名规范、质量自检标准、Obsidian vault 路径都是个人化的,放在 workflow 里管理。
执行闭环:从文件到行为
系统跑起来后,日常执行流程是这样的:
收到任务
│
├─ 匹配 WORKFLOW.md 触发词?
│ ├─ 命中 → read 对应 Playbook → 检查 TTL → 执行
│ └─ 未命中 → 自由推断
│
└─ 执行完成
├─ 追加执行记录到当日日记
└─ 更新 Playbook 的 last_run 字段
每晚 23:45 反思 cron
└─ 扫描今日执行过的 workflow
└─ 生成报告:执行结果 + 偏差 + 改进建议
└─ 用户确认改进点 → 回写 Playbook
闭环的关键设计:改 SOP 需要人确认,AI 只提建议不单方面修改。 这保证了 Playbook 不会在没有人知情的情况下悄悄演化。
搭这套系统的一些观察
写 Playbook 本质上是在梳理自己对这件事的完整认知。 把隐性知识显式化的过程里,你会发现很多自己平时”知道但没说出来”的约束和偏好——比如”日历要读 SQLite 不要用 AppleScript”这件事,如果不是为了写 Playbook,我可能永远不会刻意记录下来。
SOP 是跑出来的,不是想出来的。 第一版 Playbook 不需要完美,够用就能跑。每次执行后有偏差,追加进异常处理。TTL 到期后发现了更好的方案,更新步骤。Playbook 会在实际执行中逐渐变得好用。
触发词写得越具体,误触发越少。 “面试”这个词很容易被别的话题意外触发,加上”候选人”、“安排面试”、“谁还没跟进”这些更具体的短语,精度会好很多。
给想搭同类系统的人
如果你在用 OpenClaw,或者任何支持自定义 system prompt / 工作目录文件的 AI 助手框架,以下是最快的路径:
第一步:找出你最近一个月里重复做过 ≥ 3 次的一件事,选其中包含最多隐性知识的。
第二步:把这件事的步骤写成 Markdown,重点写”为什么这样做”和”遇到 X 情况怎么处理”,不只是步骤列表。把所有你知道但没人告诉你就不知道的东西——工具约束、踩坑、个人偏好——都写进去。
第三步:在 AGENTS.md(或对应的 system prompt 文件)里写一条规则:收到 [触发词] 时,读这个文件,按步骤执行。
第四步:跑一次,看哪里卡了,补进去。给这个 Playbook 设一个 TTL。
就这四步。不需要一次设计完整,系统会在执行中自己成熟。