☰
OpenBot Workflow Playbook 技能实战:把重复流程写成可执行 Playbook 与最小自动化规格
2026/10/28 1:48:07 网站建设 项目流程

【免费下载链接】openbot

A local-first desktop workspace for persistent AI teammates. Run Codex, Claude, and Grok with dedicated workspaces, task queues, file sharing, browser control, and agent-to-agent collaboration.

项目地址:https://gitcode.com/GitHub_Trending/openbo/openbot
点击查看免费下载

在 OpenBot 的生产环境 Skill 目录中,workflow-playbook负责把“我们每周都在手工做的那件事”整理成一份人能照着做、Agent 能照着跑、并且可以逐段验收的流程说明,同时只在条件成熟的地方提出最小自动化方案。本文以 SKILL.md 为骨架,结合仓库中的 Skill 装载机制、Routine 调度 schema 与 Automation API,讲清楚这个技能的四步工作流如何落到 OpenBot 的真实执行原语上,以及哪些边界一旦越界就会把“可靠的 playbook”变成“看起来跑起来了的假自动化”。

技能定位:一个 automation 类别的 Marketplace Skill

workflow-playbook在 catalog.json 中的元数据非常克制:slug为workflow-playbook,category为automation,source为openbot,featured为false。它不作为独立 Agent 出现,而是被Operations Planner这个 Agent 引用:

项目内容
AgentOperations Planner
定位Turns repeatable work into reliable playbooks
绑定技能workflow-playbook+project-plan
关键约束“Do not claim an automation is connected or running until it has actually been configured and tested.”

这条约束与技能正文最后一句“do not enable a recurring job without a request”互为表里:流程文档可以立刻交付,自动化必须显式被请求、并且被验证过。同目录的project-plan负责范围、依赖与验收口径,workflow-playbook负责流程本身的逐步建模,两者组合后,一个“把流程交出去”的任务才会同时具备范围感和可执行性。

从技能装载角度看,它遵循 Agent Skills 规范:一个文件夹<name>/加一个SKILL.md,frontmatter 只有name(等于文件夹名)与description。按 skills-and-plugins 文档 的说明,OpenBot 安装技能时会同时写入.agents/skills/<slug>与.claude/skills/<slug>(因为 Claude Code 不读.agents/skills),副本而非软链,哈希记录在.openbot/skills-lock.json,禁用项存放在.openbot/skills-disabled/。这意味着技能本身是一份纯文本资产:它的价值全部体现在你写下的流程结构里,而不是某个隐藏的运行时。

输入盘点:先确认事实,再谈流程

技能的第一节Inputs要求先识别六类事实:

  1. 触发(trigger)——这件事什么时候开始?是收到工单、每周一早上,还是某人说“该发版了”。
  2. 输入(inputs)——开始之前必须已经存在什么:导出文件、工单号、上一版发布说明。
  3. 相关人(people)——谁做决策、谁执行、谁验收。
  4. 已有工具(tools already available)——注意措辞是 “already available”。
  5. 期望产出(expected output)——交付物长什么样,写到哪。
  6. 当前失败点(current failure points)——过去在哪一步卡住、返工或漏项。

最关键的一句是:“Do not assume access to a service simply because it is named.” 流程里出现“把结果同步到 CRM”,并不等于 Agent 或当前账号真的能访问 CRM。在 OpenBot 里这句话有非常具体的落点:技能的可用工具取决于 Agent 安装了什么技能、挂了哪些 MCP server、以及浏览器是否已经在目标站点登录。文档里说 MCP 配置不存在统一文件格式,OpenBot 在会话开始时才把 server 交给各 provider;密码类凭据则由 1Password / Bitwarden 连接器托管,Agent 拿不到 token。因此输入盘点阶段就应该把“名字”翻译成“可用性证据”,否则第 4 步的自动化建议会全线失真。

一个可直接复用的盘点表:

