【智能体】从一个聊天工作流了解LangGraph

1. 前言

这篇文章将从如何搭建一个带网络搜索功能的聊天机器人工作流,带你初步了解 LangGraph。

 2. 前提条件

  • 已搭建 Python 开发环境,使用 3.11 以上版本。

  • 已熟悉 Python 基础语法。可参考:【LLM】Python 基础语法_llm python入门-CSDN博客文章浏览阅读1k次,点赞18次,收藏28次。Python 作为最佳的机器学习和深度学习语言,如果你想入门大模型(如 GPT、BERT 等)与自然语言处理(NLP),那么 Python 一定是最佳选择,这篇文章将带你入门Python语法。_llm python入门 https://blog.csdn.net/u013176571/article/details/144773581?spm=1001.2014.3001.5501

3. 什么是LangGraph

LangGraph 是由 LnagChain 创造者 LangChain Inc 开发的一款基于图结构的开源框架,其专注于构建有状态、多角色的应用程序,特别是与大型语言模型(LLMs)一起使用时,用于创建智能体和多智能体工作流。

3.1 为什么选择LangGraph

LangGraph 作为底层基础设施,支持 LLM 应用中的工作流(Workflow)和智能代理(Agentic System),提供持久化、流式处理和调试部署能力,助力构建更强大、更可控的 LLM 应用。其有以下三大核心优势:

1. 持久化(Persistence)  

  • 记忆能力(Memory):支持存储应用状态,实现对话记忆和跨用户交互的状态管理。

  • 人机协作(Human-in-the-loop):状态检查点化,支持执行中断与恢复,便于人工决策、验证和修正。  

2. 流式处理(Streaming)  

  • 支持工作流/代理状态的流式传输,使用户或开发者能在执行过程中获取实时反馈。  

  • 允许流式传输事件(如工具调用反馈)和 LLM 生成的 tokens,以提升交互体验。  

3. 调试与部署(Debugging and Deployment)

  • 通过 LangGraph Platform 提供简便的测试、调试和部署能力。  

  • 通过 LangGraph Studio 提供可视化工作流,支持交互式调试。

  • 提供多种部署选项,方便应用上线。  

3.2 和LangChain的关系

LangGraph 是 LangChain 生态中的一个子项目,专门用于构建图(Graph)结构的 LLM 工作流。它可以被认为是 LangChain 的补充,用于管理复杂的流程控制。它可以独立于LangChain使用。

3.3 LangGraph核心概念

LangGraph 框架中,会将智能体工作流(agent workflows)建模为图(Graphs),构建和运行图(Graphs)有三个核心概念:

1. State(状态):

  • 通常为 TypedDict(字典)或 Pydantic BaseModel(对象), 用于存储图运行时的状态信息。它在图的执行过程中被传递给各个节点和条件函数,用于存储和传递数据。你可以将 State 理解为各节点和条件函数间的上下文。

2. Nodes(节点):

  • 是一个 Python 函数,用来执行特定的操作或逻辑(比如数据处理、调用外部服务等)。节点接收当前的 State 作为入参,在执行一系列业务逻辑后,并返回更新后的 State。

3. Edges(边):

  • 也是一个 Python 函数,用于定义节点之间的连接关系,控制图的执行流程。边可以是无条件的,也可以是条件的。

简而言之,节点用于执行工作,边指示下一步做什么。

4. 聊天机器人实现

4.1 安装LangGraph

这个例子中需要使用 LangChain 构建与大模型对话的 ChatModel,所以我们需要安装 LangChain 相关包。我使用的是 0.3.0 版本。

# 安装 LangChain 和 LangChain OpenAI
pip install langchain==0.3.0 
pip install -U langchain-openai# 安装最新版 LangGraph
pip install -U langgraph# 安装tavily,tavily是一个网络检索工具 
pip install -U tavily-python

4.2 准备工作

4.2.1 选择模型

