OC-Flow:为你的 OpenClaw 注入“确定性”。OC-Flow 完全嵌入 OpenClaw 体系,赋予 Agent 完整流程控制:条件分支、循环遍历、精准等待、状态管理。通过 YAML 剧本实现固定流程、多步循环、严苛逻辑的任务。适用于财务办公、开发运维、个人助理。
在不破坏 OpenClaw 灵活性的前提下,按 YAML 剧本执行 100% 确定性逻辑:判断、循环、脚本、LLM 调用、Skill 调用。
这是一个符合 OpenClaw / AgentSkills 目录约定的 Skill:
SKILL.md:触发条件与使用说明scripts/:可执行入口与运行时代码references/:参考文档与示例工作流重要: 脚本内置了 stdout 行缓冲,不需要额外设置
PYTHONUNBUFFERED。
bash
# 运行工作流
python3 {baseDir}/scripts/openclaw_workflow.py execute <workflow.yaml>
# 验证工作流语法
python3 {baseDir}/scripts/openclaw_workflow.py validate <workflow.yaml>
# 列出可用工作流
python3 {baseDir}/scripts/openclaw_workflow.py list
# 查看历史运行
python3 {baseDir}/scripts/openclaw_workflow.py runs
# 从断点恢复
python3 {baseDir}/scripts/openclaw_workflow.py resume <run_id>
# 可视化面板
python3 {baseDir}/scripts/openclaw_workflow.py dashboard
推荐目录(OpenClaw 自建/自维护流程):
bash
~/.openclaw/workspace/workflows
面板与 CLI 会优先发现以下位置:
{baseDir}/references/examples~/.openclaw/workspace/workflows说明:面板只扫描固定目录,不会递归读取整个 ~/.openclaw/workspace。
示例:
bash
# 运行示例工作流
python3 {baseDir}/scripts/openclaw_workflow.py execute {baseDir}/references/examples/basic_test.yaml
# 运行深度集成测试
python3 {baseDir}/scripts/openclaw_workflow.py execute {baseDir}/references/examples/deep_integration.yaml
# 查看补充设计说明
cat {baseDir}/references/readme.md
JSON 运行记录,包含:
run_id — 运行唯一 IDflow_id — 工作流名称status — success | failed | abortedsteps — 每步执行结果(状态、输出、耗时、重试次数)started_at / finished_at — 起止时间终端同时输出人可读的步骤进度日志。
llm / agent / skill 节点通过 Gateway RPC 调用,不是本地直连模型。yaml
name: "我的流程"
steps:
- id: fetch
type: script
command: "curl -s https://api.example.com/data"
- id: analyze
type: llm
prompt: "分析: {{fetch.output}}"
- id: delegate
type: subagent
task: "根据以下分析结果生成一份详细报告: {{analyze.text}}"
label: "报告生成器"
wait: true
timeout: 300
- id: notify
type: message
channel: imessage
target: "+861760051xxxx"
message: "结果: {{delegate.result}}"
类型说明关键参数scriptShell/Python 脚本command, inline, timeout``llmLLM 推理 (Gateway session)prompt, thinking, session``agentAgent 调用 (Gateway session)message, thinking, deliver``subagent创建子代理执行独立任务task, label, model, wait``wait_subagents等待多个 Subagent 完成并收集结果tracker, max_wait, poll_interval``skill调用 OpenClaw Skill (Gateway session)action, args, instruction``conditionIf-Else 分支if, then, else``loop循环遍历foreach/ times, as, do``set设置变量var, value``log日志输出message, level``httpHTTP 请求url, method, headers, body``code内联 Python (沙箱)python``wait延时/等待条件seconds, until``message发送消息channel, target, message
{{variable}} — 全局变量{{step_id.output}} / {{step_id.text}} — 步骤输出{{item}} — 循环当前元素{{env.HOME}} — 环境变量每步可配置: retry: 3, retry_delay: 10, on_error: retry|skip|stop
subagent 节点通过 OpenClaw sessions_spawn 工具创建独立子代理。
与 agent 节点的区别:
agent: 在共享 session 中调用主 Agent,同一上下文subagent: 创建独立子代理,有自己的 session、系统提示和模型配置每个 subagent 的创建需要两层 session:
sessions_spawn 工具调用的"载体 session"sessions_spawn 在 Gateway 侧创建的实际子代理 session ( agent:main:subagent:<uuid>)sessions_spawn 是 Agent 工具 (不是 Gateway 直接 RPC),所以必须通过 agent_call 在某个 session 中触发。spawn session 本身只是工具调用的容器,子代理真正执行任务的是 child session。
每个 spawn 创建一个临时的 spawn:<hex> session → agent_call 让 Agent 调用 sessions_spawn → 提取 childSessionKey → 立即删除 spawn session。
所有 spawn 复用同一个 factory:<hex> session → 每 20 次轮换新 session → 用 factory_lock 序列化访问。
factory_lock 强制所有 spawn 串行执行,即使在并行循环中原问题 1: 循环中工厂模式强制串行
已通过批量 spawn 解决。循环中自动检测并使用批量创建。
原问题 2: Gmail 24 封邮件超时
批量 spawn 10 个 subagent 仅需 ~77s,24 个预计 ~90-120s,远低于超时限制。
2026-03-18 架构更新: 子会话模式
非循环场景下的单个 subagent 节点不再通过 sessions_spawn 间接创建,而是直接创建新会话执行任务。 会话就是 subagent,省去了 spawn 中间层。
参数:
参数必需默认值说明task✅—子代理要执行的任务描述label—(空)子代理显示名称model—(继承)覆盖使用的模型thinking—(关)思考级别: off/minimal/low/medium/hightimeout—300超时秒数wait—false是否等待子代理完成poll_interval—15等待时轮询间隔 (秒)mode—runrun (一次性) 或 session (持久)cleanup—autokeep (保留) 或 auto (wait 完成后自动删除 session)throttle_timeout—300并发等待超时 (秒),达到 maxConcurrent 限制时等待空位spawn_timeout—120000Gateway 调用超时 (ms)spawn_retries—2Gateway timeout 重试次数
示例 — fire-and-forget:
yaml
- type: subagent
task: "整理今天的新闻摘要"
label: "新闻助手"
示例 — 等待结果:
yaml
- id: research
type: subagent
task: "研究 {{topic}} 并写一份 500 字的分析报告"
label: "研究员"
wait: true
timeout: 600
poll_interval: 20
- type: log
message: "研究结果: {{research.result}}"
wait_subagents 节点实现标准的 subagent fan-in (汇合) 模式:
subagent 节点 (wait: false) 创建多个并行子代理wait_subagents 节点轮询所有子代理的 JSONL completion event,全部完成后返回结果列表即时清理: 子会话模式 wait=true 完成后立即删除 child session
汇合清理: wait_subagents 节点完成后批量清理所有 child session (cleanup: auto)
兆底清理: 工作流结束时 (无论成功/失败/中断),engine.py 的 finally 块会清理:
agent:main:openclaw-workflow:<ns>)get_factory_child_session_keys)subagent 节点在创建时会检查两个配置:
agents.defaults.subagents.maxConcurrent (子代理专属限制,默认 20)agents.defaults.maxConcurrent (Gateway 全局嵌入式运行并发限制,默认 4)取两者较小值作为实际限制。并发计数仅统计 :spawn: session (瞬态占位),不统计 :subagent: session (因为完成后仍残留在 sessions.json 中会导致误判)。
subagent 节点对 Gateway timeout 错误内置 2 次重试 (spawn_retries=2),spawn 超时时间 120s (spawn_timeout=120000ms)。
参数:
参数必需默认值说明tracker✅—spawn 信息列表 (需包含 spawn_session_key, child_session_key)max_wait—600最大等待秒数poll_interval—5轮询间隔秒数extra_fields—[]从 tracker item 透传到结果中的额外字段名cleanup—autoSession 清理策略: auto (全部清理), completed (仅清理已完成的), keep (不清理)
示例 — 并行分类:
yaml
# 1) 初始化 tracker
- id: init_tracker
type: code
python: "result = []"
# 2) loop 中 fire-and-forget spawn + 收集信息
- type: loop
foreach: "{{items}}"
as: item
do:
- id: spawn_task
type: subagent
task: "分析: {{item.data}}"
wait: false
- id: collect
type: code
python: |
tracker = init_tracker if isinstance(init_tracker, list) else []
tracker.append({
"item_id": item.get("id", ""),
"spawn_session_key": spawn_task.get("spawn_session_key", ""),
"child_session_key": spawn_task.get("child_session_key", ""),
})
result = tracker
# 3) 等待全部完成
- id: wait_all
type: wait_subagents
tracker: "{{init_tracker}}"
max_wait: 600
poll_interval: 5
extra_fields:
- item_id
# 4) 使用结果
- type: agent
message: "汇总: {{wait_all}}"
下面补全每个节点的常用写法,优先覆盖实际引擎支持的字段。
字段说明id步骤唯一标识,建议填写,便于引用 {{step_id.output}}``name人类可读名称,仅用于日志type节点类型retry失败重试次数retry_delay每次重试间隔(秒)on_error``retry / skip / stop
script 节点#执行 shell 命令或内联 Python。
支持字段:
command / script / file:三选一inline:内联 Python 代码(会写入临时 .py 执行)timeout:默认 300 秒cwd:工作目录env:环境变量字典yaml
- id: fetch_data
type: script
command: "curl -s https://api.example.com/data"
timeout: 30
- id: build_report
type: script
inline: |
import json
print(json.dumps({"ok": True, "ts": "{{env.HOME}}"}, ensure_ascii=False))
llm 节点#通过 Gateway 调用模型推理,默认复用当前工作流会话。
支持字段:
prompt(必填)thinking: off|minimal|low|medium|hightimeout:秒,默认 120session: shared(默认)或 isolatedyaml
- id: summarize
type: llm
prompt: "请总结以下内容:{{fetch_data.output}}"
thinking: low
session: shared
agent 节点#调用主 Agent。与 llm 相比,支持投递能力(deliver)。
支持字段:
message(必填)thinkingtimeout:默认 300deliver:是否自动投递deliver_channel / deliver_targetyaml
- id: agent_reply
type: agent
message: "根据 {{summarize.text}} 输出客户可读版本"
deliver: true
deliver_channel: imessage
deliver_target: "+8617600510003"
skill 节点#让 Agent 在当前会话中调用已有 Skill。
支持字段:
action(必填)args:参数对象instruction:自定义指令(有则优先)timeout:默认 300yaml
- id: call_tool_skill
type: skill
action: "transmission.add"
args:
url: "magnet:?xt=..."
instruction: "请添加该任务并返回任务ID"
condition 节点#条件分支,执行 then 或 else 子步骤。
支持字段:
if(必填):Python 表达式字符串then:条件为真时执行的步骤数组else:条件为假时执行的步骤数组yaml
- id: check_items
type: condition
if: "len(load_emails) > 0"
then:
- type: log
message: "有邮件"
else:
- type: log
message: "无邮件"
loop 节点#循环执行子步骤,支持 foreach 或 times。
支持字段:
foreach:列表/可解析为列表的值times:整数次数(与 foreach 二选一)as / var:循环变量名,默认 itemdo / steps:子步骤数组yaml
- id: iterate
type: loop
foreach: "{{items}}"
as: item
do:
- type: log
message: "当前: {{item}}"
- id: retry_three_times
type: loop
times: 3
as: i
do:
- type: log
message: "第 {{i}} 次"
set 节点#设置全局变量。
支持字段:
var(必填)value(必填)yaml
- id: set_topic
type: set
var: topic
value: "PiSugar"
log 节点#写运行日志。
支持字段:
message(必填)level:默认 INFOyaml
- type: log
level: "WARN"
message: "当前数据为空,进入降级路径"
http 节点#发送 HTTP 请求。
支持字段:
url(必填)method:默认 GETheadersparams:Query 参数body:可为对象/数组/字符串timeout:默认 30yaml
- id: request_api
type: http
method: POST
url: "https://api.example.com/v1/report"
headers:
Authorization: "Bearer {{token}}"
body:
title: "日报"
content: "{{summarize.text}}"
code 节点#执行沙箱 Python。将当前变量与历史步骤输出注入运行环境。
支持字段:
python(必填)结果约定:
result 作为节点输出result,则返回 print 输出文本yaml
- id: calc_stats
type: code
python: |
items = load_emails if isinstance(load_emails, list) else []
result = {
"count": len(items),
"subjects": [x.get("subject", "") for x in items[:5] if isinstance(x, dict)]
}
wait 节点#固定延时或轮询等待条件。
支持字段:
seconds:固定等待秒数until:条件表达式(与 seconds 二选一)poll_interval:默认 5max_wait:默认 300yaml
- type: wait
seconds: 10
- type: wait
until: "task_done == True"
poll_interval: 3
max_wait: 180
message 节点#发送消息。默认通过 Agent 代发, direct: true 时走 CLI 直发。
支持字段:
channel:默认 imessagetarget(必填)message / media:至少一个account:可选账号direct:默认 falsewhen:条件守卫,不满足则跳过yaml
- id: notify
type: message
channel: imessage
target: "+8617600510003"
message: "📬 报告如下:{{agent_reply.text}}"
when: "len(agent_reply.text) > 0"
subagent 节点#创建子代理执行独立任务,支持异步或等待模式。
支持字段:
task(必填)label / model / thinkingtimeout:默认 300wait:默认 falsepoll_interval:默认 5mode: run(默认)/ sessioncleanup: auto(默认)/ keepthrottle_timeout:并发等待超时,默认 300spawn_timeout:Gateway 调用超时 (ms),默认 120000spawn_retries:Gateway timeout 重试次数,默认 2yaml
- id: classify_one
type: subagent
task: "请分类此邮件:{{email.body}}"
label: "邮件分类器"
wait: true
timeout: 120
cleanup: auto
wait_subagents 节点#汇合多个 wait: false 子代理,集中等待并收集结果。
支持字段:
tracker(必填)max_wait:默认 600poll_interval:默认 5extra_fields:透传字段cleanup: auto(默认)/ completed / keepyaml
- id: wait_all
type: wait_subagents
tracker: "{{init_tracker}}"
extra_fields: [email_id, subject]
cleanup: auto
id,避免后续引用困难。loop + subagent(wait:false) + code(collect) + wait_subagents 是推荐并行模式。Engine 会自动检测此模式并使用 批量 spawn(单次 agent_call 并行创建多个 subagent),无需额外配置。timeout、 retry 和 on_error。llm.session: isolated 或 subagent。code 节点输出结构化 result。spawn_batch_size 调整每批数量,默认 8。核心思路: OpenClaw Agent 在单次对话回复中可以并行调用多次 sessions_spawn 工具。利用这一点,engine 在一次 agent_call 中指示 Agent 同时创建 N 个 subagent,而不是每个 subagent 单独调一次。
自动触发条件: _execute_loop() 会自动检测循环体是否符合 "subagent(wait=false) + code(collect)" 模式。如果符合且 len(items) > 1,自动走批量 spawn 路径,无需任何 YAML 配置变更。
批量 spawn 流程:
engine._detect_batch_spawn_pattern(sub_steps) → 检测循环体结构
engine._execute_loop_batch_spawn() → 开 factory session → 分批调用 batch_spawn_subagents()
nodes.batch_spawn_subagents(items, step_template, ctx, log, bridge, batch_size):
batch_size (默认 8) 分批sessions_spawnbridge.agent_call() 发送到 factory sessionbridge.extract_all_spawn_info_from_session_log() 从 JSONL 提取所有 childSessionKey所有 spawn 完成后,逐个执行 collect step (记录 spawn 信息到 tracker)
关闭 factory session
性能对比:
模式10 个 subagent24 个 subagent (Gmail)Session 开销子会话模式 (单个)25sN/A (非循环)1 childsubagent 串行250s (25s×10)~600s (超时❌)N + 几个批量 spawn****~77s ✅预计 ~90-120s ✅N + 1 factory
实测数据 (batch_test10, 2026-03-17):
关键代码路径:
engine.py _detect_batch_spawn_pattern() → 模式检测engine.py _execute_loop_batch_spawn() → 批量执行入口nodes.py batch_spawn_subagents() → 核心批量 spawn 逻辑bridge.py extract_all_spawn_info_from_session_log() → 从 JSONL 提取全部 spawn 结果bridge.py 工厂 session 管理 (open/close/rotate/track) — 仍然使用参数:
参数默认值说明spawn_batch_size8每批并行创建的 subagent 数量 (YAML step 级别可配)spawn_timeout180000ms批量 spawn 的 Gateway 超时 (比单个 spawn 的 120000ms 更长)spawn_retries2Gateway timeout 重试次数
注意事项:
sessions_spawn 的 cleanup 字段只接受 "delete" 或 "keep",不接受 "auto"min(subagents.maxConcurrent=20, maxConcurrent=8)