维度必须写下的内容反例(不可接受)
触发事件来源与判定条件“有人要求的时候”
输入字段、格式、来源系统、责任人“相关数据”
工具具体工具名或 MCP 工具名、登录状态“用你手上的工具”
产出目标位置、格式、验收人“整理一下发出来”
失败点最近三次失败的具体位置“有时候会出问题”

第 1 步:把每一步映射到输入、动作、输出、负责人

Workflow的第 1 条要求:“Map each step to its input, action, output, and owner. Separate decisions from mechanical transformations.”

这一步的产出是一张四列表,而不是散文:

#输入动作输出负责人类型
1已合并 PR 列表汇总变更条目变更清单发布负责人机械变换
2变更清单判断是否构成破坏性变更升级说明段落技术负责人决策
3升级说明写入发布说明文件草稿 PR发布负责人机械变换
4草稿 PR批准公开已批准 PR产品负责人决策

“区分决策与机械变换”不是为了排版好看,而是因为它直接决定哪一段可以被自动化。机械变换只要输入齐、输出可校验,就有自动化空间;决策段即使能被模型草拟,也必须保留一个人来签字。这与 OpenBot 的权限模型一致:审批(approvals)需要人响应,而浏览器接管(browser takeover)和密钥类问题必须回到 OpenBot 内完成,不能通过本地脚本接口代办(详见 automation 文档)。

同时注意owner列不能空着。“未分配”是一个显式状态,而不是省略——这一点与project-plan里 “owner or unassigned” 的写法相呼应。

第 2 步:定义完成条件、重试上限、重复防护与可恢复状态

第 2 条要求:“Define completion, retry limits, duplicate prevention, and the state needed to resume safely after interruption.”

这四项恰好在 OpenBot 中都有对应实现,可以逐条落到字段和行为上。

完成条件(completion)

完成条件必须是可判定的断言,例如“发布说明 PR 已被批准且 CI 通过”,而不是“弄好了”。在 OpenBot 中,一次 Routine 运行的终态由RoutineRunStatus表达,取值包括queued、running、needs-attention、succeeded、failed、interrupted、cancelled(见 ipc-routines.ts)。这给验收提供了一个机器可读的判据:succeeded才算跑完,needs-attention意味着有人在等回答,interrupted意味着被打断需要重跑。

重试上限(retry limits)

重试上限要写成数字和条件,例如“失败后最多重试 2 次,间隔 10 分钟;连续 3 次失败升级到值班”。在 OpenBot 侧,一个 run 本身不带重试键——automation 文档明确指出 “Routine runs have no retry key; retrying a run can start it twice.”,因此重试策略必须写在 playbook 里,由执行者(人或外层脚本)来保证,不能指望运行时替你幂等。

重复防护(duplicate prevention)

重复防护有两层实现证据。

第一层是命名去重:create_routine在创建前会把名字trim().toLowerCase()后与已有 routine 比较,命中则直接报错并提示改用update_routine,错误信息里带出已存在 routine 的routineId(routine-scheduler.ts)。这让“同名重复创建”在工具层就被拦住。

第二层是消息去重:消息路由支持clientMessageId(1–128 字符),同一 agent 与同一 key 在 24 小时内(包括重启后)返回首次回执。对应的自动化 curl 示例在 automation 文档 中给出。注意:这条幂等保证属于消息路由,不属于 routine run 路由,写 playbook 时要区分清楚。

可恢复状态(state needed to resume safely)

“中断后可安全恢复”要求你把状态显式落在文件或记录里,而不是留在某次对话的上下文里。OpenBot 提供了两个原语:

  • Routine 运行历史:RoutineRunFields记录scheduledFor、status、error,以及可选的missed(count与until,用于表示“OpenBot 关闭期间积压的到期次数”,上限常量为ROUTINE_MISSED_COUNT_LIMIT = 999)。
  • 等待(wait):Agent 用openbot.await_event打开一个等待,把waitId交给用户;之后由某次 routine 运行或带waitId的本地脚本事件唤醒,运行会重放请求与备注。Agent 最多同时有 20 个打开的等待,可用openbot.list_waits/openbot.close_wait管理。