选择一个支持函数调(Function Calling)用的模型,并创建一个 ChatModel,我使用的是月之暗面的 moonshot-v1-8k 模型。

from langchain_openai import ChatOpenAI# 构建一个chatModel
llm = ChatOpenAI(model="moonshot-v1-8k",openai_api_base="https://api.moonshot.cn/v1",openai_api_key="your_api_key",temperature=0.7,streaming=True,
)

4.2.2 申请tavily秘钥

tavily 是一个网络检索工具,我们需要在tavily官网申请一个秘钥来使用它(tavily 每月免费提供1000条搜索返回)。地址:Tavily AI。

定义 Tavily Search 工具

tavily_tool = TavilySearchResults(# 返回的最大搜索条数max_results=2,tavily_api_key="your_tavily_api_key",
)

4.3 代码实现

4.3.1 流程图

工作流主要包含两个节点和两个条件边:

  • chatbot:聊天节点,负责与 LLM 交互。

  • tools:工具节点,负责调用 Tavily 搜索工具。

  • edge1:条件边(使用虚线表示),LLM会根据用户输入的内容自动判断是否调用tools节点,如果不需要调用会直接返回。

  • edge2:普通边,tools节点完成搜索任务后,返回chatbot节点继续对话。

4.3.2 完整代码

以下是整个带网络搜索功能的聊天机器人的完整代码

from typing import Annotatedfrom langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
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
from typing_extensions import TypedDict# 定义一个状态类型,用于保存工作流中的上下文信息,为 TypedDict 类型
class State(TypedDict):# messages 用于记录与AI对话的记录,为 list 类型# add_messages 用于定义这个值的更新方式,即 将对话消息追加到列表中,而不是覆盖messages: Annotated[list, add_messages]# 定义一个工作流,使用 State 类型作为输入和输出
working_flow = StateGraph(State)# 定义 TavilySearchResults 工具
tavily_tool = TavilySearchResults(max_results=2,tavily_api_key="",
)
# 定义 ChatOpenAI 模型,并绑定工具
llm = ChatOpenAI(model="moonshot-v1-8k",openai_api_base="https://api.moonshot.cn/v1",openai_api_key="",temperature=0.7,streaming=True,
)
# 绑定工具
tools = [tavily_tool]
llm_with_tools = llm.bind_tools(tools)# 聊天节点逻辑
def chatbot(state: State):# 调用大模型,LLM 会自动决定是否调用Tavily工具# 返回值是更新后的聊天记录return {"messages": [llm_with_tools.invoke(state["messages"])]}# 添加节点
working_flow.add_node("chatbot", chatbot)
tool_node = ToolNode(tools=tools)
working_flow.add_node("tools", tool_node)# 添加条件边和普通边
working_flow.add_conditional_edges("chatbot", tools_condition, )
working_flow.add_edge("tools", "chatbot")# 设置起点
working_flow.set_entry_point("chatbot")# 创建MemorySaver,用于存储工作流的对话历史
memory = MemorySaver()
# 编译工作流
graph = working_flow.compile(checkpointer=memory)

4.3.3 运行测试

以下代码用于使用工作流并进行问答:

# 配置参数,包括唯一的线程ID,用于记录对话历史
config = {"configurable": {"thread_id": "1"}}
def stream_graph_updates(user_input: str):# 流式处理图的事件for event in graph.stream({"messages": [{"role": "user", "content": user_input}]},config,):for value in event.values():# 打印助手的回复print("Assistant:", value["messages"][-1].content)while True:try:# 获取用户输入user_input = input("User: ")# 检查退出条件if user_input.lower() in ["quit", "exit", "q"]:print("再见!")break# 调用函数处理用户输入stream_graph_updates(user_input)except KeyboardInterrupt:# 处理用户中断输入的情况print("\n输入被中断,再见!")breakexcept Exception as e:# 捕获其他异常并打印错误信息print(f"发生错误: {e}")break

首先我们先问几个简单的问题,比如“你好”、“你是谁”,这些问题不足以让大模型调用Tavily工具。

