人工智能(AI)是一个迅速发展的领域。语言模型已经发展到能够让AI Agent执行复杂任务和做出复杂决策。然而,随着这些Agent的技能不断提升,支持它们的基础设施难以跟上。
LangGraph,这是一个革命性的库,旨在革新AI Agent的 构建和运行时 执行。
LangGraph 提出了一个新的Agent构建和运行时构造范式,它将Agent工作流视为基于循环图拓扑的结构。
LangGraph 是什么
LangChain 的一个重要价值主张是能够轻松创建自定义链。然而,LangChain 缺乏一种简单的方法来在这些链中引入循环。实际上,这些链是有向无环图(DAG)—— 就像大多数数据编排框架一样。
人们构建复杂的LLM应用时常见的一个模式是:在运行时中引入循环。这些循环常常借助LLM来推理循环中的下一步行动。这本质上相当于在for循环中运行LLM。这类系统通常被称为Agent。
最简单的形式是一个有两个步骤的循环:
-
调用LLM确定采取哪些行动,或给用户什么回应
-
执行给定的操作,然后返回到第 1 步
这些步骤会重复,直到生成最终响应。这就是驱动 LangChain核心AgentExecutor 的循环,这是一个非常简单的循环,也最关键,是因为通过它将几乎所有的决策和推理能力交给了LLM。
需要注意的是,这个过程通常需要更多的控制。比如强制Agent首先调用特定工具、对工具的调用方式做更多控制、根据Agent所处的状态做不同的提示等
这些受控的流程,LangChain称之为“状态机”
这些状态机具有循环的能力,然而,在该循环的构造方面,需要一定的人工干预。
LangGraph 是通过将这些状态机指定为图的方式来创建它们。
LangGraph 建立在 LangChain 基础上,并与 LangChain 生态系统完全互操作。它主要通过引入一种简单的方法来创建循环图而增加了新价值。这在创建Agent runtimes是非常有用的。
这种方法使Agent能够展现出比其前辈的线性执行模型更多的可变且细微的行为。利用图论,LangGraph为开发复杂的网络化Agent系统提供了新的途径。
图:一个用于生成代码的LangGraph
一个例子:动态问答系统
场景 :用户可能是一步一步的提供给模型信息,而不是一次性发送所有的信息。
解决方案 :使用循环图:
-
让 LLM 生成初步回答。
-
如果答案不完整或需要更多信息,生成新问题并继续询问用户。
-
直到用户确认问题已解决。
循环图的结构
-
节点(Nodes): 每个节点代表一个具体的任务或操作,比如文本生成、问题回答、数据处理等。
-
边(Edges): 节点之间的连接表示任务执行的先后顺序,可能带有条件判断。
-
循环路径(Looping Path): 当某个节点的输出需要反馈回之前的节点,或需要反复执行时,就会形成循环。
-
终止条件(Stopping Condition): 循环图会设定某种终止条件,例如结果的质量满足要求、达到设定的次数限制,或者外部触发的停止信号。
为什么使用 LangGraph ?
-
灵活性 :随着AI Agent的发展,开发者需要对Agent运行时进行更多控制,以实现个性化的行动计划和决策程序。
-
AI推理的循环性质 :许多复杂的LLM应用在使用链式推理等策略时依赖于循环执行。LangGraph 提供了一个自然的框架,用于建模这些循环过程。
-
多智能体系统 :随着多智能体工作流变得越来越普遍,对能够高效管理和协调多个自主智能体的系统的需求也在增加。
使用代码来看 LangGraph 如何工作
LangGraph 的功能基于几个基本元素:
-
Nodes: 这些是函数或Agent的工具。
-
Edges: 定义Agent系统中执行和数据流向的路径,连接节点。
-
StateGraph : LangGraph 通过管理和更新状态对象来允许在执行周期之间保持持久数据,数据在节点之间流动。
图:LangGraph的基本工作流程
StateGraph 状态图
StateGraph
是一个表示图的类。您通过传入 state
定义来初始化此类。该状态定义表示一个中心状态对象,随着时间的推移不断更新。此状态由图中的节点更新,节点以键值存储的形式返回对该状态属性的操作。
import os # 导入操作系统模块 os.environ['OpenAI_API_KEY'] = 'hk-iwtbi1e427' 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 的类型为“list”。Annotated中的“add_messages” 定义了如何更新messages # 在本例中,messages是追加到list中的,而不是覆盖 messages: Annotated[list, add_messages] # 创建StateGraph的实例,传入State类 graph_builder = StateGraph(State)
Nodes 节点
创建一个 StateGraph
后,可以使用 graph.add_node(name, value)
语法添加节点。 name
参数是一个字符串,是节点name。 value
参数是一个函数或可运行的 LCEL,将被调用。
这个函数/LCEL 接受一个与 State
对象具有相同形式的字典作为输入,并输出一个使用 State
对象的键来更新的字典。
from langchain_openai import ChatOpenAI # 从langchain_openai模块导入ChatOpenAI llm = ChatOpenAI( # 创建ChatOpenAI的实例 model="gpt-4o-mini", # 指定模型 temperature=0, # 设置温度 base_url="https://api.openai-hk.com/v1"# 设置基础URL ) def chatbot(state: State):# 定义chatbot函数,接受State类型的参数 """ 处理聊天机器人请求并返回消息。 参数: state (State): 包含消息的状态。 返回: dict: 机器人生成的消息的字典。 """ return {"messages": [llm.invoke(state["messages"])]} # 返回包含消息的字典 # 第一个参数是节点name # 第二个参数是被调用的函数或对象 graph_builder.add_node("chatbot", chatbot) # 向图中添加节点,节点名称为"chatbot"
Edges 边
表示其中一个节点始终在另一个节点之后被调用
`# 添加从START到"chatbot"的边 graph_builder.add_edge(START, "chatbot") # 添加从"chatbot"到END的边 graph_builder.add_edge("chatbot", END)`
Compile 编译
定义我们的图形后,我们可以将其编译为可运行的!暴露与 LangChain 相同的方法( .invoke
, .stream
, .astream_log
等),允许以与链相同的方式调用它。
graph = graph_builder.compile() # 编译图
运行
def stream_graph_updates(user_input: str): # 定义stream_graph_updates函数,接受用户输入 """ 使用user_input流式更新图的消息。 参数: user_input (str): 用户输入的消息。 返回: None """ # 遍历图的流事件,传入用户消息以获取模型的响应 for event in graph.stream({"messages": [("user", user_input)]}): # 遍历图的流事件 for value in event.values(): # 遍历事件的值 print("Assistant:", value["messages"][-1].content) # 打印助手的最后一条消息 whileTrue: try: user_input = input("User: ") # 获取用户输入 if user_input.lower() in ["quit", "exit", "q"]: # 检查用户是否想退出 print("Goodbye!") break# 退出循环 # 调用stream_graph_updates函数处理用户输入 stream_graph_updates(user_input) except: # 捕获异常 # fallback if input() is not available user_input = "What do you know about LangGraph?"# 设置默认用户输入 print("User: " + user_input) # 打印用户输入 stream_graph_updates(user_input) # 调用stream_graph_updates函数处理默认输入 break# 退出循环
可视化“图”(可选)
在Jupyter Notebook环境中,可视化“图”
运行效果
像LangGraph这样的框架随着人工智能的发展变得越来越重要。
随着开发者对LangGraph特性的更加熟悉,我们可以期待看到更多先进的AI Agent,它们能够执行更加复杂的任务。
总之,LangGraph在AI Agent开发方面是一个重大的进步。它通过消除早期系统的缺陷,并提供一个用于Agent构建和执行的灵活的、基于图的框架,使开发者能够推动AI Agent的可能性极限。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 的正确特征了。