Workflow vs Agent:别再搞混了,这是两个完全不同的东西
Workflow vs Agent:别再搞混了,这是两个完全不同的东西
如果你分不清 Workflow 和 Agent,你设计的 AI 系统会既不可控,又不可预测。
更糟的是,你甚至可能不知道自己用错了。
一、先说清楚:什么是 Workflow?什么是 Agent?
1.1 一句话定义
Workflow(工作流):你定义每一步做什么,LLM 只负责执行。
Agent(智能体):LLM 决定下一步做什么,你只定义它能用的工具。
看出来区别了吗?
- Workflow:你在驾驶
- Agent:LLM 在驾驶,你只给了它方向盘和地图
1.2 代码层面的直观对比
Workflow 示例(用 LangGraph 实现):
from langgraph.graph import StateGraph, END
# Workflow:你定义每一步
def step1(state):
"""步骤 1:提取关键词"""
keywords = llm.invoke(f"提取关键词:{state['query']}")
state["keywords"] = keywords
return state
def step2(state):
"""步骤 2:检索文档"""
docs = vector_db.search(state["keywords"])
state["docs"] = docs
return state
def step3(state):
"""步骤 3:生成回答"""
answer = llm.invoke(f"基于{docs},回答问题:{state['query']}")
state["answer"] = answer
return state
# 构建 Workflow(你定义流程)
graph = StateGraph()
graph.add_node("extract_keywords", step1)
graph.add_node("retrieve_docs", step2)
graph.add_node("generate_answer", step3)
graph.add_edge("extract_keywords", "retrieve_docs")
graph.add_edge("retrieve_docs", "generate_answer")
graph.add_edge("generate_answer", END)
workflow = graph.compile()
关键点:流程是固定的。step1 → step2 → step3,永远不会变。
Agent 示例(用 LangGraph 实现):
from langgraph.graph import StateGraph, END
from langchain.tools import Tool
# Agent:LLM 决定下一步调用哪个工具
def should_retrieve(state):
"""LLM 判断:需要检索吗?"""
decision = llm.invoke(f"需要检索知识库吗?问题:{state['query']}")
return decision # "yes" or "no"
def retrieve_tool(state):
"""检索工具"""
docs = vector_db.search(state["query"])
state["docs"] = docs
return state
def answer_tool(state):
"""回答工具"""
answer = llm.invoke(f"基于{state.get('docs', '')},回答:{state['query']}")
state["answer"] = answer
return state
# 构建 Agent(LLM 决定流程)
tools = [
Tool(name="Retrieve", func=retrieve_tool, description="检索知识库"),
Tool(name="Answer", func=answer_tool, description="生成回答"),
]
# Agent 循环:LLM 每次决定调用哪个工具
def agent_loop(state):
"""LLM 选择下一个动作"""
action = llm.invoke(
f"问题:{state['query']}\n可选工具:{tools}\n选择下一个工具:"
)
return action # 返回 "Retrieve" 或 "Answer"
graph = StateGraph()
graph.add_node("agent", agent_loop)
graph.add_node("retrieve", retrieve_tool)
graph.add_node("answer", answer_tool)
# 关键区别:边是动态的,由 LLM 决定
graph.add_conditional_edges(
"agent",
lambda state: should_retrieve(state),
{"yes": "retrieve", "no": "answer"}
)
graph.add_edge("retrieve", "agent") # 检索完,回到 agent 决策
graph.add_edge("answer", END)
agent = graph.compile()
关键点:流程是动态的。LLM 每次决定"下一步调哪个工具"。
二、核心区别:5 个维度深度对比
| 维度 | Workflow | Agent |
|---|---|---|
| 控制权 | 你(开发者)完全控制流程 | LLM 控制流程,你只定义工具 |
| 可预测性 | 高(流程固定,每次执行路径相同) | 低(LLM 决策,每次可能不同) |
| 适用场景 | 流程明确、步骤固定、可枚举 | 流程不确定、需要动态决策、开放性问题 |
| 成本 | 低(LLM 调用次数固定) | 高(可能多轮调用,甚至死循环) |
| 调试难度 | 低(流程固定,容易复现) | 高(LLM 决策不确定,难以复现) |
2.1 控制权:谁在驾驶?
Workflow:你在驾驶。
- 你定义:
step1 → step2 → step3 - LLM 只是执行者,不决定流程
- 适合:你知道"正确流程"是什么
Agent:LLM 在驾驶。
- LLM 决定:下一步调哪个工具?需要几次检索?什么时候输出答案?
- 你只定义:LLM 能用的工具列表
- 适合:你不知道"正确流程"是什么(或者不固定)
一个具体例子
任务:回答用户的技术问题。
Workflow 方案:
用户输入 → 提取关键词 → 检索文档 → 生成回答 → 输出
流程是固定的,永远不会变。
Agent 方案:
用户输入 → LLM 决策:
- 如果简单问题 → 直接回答
- 如果需要查文档 → 调用检索工具 → 再决策:需要查更多信息吗?
- 如果需要计算 → 调用计算器工具 → 再决策:结果合理吗?
- ...(LLM 动态决定)
流程是动态的,每次可能不同。
2.2 可预测性:每次执行路径相同吗?
Workflow:是。
- 输入相同 → 执行路径相同 → 输出相同(如果 LLM 确定性输出)
- 优点:容易测试、容易调试、容易保证质量
- 缺点:不够灵活,无法处理意外情况
Agent:不一定。
- 输入相同 → 执行路径可能不同(LLM 决策有随机性)
- 优点:灵活,能处理复杂、开放性任务
- 缺点:难以测试、难以调试、可能失控
一个真实案例
场景:客服机器人处理退货请求。
Workflow 方案:
接收请求 → 检查订单状态 → 如果已发货 → 拒绝退货 → 如果未发货 → 同意退货
问题:如果用户说"我收到的商品有质量问题,但订单显示已发货",Workflow 会直接拒绝,因为它只检查"订单状态",不理解"质量问题"这个例外。
Agent 方案:
接收请求 → LLM 分析:
- 如果订单未发货 → 同意退货
- 如果订单已发货 → LLM 进一步检查:"用户理由是什么?"
- 如果是"质量问题" → 转人工处理
- 如果是"不想要了" → 拒绝退货
区别:Agent 能处理例外情况,Workflow 只能处理预设情况。
2.3 适用场景:什么时候用哪个?
Workflow 适合:
- 流程明确:你知道每一步应该做什么
- 步骤固定:流程不会根据输入变化
- 可枚举:所有可能的路径都能提前定义
- 要求可预测:每次输出必须一致(比如金融、医疗)
例子:
- 文档摘要(固定流程:分割 → 摘要 → 合并)
- 数据 ETL(固定流程:抽取 → 转换 → 加载)
- 报表生成(固定流程:查询数据 → 格式化 → 生成图表)
Agent 适合:
- 流程不明确:你不知道"正确流程"是什么
- 需要动态决策:根据输入,每一步的决策可能不同
- 开放性问题:无法枚举所有可能的路径
- 容错率高:偶尔出错可以接受(比如聊天机器人)
例子:
- 智能客服(需要根据用户问题动态决定:查订单?查物流?转人工?)
- 代码助手(需要根据需求动态决定:写代码?改代码?解释代码?)
- 研究助手(需要动态决定:搜哪些论文?读哪些章节?怎么总结?)
2.4 成本:LLM 调用次数可控吗?
Workflow:可控。
- 你定义了 3 步 → 每次执行恰好 3 次 LLM 调用
- 成本可预测,容易做预算
Agent:不可控。
- LLM 可能调用 1 次就给出答案,也可能调用 10 次还在循环
- 成本不可预测,可能失控
代码示例:成本控制
Workflow(成本固定):
# Workflow:固定 3 次 LLM 调用
def workflow(query):
step1 = llm.invoke(f"提取关键词:{query}") # 第 1 次调用
step2 = llm.invoke(f"检索文档:{step1}") # 第 2 次调用
step3 = llm.invoke(f"生成回答:{query},{step2}") # 第 3 次调用
return step3
# 每次调用 workflow(query),恰好 3 次 LLM 调用
# 成本 = 3 × (input_tokens + output_tokens) × 单价
Agent(成本不可控):
# Agent:LLM 决定调用次数
def agent(query, max_steps=10):
state = {"query": query, "history": []}
for i in range(max_steps):
# LLM 决策:下一步做什么?
action = llm.invoke(f"选择动作:{state}") # 每次循环都调用 LLM
if action == "answer":
return llm.invoke(f"生成回答:{state}") # 再调用 1 次
elif action == "retrieve":
state["docs"] = retrieve(state["query"])
elif action == "calculate":
state["result"] = calculate(state["query"])
# ... 可能还有很多其他动作
# 问题:如果 LLM 一直不选择 "answer",会循环到 max_steps
return "超时,未得到答案"
# 每次调用 agent(query),LLM 调用次数可能是 1-10 次
# 成本不可预测
关键区别:
- Workflow 的成本是 O(1)(常数次 LLM 调用)
- Agent 的成本是 O(n)(n 由 LLM 决策决定,可能很大)
2.5 调试难度:出错了怎么排查?
Workflow:容易。
- 流程固定 → 出错时,你能精确定位是哪一步的问题
- 可以单独测试每一步
- 可以复现错误(输入相同 → 错误必现)
Agent:困难。
- 流程动态 → 出错时,你可能不知道 LLM 为什么做了某个决策
- 难以单独测试(因为 LLM 决策有随机性)
- 难以复现错误(输入相同,LLM 决策可能不同)
代码示例:调试
Workflow 调试:
# Workflow:可以单独测试每一步
def test_workflow():
# 测试 step1
state = {"query": "什么是 Agent?"}
state = step1(state)
assert "Agent" in state["keywords"] # 如果失败,精确定位到 step1
# 测试 step2
state = step2(state)
assert len(state["docs"]) > 0 # 如果失败,精确定位到 step2
# 测试 step3
state = step3(state)
assert "Agent" in state["answer"] # 如果失败,精确定位到 step3
Agent 调试:
# Agent:难以单独测试,因为 LLM 决策有随机性
def test_agent():
# 第一次运行
result1 = agent("什么是 Agent?")
# 第二次运行(相同输入)
result2 = agent("什么是 Agent?")
# 问题:result1 和 result2 的执行路径可能不同!
# LLM 第一次可能调用 3 次工具,第二次可能调用 5 次
# 如果 result1 正确,result2 错误,你怎么调试?
调试 Agent 的方法(比 Workflow 复杂):
- 记录 LLM 的每次决策(用 LangSmith 或自定义日志)
- 设置最大步数(防止死循环)
- 用更确定的模型(降低 temperature)
- 人工审查边界案例
三、代码示例:同一个任务,两种实现
为了让你更直观地理解,我用同一个任务,分别用 Workflow 和 Agent 实现。
任务:智能客服处理用户问题。
要求:
- 如果用户问"订单状态",调用订单查询工具
- 如果用户问"退货政策",检索知识库
- 如果问题复杂,转人工
3.1 Workflow 实现
from langgraph.graph import StateGraph, END
# Workflow:你定义所有路径
def route_query(state):
"""路由:根据关键词,决定下一步"""
query = state["query"]
if "订单" in query or "物流" in query:
return "check_order"
elif "退货" in query or "退款" in query:
return "check_policy"
else:
return "transfer_human"
def check_order(state):
"""查询订单"""
order_id = extract_order_id(state["query"])
order_status = order_api.get_status(order_id)
state["response"] = f"订单状态:{order_status}"
return state
def check_policy(state):
"""检索退货政策"""
docs = vector_db.search("退货政策")
state["response"] = summarize(docs)
return state
def transfer_human(state):
"""转人工"""
state["response"] = "正在为您转接人工客服..."
return state
# 构建 Workflow
graph = StateGraph()
graph.add_node("route", route_query)
graph.add_node("check_order", check_order)
graph.add_node("check_policy", check_policy)
graph.add_node("transfer_human", transfer_human)
# 你定义所有路径
graph.add_conditional_edges(
"route",
lambda s: route_query(s), # 返回 "check_order" / "check_policy" / "transfer_human"
)
graph.add_edge("check_order", END)
graph.add_edge("check_policy", END)
graph.add_edge("transfer_human", END)
workflow = graph.compile()
# 测试
print(workflow.invoke({"query": "我的订单什么时候到?"}))
# → 走到 check_order
print(workflow.invoke({"query": "怎么退货?"}))
# → 走到 check_policy
print(workflow.invoke({"query": "你们公司怎么样?"}))
# → 走到 transfer_human
关键点:
- ✅ 流程完全可控
- ✅ 每次执行路径完全相同
- ❌ 不够灵活:如果用户输入"订单号 12345 到哪了?",Workflow 可能识别不出"订单"关键词
3.2 Agent 实现
from langgraph.graph import StateGraph, END
from langchain.tools import Tool
# Agent:LLM 决定调用哪个工具
def order_tool(state):
"""订单查询工具"""
order_id = state.get("order_id")
if not order_id:
# LLM 先从用户消息中提取 order_id
order_id = llm.invoke(f"提取订单号:{state['query']}")
state["order_id"] = order_id
order_status = order_api.get_status(order_id)
state["response"] = f"订单状态:{order_status}"
return state
def policy_tool(state):
"""退货政策工具"""
docs = vector_db.search("退货政策")
state["response"] = summarize(docs)
return state
def human_tool(state):
"""转人工工具"""
state["response"] = "正在为您转接人工客服..."
return state
# LLM 决策:下一步调用哪个工具?
def agent_decide(state):
"""LLM 选择工具"""
tools = [
"OrderTool(查询订单)",
"PolicyTool(查询退货政策)",
"HumanTool(转人工)"
]
decision = llm.invoke(f"""
用户问题:{state['query']}
可选工具:{tools}
选择最合适的工具:
""")
return decision # 返回 "OrderTool" / "PolicyTool" / "HumanTool"
# 构建 Agent
graph = StateGraph()
graph.add_node("agent", agent_decide)
graph.add_node("order_tool", order_tool)
graph.add_node("policy_tool", policy_tool)
graph.add_node("human_tool", human_tool)
# 动态边:LLM 决定下一步
graph.add_conditional_edges(
"agent",
lambda s: agent_decide(s),
{
"OrderTool": "order_tool",
"PolicyTool": "policy_tool",
"HumanTool": "human_tool",
}
)
graph.add_edge("order_tool", END)
graph.add_edge("policy_tool", END)
graph.add_edge("human_tool", END)
agent = graph.compile()
# 测试
print(agent.invoke({"query": "我的订单什么时候到?"}))
# → LLM 决策:调用 OrderTool
print(agent.invoke({"query": "怎么退货?"}))
# → LLM 决策:调用 PolicyTool
print(agent.invoke({"query": "你们公司怎么样?"}))
# → LLM 决策:调用 HumanTool
关键点:
- ✅ 灵活:LLM 能理解"订单号 12345 到哪了?"中的"订单"意图
- ❌ 不可控:LLM 可能决策错误(比如把"退货"问题路由到 OrderTool)
- ❌ 成本不可控:每次都至少 2 次 LLM 调用(1 次决策 + 1 次工具执行)
四、决策框架:什么时候用哪个?
为了帮你做决策,我总结了一个决策树:
你的任务流程是否固定?
│
├─ 是 → 用 Workflow
│ │
│ └─ 是否要求可预测性?(每次输出必须一致)
│ │
│ ├─ 是 → 必须用 Workflow
│ └─ 否 → 仍推荐 Workflow(成本低、易调试)
│
└─ 否 → 考虑用 Agent
│
├─ 是否容错率高?(偶尔出错可以接受)
│ │
│ ├─ 是 → 可以用 Agent
│ └─ 否 → 用 Workflow + 人工审核(混合架构)
│
└─ 成本是否敏感?
│
├─ 是 → 谨慎用 Agent(设置 max_steps 限制)
└─ 否 → 可以用 Agent
4.1 用 Workflow 的场景(80% 的情况)
场景 1:文档处理
- 任务:把 100 个 PDF 转换成结构化数据
- 流程:读取 PDF → 提取文本 → 结构化 → 写入数据库
- 为什么用 Workflow:流程固定,不需要 LLM 决策
场景 2:日报生成
- 任务:每天早上生成昨日数据报告
- 流程:查询数据库 → 计算指标 → 生成图表 → 发送邮件
- 为什么用 Workflow:流程固定,成本低
场景 3:数据 ETL
- 任务:从多个数据源抽取数据,转换后加载到数据仓库
- 流程:抽取 → 清洗 → 转换 → 加载
- 为什么用 Workflow:流程固定,要求可预测性(数据不能错)
4.2 用 Agent 的场景(20% 的情况)
场景 1:智能客服
- 任务:回答用户的各种问题(订单、物流、退货、产品咨询…)
- 为什么用 Agent:问题类型不确定,需要根据用户问题动态决策
场景 2:代码助手
- 任务:根据用户需求,写代码、改代码、解释代码、调试代码
- 为什么用 Agent:用户需求不确定,需要动态决定下一步
场景 3:研究助手
- 任务:根据用户研究主题,搜索论文、阅读、总结、回答
- 为什么用 Agent:研究路径不确定,需要动态决定搜索哪些论文、读哪些章节
4.3 混合架构:Workflow + Agent(推荐)
核心思路:用 Workflow 定义主干流程,在需要动态决策的地方,插入 Agent。
示例:智能客服系统
# 混合架构:Workflow 主干 + Agent 节点
graph = StateGraph()
# Workflow 部分(固定流程)
graph.add_node("receive_query", receive_query) # 接收用户问题
graph.add_node("classify_intent", classify_intent) # 分类意图(简单/复杂)
# Agent 部分(动态决策)
graph.add_node("simple_agent", simple_agent) # 处理简单问题(Agent)
graph.add_node("complex_agent", complex_agent) # 处理复杂问题(Agent)
# Workflow 部分(固定流程)
graph.add_node("log_interaction", log_interaction) # 记录对话
graph.add_node("send_response", send_response) # 发送回复
# 主干流程(Workflow)
graph.add_edge("receive_query", "classify_intent")
# 分支:简单问题 → simple_agent,复杂问题 → complex_agent
graph.add_conditional_edges(
"classify_intent",
lambda s: "simple" if is_simple(s) else "complex"
)
graph.add_edge("simple_agent", "log_interaction")
graph.add_edge("complex_agent", "log_interaction")
graph.add_edge("log_interaction", "send_response")
graph.add_edge("send_response", END)
优点:
- ✅ 主干流程可控(Workflow)
- ✅ 需要灵活的地方灵活(Agent)
- ✅ 成本可控(Agent 只在需要时调用)
五、真实案例:用错了会导致什么问题?
案例 1:用 Agent 做 ETL(错误)
背景:某团队用 Agent 做数据 ETL(抽取 → 转换 → 加载)。
问题:
- 成本失控:ETL 任务每天运行 1000 次,每次 Agent 调用 5-10 次 LLM,成本是从 0.5 元/次飙升到 5 元/次
- 不可预测:有时候 ETL 成功,有时候失败(LLM 决策错误)
- 难以调试:数据错误时,无法复现(因为 LLM 决策有随机性)
正确做法:用 Workflow。ETL 流程是固定的,不需要 LLM 决策。
案例 2:用 Workflow 做智能客服(错误)
背景:某团队用 Workflow 做智能客服。
问题:
- 不够灵活:只能处理预设的问题类型,无法处理用户的新问题
- 用户体验差:用户问"订单号 12345 到哪了?“,Workflow 识别不出"订单"关键词(因为用户没说"订单状态”),直接转人工
正确做法:用 Agent。客服问题类型不确定,需要 LLM 理解用户意图。
案例 3:混合架构(正确)
背景:某电商公司做智能客服系统。
架构:
- Workflow 主干:接收问题 → 分类意图 → 简单问题 → Agent1,复杂问题 → Agent2 → 记录 → 发送
- Agent1(简单问题):处理订单查询、物流查询(2-3 个工具)
- Agent2(复杂问题):处理退货、换货、投诉(5-10 个工具,可能需要多轮对话)
效果:
- ✅ 成本可控(简单问题用 Agent1,成本低;复杂问题用 Agent2,成本高但有价值)
- ✅ 灵活(Agent 能处理各种问题)
- ✅ 可维护(Workflow 主干固定,容易调试)
六、常见误区:你可能在用的错误认知
误区 1:“Agent 比 Workflow 更先进”
错误。Agent 和 Workflow 是不同的工具,适合不同的场景。
正确认知:
- 流程固定 → Workflow
- 流程不确定 → Agent
- 大部分情况 → Workflow(80%),因为只有 20% 的任务需要动态决策
误区 2:“用 Agent 才能体现 AI 的能力”
错误。Workflow 也能体现 AI 的能力(比如用 LLM 做摘要、提取、分类)。
正确认知:
- Workflow + LLM = 自动化固定流程
- Agent + LLM = 自动化动态决策
- 两者都有价值,取决于你的任务
误区 3:“Agent 一定能处理更复杂的问题”
错误。Agent 能处理更多样化的问题,但不一定能处理更复杂的问题。
例子:
- 复杂但固定:财务报告生成(需要多个步骤,但流程固定)→ Workflow 更合适
- 简单但多样:客服问答(步骤少,但问题类型多)→ Agent 更合适
误区 4:“用了 Agent,就不需要定义流程了”
错误。Agent 也需要你定义:
- 工具列表:Agent 能调用哪些工具?
- 工具描述:每个工具是做什么的?(LLM 根据描述选择工具)
- 终止条件:什么时候停止调用工具?(比如"用户满意"或"达到最大步数")
你没有"不需要定义流程",你只是把流程定义成了"工具 + LLM 决策规则"。
七、总结:怎么选?
| 你的任务 | 推荐方案 |
|---|---|
| 流程固定、步骤明确 | Workflow |
| 流程不确定、需要动态决策 | Agent |
| 要求可预测性(每次输出必须一致) | Workflow(必须) |
| 容错率高(偶尔出错可以接受) | Agent(可以用) |
| 成本敏感 | Workflow(优先)或 Agent + max_steps |
| 需要灵活性 | Agent 或 混合架构 |
一句话总结:
如果你能提前画出流程图,用 Workflow。如果你画不出,用 Agent。
八、实践建议
8.1 从 Workflow 开始
大部分任务都能用 Workflow 解决。只有当你发现 Workflow 不够灵活时,才考虑引入 Agent。
8.2 用混合架构
在 Workflow 的某些节点,如果需要动态决策,插入一个 Agent 节点。
8.3 设置安全边界
如果用 Agent:
- 设置 max_steps(防止死循环)
- 记录 LLM 的每次决策(方便调试)
- 人工审核边界案例(比如"不确定"的情况)
九、结语
Workflow 和 Agent 不是"谁更先进"的问题,而是"谁更适合你的任务"的问题。
记住:
- Workflow:你驾驶,LLM 执行
- Agent:LLM 驾驶,你给地图和工具
选对了,你的系统既可控又灵活。选错了,你的系统既不可控又不可预测。
别再搞混了。
如果你觉得这篇文章有帮助,欢迎分享给你的团队。大部分 AI 项目的失败,都是因为用错了 Workflow 和 Agent。
更多推荐



所有评论(0)