Agent 智能体开发框架选型指南

本文通过作者的实践对比发现,框架的选择应基于项目具体需求和团队特点,而不是简单追求某个特定框架。不同框架各有优势:

  1. 无框架方案实施最为简单直接,代码结构清晰,适合理解智能体原理,但随着项目复杂度增加可能变得难以维护。

  2. LangGraph提供完整的智能体结构规范,特别适合团队协作和智能体结构新手,但框架限制较多,如不认同其理念可能面临较大调试挑战。

  3. LlamaIndex Workflows采用事件驱动架构,在框架约束和开发自由度之间取得平衡,对框架依赖较少,但其固有的异步特性可能增加某些场景的复杂度。

    框架选择需要考虑三个关键因素:项目是否已深度集成了特定框架、团队对智能体架构的熟悉程度、是否有可供参考的相似项目案例。

智能体(Agents)正迎来辉煌时刻。伴随着众多新框架的涌现和对该领域的持续投资[1],现代 AI 智能体正在跨越起初的不稳定阶段[2],迅速取代 RAG 成为开发首选。那么,2024 年是否会成为 autonomous AI 系统全面接管撰写邮件、预订航班、数据分析等任务的一年呢?

也许吧,但要实现这一点还有很多工作要做。开发人员在构建智能体时,不仅要决定使用何种模型、应用场景和技术架构,还要挑选合适的开发框架。是坚持较为早期的 LangGraph,还是转向新兴的 LlamaIndex Workflows?或者走传统路线,自己编写全部代码呢?

这篇文章的目的就是让您更轻松地做出选择。在过去几周里,我使用多个主流框架构建了相同的智能体,并从技术角度分析了它们各自的优缺点。每个智能体的所有代码都可以在此代码仓库[3]中找到。

本文测试用智能体的基本概述

本次测试所采用的智能体整合了多项功能,包括执行函数调用(function calling)、使用多种工具或技能、与外部资源建立连接,以及实现状态或记忆的共享。

该智能体具备以下几项核心能力:

  1. 基于知识库进行问题解答

  2. 数据交互:针对 LLM 应用程序的数据进行问题解答

  3. 数据洞察:对获取的数据进行更高层次的趋势和模式分析

为了达成上述目标,智能体需要掌握三项基本技能:结合产品文档的 RAG、在相关数据库上生成 SQL 语句的能力,以及数据分析技巧。智能体的用户界面使用 gradio 搭建,而智能体本身则以聊天机器人(chatbot)的形式构建。

01.Code-Based Agent(不使用智能体框架)

在着手开发智能体时,您可以选择不依赖任何框架,而是完全自主构建。在启动这个项目之初,我首先采用了这种方法。

1.1 纯代码架构

下面是基于纯代码构建的智能体,其核心是一个由 OpenAI 提供支持的技能路由器,它通过函数调用来确定使用哪项技能。技能执行完毕后,控制权将返回给技能路由器,以便调用其他技能或直接向用户作出回应。

智能体会持续记录用户消息和智能体响应,并在每次调用时将这一完整列表传递给技能路由器,确保在整个交互过程中保留上下文。

各项技能均在独立的类中进行定义(例如“GenerateSQLQuery”类),这些类都保存在 SkillMap 中。技能路由器仅与 SkillMap 进行交互,通过它来加载技能的名称、描述以及可调用的函数。这种设计理念使得向智能体中添加新技能变得非常简单:只需将该技能编写为一个独立的类,并将其加入到 SkillMap 的技能列表即可。这样做的目的是为了在不影响技能路由器代码的前提下,轻松实现新技能的添加。

总的来说,这种实现方式虽然简单易行,但仍然存在一些需要克服的难题。

1.2 使用纯代码智能体面临的挑战

第一个困难在于如何设计技能路由器的系统提示词(system prompt)。在上面的例子中,技能路由器往往倾向于自行生成 SQL 语句,而不是交给相应的技能模块去处理。如果你有过试图让大语言模型停止执行某项任务的经历,那你可能深知这其中的挫败感;为了找到合适的提示词,我不得不进行了多次调试。此外,处理每个步骤产生的不同输出格式也是一项复杂的工作。由于我选择不使用结构化输出,因此必须为技能路由器和各项技能中大语言模型的调用准备多种格式的应对策略。

