主题
Agent 还是 Workflow:执行路径写得出来,就别上 Agent
本文是 AI 应用系统学习系列的 L2 核心篇。前置:35. Agent 系统:ReAct、工具与记忆。 学完可以配合面试题食用:05-agent-architecture-design、30-langgraph-mcp-weekly-recap、38-production-agent-architecture
一条判断标准就够了
下班回家不用开导航:路线固定。跨城自驾遇上封路,才需要导航按实时路况临场决策。这两种驾驶模式的区别,就是 Workflow 和 Agent 的区别。
落到 LLM 应用上,三种模式各占一格:
- 传统编程:程序员写死每一步,
if和else全在代码里,模型不参与决策 - Workflow:流程图固定,节点做什么、边怎么跳都提前定好,模型只在某些节点里被调用一次
- Agent:用户只给意图,每一步调什么工具、要不要走循环,由模型看着中间结果临场决定
选型只要问一个问题:执行路径能不能提前写出来。能→Workflow;不能→Agent;主流程写得出、个别环节写不出→Agentic Workflow。没有第四种答案。
Workflow 的三个核心抽象
以 LangGraph 为例,Workflow 的全部逻辑就三样东西:
- Node(节点):干活的函数。收一份 State,返回增量更新,里面可以调 LLM,也可以就是普通代码
- Edge(边):定跳转。固定边把两个节点直接接起来;条件边按 State 里的值决定去向;循环边让流程能回头
- State(状态):全图共享的数据结构,在节点间传递,每个节点只改自己负责的字段
拿产品提的需求翻译一下:"写稿后审核,审核不通过就重写,最多改 3 次"。这句话对应 ReviewNode 到 ReviseNode 的一条循环边,加上 State 里的 revisions 计数到 3 强制跳出。产品的每句话都能映射成图里的元素,这需求就是 Workflow:
mermaid
stateDiagram-v2
[*] --> 写稿
写稿 --> 审核
审核 --> 通过: 评分 >= 8
审核 --> 重写: 评分 < 8 且 已改次数 < 3
重写 --> 审核
审核 --> 人工兜底: 已改次数 >= 3
通过 --> [*]这张图有两个用处:拿去和产品对需求,以及给每个节点单独喂输入做单测,不用起完整 LLM 链路。
Agentic Workflow:主流程固定,局部放权
纯 Workflow 处理不了开放问题。比如"帮我调研某产品的竞品",要搜几轮、搜到什么程度算够,事先写不出来。硬套固定节点只会得到假自主:写死"搜索 3 次",第 2 次已经查清楚了也照样搜第 3 次。
Agentic Workflow 是折中方案:全局流程固定,只在路径不确定的局部嵌一个 ReAct 子循环。比如流水线是"取数 → 分析 → 写报告","分析"这一步内部让模型自主决定调哪些工具、调几轮,外层两步照旧是死代码。
最简单的混合是 Plan-and-Execute:先让模型生成一份步骤列表,计划一旦生成,路径就固定了,逐步执行,每步内部允许自主调工具。执行过程可枚举,出问题能定位到第几步。
吴恩达提过四个 agentic 设计模式:Reflection、Tool Use、Planning、Multi-agent。真实项目里它们不是四选一,而是嵌进 Workflow 的对应节点:审核节点里加 Reflection,规划节点用 Planning,其余节点就是普通函数。
代价账:Agent 贵在哪
拿同一需求算笔账:
- Workflow 版:3 个节点各调一次 LLM,最坏循环 3 轮,上限 7 次调用,每次 prompt 长度固定可预估
- Agent 版:每一步都要把历史轨迹、工具定义全量塞进上下文,10 步任务的 token 消耗通常是 Workflow 的 3 到 5 倍;一次跑歪,重试就是整条轨迹重来
调试难度差距更大。Workflow 挂了,日志直接告诉你是哪个节点;Agent 挂了,你要读一长串决策轨迹,判断是第 3 步选错了工具,还是第 5 步幻觉了一个参数。测试同理:Workflow 的节点能写单测,Agent 只能端到端评测,跑一轮评测就是真金白银。
所以 To B 场景默认选 Workflow:客户要产出一致、能过审计、SLA 可承诺,Agent 一样都给不了。
最常见的选型错误是反过来的:需求没拆清楚就喊"路径不确定",急着上 Agent。真拆成节点画出来,会发现所谓的不确定,大部分是"固定节点里调一次 LLM",剩下用条件边就能表达。
动手实操
同一个需求,两版代码对着看。先是 Workflow 版(LangGraph):
python
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
class State(TypedDict):
draft: str # 当前稿件
score: int # 审核评分
revisions: int # 已重写次数
def write_draft(s: State) -> dict:
return {"draft": call_llm("写一篇 500 字产品介绍")}
def review(s: State) -> dict:
# 只干评分这一件事,输出结构固定,可单测
return {"score": call_llm_score(s["draft"])}
def revise(s: State) -> dict:
draft = call_llm(f"按反馈重写:{s['draft']}")
return {"draft": draft, "revisions": s["revisions"] + 1}
def route(s: State) -> str: # 条件边:审核后的去向
if s["score"] >= 8:
return "pass"
if s["revisions"] >= 3: # 循环必须有出口
return "fail"
return "revise"
g = StateGraph(State)
g.add_node("write", write_draft)
g.add_node("review", review)
g.add_node("revise", revise)
g.add_edge(START, "write")
g.add_edge("write", "review")
g.add_conditional_edges("review", route,
{"pass": END, "fail": END, "revise": "revise"})
g.add_edge("revise", "review") # 循环边:改完再审
app = g.compile()
result = app.invoke({"draft": "", "score": 0, "revisions": 0})再看裸 while 的 Agent 版(伪代码,省略工具 schema 细节):
python
def agent_run(goal: str, max_steps: int = 10) -> str:
trace = [{"role": "user", "content": goal}]
for step in range(max_steps): # 上限兜底,防死循环
resp = call_llm(tools=DRAFT_TOOLS, messages=trace)
if resp.finish_reason == "stop": # 结束时机交给模型判断
return resp.text
trace.append(resp.message)
if resp.tool_name == "write":
trace.append(tool_result(save_draft(resp.args)))
elif resp.tool_name == "review":
trace.append(tool_result(score(resp.args["draft"])))
elif resp.tool_name == "rewrite":
trace.append(tool_result(save_draft(resp.args)))
# 每加一个工具,这里多一个分支,且全靠模型选对
raise RuntimeError("超过步数上限,模型没收敛")三个差别一眼可见。Agent 版把"何时结束"交给模型,必须加 max_steps 兜底;每加一个工具,分发分支要手动维护;出了问题只能读 trace 全文排查。Workflow 版每个节点的输入输出都确定,review 挂了就单测 review。
常见误区与小结
- 把"用了 LLM"当成"需要 Agent"。节点里调一次 LLM 做分类或打分,这是 Workflow,不是 Agent
- 用 Agent 是因为不想画流程图。省下的两小时设计,会在调试决策轨迹时加倍还回去
- 循环没有退出条件。重写循环必须有计数上限,否则模型一次抽风就是死循环烧钱
- 把确定性逻辑塞给模型。路由、参数校验、重试策略用代码写,模型只做真正需要理解语言的部分
- To B 项目用 Agent 图上线快。客户验收要可复现、可审计,路径不固定这些全过不了
小结:判断标准只有一条,执行路径写得出来就用 Workflow,写不出来才用 Agent,混合场景用 Agentic Workflow 在局部放权。下一篇 47. 向量数据库:HNSW 为什么快,Milvus/Qdrant/PGVector 怎么选,讲 RAG 检索层的索引原理与选型。
参考
- LangGraph 官方文档:https://langchain-ai.github.io/langgraph/concepts/
- Anthropic, Building Effective Agents(2024-12):https://www.anthropic.com/research/building-effective-agents
- DeepLearning.AI, Agentic Design Patterns(吴恩达课程)