Agent 小知识 | Agent 编排的三种方式:ReAct、Plan-and-Execute 与 Workflow Graph

上一期我们聊了 Agent 小知识|长任务不重来:Agent 状态保存的工程设计现在 Agent 能记住任务做到了哪里、此前发生了什么,也能在中断后从检查点继续执行。

可 Agent 记住当前状态后,下一步该往哪里走,又应该由谁决定?是让模型边观察边行动,还是先列出计划再执行,或者直接把固定路径写进系统?这些问题构成了本文要讲的主题——Agent 的编排。

懒人图解版

1

状态、编排与行动的关系

假设一个 Agent 正在执行代码发布任务,当前状态记录了这些信息:

当前目标:发布到测试环境
当前阶段:运行测试
构建结果:成功
测试结果:失败
最近错误:数据库连接超时

这份状态可以告诉系统,任务停在测试阶段,构建已经完成,但测试还没有通过。至于下一步是重试测试、进入问题诊断、终止发布,还是请求人工处理,需要系统结合当前状态、执行结果和状态转移规则进行判断。

测试失败
   ↓
判断失败原因
 ├─ 可重试 → 重新测试
 ├─ 需要排查 → 进入问题诊断
 ├─ 无法继续 → 终止发布
 └─ 需要决策 → 请求人工处理

负责组织这些执行路径的,就是 Agent 的编排逻辑。

编排会读取当前状态,再根据任务规则选择下一条合法路径。如果需要调用工具,它会把任务交给对应的执行节点;如果遇到高风险操作,它会暂停任务并等待用户确认;如果任务已经达到结束条件,它会终止执行循环。可以把三者的关系简单理解为:

  • 状态记录任务现在在哪里;

  • 编排判断接下来允许往哪里走;

  • 工具把判断变成真实行动。

2

图 1. 从状态到行动。状态保存任务位置和执行结果,编排读取状态并应用规则,行动层调用工具、进入节点或请求人工确认。

前五期提到的上下文、Prompt、工具和状态,也会在这套编排过程中重新组合起来。每次行动前,系统根据当前状态组织上下文和动态 Prompt;模型读取信息后提出工具调用;Harness 校验并执行工具;工具结果写回状态;编排逻辑再根据新的状态决定任务如何继续。

ReAct 的动态决策循环

其实在第一期内容中,我们聊过 ReAct。它把判断、行动和观察放进一个循环:模型先根据已有信息选择行动,再根据环境返回的新结果决定下一步。

模型选择下一步行动
      ↓
Harness 校验并执行工具
      ↓
环境返回新的结果
      ↓
模型再次判断

以测试失败为例,Agent 一开始可能只知道数据库连接超时。它还不知道问题出在数据库服务、网络配置、环境变量,还是测试代码本身。这时候很难提前写出一条完整的排查路径。Agent 可以先读取测试日志,再根据日志选择下一项检查。

它可能先调用 Shell 工具查看数据库容器:

docker ps

如果发现容器没有启动,它会继续读取 docker-compose.yml;如果容器已经正常运行,它可能转去检查端口、数据库地址或者测试环境变量。

前一次工具调用产生的结果,会直接改变下一次行动。代码排错、开放式资料搜索、陌生代码库探索和复杂环境诊断,都有类似特点:问题路径无法提前确定,需要持续读取外部信息,中间结果还会不断改变后续方向。这类任务就适合使用 ReAct。

不过,ReAct 循环不代表模型想做什么就做什么。Harness 仍然要负责工具权限、参数校验、最大执行轮次、超时和停止条件。模型负责提出行动,系统负责判断这个行动是否允许执行。ReAct 擅长处理的是“不知道下一步会遇到什么”的任务。

Agent 自主决策的工程边界

一次完整的版本发布,不只有未知问题需要探索,还包含很多已经明确、不能跳过的流程。

假设我们把整条发布流程都交给 Agent 临场决定。Agent 构建完项目后,可能认为这次修改范围很小,只运行了部分测试;测试失败以后,它一边修改代码一边重试,逐渐把发布任务做成了代码重构;它也可能记得运行测试,却忘记执行安全扫描。

更危险的情况是,Agent 看到测试通过,直接调用部署工具,没有等待人工确认。部署结束后,它生成了一份完整的发布报告,却没有真正检查服务是否正常启动。

模型可能知道测试、安全扫描和人工确认都很重要,但“模型知道应该执行”与“系统保证一定执行”之间,仍然隔着一道工程边界。如果每一步都由模型临场决定,执行路径可能偏离原始目标,关键步骤也可能被遗漏。同样的任务每次走不同路径,还会增加测试、复现和审计的难度。

因此,需要探索的步骤可以交给 Agent,但必须执行的步骤,要写进系统规则。

Plan-and-Execute 的计划执行机制

如果一个任务的目标已经明确,也能拆成若干子任务,但在执行过程中还可能遇到变化,可以采用 Plan-and-Execute。它会先生成一份计划,再按照子任务之间的依赖关系逐步执行。

生成计划
    ↓
按依赖顺序执行
    ↓
更新任务状态
    ↓
遇到异常时修改计划