把这两者写进 playbook 的形式是:“若构建未结束,登记 waitId 并结束本轮;由build-finishedroutine 唤醒;若 6 小时未唤醒,由人接手。” 这样“中断”就不再是丢失状态,而是一个有名字、有超时、有兜底的中间态。

与“关闭期间到期”相关的策略

missedPolicy决定 routine 在 OpenBot(或服务器)关闭期间到期的那些occurrence怎么处理(ipc-routines.ts、routine-tool-schema.ts):

取值行为
skip记录并丢弃这些到期点(默认,一次性计划除外)
run-onceOpenBot 启动时只跑最新的一次,其余记录在案(once计划默认)

这条策略必须写进 playbook 的异常处理节,否则“周一早上的汇总”在长假后会变成十次连跑。

第 3 步:授权边界、人工裁决与凭据隔离

第 3 条要求:“Identify which external changes require authorization and where a person must resolve ambiguity. Keep credentials out of the playbook.”

哪些外部变更需要授权

判断标准是“变更是否对外可见或不可撤销”。在 OpenBot 的实现里,可以把这条规则落成三档:

档位例子OpenBot 中的落点
只读拉取导出、读取工单无额外授权
可逆写写草稿、建分支由 Agent 权限与审批策略约束
不可逆/对外发送邮件、合并、改配置必须有人批准;浏览器接管与密钥问题回到 App 内完成

本地脚本接口明确写着:它可以回答问题和接受/拒绝审批,但浏览器接管与 secret 问题必须在 OpenBot 中完成;并且“A script cannot change the agent's permissions or turn Local scripts on”。这正好支撑“授权点必须显式标注在执行者列上”这一要求。

人在哪里裁决歧义

歧义不是失败,而是需要指定裁决人的分支。常见写法:“若变更清单里存在数据库迁移,则由技术负责人在 30 分钟内判定是否需要回滚方案;未判定前流程停在草稿状态。” 在 OpenBot 里,这类停顿表现为 run 进入needs-attention,或 Agent 打开一个等待并在聊天中告知用户。

凭据绝不进入 playbook 正文

这是技能里唯一一条带“Keep ... out of”的硬性要求。仓库中有两条对应的安全设计可以作为依据:

  • 任务需要的 API key 通过openbot.request_api_key走表单收集,保存为<userData>/agent-api-keys/<agentId>/<NAME>(0600 文件、0700 目录,位于所有 workspace 之外),Agent只拿到名字和路径,由它自己在命令里读取;保存时会注册到日志脱敏。
  • 密码类凭据由 1Password / Bitwarden 连接器托管,Agent 与 provider 都拿不到 token、密码或验证码;连接器的面板会遮蔽 header 与环境变量值。

因此 playbook 里应该写“从$OPENBOT_API_KEY_FILE读取密钥”,而不是写密钥本身,也不是写读取密钥的具体命令行参数(避免凭据出现在进程参数里)。automation 文档对 token 也有同样告诫:不要把 token 放进命令参数,Linux 上其他用户能读到进程参数,应使用-H @headers。

第 4 步:只对“输入齐备且结果可验证”的步骤提出自动化

第 4 条要求:“Propose automation only for steps with available inputs and a verifiable result. State integration gaps instead of claiming the workflow is connected.”

这是一条筛选规则,可写成两个问题的与运算:

  1. 输入是否已经在手(文件路径、API 返回、上一段产出)?
  2. 结果是否可验证(能比对、能断言、能被人一眼判对错)?

两者都为真,才进入自动化候选;否则进入“集成缺口”清单。

自动化候选的落地形态:create_routine

在 OpenBot 中,“周期性或时间相关的重复工作”应交给 Routine,而不是让 Agent 反复手动执行。这一点在开发者指令里写得很直接:遇到 “every morning” 或 “remind me” 这类请求,应创建 routine。工具定义位于 openbot-tools.ts,参数如下:

参数类型/取值说明
agentId可选字符串目标 Agent;省略即自己
name1–80 字符Routine 名,同名会被拒绝并提示改用update_routine
instruction1–100000 字符每次运行要做什么,必须自包含
scheduleRoutineSchedule见下表
active布尔,默认true是否启用;建议在评审前以false创建
timezoneIANA 时区,≤128 字符省略时取该轮对话发送者的时区,未知则取服务器时区
limitPolicywait/skip,默认waitprovider 额度用尽时的行为
missedPolicyskip/run-onceOpenBot 关闭期间到期点的处理

schedule的完整形态定义在 ipc-routines.ts,校验形态在 routine-tool-schema.ts:

kind必填字段约束
hourlyminute0–59每小时固定分钟
dailytimeHH:mm每天
weekdaystime周一至周五
weeklyweekday0–6(0=周日)、time每周
monthlyday1–31、time每月
intervalamount1–100000、unitminutes/hours/days、anchorAtISO 时间最小 3 分钟(ROUTINE_MINIMUM_INTERVAL_MINUTES)
advancedmonths1–12、days、timedays支持every-day/days-of-week/days-of-month;time支持at-time或every(分钟/小时)
customexpression≤255 字符Cron 表达式,最小间隔同为 3 分钟
oncedateYYYY-MM-DD、time只跑一次,随后自动暂停;仅存在于本机 host,发布的 Team API 会拒绝

其中once的“仅本机”特性是一个值得在 playbook 里明说的边界:一次性提醒在团队 API 投影里不存在,跨设备/服务端场景不要依赖它。

指令必须自包含

ROUTINE_INSTRUCTION_RULE是workflow-playbook与实现之间最重要的一座桥(routine-tool-schema.ts):每次运行都会开一个新的 provider 会话,只能看到最新的聊天消息。所以“按之前那样检查邮箱”这种写法会让运行直接失去上下文。

规则要求指令里写明:

  • 用哪个服务、哪个工具(例如openbot_browser+ 站点 + 已登录标签页,或具体的 MCP 工具、协作 Agent);
  • 用哪个账号;
  • 具体步骤;
  • 报告什么、报到哪;
  • 什么时候什么都不报;
  • 禁止出现 “as before” 或对聊天的指代。

“什么时候什么都不报”不是客套。OpenBot 为此提供了routine_no_update工具:在定时/脚本/webhook 运行中,如果确实没有可报告的内容,调用它会把本轮文本答案折叠进运行记录、不发通知;而如果确实需要报告,就不该调用它。对应的失败语义由routine_report_failure承担:任务因依赖不可用而无法完成时,运行以失败终态结束,并在历史中可见,但答案照常给出。

这两条工具的存在,让 playbook 的“完成 / 无事 / 失败”三分法可以真正被机器表达,而不是靠人在通知里猜。

集成缺口要明说

“State integration gaps instead of claiming the workflow is connected.” 的落地写法示例:

缺口:当前 Agent 没有挂载 CRM 的 MCP server,第 5 步“回写客户记录”只能产出待粘贴文本。 需要:在 Agent 的 MCP 设置中启用对应 server,或用openbot_browser打开已登录的 CRM 标签页。

对比一下错误写法:“第 5 步会自动回写 CRM。”——这正是 Operations Planner 明确禁止的“声称已连通”。

从 Playbook 到 Routine:一次完整的映射示例

把前四步的产出压缩成一条可创建的最小自动化,示意如下(字段名均来自create_routine的 schema):

{ "name": "weekly-release-notes", "instruction": "Read merged pull requests from the last 7 days in repository openbot (use the GitHub MCP tool with owner and repo arguments). Group them as Added / Fixed / Changed. Write the draft to releases/next.md in the workspace. Report the file path and the count of entries. Flag any entry whose title contains 'breaking'. Report nothing if no pull requests were merged; call routine_no_update in that case.", "schedule": { "kind": "weekly", "weekday": 1, "time": "09:00" }, "active": false, "timezone": "Asia/Shanghai", "limitPolicy": "wait", "missedPolicy": "run-once" }

