第 2 章:Workflow 与 Agent 的边界

本章导读

  • 核心问题:如何判断一个任务应该使用 Prompt、Workflow 还是 Agent。
  • 关键词:Workflow、Agent、控制流、不确定性、混合架构
  • 学习产出:形成企业场景的任务分类框架,并为 CI 失败分析设计 Workflow + Agent 混合方案。

1. 本章要解决什么问题

上一章我们讨论了为什么需要 Agent。

但这很容易带来另一个误区:

既然 Agent 更强,是不是所有 AI 应用都应该做成 Agent?

答案是否定的。

在真实工程中,很多失败的 Agent 项目并不是因为模型不够强,而是因为系统设计者一开始就选错了抽象:明明是一个固定流程问题,却做成了高度自主的 Agent;明明只需要一次分类和生成,却设计了 Planner、Executor、Memory、Reflection、Multi-Agent 等复杂结构。

Anthropic 在 Building Effective Agents 中反复强调:

从简单开始,只有当简单方案不够时,才逐步增加复杂度。

本章的核心问题就是:

什么时候用 Prompt?
什么时候用 Workflow?
什么时候才需要 Agent?

这不是概念区分,而是架构决策。

因为一旦选错,后续会直接影响:

  • 系统复杂度;
  • 调试难度;
  • 成本;
  • 延迟;
  • 可观测性;
  • 权限控制;
  • 企业合规;
  • 用户信任。

本章重点回答:

  • Workflow 和 Agent 的本质区别是什么;
  • Anthropic 提到的几类 Workflow 分别适合什么场景;
  • 为什么 Agent 的能力来自动态控制流;
  • 如何判断一个任务是否真的需要 Agent;
  • 如何在 Java / Spring Boot 中同时支持 WorkflowExecutor 与 AgentExecutor。

2. 对应 Anthropic 文章

本章主要对应 Anthropic Engineering 的文章:

  • Building Effective Agents

这篇文章把 agentic system 分成三个层次:

Augmented LLM
  ↓
Workflow
  ↓
Agent

其中 Workflow 和 Agent 是最容易混淆的两个概念。

Anthropic 对二者的区分非常重要:

  • Workflow:LLM 和工具通过预定义代码路径被编排;
  • Agent:LLM 自主规划、调用工具,并根据环境反馈动态决定下一步。

换句话说:

Workflow 的控制权主要在程序手里。
Agent 的控制权部分交给模型。

这句话是本章最重要的判断标准。

3. 原文核心观点

3.1 先用最简单的方案

Anthropic 的第一条建议不是“构建 Agent”,而是:

尽量保持简单。

很多 AI 应用可以用下面三种方式解决:

单次 Prompt
  ↓
Prompt + RAG
  ↓
固定 Workflow

只有当这些方式无法处理任务的不确定性时,才应该进入 Agent。

这和传统软件工程非常相似。

我们不会为了一个简单的 CRUD 页面引入复杂的分布式工作流引擎。同样,也不应该为了一个简单的文本分类任务引入 Agent Runtime。

工程解释

复杂度不是免费的。

Agent 会带来:

  • 多轮模型调用;
  • 更多 token 消耗;
  • 更高延迟;
  • 更多不可预测行为;
  • 更复杂的日志和追踪;
  • 更严格的权限管理;
  • 更难的测试和评估。

所以第一个原则是:

如果 Prompt 能解决,就不要 Workflow;如果 Workflow 能解决,就不要 Agent。

3.2 Workflow 是可预定义控制流

Workflow 的特点是:

开发者提前知道大致步骤
程序控制节点顺序
LLM 只在某些节点完成局部任务

例如,一个合同审查系统可能是:

上传合同
  ↓
提取条款
  ↓
识别风险类别
  ↓
调用不同审查模板
  ↓
生成审查意见
  ↓
合规检查
  ↓
输出报告

这里虽然每一步可能都用到 LLM,但整个流程是固定的。

这种任务用 Workflow 更好,因为它:

  • 容易测试;
  • 容易监控;
  • 容易优化;
  • 容易解释;
  • 容易满足合规;
  • 容易控制成本。