对于发布任务,Agent 会先列出:

1. 检查当前分支和代码变更
2. 构建项目
3. 运行单元测试和集成测试
4. 执行安全扫描
5. 生成发布说明
6. 请求用户确认
7. 部署到测试环境
8. 验证服务状态

真正交给系统执行的计划,通常会比自然语言列表更结构化。每个步骤可以带上任务 ID、依赖项、完成条件和当前状态:

{
  "id": "run_tests",
  "task": "运行测试套件",
  "dependencies": [
    "build_project"
  ],
  "success_criteria": "所有必要测试通过",
  "status": "pending"
}

有了这些字段,Harness 可以知道 run_tests 必须等待 build_project 完成,也能根据测试结果判断这个步骤是否真正结束。

规划阶段负责拆分任务和建立依赖关系。执行阶段负责调用工具,并将结果写回状态。如果某个步骤失败,系统再根据最新状态修改后续计划。

原计划可能是:

测试
→ 安全扫描
→ 生成发布说明

测试失败后,计划被修改成:

测试失败
→ 诊断数据库连接
→ 修复配置
→ 重新构建
→ 重新测试
→ 安全扫描

这份计划要跟着任务状态一起更新。如果 Agent 已经确认问题来自测试数据库配置,后续就不用重新检查所有依赖;如果修复过程中修改了代码和配置,原来的构建结果也要标记为失效。

Plan-and-Execute 适合目标明确、可以拆成多个子任务、子任务之间存在依赖,同时允许执行路径根据结果适度调整的任务。研究报告、复杂代码修改、跨多个系统的数据整理等任务,都可以先列计划再执行。

不过,初始计划可能建立在错误假设上。环境变化越频繁,计划过期得越快。如果系统每走一步都重新生成完整计划,模型调用成本也会继续增加。

计划中出现“部署”或“删除文件”这样的步骤,也不代表 Agent 自动获得了对应权限。Harness 仍然要在执行前检查工具权限和人工审批条件。

Plan-and-Execute 提供的是一份可以调整的任务结构,它让 Agent 少一点走一步看一步,多一点先想清楚再行动。

Workflow Graph 的流转规则

还有一类任务,执行路径已经比较稳定。以一个简化的发布流程为例,构建成功后才能运行测试,测试通过后才能执行安全扫描,获得人工确认后才能部署。部署完成以后还要运行健康检查,检查失败则进入回滚或人工处理。实际节点和顺序取决于团队的发布策略。安全扫描可以和测试并行,低风险测试环境也不一定需要人工审批。这里使用简化流程说明编排关系。这类流程可以固化成 Workflow Graph:

构建
  ↓
测试
  ├─ 失败 → 终止当前发布 → 进入诊断流程
  └─ 通过
       ↓
    安全扫描
       ↓
    人工审批
       ↓
    部署
       ↓
    健康检查
       ├─ 通过 → 完成
       └─ 失败 → 回滚

在 Workflow Graph 中,节点代表一个执行阶段,边(也就是连接节点的有向箭头)代表节点之间允许发生的流转,条件决定任务可以进入哪条分支。节点不一定都由模型执行:

  • “构建项目”可以是 Shell 命令节点;

  • “运行测试”可以是 CI 服务节点;

  • “安全扫描”可以调用固定扫描工具;

  • “人工审批”需要等待用户输入;

  • “失败诊断”则可以交给 Agent。

Workflow Graph 不一定是 DAG——有向无环图,指节点之间存在明确的流转方向,但不会形成可以回到原节点的循环。如果任务只需按照依赖关系单向推进,不需要返回之前的节点,就可以使用 DAG。

当发布任务中存在“测试失败—修复—重新构建—重新测试”的回路,这种结构就已不是 DAG,更接近带循环的 Workflow Graph 或显式状态机。状态机可以把任务划分成:

BUILDING
TESTING
DIAGNOSING
WAITING_FOR_HUMAN
DEPLOYING
VERIFYING
DONE
FAILED

每个状态都有明确的进入条件和退出条件。测试没有通过,就不能从 TESTING 进入 DEPLOYING;用户没有确认,任务就只能停在 WAITING_FOR_HUMAN。模型在某个节点内部依然可以自主行动,但它只能沿系统允许的路径交还控制权。

Workflow Graph 把测试、审批以及失败后的回滚路径,从模型判断变成了系统规则。这些规则不能只画在图中,Harness 还要执行工具白名单、权限检查、状态转移校验和审批条件。

如果诊断 Agent 没有获得部署工具,它就无法在排查过程中绕过发布主干;当前状态不满足进入条件,路由器也不能把任务直接送进部署节点。

因此,路径稳定、规则明确、存在必经步骤、需要测试与审计的任务,更适合固化成 Workflow Graph。

三种编排方式的选择依据

ReAct、Plan-and-Execute 和 Workflow Graph 不是三种能力等级。区别在于执行路径由谁产生,又在什么时候确定。

3

图 2. 三种编排模式对比。ReAct 的路径在运行过程中逐步生成;Plan-and-Execute 在任务开始时生成计划,并允许根据执行结果修订;Workflow Graph 由开发者预先定义合法节点和流转范围。

