跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI

LangChain 中基于图论实现多 Agent 的利器:LangGraph

综述由AI生成LangGraph 是基于图论构建的多智能体框架,解决了 LangChain 中 Agent 循环控制黑盒的问题。通过状态机技术,开发者可以精确控制节点执行顺序、工具调用及人机交互。 LangGraph 的核心组件 StateGraph、Node 和 Edge,演示了如何定义状态、添加节点与边,并编译运行图。此外,还探讨了条件边路由机制及与 AutoGen 的对比,为构建复杂 LLM 应用提供了更清晰的逻辑流。

忘忧发布于 2025/2/6更新于 2026/6/623 浏览
LangChain 中基于图论实现多 Agent 的利器:LangGraph

LangGraph 的出现

在 LangChain 框架中,智能体(Agent)从数据结构的角度来讲等同于一个有向无环图(DAG)。这意味着标准的 Chain 在推理过程中无法被循环调用。尽管 AgentExecutor(代理执行器)支持循环逻辑,但它缺乏精确的控制能力,时常导致失控或陷入死循环。

使用 AgentExecutor 实现循环调用大语言模型(LLM)的能力,其调用过程主要有两步:

  1. 通过大模型来决定采取什么行动、使用什么工具,或对用户输出响应。
  2. 执行步骤 1 中的行动,并将结果继续交给大模型来决定下一步操作。

AgentExecutor 存在的问题是决策过程隐藏在背后,过于黑盒,缺乏更精细的控制能力,在构建复杂的 Agent 时受到限制:

  • 难以控制工具的使用顺序。
  • 在执行过程中添加人机交互较为困难。
  • 难以灵活地更换 Prompt 或背后的 LLM。

在 LangChain 中,简单的链不具备循环能力,而 AgentExecutor 调用 Agent 又过于黑盒,因此需要一个具备更精细控制能力的框架来支持复杂场景的 LLM 应用。LangGraph 的出现标志着 LangChain 进入到多智能体框架领域。LangGraph 是基于图论运作的,它提供了一种状态机技术,可驱动循环代理调用,实现有向有环图。因此,LangGraph 有三个关键元素:

StateGraph:状态图

StateGraph 是 LangChain 的一个类,表示图的数据结构并反映其状态,节点会更新图的状态。它是整个图的核心容器。

Node:节点

图中关键元素之一,每个 LangGraph 节点都有一个名称的值,可以是 LangChain 表达式中的函数或者可运行项(Runnable)。每个节点接收一个字典类型的数据(即 State),节点返回具有相同结构的更新状态。有一个名为 END 的特殊节点,用于识别状态机的结束状态。

Edge:边缘

边维系节点之间的关系,分为三种类型:开始边(没有上游节点)、普通边和条件边。

  • 普通边:定义上游节点应始终调用的下游节点。
  • 条件边:通过函数(路由器)来确定下游节点。条件边需要三个元素:
    • 上游节点:边的起点,表示转换的起点。
    • 路由函数:此函数根据返回值有条件的确定应进行转换的下游节点。
    • 状态映射:根据路由函数的返回值,来指定下游节点。它将路由函数有可能的返回值与相应的下游节点相关联。

构建 LangGraph 实例

LangGraph 的状态

类似于状态机(State Machine),由一组状态(State)和状态之间的转换(Transition)组成,用于表示系统在不同状态之间的转换和响应事件的行为。

from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages

class State(TypedDict):
    # Messages have the type "list". The `add_messages` function
    # in the annotation defines how this state key should be updated
    # (in this case, it appends messages to the list, rather than overwriting them)
    messages: Annotated[list, add_messages]

graph_builder = StateGraph(State)

这个状态定义了随时间更新的核心状态对象,它接收一些操作以及属性定义,并且会被节点更新;会在每一个 Node 之间传递不同的状态信息。然后每一个节点会根据自己定义的逻辑去更新这个状态信息。

节点信息

Node 可以是一个 LangChain 的 Runnable 或者是一个可执行的函数,也可以是一个 Graph。构建完成的 Graph 也是一个 LangChain 的 Runnable,这也正是 LangGraph 作为 LangChain 的扩展可以与 LangChain 完美衔接的关键。

添加节点直接使用 Graph 实例中的 add_node 方法添加即可,当然这个节点应当有一个名字:

graph_builder.add_node("node", node)

其中 node 就是 LangChain 的 Runnable 对象或者可执行函数,具体在开发中定义。

绘制图的边

边(Edge)描述的是节点与节点之间的关系,可以是普通的或者是有条件的。它们都有方向,Edge 描述的上游节点与下游节点的关系(开始边除外)。

Edge 的实现由 Graph 实例中的 add_edge 方法添加,同样这个边也有一个名字,这个名字就是节点的名字,代表的是上游节点:

graph_builder.add_edge("node", next_node)

next_node 就是 node 节点的下游节点。

条件边的实现由 Graph 实例中的 add_conditional_edge 进行添加:

graph_builder.add_conditional_edge(
    "node",
    should_continue,
    {
        "end": END,
        "continue": "next_node"
    }
)

should_continue 就是条件边三个组成元素的路由函数了,用于确定下一个的可调用对象是一个或多个节点。

编译图

到现在就完成一个图所需要的基本条件了,这也是一个最简单的 LangGraph 例子。编译图也是由 Graph 实例对象的方法实现:

graph = graph_builder.compile()

编译之后的 graph 是一个 LangChain 的 Runnable 对象,同样具有 .invoke() 和 .stream() 方法,也具备成为一个节点的能力。

由 LangGraph 构建的简单聊天机器人

以下是一个完整的示例,展示了如何构建一个简单的循环聊天机器人:

import os
from dotenv import find_dotenv, load_dotenv

# 加载环境变量
load_dotenv(find_dotenv())
OPENAI_API_BASE = os.environ.get('OPENAI_API_BASE') 
OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY') 

from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI

class State(TypedDict):
    messages: Annotated[list, add_messages]

# 初始化 LLM
llm = ChatOpenAI(model="gpt-3.5-turbo")

def chatbot(state: State):
    # 调用 LLM 生成回复
    response = llm.invoke(state["messages"])
    return {"messages": [response]}

# 构建图
graph_builder = StateGraph(State)
graph_builder.add_node("chatbot", chatbot)

# 设置入口点和结束点
graph_builder.set_entry_point("chatbot")
graph_builder.set_finish_point("chatbot")

# 编译图
graph = graph_builder.compile()

# 运行循环
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 的应用

想要让单个 Agent 干很多活儿,就必须有极强的推理能力以及定义好工具之间的关系,和精确到控制能力。而单个 Agent 的执行过程过于黑盒等问题导致单个 Agent 很难集多种本领于一身,同时 LangChain 却没有一个能实现多 Agent 的方法或者技巧。LangGraph 作为 LangChain 的扩展就可以实现多 Agent(Multi-agent)。

当然,单个 Agent 有单个的好处,分开也有分开的优势。单 Agent 的构建较为简单,不仅编码简单,逻辑也比较清晰。LangGraph 与之相比就太过于复杂了,不仅要有清晰的逻辑关系,还要有一个图的数据流向。构建一个简单的图人脑还是能应对,一旦节点、边多起来了,就需要借助工具进行设计了,在复杂的逻辑链路中抽丝剥茧。

LangGraph 构建多 Agent 在编码的过程中或许会比较难受,但是实现效果不是单个 Agent 能够相比的。

与 AutoGen 的对比

AutoGen 中的多 Agent 是基于会话实现的,通常包含多个 Agent 角色,构建过程要比 LangGraph 简单,侧重于对话管理。与 LangGraph 不同,LangGraph 具有更清晰的逻辑条理,更适合需要精确控制流程、状态持久化和复杂路由的场景。

最佳实践建议

  1. 状态设计:State 的设计应尽量精简,只包含必要的上下文信息,避免状态爆炸。
  2. 错误处理:在节点内部增加 try-except 块,防止因 LLM 异常导致整个图崩溃。
  3. 调试工具:利用 LangGraph 提供的可视化功能(如 graph.get_graph().draw_mermaid_png())来检查图的结构。
  4. 版本迭代:当前的 LangGraph 还处在一个初期发展的阶段,在 LangChain 的后续版本迭代中,Agent 应该会占据一个重要地位。相信在未来的 LangGraph 构建会更容易。

总结

LangGraph 为 LangChain 生态引入了强大的图计算能力,使得开发者能够以状态机的形式构建复杂的 AI 工作流。通过明确定义状态、节点和边,开发者可以获得对 Agent 行为的完全控制权,从而构建出稳定、可解释且易于维护的多智能体系统。对于需要复杂逻辑编排的企业级应用,LangGraph 是目前最理想的解决方案之一。

目录

  1. LangGraph 的出现
  2. StateGraph:状态图
  3. Node:节点
  4. Edge:边缘
  5. 构建 LangGraph 实例
  6. LangGraph 的状态
  7. 节点信息
  8. 绘制图的边
  9. 编译图
  10. 由 LangGraph 构建的简单聊天机器人
  11. 加载环境变量
  12. 初始化 LLM
  13. 构建图
  14. 设置入口点和结束点
  15. 编译图
  16. 运行循环
  17. LangGraph 的应用
  18. 与 AutoGen 的对比
  19. 最佳实践建议
  20. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 医疗大模型商业化现状:应用场景、部署模式与硬件挑战
  • 职场人如何利用 AI 提升效率与创造副业收入
  • Python 入门教程:从基础语法到面向对象编程详解
  • 异步消息队列设计与 Rust 实战集成
  • AI Agent 综述:核心概念、架构设计与开源实践
  • 学术论文降重与 AIGC 检测应对策略指南
  • 基于 DeepFace 和 OpenCV 的情绪分析器
  • 基于 HTML5+CSS3+JavaScript 的高木同学圣诞 GalGame 开发
  • 8 个适合 Python 开发的接单平台及兼职建议
  • ChatGPT-4o 发布:AI 大模型迈入感知时代
  • 大模型基本概念详解:定义、发展、分类与微调技术
  • BFS 解决拓扑排序
  • Python 中使用 HTML 模板的完整指南
  • Spring Boot 整合 Spring Security 构建安全 Web 应用
  • RAG 与微调在大模型应用中的抉择
  • AI 大模型所需的数据类型与质量要求
  • Meta Llama 3.1 70B 与 Mistral Large 2 128B 深度对比
  • 央国企加速布局大模型落地应用
  • Java 实现:统计数组中出现频率最高的元素
  • C++11 新特性(下):Lambda、可变参数模板与包装器

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online