LangGraph概念全解
智能体(Agent)
随着LLM能力不断提升,越来越多系统开始接入LLM,让LLM成为系统中的一个关键组件。大家目前也都习惯把这些应用系统叫做智能体系统(Agentic),究竟什么是智能体系统呢?一个智能体系统应该具备什么能力?总体来说就是:一个系统不再通过硬编码或者规则编码来控制工作流,而是让LLM来决定。
特斯拉的自动驾驶系统早期一直依赖基于规则的算法。整个系统从车辆摄像头获取视觉数据,识别车道标记、行人、车辆、交通信号及8个摄像头范围内的所有事物,再应用一系列规则,比如红灯停、绿灯行、保持在车道线标记正中、不越过双黄线闯入对面车道等等,特斯拉的工程师编写了数十万行C++代码来来应对各种复杂的场景。直到史洛夫找到马斯克提出用AI来解决自动驾驶问题,后来他们发现,直接用AI来实现自动驾驶后,不仅直接可以删除那30多万行代码,而且整体运行速度比之前还快了10倍。
整体来说,Agent目前主要体现在以下几个能力上:
- 工具调用(Tool calling):一般Agent识别用户意图后,常常需要调用工具来执行,获取工具结果
- 采取行动(Action taking):识别用户意图,采取相应的行动,一般包括工具调用
- 记忆(Memory):让Agent拥有记忆能够使得在问题理解上更智能,不那么呆板
- 计划(Planning):智能体能够自己基于问题的复杂度进行规划,拆分成可执行的步骤。
LangGraph的三个核心理念
-
可控制性(Controllability) :
众所周知,LLM的输出不稳定,同样一个问题,大模型都可能采用不同的回复,甚至出现不同的理解,导致结果南辕北辙,如何通过框架设计,让大模型能够可控的输出是非常重要的一项框架能力。
-
人机协同(Human-in-the-Loop)
用过LLM的聊天模型可以发现一个问题,不管你的问题有多简略,大模型都会始终想办法去揣测你的意图,然后一定会给你一些回答。要让Agent像人一样,就应该也能够支持分析用户提问意图,当意图不清晰时,Agent应该能够进一步跟人类进行沟通,澄清,直到完全明白用户的问题后再去执行任务。LangGraph目前根据一些具体场景,支持了该模式。
-
流式输出(Streaming First)
LangGraph认为大模型的处理一般都是IO耗时的任务,所以能够实时看到大模型的输出是非常重要的一个特性。
LangGraph中引入的主要概念
图(Graphs)
LangGraph的核心概念就是把Agent工作流以图的方式进行建模。
Graphs使用以下三个关键组件:
-
状态(State)
状态是一个共享的数据结构,通常是一个TypedDict或者Pydantic的BaseModel类型
-
节点(Nodes)
节点是一个Python函数,接受一个State作为输入,经过内部计算后,返回更新后的State -
边(Edges)
边也是一个Python函数,基于当前State,决定下一步执行哪个/哪一些节点。
LangGraph的图,借鉴于Google的Pregel图计算系统。有兴趣可用了解下。
状态图(StateGraph)
StateGraph是LangGraph主要使用的一个类,这是由用户定义的State对象参数化的。
消息图(MessageGraph)
MessageGraph是Graph的一个特例,Graph的State类是一个消息列表,主要用于聊天型Agent。
状态(State)
通常,定义一个StateGraph前,先要定义一个State。定义一个State一般需要定义它的Schema和reducer函数,reducer函数实现了如何更新状态图的方法。
图的schema会作为所有Node和Edge输入schema。State一般继承一个TypedDict或者Pytdantic类。
以下用一个代码例子来说明:
from typing import TypedDict, Annotated
from operator import add
# 定义一个节点函数
def change_bar(state):
return {
"bar":["bye"]}
# 定义状态
class State(TypedDict):
foo:int
bar:Annotated[list[str],add] #reducer函数为add
from langgraph.graph import StateGraph