3.3 Agent 是动态控制流

Agent 的特点是:

目标由用户给出
路径无法完全预定义
模型根据环境反馈决定下一步

例如:

请帮我分析这个 Java 项目为什么 CI 失败,并给出修复建议。

这个任务的路径无法提前写死。

Agent 可能会:

读取 CI 日志
  ↓
发现是单元测试失败
  ↓
定位失败测试类
  ↓
搜索相关业务代码
  ↓
查看最近提交
  ↓
判断是数据构造问题还是业务逻辑问题
  ↓
必要时运行局部测试
  ↓
输出原因和建议

但也可能会走另一条路径:

读取 CI 日志
  ↓
发现是依赖下载失败
  ↓
检查 Maven 仓库配置
  ↓
判断是网络问题或版本冲突
  ↓
输出基础设施修复建议

同一个目标,不同输入,路径完全不同。

这就是 Agent 的适用场景。

3.4 Workflow 与 Agent 不是对立关系

一个成熟的企业系统中,Workflow 和 Agent 往往会同时存在。

常见组合方式是:

外层 Workflow 控制业务边界
局部节点使用 Agent 处理开放任务

例如:

需求单进入
  ↓
Workflow 判断类型
  ↓
如果是简单问答:走 RAG
  ↓
如果是代码分析:调用 Coding Agent
  ↓
如果是审批类任务:走传统审批流
  ↓
统一记录审计日志

这是一种更符合企业生产环境的设计。

Agent 不应该接管整个业务系统,而应该成为 Workflow 中可以被调用、被限制、被观察的能力单元。

3.5 选择边界取决于“不确定性”

判断一个任务是否需要 Agent,关键不是看它是否“复杂”,而是看它是否“不确定”。

有些任务看起来复杂,但流程稳定。

例如发票识别:

上传文件
  ↓
OCR
  ↓
字段抽取
  ↓
校验
  ↓
入库

这可能很复杂,但更适合 Workflow。

有些任务看起来简单,但路径不确定。

例如:

这个接口为什么最近变慢了?

它可能涉及:

  • 日志;
  • 指标;
  • 链路追踪;
  • 数据库慢查询;
  • 最近发布;
  • 依赖服务;
  • 缓存命中率;
  • 配置变更。

这类任务更接近 Agent。

所以判断标准不是“难不难”,而是:

能不能提前写出稳定流程?

4. Anthropic 提到的 Workflow 模式

Building Effective Agents 中总结了几种常见 Workflow 模式。它们是理解 Agent 前非常重要的中间形态。

4.1 Prompt Chaining:提示链

Prompt Chaining 是最容易理解的 Workflow。

它把一个任务拆成多个固定步骤,每一步都是一次 LLM 调用。

例如:

生成文章大纲
  ↓
检查大纲是否符合要求
  ↓
根据大纲写正文
  ↓
润色正文

适用场景:

  • 任务可以清晰拆分;
  • 每一步输入输出明确;
  • 上一步结果自然成为下一步输入;
  • 可以在中间增加程序化校验。

Java 企业场景示例:

生成接口文档
  ↓
检查字段完整性
  ↓
生成 OpenAPI 描述
  ↓
生成 Markdown 文档

不适合场景:

  • 下一步取决于复杂环境反馈;
  • 中间路径无法提前定义;
  • 需要反复搜索、尝试和修正。

4.2 Routing:路由

Routing 是根据输入类型,把任务分发到不同处理路径。

例如客服系统:

用户问题
  ↓
分类:退款 / 技术支持 / 账号问题 / 普通咨询
  ↓
进入不同处理流程

适用场景:

  • 输入类型可以稳定分类;
  • 不同类别需要不同 Prompt、模型或工具;
  • 分类准确率较高;
  • 路由后的处理路径相对固定。

企业 Agent 平台中,Routing 很适合放在入口层:

用户任务
  ↓
TaskClassifier
  ↓
Prompt / Workflow / Agent