1.3 纯代码智能体的优点

基于代码的方法提供了一个扎实的基础和出发点,是一种绝佳的学习途径,让我们可以在不依赖现成框架提供的智能体教程的情况下,了解智能体的运作原理。虽然引导大语言模型按既定行为模式运作确实存在难度,但代码结构本身简洁明了,易于操作,对于某些使用场景而言,这种做法是完全合理的(具体分析将在下文展开)。

02.LangGraph

LangGraph 是众多智能体框架中历史最为悠久的之一,它于 2024 年 1 月首次发布。该框架的设计初衷是为了解决现有流程和链条的非循环性问题,它通过采用 Pregel 图结构来解决这一问题。LangGraph 通过引入节点(nodes)、边(edges)以及条件边(conditional edges)的概念,简化了在智能体中创建循环流程的过程,使得图的遍历变得更加直观。LangGraph 是基于 LangChain 构建的,它继承了后者的对象(objects)和类型(types)。

2.1 LangGraph 架构

从表面上看,LangGraph 智能体与基于代码的智能体有相似之处,但它们的底层代码却有大不相同。虽然 LangGraph 在技术上也使用了“路由器(router)”这一概念,即通过代码函数调用 OpenAI 并利用其响应来推进到下一个步骤,但程序在不同技能之间的切换控制机制却完全不同。

在此定义的图(graph)中,包含了一个用于初始化 OpenAI 调用的节点,即上文中提到的“agent”,以及一个用于工具处理步骤节点,即“tools”。LangGraph 内置了一个名为 ToolNode 的对象,它能够接收一系列可调用的工具,并根据 ChatMessage 的响应来触发这些工具,完成操作后再次回到“agent”节点。

每当“agent”节点(也可以理解为基于代码的智能体中的技能路由器(router))被调用之后,should_continue 这条边将判断是将响应直接返回给用户,还是转给 ToolNode 来处理工具调用。

在每个节点中,“state” 负责保存与 OpenAI 的交互消息和响应列表,这一点与基于代码的智能体保持上下文的方式相似。

2.2 使用 LangGraph 面临的挑战

在处理 LangGraph 构建的智能体示例时,遇到的主要难题在于必须借助 Langchain 对象才能确保流程的顺畅。

挑战 1:函数调用的 validation 错误

为了能够使用 ToolNode 对象,我不得不对 Skill 代码进行大规模的重构。ToolNode 需要一组可调用的函数列表,我本以为可以直接使用现成的函数,但是函数参数配置出了问题,导致流程受阻。

这些技能(skills)是以类形式定义的,每个类都有一个可调用的成员函数,其中“self”是首个参数。GPT-4o 足够智能,能够在生成函数调用(function call)时自动排除“self”参数,但 LangGraph 却因此认为缺少了必要参数,从而抛出了 validation 错误。

这个问题让我摸索了好几小时才搞清楚,因为错误信息把函数里的第三个参数(数据分析技能中的“args”)错误地标记为缺失参数(missing parameter):

需要指出的是,这个误导性的错误信息其实来自 Pydantic,而非 LangGraph。

最后,我下定决心,改用 Langchain 的 @tool 装饰器将我的技能(skills)重新编写为基本方法,这样程序就能正常运行了。

挑战 2:Debugging

正如前文所述,在框架中调试非常困难。主要是因为错误信息混乱不清,以及框架中的抽象概念,它们使得追踪和查看变量变得非常复杂。

抽象概念主要体现在尝试跟踪智能体间传递的消息时。LangGraph 会将消息保存在 state[“messages”] 里。Graph 中的一些节点会自动从这些消息(messages)中提取信息,这样的自动化过程可能会让节点在访问消息(messages)时,我们难以把握消息(messages)的具体内容。

智能体行动的顺序视图

