## 用一个例子理解完整生命周期

<!-- slot: 目标 -->
Workflow 把一项工作从“想法”变成“可复用、可观察的执行”。这条生命周期由四个对象串起来：可复用的 **Plan**、可选的 **触发器（Binding）**、一次 **调用（Invocation）**、以及执行它的 **运行（Run）**。本章用一个贯穿例子——“每日 Bug 分诊”——带你走完从创作到产出的主路径，看清四个对象各自的位置，并理解“改了 Plan 之后，正在跑的 Run 会怎样”。

<!-- slot: 边界 -->
本章覆盖从创作到运行的主路径，并点出四个对象各自的位置；不展开各节点类型的配置、异常恢复或外部系统实现——这些在后续篇章。四个对象的内部结构在核心对象一章展开。

<!-- slot: 提示词 -->
本章不涉及从提示词创建 Workflow；手动创建与校验 Plan 的具体操作在后续篇章展开。

<!-- slot: 媒体槽位 -->
![Plan、触发器（Binding）、Invocation 与 Run 的关系](../../media/shared/diagrams/workflow-lifecycle.svg){#fig-workflow-lifecycle width=92%}

<!-- slot: 流程 -->
以“每日 Bug 分诊”为例：每天到一个时间点，自动把新 Bug 交给分诊 Agent 归类、人工确认、再通知结果。它的主路径如下：

1. **描述目标与输入**：确定要解决的问题（分诊新 Bug），以及需要的输入（Bug 摘要、目标频道）。这时还没有 Plan，只有业务意图。
2. **创建并校验 Plan 草稿**：在 YAML 或可视化画布里编排节点与边——例如“调用分诊 Agent → 人工审批 → 通知”。校验后确认 `diagnostics=[]`（编辑器的校验，或 `loop exec workflow plan` 的 validate 动作）。这一步产出可复用的 **Plan**。
3. **发布 Plan**：普通 Plan 直接发布为不可变版本；Team Plan 要先经 Owner 审批再发布。发布后 Plan 拿到一个确定的版本。
4. **发起执行**：手动运行一次（直接对 Plan 发起调用），或创建并启用一个触发器（Binding）按计划自动发起。无论哪种，被接受的那一次请求就是一次 **Invocation**。
5. **执行与等待**：**Run** 按 Invocation 指向的 Plan 版本执行。遇到 `wait` 它会等到时间到；遇到 `request_approval` 它会停在 `waiting` 等人决策；遇到 `send_message(completion: callback)` 它会等 Agent 回传。每一类等待都表现为 Run 的 `waiting` 状态，没有单独的“超时”或“等待审批”状态。
6. **完成或失败**：所有路径走到 `end` 节点后，Run 进入终态 `succeeded` 或 `failed`；审批被驳回会沿 `rejected` 边走到失败的 `end`。
7. **演进**：业务变了就修改 Plan 草稿、发布新版本。**关键：已经被接受的 Run 继续使用它发起时的版本快照**——你改了 Plan 不会影响正在跑的旧 Run。此后手动新发起的调用可以用新版本；但**已经存在的触发器（Binding）固定指向它创建时绑定的那个 Plan 版本，不会自动漂移到新版本**——要让计划调用切到新版本，需要显式更新或新建一个指向新版本的 Binding 再启用。

把这条路径对应到四个对象：Plan 是“做什么”的定义；触发器（Binding）决定“何时自动做”；Invocation 是“一次被接受的请求”；Run 是“这次请求的执行过程”。

在运行视图里你能看到这张图被“点亮”的过程：当前停在哪个 Node、它在等什么（计时器到期、等人审批、等 Agent 回调）、已经发出了哪些消息和效果、哪些路径已经走完。如果某个工作流长期卡在 `waiting`，你可以在运行视图里直接看出它在等谁，而不是去翻聊天记录。

再以版本演进为例：把分诊 Agent 的提示词改得更准后，你会发布一个新版本的 Plan；但今天已经开始的那次 Run 仍按旧版本跑完——这就是“版本快照”的含义。这里要特别提醒：触发器（Binding）本身也是版本绑定的，它固定指向创建时指定的那个 Plan 版本，**发布新版本并不会让现有触发器自动改用新版本**。所以“发布新版本”和“现有触发器自动升级”是两件事——要让计划调用用上新版本，需要显式更新或新建一个指向新版本的 Binding，再启用它；而手动新发起的调用若不指定版本，才会落到新的默认版本。

再看失败与人工环节，这也是运行视图最能体现价值的地方。如果分诊 Agent 回传的结果不符合声明的回调结构，这次完成请求会被拒绝（`ErrCallbackOutputInvalid`），Agent 可以修正后重新提交，而 Run 会继续停在等待，不会自动重跑整个节点；节点上的 `retry` 只负责把消息或审批重新投递出去，不校验回调内容。如果人工审批被驳回，Run 会沿 `rejected` 边走到一个失败的 `end`，最终状态是 `failed`，并在审批收件箱里留下可追溯的记录。也就是说，每一次等待的原因、每一次决策的结果，以及整条路径最终走向成功还是失败，都被结构化地记录下来——这正是 Workflow 相比“在群里手动跟进”最大的差别。

顺带说清“手动运行”与“触发器”的差别，这是新手最常问的问题。手动运行是你在需要时点一下、对 Plan 发起一次调用，适合不固定的、按需的场景，比如临时跑一次数据校对。触发器（Binding）则是给那些“到了点就该自动跑”的场景——每天早上的分诊、每小时的同步。一个 Plan 可以既被手动运行，又挂上多个触发器；它们各自产生 Invocation、互不干扰。判断该用哪个，只看一件事：是不是到了固定时间就该自动跑。

<!-- slot: 配置 -->
发现与调用 Extension（由 App 承载的 Agent 动作）通过统一命令：

```bash
$ loop exec --help
$ loop exec <extension-name> <action> --input-schema
```

注意：这是 Agent 侧的能力发现，**不是** Plan 里的节点；Workflow 通过 `send_message` 与 Agent 协作，由 Agent 决定是否调用 Extension。

<!-- slot: 异常 -->
本章不展开失败处置；运行态异常与恢复策略（重试、回调拒绝、审批驳回）在可靠流程设计篇说明。

<!-- slot: 审批 -->
Team Plan 发布前可能需要 Owner 审批；运行时 `request_approval` 节点在可靠流程设计篇展开。本章只说明审批在生命周期中的位置。注意有两类审批不要混：发布审批决定一个 Plan 版本能不能上线，运行时审批决定某一次 Run 能不能继续——它们发生的时间点和作用都不一样。

<!-- slot: 外部系统 -->
后续篇章会展示外部 CRM、HRIS、ERP 和工单系统如何通过 App + Extension 参与 Workflow——由 Agent 调用 `loop exec` 动作，而非 Workflow 直接调用。

<!-- slot: 验收 -->
- [ ] 能按顺序说明 Plan、触发器（Binding）、Invocation、Run 的关系，并用“每日 Bug 分诊”对应到每一步。
- [ ] 能说出 Run 遇到 `wait` / `request_approval` / `send_message(callback)` 时分别等什么，以及它们都表现为哪个状态。
- [ ] 能解释为什么修改 Plan 不影响已接受的 Run（版本快照）。
- [ ] 能把四个对象对应到“做什么 / 何时做 / 一次请求 / 执行过程”。