这可以避免所有任务都进入昂贵的 Agent Loop。

4.3 Parallelization:并行化

Parallelization 是把任务拆成多个可以并行执行的子任务,然后汇总结果。

例如:

同一份代码变更
  ↓
安全风险检查
  ↓
性能风险检查
  ↓
代码风格检查
  ↓
测试覆盖检查
  ↓
汇总评审意见

适用场景:

  • 子任务之间相互独立;
  • 需要多个视角分析同一输入;
  • 延迟敏感,希望并发完成;
  • 汇总逻辑清晰。

这和 Multi-Agent 有相似之处,但不一定需要真正的 Agent。很多时候,几个并行 LLM 调用加一个汇总器就够了。

4.4 Orchestrator-Workers:编排者-工人

Orchestrator-Workers 模式中,一个中心 LLM 动态拆分任务,然后分配给多个 Worker。

它已经接近 Agent,但仍然可以被视为一种 Workflow,因为总体结构是固定的:

Orchestrator
  ↓
拆分任务
  ↓
多个 Worker 执行
  ↓
Orchestrator 汇总

适用场景:

  • 子任务数量无法提前确定;
  • 但总体协作模式稳定;
  • 需要多个 Worker 并行处理;
  • 最终需要统一综合。

例如:

分析一个大型代码变更
  ↓
Orchestrator 判断涉及模块
  ↓
Worker A 分析 Controller
  ↓
Worker B 分析 Service
  ↓
Worker C 分析 Repository
  ↓
汇总代码评审意见

4.5 Evaluator-Optimizer:评估器-优化器

Evaluator-Optimizer 是一个循环:

生成结果
  ↓
评估结果
  ↓
给出反馈
  ↓
继续优化

适用场景:

  • 有明确评估标准;
  • 迭代改进可以带来明显收益;
  • 评估器能够给出有效反馈;
  • 任务允许多轮优化。

典型场景:

  • 文案润色;
  • 翻译质量提升;
  • 单元测试生成后检查覆盖点;
  • SQL 生成后检查安全性和性能;
  • 代码修改后运行测试并修复。

这个模式也是后续 Harness Engineering 的基础。

5. Workflow 与 Agent 的判断框架

下面给出一个实用判断表。

维度 Prompt Workflow Agent
任务路径 一步完成 可提前定义 无法提前完全定义
控制权 用户 + Prompt 程序 模型 + 程序边界
工具调用 通常不需要 固定位置调用 动态选择调用
上下文 输入即上下文 每步传递上下文 持续管理上下文
反馈循环 无或很少 固定检查点 根据环境反馈循环
成本
可测试性 中等偏低,需要额外评估
可观测性 简单 清晰 必须专门设计
适用场景 改写、总结、生成 分类、抽取、审核、固定流程 编码、排障、研究、复杂操作

可以进一步浓缩成三个问题:

1. 这个任务能不能一次完成?
   能:Prompt。

2. 这个任务能不能拆成固定步骤?
   能:Workflow。

3. 这个任务是否需要根据中间结果动态决定下一步?
   是:Agent。

6. 架构图 / 流程图

Prompt / Workflow / Agent 判断树
图 2-1 Prompt / Workflow / Agent 判断树 这张图帮助判断一个任务应该使用单次 Prompt、固定 Workflow,还是由 Agent 动态决策。 Mermaid 源文件

6.1 选择 Prompt、Workflow 还是 Agent

选择 Prompt、Workflow 还是 Agent
图 2-2 选择 Prompt、Workflow 还是 Agent Mermaid 源文件

6.2 Workflow 的控制权

Workflow 的控制权
图 2-3 Workflow 的控制权 Mermaid 源文件

在 Workflow 中,LLM 负责局部智能,程序负责流程控制。

6.3 Agent 的控制权

Agent 的控制权
图 2-4 Agent 的控制权 Mermaid 源文件

在 Agent 中,LLM 不只是生成文本,还参与下一步动作选择。

6.4 企业中的混合架构

企业中的混合架构
图 2-5 企业中的混合架构 Mermaid 源文件

