深度剖析 Agent 框架:以 LangGraph 为例,探索 AI 开发新范式
Agent 框架正在彻底改变人工智能系统的运行方式,使智能、自主的 Agent 能够动态推理、计划和交互。在文章中,我们探讨了 Agent 框架的重要性,介绍了 8 个 Agent 框架,并比较了它们的优势。然后,我们深入研究了 LangGraph,了解了它基于图的架构、状态管理和现实世界的应用程序。动手部分展示了如何使用 LangGraph 构建具有内存、人在回路功能和可扩展工作流的人工智能 Agent。
更多 LLM 架构文章点击查看:LLM 架构专栏
大模型架构专栏文章阅读指南
Agent系列 1W字用Python从零搭建AI智能体
欢迎加入大模型交流群:加群链接 https://docs.qq.com/doc/DS3VGS0NFVHNRR0Ru#
公众号【柏企阅文】
1. 介绍
Agent 框架让自主系统能够动态感知、推理和行动,彻底革新了人工智能领域。本节将深入探究 Agent 框架的核心概念,并着重强调开源解决方案在现代 AI 开发中,对于创新和可扩展性的重要意义。
1.1 什么是 Agent 框架?
Agent 框架代表着人工智能系统设计模式的重大转变。与依赖静态、预定义工作流程的传统 AI 应用程序不同,Agent 框架引入了动态自适应系统,该系统具备自主感知、推理和行动的能力。这些框架可以把复杂任务拆解成多个小子任务,交给专门的 Agent 协作完成,以实现更宏大的目标。借助大型语言模型(LLM),Agent 框架能够管理工作流程、做出决策,还能无缝集成各种工具,这使得它成为动态决策、实时问题解决等高级应用的理想之选。
关键参考:像 LangGraph 和 CrewAI 这样的 Agent 框架,就是这种动态方法的典型代表,它们帮助开发者突破单 Agent、线性工作流程的局限,进入多 Agent 协作系统的全新领域。
1.2 为什么它们很重要?
从头开始构建 Agent 绝非易事。LangGraph、CrewAI 和 OpenAI Swarm 等框架大大简化了这个过程,让开发者能够把精力集中在应用程序逻辑上,而不用在状态管理、编排和工具集成这些方面重复造轮子。
Agent 框架的核心优势体现在:
- 定义 Agent 和工具的简便方式:提供简单直观的方法来定义 Agent 和工具,降低开发门槛。
- 编排机制:具备高效的编排机制,能够合理安排任务执行顺序。
- 状态管理:实现可靠的状态管理,确保系统在运行过程中状态的稳定和准确。
- 附加工具:拥有一系列附加工具,可支持更复杂的应用开发,比如持久层(内存)、中断处理等功能。
接下来的章节,我们将详细介绍这些内容。
2. 流行的 Agent 框架和库
现在,让我们深入了解当下一些最知名的 AIAgent 框架和工具:
2.1 Langchain
LangChain 是一个强大且适应性很强的框架,它让开发由大型语言模型(LLM)驱动的应用程序变得更加轻松。凭借丰富的工具集和抽象概念,开发者利用它可以设计出功能强大的人工智能 Agent,这些 Agent 具备复杂推理、任务执行能力,还能与外部数据源和 API 进行交互。
从根本上讲,在长时间对话中保持上下文连贯性、整合外部信息以及协调多步骤项目,是开发者在与 LLM 合作时面临的几个难题,而 LangChain 恰好能解决这些问题。得益于其模块化架构,该框架可以很方便地由各种组件组合而成,满足不同的开发需求。
2.2 LangGraph
LangGraph 是 LangChain 的扩展框架,它支持使用大型语言模型(LLM)创建有状态的多参与者应用程序。在构建涉及规划、反思、思考以及多 Agent 协作的复杂交互式 AI 系统时,LangGraph 特别有用。
GitHub 链接:LangGraph
文档链接:LangGraph 文档
2.3 CrewAI
CrewAI 是一个用于编排角色扮演 AIAgent 的框架。借助它,开发者能够创建一个 AIAgent“团队”,团队中的每个 Agent 都有明确的角色和职责,共同协作完成复杂任务。对于构建那些需要多种专业知识协同合作,以解决多方面问题的协作 AI 系统而言,这个框架非常实用。
GitHub 链接:CrewAI GitHub
文档:CrewAI 文档
2.4 微软语义内核(Microsoft Semantic Kernel)
微软语义内核旨在缩小传统软件开发和人工智能能力之间的差距,尤其专注于将大型语言模型(LLM)集成到现有的应用程序中。该框架为开发者提供了一系列工具,使得他们无需彻底修改现有代码库,就能轻松融入人工智能功能。
SDK 的轻量级特性以及对多种编程语言的支持,让它能很好地适应各种开发环境。其编排器可以管理复杂的多步骤人工智能任务,帮助开发者在应用程序内创建复杂的 AI 驱动工作流。
GitHub 链接:Microsoft Semantic Kernel github
文档链接:Microsoft 语义内核 documentation
2.5 微软 AutoGen(Microsoft AutoGen)
Microsoft AutoGen 是一个开源框架,主要用于构建高级 AIAgent 和多 Agent 系统。它由微软研究院开发,为创建对话式和任务完成型的 AI 应用程序,提供了一套灵活且强大的工具包。该框架强调模块化、可扩展性和易用性,能帮助开发者高效构建复杂的 AI 系统。
AutoGen 文档
GitHub 链接:Microsoft Autogen
2.6 Smolagents
Smolagent 是一个处于前沿的开源框架,旨在彻底变革人工智能 Agent 的开发方式。它为开发者提供了一套全面的工具包,用于构建智能、协作的多 Agent 系统。该框架注重灵活性和模块化,所创建的复杂人工智能系统既可以独立运行,也能在人类监督下协同工作。
Smolagents 文档
Smolagents GitHub 链接
2.7 AutoGPT
AutoGPT 基于强大的 GPT-4 语言模型,通过语言输入就能执行目标导向的任务,它标志着自主人工智能 Agent 领域取得了重大进展。这款先进的人工智能助手将决策能力提升到了新高度,超越了基础的反射 Agent,集成了众多复杂功能,使其在各类应用场景中都极具价值。
2.8 Agno(Phidata)
我们要讨论的最后一个 AIAgent 框架是 Phidata。这是一个多模态 Agent 框架,可用于开发协作执行任务的 Agent 系统。它还能与内存、工具等组件协同工作,助力 Agent 自主、稳定地运行。
默认情况下,PhidataAgent 支持文本、图像、音频等多模态数据,这使得它无需依赖外部工具就具备很高的价值。该框架还提供了 Agent 用户界面,如果您喜欢通过可视化方式与 Agent 交互,这个界面就能派上用场。此外,他们还是 Agent 检索增强生成(Agentic RAG)技术的先驱,Agent 可以利用该技术搜索知识库。
3. Agent 框架的比较
下面的图表对本文讨论的关键 AIAgent 框架进行了高层次的对比。通过这种对比,我们可以清楚地看到每个框架的独特优势和重点应用领域,方便开发者和研究人员根据自身具体需求,选择最合适的工具。
4. 深入了解 LangGraph
LangGraph 是 LangChain 团队开发的一个库,目的是帮助开发者创建基于图的单 Agent 或多 AgentAI 应用程序。作为底层框架,LangGraph 赋予开发者控制 Agent 交互方式、工具选择以及应用程序内信息流的能力。
4.1 什么是图?
想象一下,有一组数据可以用网络来表示,其中每个数据或实体都与其他数据或实体存在某种关系,而且这种关系可以是一对一、一对多、多对多等多种类型。图主要由两个部分组成:节点和边。
交通数据、社交媒体网络数据就是这类数据的典型例子。在社交媒体网络中,每个用户与其他用户之间都存在关联关系,使用图结构能够很直观地将这种数据可视化呈现出来。
图主要分为两种类型:
- 有向图:在有向图中,边是有方向的,它表示节点之间的流向或关系。比如在社交媒体上的“关注”关系,就可以用有向图来表示。
- 无向图:无向图中的边没有方向,代表着对称关系。像领英上的“连接”关系,就是无向图的体现。
4.2 关键概念
4.2.1 图结构
LangGraph 设计的核心,是用基于图的方式来表示应用程序的工作流程。这个图主要包含两个基本元素:
- 节点——工作的基本单元:LangGraph 中的每个节点,都代表着应用程序中一个独立的工作或操作单元。这些节点本质上是用 Python 编写的函数,封装了特定的任务。这些任务涵盖范围很广,例如:
- 与 LLM 直接通信,进行文本生成、摘要提取或其他基于语言的任务。
- 与外部工具和 API 交互,获取数据或在现实场景中执行操作。
- 通过格式化、过滤、转换等操作处理数据。
- 与用户进行交互,收集用户输入或展示信息。
- 边——信息流和控制的引导者:边在 LangGraph 中就像连接组织一样,为信息流构建路径,并决定操作的执行顺序。LangGraph 支持多种类型的边:
- 简单边:简单边表示从一个节点到另一个节点的直接、无条件的信息流。前一个节点的输出会直接作为后一个节点的输入,形成线性的处理流程。
- 条件边:条件边为工作流程引入了动态特性,它能让工作流根据特定节点的操作结果进行分支。比如,根据用户的回复内容,图结构可以决定是终止交互,还是继续调用某个工具。这种决策能力对于开发能够适应不同场景的应用程序至关重要。
4.2.2 状态管理
管理多 Agent 系统时,确保所有 Agent 对任务当前状态有一致的理解是非常关键的。LangGraph 通过自动状态管理机制解决了这个问题。这意味着,当 Agent 执行任务时,该库会自动对中央状态对象进行跟踪和更新。
这个状态对象就像是一个信息仓库,存储着工作流程中不同节点都可能需要访问的关键信息,主要包括:
- 对话历史:在聊天机器人应用里,状态可以记录用户和机器人之间的实时对话内容,这样机器人就能根据上下文给出更合适的回复。
- 上下文数据:与当前任务相关的信息,比如用户偏好、过往行为数据,或者相关的外部数据等,都可以存储在状态中,供 Agent 在决策时参考。
- 内部变量:Agent 可以利用状态来记录内部标志、计数器或其他变量,这些变量会影响 Agent 的行为和决策。
5. 动手使用 LangGraph
5.1 安装
要开始使用 LangGraph,首先需要进行安装。在终端或命令提示符中,输入以下命令:
pip install -U langgraph
这个命令会下载并安装最新版本的 LangGraph。其中,-U
参数用于确保安装的是最新版。
5.2 在 LangGraph 中创建基本聊天机器人
这个示例是帮助大家理解 LangGraph 基本概念的绝佳起点。
- 导入必要的库:首先,从 LangGraph 和其他相关库中导入所需的类和模块。
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
- 定义状态结构:创建一个类,用于定义状态对象的结构。这个状态对象将存储图中节点之间需要共享和更新的信息。
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
- 初始化 LLM:实例化你选择的 LLM 模型,并提供必要的 API 密钥或配置参数。这个 LLM 将为聊天机器人的回复提供支持。
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
- 创建聊天机器人节点:定义一个 Python 函数,封装聊天机器人节点的逻辑。该函数以当前状态作为输入,并根据 LLM 的输出生成回复。
def chatbot(state: State):
response = llm.invoke(state["messages"])
return {"messages": [response]}
graph_builder.add_node("chatbot", chatbot)
- 定义入口和终点:在图中明确工作流程的起始点和结束点。
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
- 编译图形:通过编译,创建图的可运行实例。
graph = graph_builder.compile()
- 可视化图形:运行一段简单的 Python 代码,就能将包含节点和边的图可视化展示出来。
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
pass
- 运行聊天机器人:实现一个循环,用于与用户交互。将用户输入传递给图,并展示聊天机器人的回复。
while True:
user_input = input("User: ")
if user_input.lower() in ["quit", "exit", "q"]:
print("Goodbye!")
break
for event in graph.stream({"messages": [("user", user_input)]}):
for value in event.values():
print("Assistant:", value["messages"][-1].content)
这段代码为 LangGraph 聊天机器人搭建了一个基础框架。你可以在此基础上进一步扩展,比如引入更复杂的状态管理机制、更换不同的 LLM 模型,或者连接外部工具和 API。关键在于,要为不同任务定义清晰的节点,并通过边来设定聊天机器人内部的信息流和控制流程。
5.3 高级图形技术
工具集成:将工具集成到 LangGraph 聊天机器人中,可以让它按照你的需求访问和处理信息,从而显著提升其功能。
使用工具集成增强我们的基本聊天机器人:我们对上一节创建的基本聊天机器人进行修改,添加一个能在网络上搜索信息的工具。这里我们使用langchain_community.tools.tavily_search
中的TavilySearchResults
工具,使用这个示例需要 Tavily API 密钥。
from typing import Annotated
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
tool = TavilySearchResults(max_results=2)
tools = [tool]
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
llm_with_tools = llm.bind_tools(tools)
def chatbot(state: State):
return {"messages": [llm_with_tools.invoke(state["messages"])]}
graph_builder.add_node("chatbot", chatbot)
tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges(
"chatbot",
tools_condition,
graph_builder.add_edge("tools", "chatbot")
)
graph_builder.set_entry_point("chatbot")
graph = graph_builder.compile()
解释:
- 导入工具:导入所需的工具类,在这个例子里是
TavilySearchResults
。 - 定义和绑定工具:创建工具实例,并使用
llm.bind_tools()
将其绑定到 LLM 上。这样 LLM 就能知道有哪些可用工具以及如何使用它们。 - 创建 ToolNode:实例化一个
ToolNode
,并传入可用工具列表。 - 将 ToolNode 添加到图中:使用
graph_builder.add_node()
把ToolNode
添加到 LangGraph 中。 - 条件路由:利用
graph_builder.add_conditional_edges()
,根据 LLM 是否决定调用工具来设置路由逻辑。tools_condition
函数会检查 LLM 的回复中是否包含工具调用指令。 - 循环返回:工具执行完成后,使用
graph_builder.add_edge()
将流程引导回聊天机器人节点,以便对话能够继续进行。
现在,当你运行这个聊天机器人,并提出一个需要外部信息的问题时,LLM 可以选择调用网络搜索工具,获取相关数据,并将其融入到回复中。
6. 为聊天机器人添加 memory
记忆对于创建聊天机器人至关重要,这些聊天机器人可以通过记住过去的互动来进行有意义的对话。
LangGraph 的检查点系统
- 检查指针:当你编译你的 LangGraph 时,你可以提供一个检查指针对象。该对象负责保存图在不同时间点的状态。
- 线程 ID:每次调用图时,都提供一个 thread_id。检查指针使用此 ID 来跟踪不同的对话线程。
- 自动保存和加载:LangGraph 自动保存给定 thread_id 的图执行的每一步后的状态。当您再次使用相同的 thread_id 调用图时,它会自动加载保存的状态,使聊天机器人能够从中断的地方继续对话。
使用检查点实现内存
在前面代码的基础上,以下是如何使用 LangGraph 的检查点添加内存:
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
graph = graph_builder.compile(checkpointer=memory)
解释:
- 导入 MemorySaver:从
langgraph.checkpoint.memory
导入MemorySaver
类。 - 创建一个 MemorySaver 对象:实例化一个 MemorySaver 对象,它将处理保存和加载图的状态。
- 传递给 compile():编译图时,将 memory 对象作为 checkpointer 参数传递。
现在,当您运行聊天机器人时,首先,使用 thread_id 作为此对话的密钥:
config = {"configurable": {"thread_id": "1"}}
每个唯一的 thread_id 都将存储其对话历史记录。
现在开始对话:
while True:
user_input = input("User: ")
if user_input.lower() in ["quit", "exit", "q"]:
print("Goodbye!")
break
for event in graph.stream({"messages": [("user", user_input)]}, config):
for value in event.values():
print("Assistant:", value["messages"][-1].content)
注意:调用我们的图时,配置作为第二个位置参数提供。
Human in the Loop
对于希望将人工监督、验证或决策纳入 AI 应用程序的情况,人在回路工作流至关重要。
使用中断实现人在环
下面的代码说明了使用 LangGraph 的interrupt_before
或interrupt_after
功能的人在循环实现。
from typing import Annotated
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDict
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
tool = TavilySearchResults(max_results=2)
tools = [tool]
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
llm_with_tools = llm.bind_tools(tools)
def chatbot(state: State):
return {"messages": [llm_with_tools.invoke(state["messages"])]}
graph_builder.add_node("chatbot", chatbot)
tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges(
"chatbot",
tools_condition,
graph_builder.add_edge("tools", "chatbot")
)
graph_builder.set_entry_point("chatbot")
memory = MemorySaver()
graph = graph_builder.compile(
checkpointer=memory,
interrupt_before=["tools"],
)
解释:
在此特定示例中,图表将在执行 tools 节点之前暂停。此 tools 节点负责运行 LLM 在轮到它时可能请求的任何工具。通过在这一点上中断,您基本上可以允许人类:
- 批准工具调用:人类可以查看 LLM 想要进行的工具调用及其输入。如果他们认为合适,他们可以简单地允许图形继续,并且工具将被执行。
- 修改工具调用:如果人类看到需要调整 LLM 的工具调用(例如,细化搜索查询),他们可以修改图的状态,然后恢复执行。
- 绕过工具调用:人类可能会决定不需要该工具。也许他们有 LLM 试图查找的答案。在这种情况下,他们可以用适当的信息更新图形状态,LLM 将收到它,就好像工具已经返回了该信息一样。
LangGraph 的实际用途
LangGraph 通过管理状态、协调多个 Agent 并允许人工反馈,让您可以构建比简单的问答机器人更复杂和更具交互性的 AI 系统。以下是可以使用 LangGraph 的一些方式:
- 更聪明的客户服务:想象一个在线购物聊天机器人,它可以记住你过去的订单和偏好。它可以回答有关产品的问题,跟踪您的货物,甚至在需要时将您与人类代表联系起来。
- AI 研究助手:研究项目需要帮助?支持 LangGraph 的助手可以搜索大量学术论文和文章,总结关键发现,甚至帮助您组织笔记。
- 个性化学习:LangGraph 可以为下一代教育平台提供动力。想象一个系统,它能适应你的学习风格,识别你需要额外帮助的领域,并推荐个性化资源。
- 精简的业务:许多业务流程涉及多个步骤和人员。LangGraph 可以自动化这些工作流程的一部分,例如路由文档以供批准、分析数据或管理项目。
这些示例突出了 LangGraph 如何帮助弥合 AI 功能与现实世界情况的复杂性之间的差距。
结论
Agent 框架正在彻底改变人工智能系统的运行方式,使智能、自主的 Agent 能够动态推理、计划和交互。在文章中,我们探讨了 Agent 框架的重要性,介绍了一些最流行的库,并比较了它们的优势。然后,我们深入研究了 LangGraph,了解了它基于图的架构、状态管理和现实世界的应用程序。动手部分展示了如何使用 LangGraph 构建具有内存、人在回路功能和可扩展工作流的人工智能 Agent。
推荐阅读
1. DeepSeek-R1的顿悟时刻是如何出现的? 背后的数学原理
2. 微调 DeepSeek LLM:使用监督微调(SFT)与 Hugging Face 数据
3. 使用 DeepSeek-R1 等推理模型将 RAG 转换为 RAT
4. DeepSeek R1:了解GRPO和多阶段训练
5. 深度探索:DeepSeek-R1 如何从零开始训练
6. DeepSeek 发布 Janus Pro 7B 多模态模型,免费又强大!
评论