Agent、Skill、Workflow到底啥区别?一文讲透AI应用三层架构
Agent、Skill、Workflow 到底有什么区别这个问题我最近几乎每周都要被问一次。不夸张地说连团队内部开会大家聊到后面都会发现彼此说的是不同的东西——有人把Agent当成一个会自己干活的机器人有人把Skill当作一段提示词模板还有人把Workflow和Agent画成同一个框。今天不绕弯子直接把我做AI应用这三年踩过的坑、拆过的代码、重构过的架构一次性说清楚。这篇不是概念百科是给真正要落地的人看的实操笔记。1. 这三个词被混着用是因为它们站在不同的抽象层1.1 混淆的根源都描述了同一个系统的不同切面先给一个总判断Agent、Skill、Workflow不是并列关系更像大脑、手、肌肉记忆的关系。它们在同一套AI应用里各管一段Agent负责思考——理解目标、拆解步骤、决定调用什么Skill负责执行——把某个具体能力读文件、发邮件、写代码、调API封装成可插拔的模块Workflow负责流程控制——把步骤固定成一条路径哪个节点失败怎么跳转全部预先画好。为什么混因为在实际代码里它们常常出现在同一个函数调用栈中。比如一个Agent内部调用了多个Skill而这些Skill可能被一个Workflow串起来。你可以在一个日志里看到三者交替出现自然就产生这不都一样吗的错觉。1.2 一句话版本的区别先看表格后续每节展开维度AgentSkillWorkflow本质自主决策的执行体可复用的能力单元预定义的流程编排核心问题接下来该做什么这件事怎么做按什么顺序做决策权自己决定动态路径内部实现细节开发时定死运行时照做灵活性高能处理未知情况中接口固定内部可换低路径固定可解释性弱过程依赖模型推理中等输入输出可追踪强流程图即文档典型产物LangChain Agent、OpenAI AssistantDify中的工具、Claude的Skill插件n8n、Dify工作流、Zapier失败处理可自行修正尝试抛出异常或返回错误信息按预设分支走或终止你发现没有Agent和Workflow解决的都是做什么的问题但一个动态一个静态Skill解决的是怎么做的问题跟前两者是互补关系。这个认知非常重要后面所有设计都以此为地基。2. Agent不是聊天机器人它是一个能自主决策的执行体2.1 Agent的完整生命周期目标、规划、调用、反思很多人把带个对话框的界面叫Agent那只是聊天机器人。真正的Agent至少要跑完这个循环接收目标用户说帮我分析上个月的销售数据并找出异常注意这不是写一段总结这么简单而是包含理解、拆解、执行、汇总的复合任务。规划Agent内部把目标拆成读取数据文件→清洗→统计→找异常→生成报告这几个步骤并且不只是线性排布可能还要判断文件格式、决定用哪个Skill。工具调用逐个调用对应的Skill这步容不得半点含糊参数要准确返回要能被后续步骤理解。结果评估与反思检查输出是否符合预期如果数据为空是直接报错还是换一种查询这是Agent和普通程序最大的不同——它能根据中间结果调整后续动作也就是常说的ReActReasoning Acting模式。我见过最精简的Agent核心循环大概长这样伪代码class Agent: def run(self, task): context {task: task, memory: []} while not task_finished(context): # 1. 思考 thought self.llm.think(context) # 2. 决定动作可能是调用skill也可能是结束 action parse(thought) # 例如 {type: call_skill, skill: read_excel, params: {...}} # 3. 执行 if action[type] call_skill: result skills[action[skill]].execute(**action[params]) context[memory].append(result) else: return answer这段代码虽然简陋但揭示了Agent的本质它没有预先写死路径每一步都靠大模型推理决定所以你可以在提示词里塞满各种奇奇怪怪的任务不一定跑得对但至少它敢试。2.2 为什么Agent记忆是刚需一旦让Agent跑多轮任务记忆就成了硬门槛。没有记忆的Agent像金鱼你说完第一步它转头就忘了前面查过什么。实现记忆有三种级别上下文记忆把历史对话全部拼进Prompt简单粗暴但token成本高且超过上下文长度就完蛋。向量记忆把关键信息存到向量数据库需要时按相似度检索适合回忆事实。工作记忆把Agent每次工具调用的结果、中间思考步骤记录成结构化日志供后续决策直接引用是我最推荐的方式。你在热词里看到agent记忆被频繁搜索说明大家都在这个环节卡过。我的建议是别一上来就上向量库先用一个简单的dict或JSON文件把中间结果存下来很多时候就够了。2.3 一个必须用Agent的典型场景读取本地文件并生成报表我把热搜词里dify 读硬盘workflow api当作引子这是一个典型的需求。比如老板让你读取本季度的所有销售报表汇总成可视化看板如果文件格式统一、路径固定、逻辑固定用Workflow就行。但现实是文件可能是PDF、Excel、CSV字段命名混乱季度的定义还不一样这时候Workflow会崩溃在第一个分支判断上必须用Agent。我在项目里的做法是让Agent先判断文件类型然后调用对应的解析SkillPDF解析、Excel解析再将多个Skill的结果汇总成标准化表格最后再让Agent检查一下有没有明显的异常值比如销售数量为负。整个过程中Agent不断根据文件内容调整后续动作这是Workflow做不到的。3. Skill不是技能那么简单它是插拔能力的最小单元3.1 Skill到底是什么接口描述 实现逻辑 描述文本很多人把Skill等价于一个函数这太窄了。真正能被Agent使用的Skill要包含三部分面向LLM的接口描述告诉Agent这个Skill是干什么的、需要什么参数、参数的类型和约束。比如一个send_email的Skill描述要写成Sends an email to a recipient. Params: to (string, email address), subject (string), body (string)。这段描述要写得足够清晰让模型能准确调用否则会出现传错参数、误解用途的问题。可执行的实现逻辑就是实际的代码可以是Python脚本、HTTP调用、Shell命令甚至是一段提示词。关键是输入输出的数据结构要稳定比如统一用JSON。错误处理与回退Agent调用Skill不总是一帆风顺。文件不存在、API超时、数据格式不符这些都要在Skill内部处理掉返回一个Agent能理解的错误信息比如{error: file_not_found, message: 2023_q1.xlsx doesnt exist in /data}而不是抛出一堆堆栈。3.2 怎样编写一个高质量Skill我以读取Excel并统计为例一步步说明首先写一个manifest.json有些平台叫SKILL.md{ name: excel_summary, description: Read an Excel file and return the row count, column list, and sum of a specified numeric column., parameters: { type: object, properties: { file_path: {type: string, description: Absolute path to the .xlsx file}, sum_column: {type: string, description: Column name to sum, optional} }, required: [file_path] } }然后写执行脚本import sys, json, openpyxl def excel_summary(file_path, sum_columnNone): try: wb openpyxl.load_workbook(file_path, data_onlyTrue) ws wb.active rows list(ws.iter_rows(values_onlyTrue)) headers rows[0] result { row_count: len(rows) - 1, columns: headers, } if sum_column and sum_column in headers: idx headers.index(sum_column) total sum(row[idx] for row in rows[1:] if isinstance(row[idx], (int, float))) result[sum] total return json.dumps(result) except FileNotFoundError: return json.dumps({error: file_not_found, message: str(sys.exc_info()[1])}) except Exception as e: return json.dumps({error: parse_error, message: str(e)}) if __name__ __main__: args json.loads(sys.argv[1]) print(excel_summary(**args))关键点在于description字段必须写清楚参数含义和返回格式因为Agent不是程序员它不会读你的代码只能靠描述来用它。你会发现其实Skill就是把业务能力封装成LLM能理解、能调用的标准接口。3.3 社区里的Skill资源为什么会有原版无删减这种说法热词里有一堆skill原版无删减版百度book to skill数学建模skill这其实暴露了社区Skill包的一个痛点版本混乱。你可能下载到一个重命名版里面的函数名被改得乱七八糟或者描述信息被精简掉了导致Agent调用时频繁出错。有些博主为了流量把Skill的README删得只剩使用截图核心配置全藏起来。我的建议是优先选择带SKILL.md、manifest.json、示例输入输出三件套的Skill包。下载后先手动跑一次单元测试确认它真的能返回预期结果再集成到Agent里。不要迷信原版因为原版不一定适合你的环境。真正重要的是接口规范不是作者的名气。4. Workflow是流程的钢管舞一切按剧本走4.1 Workflow的本质节点和边的有向图Workflow的核心思想是把一个业务流程拆成节点节点之间用边连接每个节点执行特定操作边决定执行顺序。这在视觉上是一张大网在代码里就是一个有向图。在LangChain、Dify、Coze这些平台里你可以拖拽节点有LLM节点、代码节点、HTTP请求节点、条件判断节点甚至还能在节点里内嵌一个Agent。但不管多花哨底层就是按预先定义的顺序执行遇到分支按条件跳转。没有任何自主决策能力它只是一台精密但死板的机器。4.2 条件分支、循环、并行如何编排复杂业务拿一个客服工单处理流程举例用Workflow可以这样描述接收工单 → 判断类型咨询、故障、投诉→ 分别进入不同处理通道故障通道判断紧急程度 → 高优先级直接通知维修人员普通通道生成自动回复所有通道结束后合并结果 → 更新工单状态。这个流程固定、规则清晰每个判断条件都是预先定义好的完全不需要Agent参与决策。好处是可解释性极强任何一个工单走到哪里打开流程图一眼就能看到。这在需要审计和合规的场景比如金融、医疗非常重要。你不可能让一个Agent在黑盒里决定这笔贷款批不批但你可以让Workflow把审批路径定得明明白白。4.3 Workflow和Agent的分界线谁来决定下一步做什么很多人纠结我应该用Workflow还是Agent我告诉你一个判断标准如果任务的每一步都是你事先能完整枚举的比如每天早上9点抓取某个网页→提取标题→写入数据库用Workflow。如果任务的中间步骤你无法预知比如帮我在网上搜有哪些便宜又靠谱的云服务商用Agent。最稳妥的架构是Workflow为主Agent为节点用Workflow处理确定性流程在需要灵活决策的节点插入Agent。举个例子工单分类可以用简单的规则但用户反馈很模糊需要理解语境这个节点就交给Agent。这样既保证了关键路径可控又让整个系统具备处理意外的能力。5. 实战组合用Agent做大脑Workflow做骨架Skill做双手5.1 一个完整的项目PDF发票信息提取与对账系统为了让你看到三者是怎么协作的我拿最近做的一个真实项目拆解。需求财务人员每天收到几十份PDF发票要提取发票号、金额、税额、开票日期然后和ERP系统里的订单对账有差异的要自动标红。如果用纯Workflow来做你需要为每一种PDF模板写一个解析节点但现实是供应商们的PDF五花八门有扫描件、有邮件截图、有加密文件根本无法预判。如果用纯Agent来做Agent自己写代码去解析PDF经常会卡在环境依赖和奇怪字符上。最后方案是这样的Workflow负责整体流程接收新文件 → 触发Agent节点 → 获取结构化结果 → 写数据库 → 比对ERP → 输出差异报告。整个流程固定每次执行都有日志可查。Agent作为处理文件的核心节点负责判断这个PDF是什么类型需要调用哪个Skill。Skill是三种文件解析器PDF文字层解析、OCR识别解析、表格转换解析。每个Skill只负责一种输入格式输出统一格式的JSON。看任务被拆成了三层Workflow操盘Agent出主意Skill干活。各自都在自己擅长的层工作。5.2 代码结构示例为了直观我简化一下# workflow.py —— 用Dify/LangChain或自己写循环这一步是骨架 def workflow_process(file_set): for file in file_set: result agent_node_execute(file) # 这个节点内部用Agent决策 is_match match_erp(result) if not is_match: mark_red(result) return report # agent_node.py —— Agent节点负责选Skill def agent_node_execute(file): prompt fGiven file {file[name]}, decide which skill to use: pdf_text, pdf_ocr, or excel_table. Return JSON. decision llm_call(prompt) skill_name decision[skill] result skills_registry[skill_name].execute(file[path]) return result # skill_pdf_ocr.py —— Skill实际干活 class PdfOcrSkill: def execute(self, path): images convert_pdf_to_images(path) text [ocr(img) for img in images] return parse_invoice_fields(text)我特意把代码写得堂而皇之因为你会发现真正的工作量全在Skill层Agent只负责选哪个Workflow只负责下一步走哪。各司其职省心。5.3 为什么这样比纯Agent或纯Workflow更稳你要是用纯Agent从零到一实现整个流程它会尝试自己调用各种工具但PDF解析这种脏活累活Agent很难自己搞定而且每次执行可能选不同的方法结果不可控。纯Workflow又没法处理不知道这个PDF是什么鬼的情况。混合架构下每个环节都可追踪、可测试、可替换。最直观的收益是当PDF格式变了我只需要改对应的Skill当流程加了需要人工审批的环节我只需要在Workflow里加一个节点当Agent选错技能我只需要回头调它的提示词或给它加更多样例。6. 选型决策指南四个问题决定你用哪个6.1 四个判断题我在做架构咨询时常用下面四个问题来帮团队做决定你可以照抄去用流程的每一步都是能提前枚举的吗是 → 优先Workflow否 → 需要考虑Agent。任务执行过程中是否会遇到需要推理的意外情况会比如用户意图不明、文件格式未知→ 引入Agent不会 → 纯Workflow或脚本。系统需要向审计人员解释为什么这么做吗需要金融、医疗→ 把Agent限制在局部节点核心链路用Workflow不需要 → 可以放手让Agent全程自主。你的维护团队能容忍黑盒吗不能 → 尽量少用Agent多用Workflow能 → 可以增加Agent的比例。这四个问题的答案组合对应下面这张表问题1问题2问题3问题4推荐架构是否是不能纯Workflow是是是能以Workflow为主Agent做节点否是否能纯Agent 大量Skill否否否不能手动流程别自动化了徒增成本6.2 从用哪个到怎么组合很多团队一上来就追新词非要用Agent好像不用Agent就落伍了。但我的经验是能用脚本解决的就用脚本能用Workflow解决的就别上帝视角硬塞Agent只有真正需要动态决策的环节才值得引入Agent。这个思路换个角度说就是Skill始终是必须的因为没有SkillAgent和Workflow都没有手Workflow和Agent之间则是一个可控性-灵活性的天平你往哪里偏取决于你对事后回溯的重视程度。7. 开发中踩过的坑如果你也这么用早晚要重构7.1 坑一把一切都塞进Agent提示词导致失控我有一次让Agent做爬取网页并总结结果它自己连续调用了20次工具把我API额度烧了。原因是我在提示词里写得太宽松既没说调用次数上限也没说失败几次要停止。后来做了三件事把风险按下去在Agent循环中加最大步数限制比如最多调用10次工具每个Skill的description明确写清楚只在什么情况下调用给Agent一个finish动作让它能主动结束。这些措施本质上是在用外部约束限制Agent的自由度。别指望大模型自己克制你得用代码给它套上笼头。7.2 坑二Skill和Workflow边界模糊导致复用性差见过有人把调用第三方API和生成邮件内容混在一个Skill里然后这个Skill只能在特定Workflow里用换个项目就废了。正确做法是遵循单一职责一个Skill只做一件事。写邮件的只负责生成邮件文本调API的只负责发请求。这样发短信、发Slack甚至别的项目要用生成邮件内容这个能力都能直接复用。边界怎么划我的标准是看这个能力是否有可能被两个以上的场景调用。会的话独立成Skill不会就写死在Workflow节点里。7.3 坑三过度编排流程硬化改需求要重新画图另一个极端是业务明明变化很频繁却把每一个细节都固化在Workflow里。结果产品经理提了个小改动把判断条件从A换成B你得花半天找哪些节点被影响了。这就得不偿失。我在实践中给自己定了条规则流程结构只固定那些轻易不变的部分比如合规步骤、数据落库环节业务逻辑中可能频繁调整的部分用AgentSkill替换改提示词或换Skill比改流程图快得多。7.4 Harness和Agent的区别控制层与决策层的纠葛热搜里有harness和agent区别这个值得单独说。Harness这个词在Claude Code出现后才流行你可以把它理解为Agent的外部加固壳它不负责思考但负责约束Agent的行为边界比如权限控制、工作目录限制、API调用配额、审批确认等。换句话说Agent是决策层Harness是策略控制层。举个例子你让Agent读硬盘里的文件Harness可以限制它只能读/data/invoice目录不能碰其他目录你让Agent调外部APIHarness可以加速率限制和URL白名单。所以Harness不是Agent的替代品而是Agent的安全带。我在做企业级Agent时一定会先设计Harness再设计Agent本身顺序不能反。7.5 安全与评估别让Agent裸奔最后提一下评估。我见过太多人把Agent跑通了就上线完全不考虑这次运行比上次好还是差。AI应用必须有一套Agent Evals机制至少要有几组固定的测试用例每次改动Skill或Workflow后都跑一遍对比输出结果。不用太复杂先把准确率、工具调用成功率、平均步数记录下来。哪怕只是一个JSON文件也能在重构时帮你兜底。就我个人体会把Agent、Skill、Workflow这三者的边界画清楚最大的好处是出了bug你能知道去哪里找。是流程走错了还是能力模块坏了还是决策逻辑偏了一查就知道不用再对着几千行日志发呆。如果你正在做类似的AI应用我建议先别急着写死代码花半天时间理清楚哪些是流程、哪些是技能、哪些需要决策这笔时间绝对值得。