这张图是企业 Agent 平台的关键:

Agent 只是平台中的一种执行方式,而不是所有任务的唯一入口。

7. Java / Spring Boot 落地方案

在企业平台中,不建议把 Prompt、Workflow、Agent 混在一个 Controller 里。

更合理的设计是抽象统一任务执行入口,然后根据任务类型路由到不同 Executor。

7.1 统一任务模型

public record AiTask(
    String id,
    String userId,
    String objective,
    TaskType type,
    Map<String, Object> metadata
) {}

任务类型:

public enum TaskType {
    PROMPT,
    WORKFLOW,
    AGENT,
    HUMAN_REVIEW
}

执行结果:

public record AiTaskResult(
    String taskId,
    TaskStatus status,
    String summary,
    Map<String, Object> output
) {}

7.2 TaskClassifier

入口处先判断任务类型:

public interface TaskClassifier {
    TaskType classify(AiTask task, ClassificationContext context);
}

一个简单规则可能是:

public class RuleBasedTaskClassifier implements TaskClassifier {

    @Override
    public TaskType classify(AiTask task, ClassificationContext context) {
        if (context.requiresCodeModification()) {
            return TaskType.AGENT;
        }
        if (context.hasFixedBusinessProcess()) {
            return TaskType.WORKFLOW;
        }
        if (context.isSimpleGeneration()) {
            return TaskType.PROMPT;
        }
        return TaskType.HUMAN_REVIEW;
    }
}

后续可以把分类交给 LLM,但第一版不建议直接完全依赖模型。

因为任务分类属于平台控制面,应该尽量稳定、可解释。

7.3 PromptExecutor

public interface PromptExecutor {
    AiTaskResult execute(AiTask task);
}

适合处理:

  • 总结;
  • 改写;
  • 翻译;
  • 模板生成;
  • 简单问答。

7.4 WorkflowExecutor

Workflow 可以抽象成多个 Step:

public interface WorkflowStep<I, O> {
    O execute(I input, WorkflowContext context);
}

Workflow 定义:

public record WorkflowDefinition(
    String name,
    List<WorkflowStep<?, ?>> steps
) {}

执行器:

public interface WorkflowExecutor {
    AiTaskResult execute(AiTask task, WorkflowDefinition workflow);
}

WorkflowContext 保存每一步输出:

public class WorkflowContext {
    private final Map<String, Object> variables = new HashMap<>();

    public void put(String key, Object value) {
        variables.put(key, value);
    }

    public <T> T get(String key, Class<T> type) {
        return type.cast(variables.get(key));
    }
}

7.5 AgentExecutor

AgentExecutor 与 WorkflowExecutor 最大区别是:

WorkflowExecutor 执行预定义步骤。
AgentExecutor 每一轮都要重新决定下一步。

接口可以这样设计:

public interface AgentExecutor {
    AiTaskResult execute(AiTask task, AgentExecutionPolicy policy);
}

执行策略:

public record AgentExecutionPolicy(
    int maxIterations,
    Duration timeout,
    Set<String> allowedTools,
    boolean requireHumanApprovalForWriteActions
) {}

AgentExecutor 内部会依赖:

ContextManager
ToolRegistry
ToolExecutor
MemoryService
StepRecorder
StopCondition

7.6 统一调度入口

最终入口可以设计成:

@Service
public class AiTaskService {

    private final TaskClassifier taskClassifier;
    private final PromptExecutor promptExecutor;
    private final WorkflowExecutor workflowExecutor;
    private final AgentExecutor agentExecutor;

    public AiTaskResult execute(AiTask task) {
        TaskType type = taskClassifier.classify(task, ClassificationContext.from(task));

        return switch (type) {
            case PROMPT -> promptExecutor.execute(task);
            case WORKFLOW -> workflowExecutor.execute(task, resolveWorkflow(task));
            case AGENT -> agentExecutor.execute(task, resolvePolicy(task));
            case HUMAN_REVIEW -> createHumanReviewTask(task);
        };
    }
}