2.3 LangGraph 的优点

LangGraph 的最大优势在于其易用性。它的图结构代码简洁且易于理解。对于那些拥有复杂节点逻辑的场景,LangGraph 能够提供一个清晰的图视图,让我们更轻松地把握智能体的连接方式。此外,LangGraph 还可以直接转换以 LangChain 构建的现有应用程序。

2.4 经验之谈

当我们只使用 LangGraph 框架的相关功能时,一切都会运行得非常流畅;但一旦我们尝试跳出框架,就要准备好进行一些令人头疼的调试了。

03.LlamaIndex Workflows

Workflows 是智能体框架领域的新晋成员,它于今年夏初首次亮相。与 LangGraph 类似,它的设计宗旨是简化可循环智能体的构建过程。此外,Workflows 特别强调其异步执行的能力。

在 Workflows 中,某些设计元素似乎是为了直接对标 LangGraph,尤其是它采用事件(events)而非边(edges)或条件边(conditional edges)作为连接逻辑的方式。在 Workflows 中,智能体逻辑被封装在“步骤(steps)”中(与 LangGraph 中的“节点(nodes)”相对应),而事件(events)的发出和接收则负责在不同的步骤(steps)间传递信息。

上述框架与 LangGraph 的结构颇为相似,但有一点不同:我给 Workflow 增加了一个初始化步骤,用于准备智能体的环境上下文,稍后我会详细介绍这一点。尽管两者的结构相似,但它们所依赖的代码实现却截然不同。

3.1 Workflows 架构

以下代码段描绘了 Workflow 的架构。与 LangGraph 相仿,在这一部分,我配置了状态信息(state),并将各项技能(skills)绑定到了 LLM 对象上。

在这里,我还定义了一个额外的步骤——“prepare_agent”。该步骤负责将用户输入转换成 ChatMessage,并将其存储到工作流的记忆存储中。将这一过程作为一个独立的步骤分离出来,意味着智能体在遍历工作步骤(steps)时可以重复回到这一步,从而避免反复将用户信息加入到记忆存储中。

在 LangGraph 的实现案例中,我通过一个位于图(graph)之外的 run_agent 方法实现了相同的功能。这一改变主要是出于风格上的考虑,但我认为,将这一逻辑整合到 Workflow 和图(graph)中,会更加整洁和高效。

在 Workflow 配置完成后,我继续编写了路由代码:

以及工具调用处理代码:

它们的实现方式似乎更接近于纯代码的智能体,而非 LangGraph 智能体。这主要是因为 Workflows 选择在各步骤(steps)中维护条件路由(conditional routing)逻辑,而不是像 LangGraph 那样使用条件边(conditional edge)(第 18-24 行在 LangGraph 中是条件边,而现在它们只是路由步骤的一部分)。另外,LangGraph 中的 ToolNode 对象能够在 tool_call_handler 方法中自动处理大部分任务。

在路由步骤之后,我们能够将 SkillMap 以及基于纯代码的智能体中已有的技能(skills)直接应用于 Workflows。这些技能(skills)无需任何修改即可与 Workflows 配合使用,这大大简化了我的工作。

3.2 使用 Workflows 面临的挑战

挑战 1:Sync vs Async

尽管对于在线运行的智能体来说,异步执行是更优的选择,但调试同步执行的智能体通常更为简便。Workflows 本身是为了异步操作而设计的,因此尝试将其改为同步执行非常困难。

起初,我以为只需去掉“async”方法标识,并将函数名“achat_with_tools”改为“chat_with_tools”即可。但是,由于 Workflow 类内部的方法同样采用了异步标记,为了实现同步运行,我不得不重新定义这些方法。尽管如此,我最终还是选择了异步处理方式,幸运的是,这并没有增加调试的难度。

智能体行动的顺序视图

挑战 2:Pydantic Validation Errors

与 LangGraph 的问题类似,在智能体的技能(skills)处也出现了令人困惑的 Pydantic Validation Errors。幸运的是,由于 Workflows 能够很好地处理成员函数,这些问题这次比较容易解决。最终,我不得不更加规范地为智能体技能(skills)创建 LlamaIndex FunctionTool 对象:

从构建 FunctionTools 的 AgentFlow.__init__ 文件中摘录

3.3 Workflows 的优点

与 LangGraph 相比,我在使用 Workflows 构建智能体时要轻松得多,主要原因是 Workflows 并未提供内置功能,而是需要我自己编写路由逻辑和工具操作代码。这也使得我的 Workflow 智能体与基于纯代码的智能体看起来极为相似。

最大的区别在于事件(events)的使用上。我使用两个自定义事件在智能体中的各个步骤之间移动:

这种基于事件的发射器-接收器架构(emitter-receiver),取代了直接调用智能体中某些方法的做法,例如工具调用处理(tool call handler)。

对于那些步骤(steps)更为复杂、异步触发且可能产生多个事件(events)的系统来说,这种架构就非常有助于干净利落地管理这些步骤。

Workflows 的其他优点还包括其轻量级特性,不会施加过多的结构限制(除了必须使用特定的 LlamaIndex 对象外),并且其基于事件(event-based)的架构为直接函数调用提供了一种有效的替代方案,这对于处理复杂、异步的应用场景尤为有益。

04.对这些方法进行比较

对比这三种方法,各有其独到之处。

无框架方法实施起来最简单。由于所有抽象层都是由开发者自行定义(如前例中的 SkillMap 对象),因此管理不同类型(types)和对象(objects)相对简单。但是,代码的可读性和易用性完全取决于开发者个人,可以预见,如果没有一定的智能体结构约束,智能体的复杂性增加后可能会变得难以驾驭。

LangGraph 提供了丰富的智能体结构支持,使得智能体的定义非常清晰。对于多人协作开发的智能体来说,这种智能体结构设定有助于统一架构规范。LangGraph 也为那些对智能体结构不太熟悉的开发者提供了帮助。不过,这样做也有代价 —— 由于 LangGraph 为你做了许多工作,如果你不完全认同这个框架,它可能会让你头疼不已;代码可能会非常简洁,但你可能要为此进行更多的调试工作。

Workflows 则处于两者之间。基于事件(event-based)的架构在某些项目中可能极具价值,而且因为它对 LlamaIndex 类型的使用要求不高,对于那些没有在应用程序中完全使用该框架的开发者来说,提供了更大的自由度。

归根结底,关键问题可能在于“你是否已经在使用 LlamaIndex 或 LangChain 来组织应用程序?” LangGraph 和 Workflows 都与它们所依赖的框架紧密集成,因此每个特定智能体框架的额外优势可能不足以成为转换使用的理由。

纯代码方法可能永远是一个有吸引力的选择。如果你能够严格地记录并执行所创建的任何抽象概念,那么确保外部框架不会成为你的阻碍就很容易了。

05.在选择智能体框架时需要考虑的关键问题

当然,单纯一句“具体情况具体分析”这样的回答总是让人不太满意。以下三个问题或许能帮你选择下一个智能体项目应该采用哪个框架。

你的项目是否已经深度集成了 LlamaIndex 或 LangChain?

如果是的话,不妨优先考虑这两个选项。

你对智能体的常见架构是否熟悉,还是更希望有人告诉你应该如何构建智能体结构?

如果你倾向于后者,那么 Workflows 可能是个不错的选择。如果你非常倾向于后者,那么 LangGraph 或许更适合你。

你要构建的智能体是否有参考样例?

框架的一个优势在于,每个框架都有大量的教程和实例供你参考。而纯代码构建智能体的参考实例相对较少。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

