1. 为什么“AI Agent”这个词正在被过度消费
打开任何一个技术社区,你都能看到“Agent”这个词被挂在各种产品介绍里。智能客服叫Agent,自动化脚本叫Agent,连一个定时发邮件的工具也敢自称Agent。这种泛化让真正在做Agent系统的人很头疼——你跟别人聊技术方案,对方脑子里想的可能只是一个if-else堆出来的工作流。
我最早接触Agent这个概念是在做自动化运维的时候。当时的需求很简单:让系统自己判断服务器负载异常,然后决定是扩容还是重启服务。听起来像个普通的自动化脚本对吧?但真正做起来才发现,难点根本不在“执行动作”,而在“判断该执行什么动作”。这个判断过程,才是Agent和普通程序的分水岭。
所以这篇内容我想做一件事:把AI Agent这个领域里被混用、滥用、误用的术语,一个一个拆开讲清楚。不是给学术定义,而是告诉你在实际做项目时,这些词到底指什么、什么时候该用哪个词、以及面试或者技术评审时别人问你“你这个算不算Agent”你该怎么回答。
适合读这篇的人:正在做LLM应用开发但被各种术语搞晕的工程师、需要评估Agent产品技术方案的产品经理、以及准备进入这个方向想先建立认知框架的开发者。我会尽量用实际项目中的例子来解释,不堆论文引用,不搞概念空转。
2. Agent、Workflow、Chain:三个最容易被混用的概念
2.1 从一次技术评审的争论说起
之前参加过一个内部技术评审,有个团队展示他们的“智能运维Agent”。演示流程是这样的:监控告警触发→调用LLM分析日志→LLM输出可能的原因→根据原因匹配预设的修复脚本→执行脚本。整个流程跑得很顺畅,演示效果也不错。
然后有人问了一个问题:“如果LLM分析出来的原因不在预设脚本列表里怎么办?”回答是:“那就输出人工介入。”又问:“那如果两个原因同时出现呢?”回答是:“目前只处理单原因场景。”
这就是典型的Workflow被包装成Agent的情况。整个系统的决策路径是预先定义好的,LLM只是其中一个环节用来做文本分类或者信息提取。它没有自主决定“下一步做什么”的能力,只是在预设的分支里走。
2.2 三者的本质区别
我用一个生活化的类比来解释:
- Chain:像流水线。原料从一头进去,经过固定的几道工序,成品从另一头出来。每道工序做什么是固定的,顺序也是固定的。LangChain早期的很多示例就是这种模式。
- Workflow:像公司的审批流程。你提交报销单,系统根据金额大小决定走哪个审批路径。路径是预设的,但可以根据输入条件走不同分支。上面那个运维例子就是这种。
- Agent:像一个有经验的维修师傅。你告诉他“三号车间机器异响”,他会先去看看,可能先检查传动带,也可能先听声音判断轴承,发现不对再换工具。他的行动顺序不是预设的,而是根据实时观察和判断动态决定的。
用技术语言来说,Agent的核心特征是自主决策循环:观察环境→思考下一步→执行动作→观察结果→继续思考。这个循环的终止条件也是动态的,不是预设的固定步数。
2.3 一个判断标准
我总结了一个简单的判断方法,在技术评审时很好用:
如果你能把系统的决策逻辑画成一张完整的流程图,每个分支条件都能提前写出来,那它就是Workflow,不是Agent。
反过来,如果系统的下一步动作取决于运行时才能获得的信息,而且这些信息无法在编码阶段穷举,那它才具备Agent的特征。
这个标准不是绝对的,因为实际系统往往是混合的。但用这个标准去审视,能帮你快速判断一个系统到底有没有“自主性”这个核心属性。
2.4 为什么这个区分很重要
有人可能觉得这是概念之争,没什么实际意义。但我在实际项目中体会到,这个区分直接影响架构设计和技术选型。
如果你做的是Workflow,那你可以用DAG编排工具,可以用状态机,测试用例可以穷举,系统行为完全可预测。但如果你做的是Agent,你就需要考虑:LLM调用失败怎么办?LLM输出了意料之外的动作怎么办?如何防止Agent陷入死循环?如何控制Token消耗?这些问题的解法完全不同。
把Workflow当Agent做,会导致过度设计,增加不必要的复杂度和成本。把Agent当Workflow做,会导致系统在实际运行中频繁卡死,因为真实世界的输入永远比预设分支多。
3. Tool Use、Function Calling、MCP:Agent的手和脚
3.1 Tool Use不是新概念
Agent要做事,就得有工具。这个概念其实在传统AI规划领域早就有了,只是那时候叫“Action”或者“Operator”。现在因为LLM的兴起,Tool Use变成了一个热门词。
简单说,Tool Use就是让LLM能够调用外部函数或API。比如你问Agent“今天天气怎么样”,它需要调用天气API;你让它“帮我订个会议室”,它需要调用日历系统的接口。
但这里有个关键问题:LLM本身只能输出文本,它怎么“调用”外部函数?
3.2 Function Calling的机制
Function Calling是OpenAI在2023年推出的一种机制,后来被其他模型厂商跟进。它的工作原理是这样的:
你在调用LLM的API时,除了传入用户消息,还可以传入一个工具列表。每个工具用JSON Schema描述,包括工具名称、功能说明、参数结构。LLM在生成回复时,如果判断需要调用某个工具,它不会直接输出自然语言,而是输出一个结构化的JSON,包含工具名和参数。
比如你定义了一个get_weather工具,参数是city。用户问“北京今天热不热”,LLM可能输出:
{ "tool": "get_weather", "parameters": { "city": "北京" } }你的程序收到这个JSON后,去实际调用天气API,拿到结果,再把结果作为新的消息传给LLM,让它生成最终回复。
这里的关键点是:LLM本身不执行任何函数,它只是输出了一个“调用意图”。实际的函数执行是你的程序做的。这个区分很重要,因为很多人以为Function Calling是LLM在“执行”代码,其实不是。
3.3 MCP想解决什么问题
MCP(Model Context Protocol)是Anthropic推出的一个协议,目标是标准化LLM和外部工具之间的交互方式。
在没有MCP之前,每个Agent框架都有自己的工具定义格式。LangChain有LangChain的格式,AutoGPT有AutoGPT的格式,OpenAI有OpenAI的格式。你为一个框架写的工具,换一个框架就得重写。
MCP的思路是定义一个通用的协议,工具提供方按照MCP标准实现一次,任何支持MCP的Agent框架都能直接使用。有点像USB接口标准化的意思——以前每个设备有自己的充电口,现在统一成Type-C。
不过MCP目前还在早期阶段,生态还在建设中。实际项目中,如果你只用一家厂商的模型和框架,直接用它的原生Function Calling机制就够了,不一定需要MCP。
3.4 工具设计的实操心得
我在实际项目中踩过不少工具设计相关的坑,分享几个关键的:
工具粒度要适中。太细的话,LLM需要调用很多次才能完成一个任务,Token消耗大且容易出错。太粗的话,LLM很难准确匹配用户意图。我的经验是,一个工具对应一个完整的业务动作,比如“查询订单状态”是一个工具,“修改订单地址”是另一个工具,而不是把“查询”和“修改”拆成数据库层面的CRUD操作。
工具描述要写清楚边界。LLM判断是否调用某个工具,完全依赖你给的描述。如果你写“查询用户信息”,LLM可能在任何涉及用户的问题上都调用它。如果你写“根据用户ID查询用户的注册邮箱和手机号,不包含订单信息”,LLM的判断会准确得多。
参数设计要简单。尽量避免嵌套的复杂结构,LLM在生成嵌套JSON时出错率明显更高。如果某个参数有固定选项,用枚举类型而不是自由文本。
4. Planning、Reasoning、Reflection:Agent的大脑怎么转
4.1 Planning不是排计划表
Planning在Agent语境下,指的是Agent为了实现一个目标,自己决定步骤序列的能力。注意关键词是“自己决定”。
传统的任务规划是人工写好的,比如“先查数据库,再调API,最后发邮件”。Agent的Planning是给它一个目标“帮我把上周的销售数据整理成报告发给团队”,它自己决定先做什么后做什么。
目前主流的Planning实现方式有几种:
一种是ReAct模式,交替进行推理和行动。Agent先想一步“我需要先获取销售数据”,然后调用数据查询工具,看到结果后再想“数据拿到了,我需要计算环比”,再调用计算工具,以此类推。这种方式灵活但Token消耗大,因为每一步都要调用LLM。
另一种是Plan-and-Execute模式,先让LLM生成一个完整的计划,然后按计划逐步执行。这种方式Token效率高,但灵活性差,如果执行过程中发现计划不可行,调整起来比较麻烦。
还有一种混合模式,先制定粗粒度计划,执行过程中根据实际情况动态调整。实际项目中这种用得比较多。
4.2 Reasoning的两种含义
Reasoning这个词在Agent语境下有两个不同的含义,经常被混淆。
第一个含义是推理能力,指的是LLM本身的逻辑推理水平。比如数学计算、因果推断、多步逻辑链。这是模型层面的能力,跟Agent架构无关。
第二个含义是推理过程,指的是Agent在决策时展示出来的思考步骤。比如Chain-of-Thought、Tree-of-Thought这些技术,都是让LLM在给出答案前先输出中间推理步骤。
在实际项目中,区分这两个含义很重要。如果是模型推理能力不足,你需要换更强的模型或者做微调。如果是推理过程不透明导致调试困难,你需要的是改进Prompt或者引入结构化输出。
4.3 Reflection:让Agent自己检查自己
Reflection是指Agent在执行动作后,对自己的输出进行批判性审视,发现错误并修正。
举个实际例子:我做过一个代码生成Agent,它写完一段代码后会自己review一遍,检查是否有语法错误、边界条件遗漏、变量未定义等问题。如果发现问题,它会重新生成。
Reflection的实现通常是在Prompt里加入一个“自我检查”的步骤,或者用一个单独的LLM调用来做review。前者的成本低但效果有限,后者效果更好但Token消耗翻倍。
我的经验是,Reflection在代码生成、数学计算、逻辑推理这类有明确对错标准的任务上效果明显。但在创意写作、开放式问答这类主观性强的任务上,Reflection容易让输出变得保守和模板化。
4.4 一个容易忽略的点:Planning的粒度
很多人在设计Agent时,把Planning的粒度设得太细,导致Agent每一步都要调用LLM,成本和延迟都不可接受。也有人设得太粗,Agent执行到一半发现方向错了,但已经消耗了大量资源。
我的做法是:把Planning分成两层。上层是战略规划,决定大方向,比如“先获取数据,再分析,再生成报告”。下层是战术执行,在每个大步骤内,Agent可以灵活决定具体怎么做。这样既保证了方向正确,又保留了灵活性。
5. Memory、Context、State:Agent的记忆系统
5.1 为什么Agent需要记忆
没有记忆的Agent,每次对话都是全新的开始。用户说“帮我查一下上个月的销售数据”,Agent查完返回结果。用户接着说“把它做成图表”,Agent就懵了——它不知道“它”指的是什么。
Memory要解决的就是这个问题:让Agent在多轮交互中保持对历史信息的感知。
5.2 短期记忆和长期记忆
短期记忆通常就是对话历史,直接放在Prompt的Context里。但Context长度有限,不能无限塞。所以需要一些策略:滑动窗口(只保留最近N轮)、摘要压缩(把早期对话总结成一段话)、关键信息提取(只保留实体和意图)。
长期记忆是跨会话的,需要持久化存储。常见方案是用向量数据库存历史交互的embedding,需要时检索相关片段。也可以用结构化存储,比如把用户偏好、历史订单等存成数据库记录。
实际项目中,短期记忆和长期记忆往往结合使用。短期记忆保证当前对话的连贯性,长期记忆提供个性化服务。
5.3 Context Window的管理策略
Context Window是LLM能处理的最大Token数。早期模型只有4K,现在主流模型都在128K以上。但即使Context Window很大,也不意味着你应该把所有东西都塞进去。
原因有两个:一是成本,Token越多费用越高;二是效果,研究表明Context太长时,LLM对中间部分信息的注意力会下降,这就是所谓的“Lost in the Middle”现象。
我的策略是:Context里只放当前任务必需的信息。历史对话做摘要,工具返回结果做截断,长期记忆按相关性检索。宁可多调用一次检索,也不要把无关信息塞进Context。
5.4 State和Memory的区别
State是Agent当前的状态,比如“正在等待用户确认”、“正在执行第三步”。Memory是Agent存储的信息,比如“用户上次说喜欢蓝色”。
State通常是结构化的,用状态机管理。Memory可以是结构化的也可以是非结构化的。State在任务完成后就重置了,Memory会持续保留。
在实际系统中,State和Memory经常一起用。比如一个订票Agent,State记录“当前正在选择座位”,Memory记录“用户偏好靠窗座位”。State决定Agent当前该做什么,Memory影响Agent做决策时的偏好。
6. Multi-Agent、Orchestration、Handoff:多个Agent怎么协作
6.1 什么时候需要多个Agent
单个Agent能处理的任务是有限的。当任务复杂度超过一定阈值,或者需要不同领域的专业知识时,就需要多个Agent协作。
比如一个软件开发助手,可能需要:需求分析Agent、代码生成Agent、代码审查Agent、测试生成Agent。每个Agent有自己的专长Prompt和工具集。
但多Agent不是没有代价的。Agent之间的通信需要额外的Token,协调逻辑增加了系统复杂度,调试难度也成倍上升。我的经验是:能用单Agent加多工具解决的,就不要上多Agent。只有当不同角色的Prompt差异很大,或者需要不同的工具权限时,才考虑拆分。
6.2 Orchestration的几种模式
Orchestration指的是如何协调多个Agent的工作。常见模式有:
中心化编排:有一个主Agent负责分解任务、分配给子Agent、汇总结果。这种模式控制力强,但主Agent容易成为瓶颈。
去中心化协作:Agent之间直接通信,没有中心节点。这种模式灵活,但容易出现死锁或无限循环。
层级编排:主Agent管理几个中层Agent,中层Agent管理底层Agent。适合任务层次分明的场景。
实际项目中,中心化编排用得最多,因为可控性最好。去中心化协作目前更多停留在研究阶段。
6.3 Handoff的机制和坑
Handoff是指一个Agent把任务转交给另一个Agent。比如客服Agent遇到技术问题,转交给技术支持Agent。
Handoff的关键是上下文传递。转交时,需要把当前对话历史、已收集的信息、当前状态都传给下一个Agent。如果传递不完整,下一个Agent就得重新问一遍用户,体验很差。
我踩过的一个坑是:Handoff时把整个对话历史都传过去了,导致下一个Agent的Context被无关信息占满。后来改成只传与当前任务相关的摘要信息,效果好很多。
另一个坑是Handoff的触发条件。如果让LLM自己判断何时Handoff,它可能过于频繁地转交,也可能该转交时不转交。我的做法是给Handoff设置明确的规则,比如“当用户问题涉及退款时,转交给退款Agent”,而不是让LLM自由判断。
7. 术语背后的工程现实
7.1 术语的通货膨胀
AI Agent领域的术语通货膨胀很严重。一个简单的Prompt模板叫“Agent框架”,一个API调用叫“Tool Use”,一个if-else叫“Planning”。这种通货膨胀对新人很不友好,也容易让技术决策者产生误判。
我的建议是:看一个系统是不是Agent,不要看它用了什么术语,要看它的决策逻辑是否动态。如果决策逻辑是写死的,不管包装成什么名字,它本质上还是Workflow。
7.2 实际项目中的术语选择
在写技术文档或者做技术分享时,我倾向于用最朴素的词。能说“调用API”就不说“Tool Use”,能说“判断下一步”就不说“Planning”。只有在跟同行交流或者写论文时,才用那些专业术语。
这样做的好处是,沟通成本低,不容易产生误解。坏处是,有时候显得不够“高级”。但我觉得,把问题讲清楚比显得高级重要得多。
7.3 给新入行的人的建议
如果你刚开始接触AI Agent,我的建议是:先动手做一个最简单的Agent,哪怕只是让LLM调用一个计算器工具。跑通之后,再逐步加Planning、加Memory、加Reflection。每加一个能力,都问自己:不加这个行不行?加了之后效果提升多少?成本增加多少?
不要一上来就追求“全栈Agent”,那只会让你陷入术语的泥潭。Agent的核心是自主决策循环,把这个循环跑通,比堆砌术语重要得多。
我在实际项目中最大的体会是:Agent系统的复杂度不在于用了多少高级技术,而在于如何处理各种边界情况。LLM输出格式错误怎么办?工具调用超时怎么办?Agent陷入循环怎么办?这些问题没有术语能帮你解决,只能靠工程手段一个一个处理。
最后分享一个实用技巧:在设计Agent时,先把它当成一个实习生来想。你会给实习生什么工具?你会怎么跟他交代任务?你会怎么检查他的工作?把这些想清楚了,Agent的设计也就清楚了。术语只是沟通工具,不是设计指南。