如何理解智能体框架(译)
本文译自 《How to think about agent frameworks》,作者深入对比分析多种智能体框架思路(含OpenAI、Anthropic观点),指出构建可靠智能体的关键在于上下文管理而非单纯抽象。详解LangGraph如何通过灵活编排提供必要控制力,平衡工作流与智能体,实现复杂任务。
内容提要:
- 构建可靠智能体系统的难点在于确保大模型在每一步都能获得适当的上下文。这既包括严格控制输入大模型的内容,也包括运行必要的步骤来生成相关内容。
- 智能体系统既包含工作流也包含智能体(以及介于两者之间的所有形态)。
- 大多数智能体框架既非声明式也非命令式编排框架,它们本质上只是一组智能体抽象。
- 智能体抽象虽然能降低入门门槛,但往往会模糊关键细节,使得确保大模型获得适当上下文变得困难。
- 无论何种形态的智能体系统(智能体或工作流),都能从同一组实用功能中受益——这些功能可由框架提供,也能自行实现。
- LangGraph最准确的定位是编排框架(同时提供声明式和命令式API),并在其上构建了一系列智能体抽象。
OpenAI最近发布的智能体构建指南中包含了一些值得商榷的观点,例如:
这段批评最初让我感到愤怒,但在着手撰写回应时我意识到:理解智能体框架确实复杂!目前存在上百种不同的智能体框架,评估维度多种多样,这些概念经常被混淆(正如上述引文所示)。这个领域充斥着炒作、立场之争和噪音,却极少有精准的分析思考。本文正是为此而作,我们将探讨:
- 背景知识
- 什么是智能体?
- 构建智能体的难点何在?
- LangGraph是什么?
- 智能体框架的类型
- “智能体” vs “工作流”
- 声明式 vs 非声明式
- 智能体抽象
- 多智能体系统
- 常见问题
- 框架的价值是什么?
- 随着模型进步,所有系统都会变成智能体而非工作流吗?
- OpenAI的观点有哪些谬误?
- 各类智能体框架如何比较?
本文会反复引用以下资料:
- OpenAI的智能体构建指南(我认为质量欠佳)
- Anthropic的有效智能体构建指南(我非常欣赏)
- LangGraph(我们用于构建可靠智能体的框架)
背景知识
为后续讨论奠定基础的重要背景。
什么是智能体
智能体并无统一定义,不同视角下有不同解读。
OpenAI采用更高层次、更具思想领导力的方式来定义智能体:
智能体是能独立代表你完成任务的技术系统。
我个人并不认同这种定义。这种模糊表述无助于真正理解智能体本质,只是思想领导力的空谈,毫无实践价值。
对比Anthropic的定义:
“智能体”有多种定义方式。有些客户将其视为能长期自主运行、使用多种工具完成复杂任务的完全自治系统;另一些则指遵循预定义流程的规范性实现。在Anthropic,我们将这些变体统称为智能体系统,但在架构上区分工作流和智能体:
工作流是通过预定义代码路径编排大模型和工具的系统。
智能体则是大模型动态自主控制流程和工具使用的系统,自主决定任务完成方式。
我更认同Anthropic的定义,原因如下:
- 他们的定义更精确且技术导向
- 提出了”智能体系统”概念,并将工作流和智能体都归入其中——这一点我非常欣赏
💡
实际生产环境中,几乎所有的智能体系统都是工作流和智能体的混合体。
在后文中,Anthropic将智能体定义为”…本质上只是大模型在循环中基于环境反馈使用工具的系统”。
尽管OpenAI最初给出了宏大的定义,但实际所指与Anthropic基本一致。
这类智能体的参数包括:
- 使用的大模型
- 系统提示词
- 可用工具
工作原理是循环调用大模型:当它决定调用工具时,执行该工具并获取观察结果/反馈,再传回大模型。循环持续直到大模型决定不再调用工具(或触发了停止条件)。
OpenAI和Anthropic都将工作流视为与智能体不同的设计模式——在前者中,大模型的控制权更小,流程更确定。这种区分很有价值!
两家公司都明确指出:并非所有场景都需要智能体。在许多情况下,工作流更简单、可靠、经济、快速且高效。Anthropic文章中有段精彩论述:
构建大模型应用时,我们建议先寻找最简单的解决方案,仅在必要时增加复杂度。有时这意味着完全不构建智能体系统。智能体系统通常以延迟和成本为代价换取更好的任务性能,需要谨慎权衡。当确实需要更高复杂度时,工作流能为明确定义的任务提供可预测性,而智能体更适合需要灵活性和模型驱动决策的场景。
OpenAI也有类似表述:
在决定构建智能体前,请明确验证你的用例是否符合这些标准。否则,确定性解决方案可能就已足够。
实践中,大多数智能体系统都是工作流和智能体的组合。这正是我反感讨论”某物是否是智能体”,而更倾向于讨论”系统的智能体化程度”的原因。感谢Andrew Ng提出的这种思考方式:
与其二元化地判断某物是否是智能体,不如将系统视为具有不同程度的智能体特性。”智能体化”这个形容词让我们能够涵盖所有这些系统,纳入这场不断发展的运动。
构建智能体的难点何在?
多数人会认同构建智能体具有挑战性。更准确地说——构建一个智能体原型很容易,但要打造能支撑关键业务应用的可靠系统?这非常困难。
真正的难点在于可靠性。在Twitter上展示一个光鲜的demo很容易,但要让其支撑关键业务?不经过大量工作根本无法实现。
几个月前我们对智能体构建者进行了调研,问题是:”将更多智能体投入生产的最大障碍是什么?”压倒性的首要答案是”性能质量”——要让这些智能体可靠工作仍然非常困难。
什么导致智能体有时表现不佳? 大模型出错。
为什么大模型会出错? 两个原因:(a) 模型能力不足,(b) 传入模型的上下文错误或不完整。
根据我们的经验,后者更常见。具体诱因包括:
- 不完整或过于简略的系统消息
- 模糊的用户输入
- 缺乏恰当的工具
- 工具描述质量差
- 未传入正确的上下文
- 工具响应格式不当
💡
构建可靠智能体系统的核心难点在于确保大模型在每一步都能获得适当的上下文。这既包括严格控制输入大模型的内容,也包括运行必要的步骤来生成相关内容。
在讨论智能体框架时,请牢记这一点。任何让控制大模型输入内容变得更困难的框架,都是在帮倒忙。确保正确上下文传入大模型本就足够困难——何必自找麻烦?
什么是LangGraph
💡
LangGraph最准确的定位是编排框架(同时提供声明式和命令式API),并在其上构建了一系列智能体抽象。
LangGraph是用于构建智能体系统的事件驱动框架,两种最常见的使用方式是:
- 声明式的基于图的语法
- 智能体抽象(构建在底层框架之上)
LangGraph还支持函数式API和底层事件驱动API,提供Python和TypeScript版本。
智能体系统可以表示为节点和边。节点代表工作单元,边代表转移关系。节点和边本质上就是普通的Python/TypeScript代码——虽然图结构是声明式表达的,但图内部的逻辑仍是常规的命令式代码。边可以是固定或条件的。因此,虽然图结构是声明式的,但图的遍历路径可以完全动态。
LangGraph内置持久化层,支持容错、短期记忆和长期记忆。
该持久化层还支持”人在回路“和”人在环上“模式,如中断、审批、恢复和时间旅行。
LangGraph内置支持流式传输:包括token流、节点更新流和任意事件流。
LangGraph与LangSmith无缝集成,提供调试、评估和可观测性支持。
智能体框架的类型
智能体框架在多个维度上存在差异。理解——而非混淆——这些维度,是正确比较框架的关键。
工作流 vs 智能体
大多数框架包含高级智能体抽象,部分框架还包含常见工作流抽象。LangGraph则是用于构建智能体系统的底层编排框架,支持工作流、智能体及介于两者之间的所有形态。我们认为这至关重要——如前所述,生产环境中的智能体系统大多是工作流和智能体的组合。生产级框架必须同时支持两者。
请记住构建可靠智能体的难点:确保大模型获得正确的上下文。工作流的价值之一就在于它能简化上下文传递过程——你可以精确控制数据流向。
在设计系统时,需要在”工作流”到”智能体”的频谱上定位,需考虑两个因素:
- 可预测性 vs 自主性
- 低门槛 vs 高上限
可预测性 vs 自主性
系统越趋向智能体,可预测性就越低。
有时出于用户信任、监管要求等原因,你需要系统保持可预测性。
可靠性虽不完全等同于可预测性,但实践中二者密切相关。
在频谱上的理想位置取决于具体应用。LangGraph可用于构建频谱上任意位置的系统,让你自由调整。
高门槛 vs 低上限
评估框架时可参考其门槛和上限:
- 低门槛:框架易上手,适合初学者
- 高门槛:需要专业知识才能有效使用
- 低上限:能力有限(很快会触达天花板)
- 高上限:支持高级用例,扩展性强(能伴随需求成长)
工作流框架提供高上限,但门槛也高——需要自行实现大量智能体逻辑。
智能体框架门槛低但上限也低——容易入门,但难以应对复杂场景。
LangGraph旨在兼具低门槛(通过内置智能体抽象降低入门难度)和高上限(通过底层功能支持高级用例)。
声明式 vs 非声明式
声明式框架有其优势,也有不足。这是程序员间永无止境的争论,各有所好。
当人们说”非声明式”时,通常暗指”命令式”作为替代。
多数人会认为LangGraph是声明式框架,但这只对了一半。
首先——虽然节点和边的连接方式是声明式的,但节点和边本身只是普通的Python/TypeScript函数。因此LangGraph实际融合了声明式和命令式。
其次——我们实际上支持声明式API之外的其他接口,特别是函数式和事件驱动API。虽然我们认为声明式API是有用的心智模型,但也理解它并非适合所有人。
关于LangGraph的常见误解是将其比作Tensorflow(声明式深度学习框架),而将Agents SDK比作Pytorch(命令式框架)。
这是完全错误的。Agents SDK(以及原始LangChain、CrewAI等)既非声明式也非命令式——它们只是抽象层。它们提供智能体抽象(Python类),内含运行智能体的逻辑。这些并非真正的编排框架,仅仅是抽象层。
智能体抽象
大多数智能体框架都包含智能体抽象。通常始于一个包含提示词、模型和工具的类,然后不断添加参数…最终你会面对一个控制多种行为的冗长参数列表,全部隐藏在类抽象之后。要了解运行机制或修改逻辑,必须深入源代码。
💡
这些抽象最终会让你难以理解或控制在每一步传入大模型的具体内容。这一点至关重要——正如前文所述,保持这种控制力是构建可靠智能体的关键。这正是智能体抽象的危险之处。
我们有过惨痛教训。这正是原始LangChain链和智能体的问题所在——它们的抽象反而成了障碍。两年前的一个原始抽象就是接收模型、提示词和工具的智能体类。这不是新概念,当时就无法提供足够控制力,现在依然如此。
明确地说,智能体抽象确实有其价值——能降低入门门槛。但我认为这些抽象还不足以(或许永远不足以)构建可靠的智能体。
我们认为最佳方式是将这些抽象视为类似Keras的存在——提供高级抽象来简化入门。但关键是确保它们构建在底层框架之上,避免过早触及天花板。
这正是我们在LangGraph之上构建智能体抽象的原因。这既提供了简单的智能体入门方式,又能在需要时轻松切换到底层LangGraph。
多智能体系统
智能体系统往往不只有一个智能体,而是包含多个。OpenAI在报告中指出:
对于复杂工作流,将提示词和工具分配给多个智能体可以提高性能和扩展性。当你的智能体无法遵循复杂指令或持续选择错误工具时,可能需要进一步拆分系统并引入更多独立智能体。
💡
多智能体系统的关键在于通信机制。再次强调,构建智能体的难点在于为大模型提供正确上下文。智能体间的通信方式至关重要。
实现方式多种多样!交接(handoffs)是一种方式——这是Agents SDK中我相当欣赏的一个智能体抽象。
但有时最佳通信方式可能是工作流。想象Anthropic博文中所有工作流图表,将其中的大模型调用替换为智能体。这种工作流与智能体的混合往往能提供最佳可靠性。
重申——智能体系统不仅是工作流或仅是智能体,它们可以是(也经常是)两者的组合。正如Anthropic在博文中所说:
组合与定制这些模式
这些构建模块并非铁律,而是开发者可以根据不同用例调整组合的常见模式。
常见问题
在定义和探讨评估框架的不同维度后,现在让我们回答一些常见问题。
框架的价值是什么?
我们经常看到人们质疑是否需要框架来构建智能体系统。智能体框架能提供什么价值?
智能体抽象
框架的通用价值在于提供有用的抽象,既降低入门门槛,又为工程师提供统一的构建方式,简化项目维护。但如前所述,智能体抽象也有明显缺陷。对大多数智能体框架而言,这是它们提供的唯一价值。我们努力确保LangGraph不限于此。
短期记忆
当前大多数智能体应用都涉及多轮(如聊天)交互。LangGraph提供支持多轮会话(threads)的生产级存储。
长期记忆
虽然尚处早期,但我非常看好智能体系统从经验中学习的能力(如跨对话记忆)。LangGraph提供跨会话长期记忆的生产级存储。
人在回路
许多智能体系统通过引入人在回路环节能获得提升,例如获取用户反馈、审批工具调用或编辑工具参数。LangGraph提供在生产系统中实现这些工作流的内置支持。
人在环上
除了允许用户实时影响智能体,让用户在事后检查智能体运行轨迹,甚至回到早期步骤修改后重新执行也非常有用。我们称之为人在环上,LangGraph提供对此的内置支持。
流式传输
大多数智能体应用运行耗时较长,因此向终端用户提供实时更新对用户体验至关重要。LangGraph内置支持token流、图步骤流和任意事件流。
调试/可观测性
构建可靠智能体的难点在于确保传入大模型的上下文正确。能够检查智能体的具体执行步骤及每一步的精确输入/输出至关重要。LangGraph与LangSmith无缝集成,提供顶尖的调试和可观测性支持。(注:AI可观测性与传统软件可观测性不同,这值得另文探讨)
容错性
容错是构建分布式应用的传统框架(如Temporal)的关键特性。LangGraph通过持久化工作流和可配置重试简化容错实现。
优化
相比手动调整提示词,有时定义评估数据集并自动优化智能体更高效。LangGraph目前未原生支持此功能——我们认为时机尚早。但提及此维度是因为它值得关注,我们也在持续观察。dspy
是目前这方面最优秀的框架。
💡
所有这些价值主张(除智能体抽象外)对智能体、工作流及其中间形态都有同等价值。
那么——你真的需要智能体框架吗?
如果你的应用不需要全部这些功能,或者你希望自行实现,那么可能不需要。其中部分功能(如短期记忆)实现并不复杂,但其他(如人在环上或大模型专属可观测性)则复杂得多。
关于智能体抽象,我完全同意Anthropic文中的观点:
如果使用框架,请确保理解底层代码。对内部机制的错误假设是客户常见错误来源。
随着模型进步,所有系统都会变成智能体而非工作流吗?
支持智能体(相对工作流)的常见论点是:虽然当前效果不佳,但未来会改善,因此你只需要简单的工具调用型智能体。
我认为以下几点可能同时成立:
- 这类工具调用型智能体的性能会提升
- 控制大模型输入内容仍然至关重要(垃圾进,垃圾出)
- 对某些应用,这种工具调用循环就足够
- 对其他应用,工作流仍会更简单、经济、快速和优秀
- 对大多数应用,生产级智能体系统将是工作流和智能体的组合
我不认为OpenAI或Anthropic会反对这些观点。Anthropic文中说:
构建大模型应用时,我们建议先寻找最简单的解决方案,仅在必要时增加复杂度。有时这意味着完全不构建智能体系统。
OpenAI文中也说:
在决定构建智能体前,请明确验证你的用例是否符合这些标准。否则,确定性解决方案可能就已足够。
是否存在简单工具调用循环就足够的场景?我认为只有当使用针对特定用例进行充分训练/微调/强化学习的大模型时才会成立。这有两种实现路径:
- 你的任务具有独特性。你收集大量数据并训练/微调/强化学习自己的模型。
- 你的任务具有普遍性。大型模型实验室正在训练/微调/强化学习与你的任务相似的数据。
(旁注:如果我正在某个垂直领域创业,而我的任务并不独特,我会非常担忧公司的长期生存能力)
你的任务具有独特性
我打赌大多数用例(当然包括大多数企业用例)属于此类。AirBnb的客户支持方式与Klarna不同,与Rakuten也不同。这些任务存在大量细微差别。Sierra——客户支持领域的领先智能体公司——并非在构建单一的客户支持_智能体_,而是客户支持智能体_平台_:
Sierra Agent SDK使开发者能使用声明式编程语言,通过可组合技能构建强大灵活的智能体来表达程序性知识
他们需要这样做,因为每家公司的客户支持体验都独特到通用智能体无法满足性能要求。
一个使用针对特定任务训练模型的简单工具调用型智能体案例是:OpenAI的Deep Research。这说明确实可行,并能产出卓越的智能体。
如果你能为特定任务训练顶尖模型——那么确实,你可能不需要支持任意工作流的框架,简单工具调用循环就足够。此时智能体会比工作流更受青睐。
我心中非常开放的问题是:有多少智能体公司会拥有为其任务训练顶尖模型所需的数据、工具或知识?目前我认为只有大型模型实验室能做到。但这会改变吗?小型垂直创业公司能否为其任务训练顶尖模型?我对这个问题非常感兴趣。如果你正在做这件事——请联系我!
你的任务具有普遍性
我认为某些任务足够通用,大型模型实验室能提供适用于简单工具调用循环的模型。
OpenAI通过API发布了他们的计算机使用模型,这是针对通用计算机使用数据微调的模型,旨在胜任该通用任务。(旁注:我认为它目前远未达标)
编程是个有趣的例子。编码相对通用,绝对是当前智能体的突破性用例。Claude代码和OpenAI的Codex CLI就是使用简单工具调用循环的编程智能体案例。我敢打赌基础模型训练使用了大量编码数据和任务(Anthropic的这篇文档就是证据)。
有趣的是——随着通用模型在这些数据上训练,数据的具体形态有多重要?Ben Hylak日前发了条引发共鸣的推文:
模型不再会使用Cursor了。它们全被优化为终端使用。这就是为什么3.7和o3在Cursor中表现极差,而在外部却惊人的原因。
这可能说明两点:
- 你的任务必须与通用模型训练的任务高度相似。相似度越低,通用模型适合你用例的可能性越小。
- 通用模型在其他特定任务上的训练可能会降低对你任务的性能。我相信用于训练新模型的数据中,与Cursor用例相似的数据量只多不少。但如果涌入的形态略有不同的新数据占优,就会压制其他类型数据。这意味着当前通用模型很难在大量任务上都表现出色。
💡
即使对于智能体明显优于任何工作流方案的应用,你仍会受益于框架提供的与底层工作流控制无关的功能:短期记忆存储、长期记忆存储、人在回路、人在环上、流式传输、容错性和调试/可观测性。
OpenAI的观点有哪些谬误?
重新审视OpenAI的立场,我们发现其基于错误的二分法,混淆了”智能体框架”的不同维度,从而夸大其单一抽象的价值。具体而言,它将”声明式vs命令式”与”智能体抽象”以及”工作流vs智能体”混为一谈。
💡
根本上,它误解了构建生产级智能体系统的主要挑战,以及框架应提供的核心价值:可靠的编排层,让开发者能精确控制传入大模型的上下文,同时无缝处理持久化、容错和人在回路等生产环境问题。
让我们分析我反对的具体部分:
“声明式 vs 非声明式图”
LangGraph并非完全声明式——但这并非我的主要异议。关键在于”非声明式”这个表述含糊且有误导性。通常当人们批评声明式框架时,他们会偏好更命令式的框架。但Agents SDK并非命令式框架,它只是个抽象层。更恰当的标题应是”声明式vs命令式”或”你需要编排框架吗”或”为什么智能体抽象就足够”或”工作流vs智能体”(取决于他们想论证什么,下文似乎两者都想论证)。
“随着工作流变得更动态复杂,这种方法会迅速变得繁琐困难”
这与声明式或非声明式无关,完全关乎工作流vs智能体。你可以轻松将Agents SDK的智能体逻辑表示为声明式图,且该图与Agents SDK同样动态灵活。
关于工作流vs智能体的观点:许多工作流并不需要这种程度的动态性和复杂性。OpenAI和Anthropic都承认这点。能用工作流时就该用工作流。大多数智能体系统都是两者的组合。是的,如果工作流确实非常动态复杂,那就用智能体。但不要在所有场景都用智能体。OpenAI在文章前段其实也这么说。
“通常需要学习特定的领域专用语言”
再次强调——Agents SDK不是命令式框架,而是抽象层。它也有领域专用语言(即它的抽象)。我认为在当前阶段,学习和适应Agents SDK的抽象比学习LangGraph抽象更糟糕。因为构建可靠智能体的难点在于确保智能体获得正确上下文,而Agents SDK在这方面比LangGraph模糊得多。
“更灵活”
这完全不属实。事实恰恰相反。Agents SDK能做的,LangGraph都能做。而LangGraph能做的,Agents SDK只能实现10%。
“代码优先”
使用Agents SDK你需要编写他们的抽象,而使用LangGraph你编写的是大量常规代码。我不明白Agents SDK如何更”代码优先”。
“使用熟悉的编程结构”
使用Agents SDK你必须学习整套新抽象,而使用LangGraph你编写的是大量常规代码。还有什么比这更熟悉?
“支持更动态适应的智能体编排”
再次说明——这与声明式或非声明式无关,完全关乎工作流vs智能体。见上文论述。
智能体框架比较
我们已经讨论了智能体框架的多个组件:
- 它们是灵活的编排层,还是仅提供智能体抽象?
- 如果是灵活的编排层,它们是声明式还是其他形式?
- 除了智能体抽象,框架还提供哪些功能?
尝试将这些维度整理成表格会很有趣。我尽量保持中立(通过Twitter征集并获得了大量反馈!)。
当前表格包含与Agents SDK、Google的ADK、LangChain、Crew AI、LlamaIndex、Agno AI、Mastra、Pydantic AI、AutoGen、Temporal、SmolAgents、DSPy的比较。
如果遗漏了某个框架(或对某个框架的描述有误),请留言指出!
💡
可在此查看实时更新的表格链接。
结论
- 构建可靠智能体系统的核心难点在于确保大模型在每一步都能获得适当的上下文。这既包括严格控制输入大模型的内容,也包括运行必要的步骤来生成相关内容。
- 智能体系统既包含工作流也包含智能体(以及介于两者之间的所有形态)。
- 大多数智能体框架既非声明式也非命令式编排框架,它们本质上只是一组智能体抽象。
- 智能体抽象虽然能降低入门门槛,但往往会模糊关键细节,使得确保大模型获得适当上下文变得困难。
- 无论何种形态的智能体系统(智能体或工作流),都能从同一组实用功能中受益——这些功能可由框架提供,也能自行实现。
- LangGraph最准确的定位是编排框架(同时提供声明式和命令式API),并在其上构建了一系列智能体抽象。