几个刻意的选择对应前文的原则:

  • active: false:先建后验,符合“未经请求不要开启周期任务”。仓库里 Dr. Eggbot 的两个健康检查 routine 也是以 paused 状态安装的("active": false)。
  • timezone显式给出,避免依赖“发送者时区”这种隐式默认。
  • missedPolicy: "run-once":长假后只补跑最新一次,而不是积压十次。
  • 指令里点名工具、仓库、输出路径、报告内容与静默条件,无任何“像之前那样”的指代。
  • 没有写任何凭据;需要 GitHub 身份时依赖已连接连接器提供的gh/git凭据助手或 MCP 授权。

创建后应立刻用list_routines读回确认(Agent Designer 技能里对 routine 也要求“创建后读回确认”),再做一次test_routine手动测试运行。test_routine只是把一次手动运行排入队列,适合当作 playbook 的第一次验收。

用本地脚本触发并验收:把“可验证结果”变成机器判据

当流程的触发点不在时间表上,而在本机某个长任务结束时,workflow-playbook的“输入齐备 + 结果可验证”对应到 OpenBot 的Local scripts API。它不是默认开启的:设置是按 Agent的、默认关闭,需要在 Agent 设置的Permissions中打开Local scripts,且 Agent 无法为自己或队友开启。

开启后,OpenBot 在<userData>/automation/写三个文件(目录 0700、文件 0600,仅同 OS 用户可读):url、token、headers。每次启动都会换新端口与新 token,命令在运行时才读取文件,所以重启前复制的命令仍然可用。

触发一次 routine 的最小写法(macOS/Linux):

long-job; curl -sS -X POST "$(cat "$OPENBOT_AUTOMATION/url")/v1/agents/<agentId>/routines/<routineId>/run" \ -H @"$OPENBOT_AUTOMATION/headers" \ -H 'Content-Type: application/json' \ -d '{"payload":"long-job ended with code 0"}'

用 CLI 时不必手写请求:

openbot-cli list # 列出开启了 Local scripts 的 Agent openbot-cli run "Ada" "Run the tests and tell me what failed" --wait openbot-cli status "Ada" <deliveryId> openbot-cli run "Ada" - --wait --json < task.md

把验收写进 playbook 时,几张表最有价值。

Routine run 的状态码与拒绝原因(automation 文档):

状态含义
202已入队,不代表已执行
400body 非 JSON、payload非字符串、waitId非法
401token 缺失或错误
403带Origin头或非本机Host,或该 Agent 未开启 Local scripts
404Agent 或 routine 不存在
409Agent 当前不能接受该运行(例如正在删除)
413body 超过 32 KiB,或 payload 超过 4000 字符
415Content-Type不是application/json
429该 Agent 最近一小时已接受 30 次本地脚本运行

CLI 退出码可以当作 playbook 的分支条件:

退出码含义playbook 中的动作
0完成(--wait时该轮结束)进入验收检查
1该轮失败/被停止/被取消,或请求被拒按重试上限重试,超限升级
2命令行错误或存在同名 Agent修正调用,不重试
3Agent 在等人(提问、审批、浏览器接管)转人工,回答后用status继续
4等待超时(Agent 仍在工作)记录 deliveryId,稍后status
5OpenBot 未运行、无 Agent 开启 Local scripts、或找不到 Agent环境检查

--timeout(90s、5m、2h;默认30m)只停止等待,不停止工作——这一点必须写进 playbook 的“超时”分支,否则执行者会误以为任务被取消了。

payload的传递也有明确语义:它会附在 routine 指令之后,位于--- event from a local script ---标题下,并带一行提示让 Agent 把它当数据而非指令阅读;运行历史会保留它,所以被重启打断的运行会重新带上它。这正是“中断后可安全恢复”的实现基础,也提醒你:payload 是数据通道,不是注入指令的地方。

