AI Workflow 和 Agent 傻傻分不清?高速公路 vs 老司机,一个比喻讲透本质区别
AI 工作流和智能体傻傻分不清?用一条高速公路和一个司机,3 分钟讲透
先说一个让很多开发者都卡过的问题:假设你正在给团队做技术选型,Leader问你:“AI Workflow和Agent,到底怎么选?”

你可能下意识地回答:“可以,用LangChain搭个Workflow——先解析PDF,再提取技能,最后匹配岗位打分。” Leader点点头,又追问了一句:“那Agent呢?” 这一问,你可能就卡住了。因为你心里清楚它们不是一回事,但就是找不到一个让人秒懂的解释。
那篇文章,我们直接会用
一个比喻、一张对比表、两个真实案例
概念层:Workflow是高速公路,Agent是开车的司机
先记住这个比喻:
Workflow是一条高速公路,Agent是一个老司机。
高速公路的特点是路线固定、出口明确、限速标好,你只需要按部就班地开。而老司机呢?他知道要去哪,但随时可以因为路况、天气、心情而改道、绕路、甚至试一条新路线。
把这个逻辑套用到AI场景里,你会立刻明白它们的本质区别:
| 场景 | AI Workflow | AI Agent |
|---|---|---|
类比 | 一条高速公路——路线固定、出口明确、限速标好 | 一个老司机——知道要去哪,但随时改道、绕路、试新路线 |
路径 | 预先铺设好,不能偏离 | 出发后才动态规划,每到一个路口重新决策 |
遇到障碍 | 撞墙(修路了,流程卡死) | 绕路(感知环境变化 → 换条路走) |
效率 | 极高——不犹豫、不探索,到了就执行 | 较低——需要思考、试错、调整 |
可控性 | 100% 可预测——每次执行结果一致 | 不可预测——同一个任务两次可能走完全不同的路径 |
适用场景 | 审批流、数据清洗、客服机器人——流程固定 | 复杂搜索、策略规划、旅游安排——需要随机应变 |
一句话就能记住:
Workflow是“你告诉AI怎么做”,Agent是“你告诉AI要什么”。
很多人对这两个概念的认知是模糊的,比如觉得“Workflow是串行的,Agent是并行的”,或者“Agent比Workflow更高级”。其实都不是。Workflow的关键词是“确定性执行”,Agent的关键词是“不确定性探索”。它们的决策主体也不同:Workflow是
人
AI
话说回来,这两个概念是怎么来的?Workflow的概念比AI老得多,19世纪的工厂流水线就是它的雏形,到了90年代,软件开发领域就有了BPM(业务流程管理)引擎。LangChain只是把这一套搬到了AI场景里,让LLM成为流水线上的一个“加工节点”。而Agent的概念则来自
强化学习
多智能体系统
感知 → 推理 → 规划 → 执行
架构层:两种范式的完整结构拆解
Workflow 架构:流水线上的固定工序
看看一个典型的简历筛选Workflow是怎么跑的。它就像一条流水线,每个节点做的都是确定的事。
复制代码输入(简历 PDF)
│
▼
┌─────────────┐
│ 节点1:PDF解析 │ ← 固定工具(PyPDF2 / OCR)
│ 输出:纯文本 │
└──────┬──────┘
│ 条件:文本长度 > 0? → 是 → 继续
▼
┌─────────────┐
│ 节点2:信息提取 │ ← 调用 LLM(固定 prompt 模板)
│ 技能/经历/教育 │ "请从以下文本提取:技能描述、工作经历、教育背景"
│ 输出:结构化JSON │
└──────┬──────┘
│
▼
┌─────────────┐
│ 节点3:岗位匹配 │ ← 调用 LLM(对比 JD)
│ 技能 vs 岗位要求 │ 匹配度打分
│ 输出:匹配分数 │
└──────┬──────┘
│ 条件:匹配度 > 80%? → 是 → 推荐
▼
┌─────────────┐
│ 节点4:排序输出 │ ← 简单逻辑节点
│ 按分数降序排列 │
│ 输出:Top N简历 │
└─────────────┘
这个Workflow的核心特征非常明显:每个节点的输入和输出都是
确定的
Agent 架构:开放空间里的自主探索
再看看Agent。同样是处理一个任务,Agent的逻辑完全不同。它像是一个在开放空间里自主探索的个体。
复制代码用户:"帮我规划一趟北京到东京的旅行,预算 1 万"
┌────────────────────────────────────────────────┐
│ Agent 循环 (ReAct) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐│
│ │ 思考 │───▶│ 行动 │───▶│ ️ 观察 ││
│ │ (Reason) │ │ (Act) │ │(Observe) ││
│ └──────────┘ └──────────┘ └──────────┘│
│ ▲ │ │
│ └──────────── 循环 ────────────────┘ │
│ 直到达到目标或超时 │
└────────────────────────────────────────────────┘
第1步 思考:"需要先查机票价格和签证要求"
行动:调用「机票搜索工具」→ 北京→东京,往返
观察:机票 3500,签证免签,继续
第2步 思考:"机票比预期贵,但预算还有 6500。查下酒店"
行动:调用「酒店搜索工具」→ 东京 3晚
观察:经济型 1500,胶囊 600。选经济型
第3步 思考:"还剩 5000,可以排景点。但刚发现雨季预警️"
行动:调用「天气查询工具」→ 确认未来7天天气
观察:后3天暴雨️ 需要调整!
第4步 思考:"前 3 天室外景点,后 3 天转室内(博物馆/购物)"
行动:调用「景点推荐工具」→ 按天气分类推荐
观察:生成最终行程 提交给用户
这里的关键点在于,Agent在第3步发现下雨后,
动态调整
从分层对比来看,二者的区别更清晰:
| 层 | AI Workflow | AI Agent |
|---|---|---|
决策层 | 人预先设计(编排时决定路径) | AI 运行时动态决定(每步推理后选方向) |
执行层 | 节点依次执行,条件分支预设 | 工具调用不预设顺序,按需组合 |
感知层 | 不感知环境变化(只检查预设条件) | 持续感知:中间结果、环境变化、新信息 |
记忆层 | 通常无记忆(或只在节点间传数据) | 有短期记忆(对话上下文)+ 长期记忆(向量库) |
容错层 | 节点失败 → 流程中断或走预设的 fallback | 失败 → 反思 → 换工具/换路径 → 重试 |
如果你硬要把“规划旅游”做成一个Workflow,比如“机票查询 → 酒店查询 → 景点推荐 → 生成行程”,问题就来了。如果查机票时发现太贵,Workflow只会按预设条件判断(“价格 > 5000?→ 换航空公司”),它不会“想到”去改日期、换邻近机场,或者调整目的地。所有“意外情况”都需要人预先穷举在流程里——而复杂场景中,你根本不可能穷举所有意外。这就是Agent存在的根本原因:
世界太复杂,靠if-else覆盖不了全部可能性。
原理层:Agent 凭什么能“自己思考”?
ReAct 模式:Agent 的核心引擎
Agent能“自己思考”的核心,就是ReAct模式。ReAct =
Re
Act
ReAct: Synergizing Reasoning and Acting in Language Models(协同推理与行动)。
为什么这样设计?因为纯推理(Chain-of-Thought)会让LLM闭门造车,容易产生幻觉。纯行动(无脑调工具)又会让LLM迷失方向。交替进行,就像人类解决问题一样:想一步,做一步,看结果,再想下一步。
底层的实现其实不复杂,可以看作是一个循环:
复制代码┌──────────────────────────────────┐
│ Agent 循环伪代码 │
│ │
│ while (未达到目标) { │
│ 思考 = LLM.reason(当前状态) │ ← Reasoning
│ 行动 = LLM.choose_tool(思考) │ ← Acting
│ 结果 = tool.execute(行动) │
│ 观察 = LLM.observe(结果) │ ← Observation
│ 状态 = 更新(观察) │
│ if (状态 === 目标达成) break; │
│ } │
└──────────────────────────────────┘
在LangChain里,对应的代码可能长这样:
复制代码// Agent 的核心循环(简化版)
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { tool } from "@langchain/core/tools";
// 定义工具:Agent 的手和脚
const searchTool = tool(async ({ query }) => {
return await searchAPI(query); // 搜索机票、酒店等
});
const agent = createReactAgent({
llm: model,
tools: [searchTool], // Agent 可调用的工具列表
});
// 一次调用,Agent 内部会循环 ReAct 直到完成
const result = await agent.invoke({
messages: [{ role: "user", content: "帮我规划北京到东京的旅行" }]
});
// Agent 自己决定:先查什么、再查什么、遇到问题怎么调整
当然,ReAct不是唯一的选择。还有其他模式,比如Plan-and-Execute(先做完整计划,再逐步执行),ReWOO(一次性规划所有工具调用,减少LLM调用次数),以及Reflexion(每次失败后自我反思,改进下一次尝试)。它们各有适用场景。
面试时,可能会被问到:Agent循环会不会死循环?怎么控制?这确实是个好问题,核心在于设置合理的终止条件和最大迭代次数。
工具调用(Tool Use):Agent 和外界交互的“手”
Agent通过调用外部工具(搜索API、数据库、计算器、代码执行器)来获取LLM自己不能产生的信息。LLM的知识截止于训练日期,而工具让它能“感知当下”。没有工具的Agent,就像一个被关在没有窗户的房间里的聪明人,他再聪明,也不知道外面在下雨、机票多少钱。
工具的定义需要三个关键要素:name(名称)、description(描述)、schema(参数Schema)。
复制代码// 工具定义的完整示例
const weatherTool = tool(
async ({ city, date }) => {
// 真实调用天气 API
const weather = await fetch(`https://api.weather.com/${city}/${date}`);
return weather.json();
},
{
name: "get_weather", // 工具名:Agent 决定调用哪个
description: "查询指定城市的天气。参数:city(城市名), date(日期 YYYY-MM-DD)", // ️ description 要足够详细
schema: z.object({ // 参数 schema:告诉 LLM 怎么传参
city: z.string().describe("城市名称,如 'Tokyo'"),
date: z.string().describe("日期,格式 YYYY-MM-DD"),
}),
}
);
这里有几个要点:名称要语义清晰,描述要足够详细,Schema要用Zod等工具定义好,确保LLM能生成正确的JSON。如果描述太短,LLM会不知道参数怎么写;不写Schema,LLM就可能随机编参数名。
面试时可能会问:一个Agent能挂多少个工具?太多会怎样?没有硬性上限,但工具超过20个时,LLM在每一步都要从20个工具的描述里选最合适的,准确率会下降。解决方案包括:
工具分组
动态工具注入
工具检索
代码层:Workflow 和 Agent 的实战对比
用 Workflow 实现简历筛选
先看一个用Workflow实现简历筛选的实例。代码的核心是固定流程和确定性。
复制代码// workflow_resume.mjs
import { ChatOpenAI } from "@langchain/openai";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { PromptTemplate } from "@langchain/core/prompts";
const model = new ChatOpenAI({ model: "gpt-4o", temperature: 0 }); // ️ temperature=0 保证稳定输出
const parser = new StringOutputParser();
// Step 1:PDF 解析(模拟,实际用 PyPDF2 或 OCR)
const parsePDF = async (input) => {
// 模拟 PDF → 纯文本
return `姓名:张三\n技能:Python, LangChain, React\n工作经历:3年AI工程师\n教育:计算机硕士`;
};
// Step 2:提取结构化信息(用 LLM + 固定 prompt)
const extractInfoPrompt = PromptTemplate.fromTemplate(`
从以下简历文本中提取信息,返回JSON格式:
{resume_text}
返回格式:{{ "skills": [], "experience": "", "education": "" }}
`);
const extractChain = extractInfoPrompt.pipe(model).pipe(parser);
// Step 3:岗位匹配
const matchJDPrompt = PromptTemplate.fromTemplate(`
岗位要求:{jd}
候选人信息:{candidate_info}
请打分(0-100)并给出理由。只返回分数。
`);
const matchChain = matchJDPrompt.pipe(model).pipe(parser);
// Step 4:完整 Workflow — 像水管一样一节节接起来
async function resumeWorkflow(resumeFile, jobDescription) {
// 流程固定的四步,绝不跳步、绝不改顺序
const text = await parsePDF(resumeFile); // 节点1
const candidateInfo = await extractChain.invoke({ // 节点2
resume_text: text
});
const score = await matchChain.invoke({ // 节点3
jd: jobDescription,
candidate_info: candidateInfo
});
return { score: parseInt(score), info: candidateInfo }; // 节点4
}
// 运行
const result = await resumeWorkflow("zhangsan.pdf", "需要3年AI开发经验,熟悉LangChain");
console.log(`评分: ${result.score}/100`);
这个Workflow的特点很明显:temperature: 0保证稳定输出;.pipe()链式调用,数据像流过水管一样;prompt模板是固定的,每个节点做的事是确定的。
用 Agent 实现旅行规划
再看一个用Agent实现旅行规划的实例,感受一下不同。
复制代码// agent_travel.mjs
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const model = new ChatOpenAI({ model: "gpt-4o", temperature: 0.7 }); // temperature 高一点,允许探索
// 定义 Agent 的工具箱——注意这些工具的调用顺序是不预设的
const searchFlights = tool(
async ({ from, to, date }) => {
// 模拟机票搜索
return `找到 3 个航班:${from}→${to},${date},价格 2500-4000 元`;
},
{
name: "search_flights",
description: "搜索机票。参数:from(出发城市), to(目的城市), date(日期)",
schema: z.object({
from: z.string(), to: z.string(), date: z.string(),
}),
}
);
const searchHotels = tool(
async ({ city, budget }) => {
return `${city}酒店:经济型 500/晚,舒适型 1200/晚。预算${budget}元。`;
},
{
name: "search_hotels",
description: "搜索酒店。参数:city(城市), budget(预算金额 元)",
schema: z.object({ city: z.string(), budget: z.number() }),
}
);
const checkWeather = tool(
async ({ city, date }) => {
return `${city} ${date}:多云转暴雨,25°C,降雨概率 80%`; // ️ 坏天气触发 Agent 调整计划
},
{
name: "check_weather",
description: "查询天气。参数:city(城市), date(日期)",
schema: z.object({ city: z.string(), date: z.string() }),
}
);
// 创建 Agent:不预设路径,只给工具 + 目标
const travelAgent = createReactAgent({
llm: model,
tools: [searchFlights, searchHotels, checkWeather],
// ️ 没有 pipe!没有固定顺序!Agent 自己决定什么时候调哪个工具
});
// 运行:给一个开放目标,Agent 自己探索怎么完成
const result = await travelAgent.invoke({
messages: [{
role: "user",
content: `帮我规划 8月15-20日 从北京出发到东京的旅行。总预算 10000 元。
注意:如果目的地天气不好,及时调整行程安排。`
}]
});
console.log(result.messages[result.messages.length - 1].content);
// Agent 输出的结果每次可能不一样——
// 如果天气好 → 安排室外景点;如果暴雨 → 自动调整为室内行程
这里的关键区别在于:temperature: 0.7,让Agent有探索的余地;只给了工具和目标,没有预设调用顺序;checkWeather工具让Agent能感知环境变化,据此调整后续计划。
总结一下,Workflow的思维是“人把所有路都铺好”,Agent的思维是“AI自己找路”。
那么,什么时候该用哪个?判断标准很简单:
| 判断标准 | 用 Workflow | 用 Agent |
|---|---|---|
步骤是否可预知 | 是——所有步骤都已知 | 否——无法提前列出全部步骤 |
异常情况能否穷举 | 能——只有 3-5 种异常 | 不能——异常情况千变万化 |
稳定性要求 | 高——每次结果必须一致 | 中——结果可以不同,但不能偏离目标 |
人工干预点 | 明确——审批、审核节点 | 事件驱动——只在关键操作时介入 |
举例 | 简历筛选、发票审批、数据 ETL | 深度研究、策略博弈、客服对话 |
进阶层:从单打独斗到组合使用
真实项目中的最佳实践:Workflow 做骨架,Agent 做大脑
纯Workflow太死板,纯Agent太不可控。在真实项目中,
两者嵌套使用
复制代码┌─────────────────────────────────────────────────┐
│ Workflow 骨架 │
│ (稳定流程 + 人工审批节点 + 日志审计) │
│ │
│ ┌──────┐ ┌──────────┐ ┌──────┐ │
│ │ 输入 │───▶│ Agent 节点│───▶│ 审批 │──▶ 输出 │
│ │ 简历 │ │ (动态分析) │ │ 人工 │ │
│ └──────┘ └─────┬────┘ └──────┘ │
│ │ │
│ Agent 自己决定用什么工具 │
│ 怎么分析、怎么对比 │
│ 但最终打分结果要人类确认 │
└─────────────────────────────────────────────────┘
代码上,可以这样体现:
复制代码// Workflow 框架 + Agent 节点 = 既高效又有智慧
async function hybridResumeScreening(resumeFile) {
// Workflow 骨架:固定流程
const text = await parsePDF(resumeFile); // 节点1:固定
const structured = await extractInfo(text); // 节点2:固定
// Agent 节点:灵活分析(在骨架中注入智能)
const analysisAgent = createReactAgent({
llm: model,
tools: [jdMatcher, skillAnalyzer, salaryEstimator, marketComparator],
// Agent 自己决定:先用哪个工具、怎么组合分析
});
const analysis = await analysisAgent.invoke({
messages: [{ role: "user", content: `分析这个候选人:${JSON.stringify(structured)}` }]
});
// Workflow 骨架:最后一步固定——人工审批
await humanReview(analysis); // 节点4:固定
return analysis;
}
在实际应用中,有几个常见的坑需要留意:
坑1:把Agent当Workflow用。
坑2:Workflow节点报错后整个流程卡死。
try-catch,设计fallback分支,加错误队列和重试机制。
坑3:Agent调用工具的费用失控。
maxIterations=10,每次循环前检查token预算,用更便宜的小模型做中间步骤。
最后,关于工具选型,Coze/Dify这样的可视化编排平台,上手快,适合产品经理和运营快速验证想法;而LangChain这样的代码编排,灵活度更高,适合开发者构建生产级应用。
总结层:一图一表一句话
决策流程图:我该用 Workflow 还是 Agent?
复制代码收到一个 AI 自动化需求
│
▼
┌─────────────────────────────┐
│ 你能不能列出所有步骤? │
└──────────┬──────────────────┘
│
┌──────┴──────┐
│ │
能 不能
│ │
▼ ▼
┌──────────┐ ┌──────────────────┐
│ 能穷举所 │ │ 异常情况能穷举吗? │
│ 有异常? │ └────────┬─────────┘
└──┬───────┘ │
│ ┌──────┴──────┐
能 │ 不能 │ │
│ │ 能 不能
▼ ▼ │ │
┌──────────┐ ▼ ▼
│ Workflow │ ┌──────────┐ ┌──────────┐
│ 就够了 │ │ Workflow +│ │ Agent │
│ │ │ fallback │ │ 更适合 │
└──────────┘ │ 分支 │ └──────────┘
└──────────┘
本质对比速查表
| 维度 | AI Workflow | AI Agent |
|---|---|---|
一句话 | 你告诉 AI 怎么做 | 你告诉 AI 要什么 |
路径 | 预定义、不可偏离 | 动态探索、实时调整 |
比喻 | 高速公路——路线固定 | 老司机——随时改道 |
决策主体 | 人(编排时决定) | AI(运行时决定) |
LLM 角色 | 流水线上的加工节点 | 思考+决策的中枢大脑 |
温度设置 | low (0-0.3) | medium-high (0.5-0.9) |
可控性 | ⭐⭐⭐⭐⭐ | ⭐⭐ |
灵活性 | ⭐⭐ | ⭐⭐⭐⭐⭐ |
成本 | 可预测(固定 LLM 调用次数) | 不可预测(ReAct 循环次数不固定) |
技术栈 | LangChain, Coze, Dify, 规则引擎 | LangGraph, CrewAI, AutoGen |
适合任务 | 审批、清洗、打分、ETL | 搜索、研究、规划、对话 |
本质区别一句话:Workflow是确定性执行——人设计路径,AI按剧本演;Agent是不确定性探索——人定目标,AI自己找路。未来最好的AI工程 = Workflow骨架 + Agent大脑。
核心收获清单
- 能用“高速公路 vs 老司机”的比喻向非技术人员解释Workflow和Agent的区别
- 理解ReAct循环是Agent的核心引擎:思考 → 行动 → 观察 → 循环
- 掌握工具调用(Tool Use)的定义方式:name + description + schema 三个要素
- 知道何时用Workflow(步骤可预知)vs Agent(步骤不可预知)vs 两者组合(骨架 + 大脑)
- 避免三个常见坑:把Agent当Workflow用、Workflow无容错、Agent费用失控
互动结尾
从LangChain的pipe到ReAct Agent,从Coze可视化工作流到自主规划——
Workflow和Agent不是“谁更高级”的竞争关系,而是“什么场景用什么范式”的互补关系。
一个检查清单帮你在下次做选型时快速决策:
复制代码□ 任务步骤是否已知且固定? → Workflow
□ 异常情况能否穷举(< 10 种)? → Workflow + fallback 分支
□ 需要根据中间结果动态调整后续行动? → Agent
□ 需要调用多种工具且调用顺序不固定? → Agent
□ 生产环境、需要审计和人工审批? → Workflow 骨架 + Agent 节点
下一步,你可以:
- 去Coze搭一个简单的Workflow(比如“输入关键词 → 搜索 → LLM总结 → 输出”),感受流水线的确定性。
- 用LangGraph写一个Agent Demo——只给目标和工具,看它怎么自己找路。
- 试着把同一个任务用Workflow和Agent各实现一遍,对比它们的执行路径差异。
留个问题给你:
你现在的项目中,哪些环节适合用Workflow固化成流程?哪些环节值得用Agent来增加灵活性?
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名