选择时,可以先看任务路径的确定程度:

  • 路径无法提前判断,需要持续读取环境反馈,使用 ReAct;

  • 目标明确、任务可以拆解,但具体步骤会随结果调整,使用 Plan-and-Execute;

  • 路径稳定、规则明确,还有不能跳过的节点,使用 Workflow Graph。

风险和结果验证方式也会影响自主度。删除数据、发送消息、支付、部署等操作,需要权限限制或人工确认;测试退出码、JSON Schema、安全扫描结果和服务健康状态可以由程序判断,更适合写进固定流程。开放式分析、故障归因和方案选择,则可以给模型保留更多决策空间。

实际系统也可以把模型生成的计划转换成临时任务图,或者在 Workflow Graph 的某个节点中动态生成子计划。Plan-and-Execute 负责规划,Workflow Graph 负责控制流,两者可以组合使用。

固定主干与局部自主

实际系统很少只使用一种编排模式。代码发布可以用 Workflow Graph 控制主干,把失败后的修复交给 Plan-and-Execute,再让 ReAct 处理无法提前确定的诊断步骤。

Workflow Graph 控制发布主干

构建
→ 测试
→ 安全扫描
→ 人工审批
→ 部署
→ 健康检查
→ 完成或回滚

测试通过,任务沿固定路径继续;测试失败,当前发布停止。系统保存失败日志和任务状态,再创建诊断与修复子任务。Plan-and-Execute 可以把修复任务拆成:

1. 分析失败日志
2. 定位相关代码和配置
3. 验证失败原因
4. 修改代码或配置
5. 检查修改范围并进行代码审查或变更确认
6. 重新运行相关测试
7. 输出修改结果

其中,“定位相关代码和配置”很难提前写死。Agent 可以在这个子任务中使用 ReAct,读取日志、搜索代码、运行命令,再根据返回结果调整排查方向。

Agent 修改代码以后,发布对象已经变化,修改前的构建、测试和扫描结果不能继续沿用。系统需要检查修改范围,按团队策略完成代码审查或变更确认,再重新构建并进入发布主干。

4

图 3. 混合编排的代码发布流程。Workflow Graph 控制构建、测试、安全扫描、人工审批、部署、健康检查和回滚;测试失败后进入 Plan-and-Execute 修复子流程;具体故障诊断节点内部运行 ReAct;代码发生修改后先进行代码审查或变更确认,再重新构建,并从测试阶段重新进入发布主干。

整套系统可以分成三层:

Workflow Graph
控制任务主干和安全边界
        ↓
Plan-and-Execute
组织复杂的诊断修复子任务
        ↓
ReAct
处理子任务内部无法预先确定的步骤

Workflow Graph 守住确定性,Agent 处理不确定性。任务可以根据现场情况调整,也不会因为一次临场判断跳过关键环节。

自主节点的控制权交还

Agent 完成自主任务后,Workflow Graph 还要判断任务能否继续。比较稳妥的方式,是给自主节点定义明确的输入输出契约。调用诊断 Agent 时,系统传入任务目标、可用工具、行为约束和完成条件:

{
  "goal": "定位并修复测试失败",
  "allowed_tools": ["read_file", "search_code", "write_file", "run_tests"],
  "constraints": ["不得提交代码", "不得部署"],
  "success_criteria": "必要测试通过"
}

allowed_tools 需要由 Harness 真正执行,不能只写进 Prompt。Agent 可以生成任务总结和修改结果;测试记录、退出码和工作区快照等验证证据,则由 Harness 或工具运行层附加:

{
  "status": "resolved",
  "changed_files": ["config/test-db.js"],
  "test_run_id": "test-run-204",
  "exit_code": 0,
  "workspace_snapshot_id": "snapshot-018",
  "suggested_route": "rerun_tests"
}

Harness 检查输出 Schema、测试记录、工作区快照和文件修改范围,再由 Workflow Graph 选择合法节点。即使 Agent 建议 rerun_tests,系统发现代码已经修改,也可以先把任务送回构建节点。

Agent 可以建议往哪里走,系统负责判断这条路是否合法。

如果 Agent 执行超时、达到最大轮次,或者返回结果无法验证,Workflow Graph 可以进入失败节点或人工处理节点。任务状态和中间产物继续保留,后续可以重试或从检查点恢复。

这样,自主节点保留完成局部任务所需的灵活性,也不会打散整个系统的控制边界。

结语

综上,Agent 能自主决定下一步,不代表整条任务链都要交给模型。路径未知时使用 ReAct,任务可拆解但步骤会变化时使用 Plan-and-Execute,流程稳定且存在必经节点时使用 Workflow Graph。

真实系统通常由 Workflow Graph 控制主干,Plan-and-Execute 组织复杂子任务,ReAct 处理局部未知问题。需要探索的地方交给 Agent,必须保证的地方交给系统。

下一期,我们继续聊 Agent 为什么需要环境,以及代码沙盒、网页、电脑操作和软件工程环境,如何构成 Agent 的观察空间与行动空间。

posted @ 2026-08-13 16:16  小七-七牛开发者  阅读(0)  评论(0)    收藏  举报