前面我们学了LangChain的使用和Agent开发,Langchain是一个线性工作流,如果想要在实际开发复杂的Agent,那么实现非常麻烦,比如可能会遇上一以下一些问题:
- • 当调用某个工具方法出现错误或不是所需要的结果,需要循环调用工具方法直到返回需要的结果
- • 当需要一次任务中,需要保存不同工作节点的状态
- • 当需要调用不同LLM模型时候
- • 当链路中断,需要从上一个工作节点继续执行
- • ......
为了解决这些问题,LangChain抽象出一个高级框架: LangGraph,接下来就开始学习LangGraph的开发。
是什么
LangGraph 是一个用于构建、管理和部署长期运行、有状态代理的低级编排框架,受到塑造代理未来的公司(包括 Klarna、Replit、Elastic 等)的信赖。
主要架构
一个LangGraph有状态(State)、节点(Node)、边(Egde)组成,如下图所示:
LangGraph
- • 状态(State) :可以理解为Agent整体上下文,用于存储Agent运行过程中产生的数据,比如:任务状态、任务结果等
- • 节点(Node) :可以理解为Agent调用的工具或函数,用于表示Agent执行过程中的一个步骤,比如:调用LLM模型、调用Tool API等
- • 边(Edge) :可以理解为Agent执行下一节点所需要执行的逻辑判断, 用于表示节点之间的链接关系,比如:判断是直接返回给用户,还是调用Tool工具
特性
- • 循环和分支:可以实现循环和条件判断
- • 持久性:在LangGraph中的每个节点Node后都会自动保存到状态State中,因此在任何时候暂时或异常中断都可以重新恢复
- • 人机交互:中断当前任务,是否允许当前节点执行还是跳过当前节点执行
- • 流Stream支持:支持流Stream输出
- • LangChain无缝集成:LangGraph、LangChain、LangSimit 无缝集成,无需额外配置
怎么做
安装
# 安装LangGraph LangChain Ollama依赖的大模型
pip install -U langgraph langchain langchain_ollama
Hello World示例
接下来我们尝试实现一个大模型调用日期Tool工具函数,实现获取当前日期的功能。
# 创建一个日期工具函数
from datetime import datetime
from langchain_core.tools import tool
from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage
# graph的各种节点与状态
from langgraph.graph import END, StateGraph, MessagesState
# 持久化状态
from langgraph.checkpoint.memory import MemorySaver
# 调用工具的node节点
from langgraph.prebuilt import ToolNode
#
@tool
def get_current_day():
"""获取今天日期"""
return datetime.now().strftime("%Y-%m-%d")
tools = [get_current_day]
# 创建工具节点
tool_node = ToolNode(tools)
# 绑定工具列表到大模型中
llm = ChatOllama(
base_url="http://localhost:11434",
model="qwen3:32b"
).bind_tools(tools)
# 定义调用LLM大模型Node节点
def call_llm(state: MessagesState):
messages = state['messages']
response = llm.invoke(messages)
return {
"messages": response
}
# 1 定义工作流和初始化状态
workflow = StateGraph(MessagesState)
# 2 添加节点
workflow.add_node("agent", call_llm)
workflow.add_node("tools", tool_node)
# 3 定义工作流入口设定为agent
workflow.set_entry_point("agent")
# 4 添加条件边, agent有条件(是否继续执行函数判断)的流转线
# 定义函数,是否继续执行
def should_continue(state: MessagesState) -> Literal["tools", END]:
messages = state['messages']
# 获取最新的消息 判断是否应该调用工具
last_message = messages[-1]
# LLM调用工具 则转到tools节点
if last_message.tool_calls:
return "tools"
return END
workflow.add_conditional_edges(
# source 表示上一个节点输出的内容
"agent",
# 接下来要执行的判断操作
should_continue,
)
# 5 添加tools到agent的普通链接,直接把tools返回内容给到agent
workflow.add_edge("tools", "agent")
# 6 添加checkpointer 经过每个节点都会保存到状态中,然后编译成LangChain链
# MemorySaver 支持redis、mongodb
checkpointer = MemorySaver()
app = workflow.compile(checkpointer=checkpointer)
# 7 执行graph
final_state = app.invoke(
{"messages": [HumanMessage(content="今天几号")]}
)
# 8 获取最终结果输出
result = final_state["messages"][-1].content
print(result)
执行上面的代码,我们可以获得到当前的日期,结果如下图:
咨询今天日期
多轮会话功能
上面我们实现了让Agent调用工具函数获取当天日期,接下来我们实现通过会话记录,让Agent可以根据之前的记录回答问题。
# 7 执行graph 添加会话id
final_state = app.invoke(
{"messages": [HumanMessage(content="今天几号")]},
# 这里config是配置是不是同一个会话的id
config={"configurable": {"thread_id": 42}}
)
# 8 获取最终结果输出
result = final_state["messages"][-1].content
print(result)
# 9 测试记录会话状态
final_state = app.invoke(
{"messages": [HumanMessage(content="我刚刚问的哪天")]},
config={"configurable": {"thread_id": 42}}
)
result = final_state["messages"][-1].content
print(result)
最终LLM大模型返回结果如下图所示:
多轮会话记录
上面代码执行完后,可以大概LangGraph执行过程有个初步了解,也可以通过生成Meraid Graph图片具体代码如下:
# 10 保存Graph到本地图片
graph_png = app.get_graph().draw_mermaid_png()
with open('langgraph1.png', 'wb') as f:
f.write(graph_png)
最终得到图片,如下图所示:
LangGraph执行流程图
- •
__start__: 代表开始节点,也可以理解成初始化StateGraph工作流 - •
agent: 代表agent节点,设置了入口第一个节点,等同于workflow.add_node("agent") - •
tools: 代表工具节点,设置了工具节点,等同于workflow.add_node("tools", tool_node) - •
实现连接线: 代表当前节点执行完后,无需条件判断,直接流转到下一个节点,等同于workflow.add_edge("tools", "agent") - •
虚线连接线: 代表条件边执行,当前节点执行完后,需要判断是否继续执行,如果继续执行则流转到下一个节点,否则流转到结束节点,等同于workflow.add_conditional_edges("agent", should_continue) - •
_end: 代表结束节点
总结
经过上面学习,总结下本篇文章:
- • LangGraph是LangChain的抽象而来的高级框架,能够实现更加复杂的工作流,如:循环、条件判断、多轮会话等
- • LangGraph的几个核心概念:
State、Node、Edge等作用 - • 一个
HelloWorld的例子,可以看出比LangChain更加简单,加上State多轮会话记录功能,减少开发工作量
原文地址:https://mp.weixin.qq.com/s/Xw6QHYb7ggz-4sRkJfpc6Q