<think>好的,我现在需要帮助用户了解如何开发智能体。根据用户的问题,他们想了解编写智能体的方法或教程,特别是编程指南。首先,我应该回顾用户提供的引用内容,看看是否有相关的信息可以利用。 用户提供的引用[1]提到实践是掌握智能体的关键,鼓励用户在实际项目中应用,比如创建个人助手或企业内部工具。这提示我需要强调实践的重要性,并在回答中建议具体的应用场景。引用[2]则讨论了提示词工程、开发框架和工作流的重要性,提到了LangChain、AutoGen等框架,这些可以作为开发工具的建议。 接下来,我需要整理开发智能体的步骤。通常,开发流程包括明确目标、选择工具、设计提示词、构建工作流、实现功能和测试优化。每个步骤都需要详细说明,确保用户能够逐步跟随。 在明确目标部分,需要建议用户确定应用场景和核心功能,比如法律助手或数据分析工具。选择工具时,根据引用[2]提到的框架,推荐LangChain、AutoGen等,并解释它们的特点。设计提示词部分需要强调清晰和逻辑性,可能给出示例。构建工作流时,要分模块处理,比如输入解析、任务执行和结果生成,并可能结合API调用。 在实现功能部分,结合引用[1]中的实践建议,可以提供一个简单的代码示例,比如使用Python和LangChain创建问答助手,这样用户能直观看到如何编码。测试优化部分需要提醒用户进行单元测试和迭代优化,确保智能体的有效性和用户体验。 然后,用户可能需要相关的开发资源,如官方文档、社区论坛和在线课程,这些都是帮助用户进一步学习的途径。最后,生成相关问题,围绕开发框架、提示词设计、工作流优化等,帮助用户深入探索。 需要确保回答符合系统级指令,如使用正确的中文、LaTeX格式(虽然当前问题可能不需要数学公式),以及引用标识。检查是否有遗漏的步骤或需要更详细解释的部分,确保结构清晰,逻辑连贯。</think>### 智能体开发方法指南 开发智能体需融合目标定义、工具选型、提示词工程和工作流设计,以下是分步指南: #### 一、开发流程 1. **明确目标** - 确定应用场景:如$法律合同解析助手$、$电商数据分析工具$ - 定义核心功能:输入输出格式、决策逻辑、外部服务集成 2. **选择开发框架** - LangChain:适合构建链式任务处理(文档解析→数据分析→报告生成)[^2] - AutoGen:支持多智能体协作(谈判场景中买卖双方Agent交互) ```python # AutoGen多智能体示例 from autogen import AssistantAgent, UserProxyAgent buyer_agent = AssistantAgent("buyer") seller_agent = AssistantAgent("seller") ``` 3. **提示词设计** - 采用$角色定义+任务描述+格式约束$结构: ```text 你是一个资深法律顾问,请完成: 1. 识别合同中的责任条款 2. 用JSON输出{条款内容, 责任方, 违约责任} 禁止添加解释性文字 ``` 4. **构建工作流** - 模块化设计: $$输入解析 \rightarrow 任务分配 \rightarrow 模型推理 \rightarrow 结果验证$$ - 异常处理机制:设置$重试次数阈值N$和$置信度阈值θ$ 5. **功能实现** - 基础版问答助手实现: ```python from langchain.chains import LLMChain prompt_template = "回答关于{topic}的问题,最多3句话" chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template)) ``` 6. **测试优化** - 建立评估矩阵:$准确率α$、$响应时间t$、$用户满意度评分S$ - A/B测试:对比$不同提示词版本V1/V2$的效果差异 #### 二、关键开发资源 1. **框架文档** - LangChain官方文档:https://python.langchain.com - AutoGen案例库:https://microsoft.github.io/autogen 2. **实践社区** - GitHub trending项目分析 - HuggingFace Spaces体验现成智能体 3. **调试工具** - LangSmith:可视化跟踪$智能体决策路径$ - W&B:监控$模型性能指标$ #### 三、典型问题解决方案 1. **意图识别不准** - 增加分类器:$P(意图|输入) > 0.7$时触发响应 - 设置澄清机制:"您想查询订单状态还是物流信息?" 2. **长上下文处理** - 采用$递归摘要法$: $$S_{new} = f(S_{prev} + C_{current})$$ - 使用Claude-3-200k等长上下文模型 [^1]: 实践是掌握扣子智能体的关键... [^2]: 智能体开发实战指南...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值