交付物:流程、异常处理、验收检查、最小自动化计划

Deliverable一节要求返回四件东西,并且只写“被请求的层级”:

Return the process, exception handling, acceptance checks, and a minimal automation plan. Draft instructions or code only at the level requested; do not enable a recurring job without a request.

建议的交付结构(可直接套用):

1. 流程

第 1 步的四列表格,加上每一步的“完成定义”。

2. 异常处理

按“异常 → 检测方式 → 处理 → 升级对象”四列写,覆盖至少这几类:

  • 输入缺失或格式不符(停止,回退到上一责任人);
  • 外部服务不可用(有限次数重试,然后记录缺口);
  • 额度用尽(limitPolicy: wait排队到重置,或skip丢弃并在历史中标记cancelled);
  • 关闭期间到期(missedPolicy行为,并说明长假后的预期);
  • 需要授权或存在歧义(转人工,等待 ID 与超时时间写清楚)。

3. 验收检查

每条都要能被别人独立执行,例如:

  • openbot-cli run ... --wait退出码为 0;
  • run 历史终态为succeeded;
  • 产出文件存在且包含 N 个小节,标题与模板一致;
  • 无变更时通知数为 0(routine_no_update生效)。

4. 最小自动化计划

只列已通过“输入齐备 + 结果可验证”双条件的步骤,每项包含:对应 routine 名、schedule、输入来源、验证方式、以及尚未解决的集成缺口。默认以active: false起草,等验收通过、并且用户明确要求后再启用。

常见失败模式

对照源码与文档,以下五种写法最容易把 playbook 写坏:

  1. 把“工具名”当“权限”。技能第一条就警告不要因为提到某服务就假设有访问权;MCP 会话按 token 绑定、凭据由连接器托管,缺的就是缺的,要写进缺口清单。
  2. 指令依赖聊天上下文。ROUTINE_INSTRUCTION_RULE说明每次运行都是新会话,只看到最新聊天消息;“as before” 会让运行失去执行路径。
  3. 把凭据写进流程。哪怕写在“附注”里也不行;正确做法是指向密钥文件路径或由连接器提供。
  4. 默认开启周期任务。create_routine的active默认是true,很容易在评审前就跑起来;技能要求“without a request 不要开启”,因此显式传false。
  5. 用重试解决幂等问题。routine run 没有重试键,盲目重试可能启动两次;重复防护要落在名字去重、clientMessageId(消息路由)和流程内的“先查后写”上。

相关文件索引

  • 技能正文:marketplace/production-catalog/skills/workflow-playbook/SKILL.md
  • 目录元数据与 Agent 绑定:marketplace/production-catalog/catalog.json
  • 发布目录说明(版本、重复与更新规则):marketplace/production-catalog/README.md
  • 技能装载与目录规则:docs/architecture/skills-and-plugins.md
  • Routine 工具定义:src/backend/openbot-tools.ts
  • Routine schema 与指令规则:src/backend/routine-tool-schema.ts
  • 调度器(含同名去重):src/backend/agent/routine-scheduler.ts
  • 契约类型(schedule / 状态 / 策略):packages/contracts/src/ipc-routines.ts
  • 输入上限常量:packages/contracts/src/input-limits.ts
  • 本地脚本 API 与 CLI:docs/automation.md
  • 相邻技能(范围与验收口径):marketplace/production-catalog/skills/project-plan/SKILL.md

【免费下载链接】openbot

A local-first desktop workspace for persistent AI teammates. Run Codex, Claude, and Grok with dedicated workspaces, task queues, file sharing, browser control, and agent-to-agent collaboration.

项目地址:https://gitcode.com/GitHub_Trending/openbo/openbot
点击查看免费下载
上一篇:27 万下载 vs 讨论度平稳:加速版是叫好不叫座,还是闷声发财?
下一篇:无线麦SayAll 源码解析(三):从 BlackHole 源码派生 MiRemoteV 2ch 虚拟麦克风驱动的原理

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询