这个设计的好处是:

  • 简单任务不会进入 Agent Loop;
  • 固定流程可以保持稳定;
  • Agent 被限制在真正需要动态决策的场景;
  • 所有执行方式都可以统一审计和观测。

8. 企业场景判断示例

8.1 自动生成周报

特点:

  • 输入数据明确;
  • 输出模板明确;
  • 不需要工具或只需要固定数据查询;
  • 不需要动态决策。

推荐:

Prompt 或简单 Workflow

不建议做成 Agent。

8.2 客服问题分流

特点:

  • 需要分类;
  • 不同类别进入不同流程;
  • 路径相对固定;
  • 可以用规则或模型路由。

推荐:

Routing Workflow

8.3 合同审查

特点:

  • 需要抽取条款;
  • 需要按风险类别审查;
  • 需要生成报告;
  • 流程相对稳定。

推荐:

Prompt Chaining + Evaluator Workflow

如果合同类型特别复杂,可以在局部引入 Agent。

8.4 自动分析 CI 失败

特点:

  • 失败原因不确定;
  • 需要读取日志;
  • 可能需要搜索代码;
  • 可能需要查看最近提交;
  • 需要根据中间结果决定下一步。

推荐:

Agent

但外层仍然可以是 Workflow:

CI 失败事件
  ↓
Workflow 创建分析任务
  ↓
Agent 分析原因
  ↓
Workflow 发送报告 / 创建 Issue

8.5 自动修改代码

特点:

  • 路径高度不确定;
  • 需要多轮工具调用;
  • 需要运行测试;
  • 需要根据错误继续修复;
  • 涉及写操作和安全风险。

推荐:

受控 Coding Agent

必须增加:

  • Git Diff 审计;
  • 写操作权限;
  • 最大迭代次数;
  • 测试验证;
  • 人工确认点。

9. 与其他框架对比

9.1 与传统工作流引擎

传统工作流引擎适合稳定业务流程,例如:

  • 审批;
  • 工单流转;
  • 财务报销;
  • 订单处理;
  • 合同归档。

Agent 适合开放式认知任务,例如:

  • 技术调研;
  • 代码分析;
  • 故障排查;
  • 根因定位;
  • 多系统信息综合。

二者不是替代关系。

企业中更常见的架构是:

Workflow 管业务过程
Agent 处理不确定节点

9.2 与 LangGraph

LangGraph 用图结构表达 LLM 应用,特别适合:

  • 多步骤状态机;
  • 条件跳转;
  • 循环;
  • Human-in-the-loop;
  • 多 Agent 协作。

从本章视角看,LangGraph 可以同时表达 Workflow 和 Agent。

关键不在于是否使用 LangGraph,而在于你是否清楚:

哪些边是程序固定的?
哪些节点允许模型动态决策?
哪些动作需要人类确认?

9.3 与 Claude Code、Codex、Pi Agent

Coding Agent 往往不能用固定 Workflow 完全表达。

因为每个代码任务的路径都不同:

  • 有的需要改一个文件;
  • 有的需要重构多个模块;
  • 有的需要先补测试;
  • 有的需要先理解框架;
  • 有的失败来自环境而不是代码。

所以 Claude Code、Codex、Pi Agent 更接近 Agent,而不是普通 Workflow。

但它们内部仍然会使用大量 Workflow 思想,例如:

  • 编辑前先读文件;
  • 修改后运行验证;
  • 失败后读取错误;
  • 输出前总结 diff。

这再次说明:

真正强大的 Agent 系统,往往是 Workflow 与 Agent 的结合。

10. 常见误区

10.1 误区一:Agent 是 Workflow 的高级版本

不是。

Agent 和 Workflow 解决的问题不同。

Workflow 追求稳定、可控、可测试。

Agent 追求灵活、动态、可探索。

不能简单说谁更高级。

10.2 误区二:只要用了工具就是 Agent

不是。

一个固定流程也可以调用工具。

例如:

查询订单
  ↓
生成回复

这只是 Workflow,不一定是 Agent。

Agent 的关键是:

模型是否根据环境反馈动态决定下一步。

10.3 误区三:Workflow 没有智能

不是。

Workflow 中每个节点都可以使用 LLM。

很多生产级 AI 系统,本质上是高质量 Workflow,而不是 Agent。

这类系统往往更可靠,也更适合企业上线。

10.4 误区四:Agent 可以完全不受流程约束

不是。

生产环境中的 Agent 必须有:

  • 任务边界;
  • 工具权限;
  • 最大步数;
  • 超时时间;
  • 成本预算;
  • 人工确认点;
  • 审计日志;
  • 失败升级机制。

没有边界的 Agent 不是先进,而是不可控。

11. 贯穿案例:CI 失败分析 Agent

在 CI 失败分析场景中,并不是所有步骤都需要 Agent。

可以拆成一个混合架构:

CI 失败事件
  ↓
Workflow 接收事件并创建任务
  ↓
Workflow 判断是否是简单失败
  ↓
简单失败直接生成报告
  ↓
复杂失败调用 Agent 动态分析
  ↓
Workflow 负责发送报告或创建 Issue

其中,Workflow 适合处理稳定流程,例如接收 CI webhook、创建任务、检查权限、发送通知。Agent 适合处理开放部分,例如根据失败日志动态决定下一步要读哪个文件、搜索哪个符号、比较哪段 Git Diff。

对于 build #4312,失败摘要显示:

Failed Test: OrderServiceTest.shouldApprovePendingReviewOrder
Exception: transition PENDING_REVIEW -> APPROVED is not allowed

这时 Agent 可以判断它不是基础设施失败,而是业务测试失败,于是继续读取 OrderStateMachineOrderStatus 和 PR #882 的 Git Diff。

这个案例体现了本章的核心判断:

企业系统中通常不是 Workflow 或 Agent 二选一,而是 Workflow 负责确定性边界,Agent 负责不确定性分析。

12. 本章小结

本章讨论了 Workflow 与 Agent 的边界。

核心结论有五点:

  1. Prompt、Workflow、Agent 是从简单到复杂的三种抽象,不应该一开始就选择最复杂的 Agent。
  2. Workflow 的控制权主要在程序手中,适合流程稳定、步骤明确的任务。
  3. Agent 的控制权部分交给模型,适合目标明确但路径不确定的开放式任务。
  4. 企业系统中,最合理的方式通常是 Workflow 与 Agent 混合使用。
  5. 判断是否需要 Agent 的关键,是看任务是否需要根据中间结果动态决定下一步。

一句话总结本章:

Workflow 解决“已知路径上的智能节点”,Agent 解决“未知路径中的动态决策”。

13. 实践任务

任务 1:分类你的 AI 场景

请列出你所在团队或公司最可能落地的 10 个 AI 场景,并填写下面表格:

场景 一次调用能否完成 流程是否固定 是否需要工具 是否需要动态决策 推荐方案
周报生成 Prompt
客服分流 可能 Workflow
CI 失败分析 Agent

任务 2:设计 TaskClassifier

为企业 Agent 平台设计一个 TaskClassifier,至少支持三类输出:

PROMPT
WORKFLOW
AGENT

并定义判断规则。

例如:

如果任务涉及写代码、运行命令、跨系统查询、未知错误排查,则倾向 Agent。
如果任务可以拆成固定步骤,则倾向 Workflow。
如果任务是单次生成、总结、改写,则倾向 Prompt。

任务 3:为“CI 失败分析”设计混合架构

请设计一个流程:

CI 失败事件
  ↓
Workflow 接收事件
  ↓
判断失败类型
  ↓
简单失败直接生成报告
  ↓
复杂失败调用 Agent 分析
  ↓
输出报告或创建 Issue

要求包含:

  • 哪些部分是 Workflow;
  • 哪些部分是 Agent;
  • Agent 可以调用哪些工具;
  • 什么时候需要人工介入;
  • 如何记录审计日志。

建议把设计结果保存到:

examples/java-agent-runtime/docs/ci-failure-analysis.md

results matching ""

    No results matching ""