然后我们尝试问大模型依据自身无法回答的问题,比如:”南京今天天气如何?“,我们发现大模型自动调用了Tavily工具,接着我们继续问“明天呢”,看看工作流是否具备聊天记忆。

到此为止,一个简单的聊天机器人就完成了。当然 LangGraph 还有很多高级功能,比如人机交互(Humman-in-the-loop)、时间旅行(Time-travel)等,我在之后的文章中会介绍。

5. 参考文档

  • LangGraph Home

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA开发:实例成员与静态成员

判断Java中的实例成员与静态成员 在Java中,可以通过以下几种方式判断一个成员是实例成员还是静态成员: 1. 通过声明方式判断 静态成员使用static关键字修饰,实例成员不使用: public class MyClass {// 实例成员int instanceVa…

Softmax 回归 + 损失函数 + 图片分类数据集

Softmax 回归 softmax 回归是机器学习另外一个非常经典且重要的模型,是一个分类问题。 下面先解释一下分类和回归的区别: 简单来说,分类问题从回归的单输出变成了多输出,输出的个数等于类别的个数。 实际上,对于分…

MySQL-存储过程

介绍 基本语法 创建 调用 查看 删除 变量 系统变量 查看 设置 用户定义变量 赋值 使用 局部变量 声明 赋值 流程控制 参数 条件结构 IF case 循环结构 while repeat loop 游标 条件处理程序 介绍 举个简单的例子,我们先select某数据&…

使用 Go 和 Gin 实现高可用负载均衡代理服务器

前言 在现代分布式系统中,负载均衡是保障服务高可用性和性能的核心技术。本文将基于 Go 语言和 Gin 框架实现一个支持动态路由、健康检查、会话保持等特性的企业级负载均衡代理服务器,并提供完整的压力测试方案和优化建议。 通过本方案实现的负载均衡代理具备以下优势: 单…

在 Linux(Ubuntu / CentOS 7)上快速搭建我的世界 MineCraft 服务器,并实现远程联机,详细教程

Linux 部署 MineCraft 服务器 详细教程(丐版,无需云服务器) 一、虚拟机 Ubuntu 部署二、下载 Minecraft 服务端三、安装 JRE 21四、安装 MCS manager 面板五、搭建服务器六、本地测试连接七、下载樱花,实现内网穿透,邀…

批量取消 PDF 文档中的所有超链接

在 PDF 文档中我们可以插入各种各样的文本也可以给文本设置字体,颜色等多种样式,同时还可以给文字或者图片添加上超链接,当我们点击超链接之后,就会跳转到对应的网页。有时候这会对我们的阅读或者使用形成一定的干扰,今…

Ubuntu xinference部署本地模型bge-large-zh-v1.5、bge-reranker-v2-m3

bge-large-zh-v1.5 下载模型到指定路径: modelscope download --model BAAI/bge-large-zh-v1.5 --local_dir ./bge-large-zh-v1.5自定义 embedding 模型,custom-bge-large-zh-v1.5.json: {"model_name": "custom-bge-large…

Vue的实例

Every Vue application starts with a single Vue component instance as the application root. Any other Vue component created in the same application needs to be nested inside this root component. 每个 Vue 应用都以一个 Vue 组件实例作为应用的根开始。在同一个应…

Linux学习笔记(应用篇三)

基于I.MX6ULL-MINI开发板 LED学习GPIO应用编程输入设备 开发板中所有的设备(对象)都会在/sys/devices 体现出来,是 sysfs 文件系统中最重要的目录结构 /sys下的子目录说明/sys/devices这是系统中所有设备存放的目录,也就是系统中…

【图论】网络流算法入门

(决定狠狠加训图论了,从一直想学但没启动的网络流算法开始。) 网络流问题 • 问题定义:在带权有向图 G ( V , E ) G(V, E) G(V,E) 中,每条边 e ( u , v ) e(u, v) e(u,v) 有容量 c ( u , v ) c(u, v) c(u,v)&am…

递归、搜索与回溯第四讲:floodfill算法

递归、搜索与回溯第四讲:floodfill算法 1.Floodfill算法介绍2.图像渲染3.岛屿数量4.岛屿的最大面积5.被围绕的区域6.太平洋大西洋水流问题7.扫雷游戏8.衣橱整理 1.Floodfill算法介绍 2.图像渲染 3.岛屿数量 4.岛屿的最大面积 5.被围绕的区域 6.太平洋大西洋水流问题…

【深度学习与实战】2.3、线性回归模型与梯度下降法先导案例--最小二乘法(向量形式求解)

为了求解损失函数 对 的导数,并利用最小二乘法向量形式求解 的值‌ 这是‌线性回归‌的平方误差损失函数,目标是最小化预测值 与真实值 之间的差距。 ‌损失函数‌: 考虑多个样本的情况,损失函数为所有样本的平方误差之和&a…

气象可视化卫星云图的方式:方法与架构详解

气象卫星云图是气象预报和气候研究的重要数据来源。通过可视化技术,我们可以将卫星云图数据转化为直观的图像或动画,帮助用户更好地理解气象变化。本文将详细介绍卫星云图可视化的方法、架构和代码实现。 一、卫星云图可视化方法 1. 数据获取与预处理 卫星云图数据通常来源…

浏览器渲染原理与优化详解

一、浏览器渲染基础原理 浏览器渲染流程主要包括以下步骤(也称为"关键渲染路径"): 构建DOM树:将HTML解析为DOM(文档对象模型)树构建CSSOM树:将CSS解析为CSSOM(CSS对象模…

基于Spring Boot的成绩管理系统后台实现

下面是一个完整的成绩管理系统后台实现,使用Spring Boot框架,包含学生管理、课程管理和成绩管理功能。 1. 项目结构 src/main/java/com/example/grademanagement/ ├── config/ # 配置类 ├── controller/ # 控制器 ├── dto/ …

实现极限网关(INFINI Gateway)配置动态加载

还在停机更新 Gateway 配置,OUT 了。 今天和大家分享一个 Gateway 的功能:动态加载配置(也称热更新或热加载)。 这个功能可以在 Gateway 不停机的情况下更新配置并使之生效。 配置样例如下: path.data: data path.…

Mean Shift 图像分割与 Canny 边缘检测教程

1. Mean Shift 简介 Mean Shift 是一种聚类算法,通过寻找图像中颜色相似的区域来实现分割。它非常适合用于场景分割或物体检测等任务。本教程将它与 Canny 边缘检测结合,突出分割区域的边界。 2. 图像分割流程 我们将按照以下步骤完成图像分割和边缘检…

Day15 -实例 端口扫描工具 WAF识别工具的使用

一、端口扫描工具 1、zenmap 我这里user是汉字名,没有解析成功。等后续换一个英文账户试一试。 魔改kali的nmap nmap -p8000-9000 8.140.159.19 2、masscan cmd启动,拖入exe文件。然后先写ip,会报错给提示 寻路犬系统 我们去找一下他的…

如何解决高并发场景下的性能瓶颈?实践分享

解决高并发性能瓶颈的核心方法包括优化系统架构、合理使用缓存技术、数据库优化及扩展策略、负载均衡设计。 其中,优化系统架构是根本解决性能问题的关键所在。良好的系统架构能够有效支撑业务高效稳定运行,避免性能瓶颈带来的损失。企业可通过微服务架构…

自动驾驶背后的数学:ReLU,Sigmoid, Leaky ReLU, PReLU,Swish等激活函数解析

随着自动驾驶技术的飞速发展,深度学习在其中扮演着至关重要的角色。而激活函数作为神经网络中的关键组件,直接影响着模型的性能和效果。前面几篇博客 自动驾驶背后的数学:特征提取中的线性变换与非线性激活 , 「自动驾驶背后的数学&#xff1…