当前位置: 首页 > news >正文

LangGraph系列教程:基于状态构建上下文感知的AI系统

本文深入探讨LangGraph中的“状态”概念及其在AI工作流中的核心作用。通过基础状态(如计数器)和复杂状态(含消息历史)的定义,结合代码示例,演示如何通过函数式编程实现状态的不可变修改。然后进一步解析了如何构建简单和复杂的工作流图(Workflow),并以实际案例(如设备预测性维护、对话机器人)说明状态管理的实际应用。附带的完整Python代码提供了可落地的操作模板,适合开发者快速掌握LangGraph的状态管理机制。

LangGraph的状态是什么?

LangGraph 已成为创建循环代理式人工智能工作流的强大工具。LangGraph 中的一个关键概念是“状态”这一理念——它是基本的构建模块,使我们的 AI 系统能够在整个流程中保持和处理信息。

在AI系统处理数据时,LangGraph中的状态是一种维护和跟踪信息的方法。可以把它想象成系统的内存,允许它在工作流或图形的不同阶段移动时记住和更新信息。
在这里插入图片描述

基本状态定义

让我们从LangGraph中最简单的状态形式开始:

from typing import TypedDictclass BasicState(TypedDict):count: int

这个基本状态定义创建了一个简单的结构,它可以保存单个整数值,也可以是任何值。虽然看起来很简单,但这种类型的状态在许多情况下都非常有用,例如:

  • 跟踪对话中的回合数
  • 统计特定事件的发生次数
  • 维持一个简单的分数、指标或AI输出

复杂状态结构

当我们进入更现实的应用程序时,我们通常需要更复杂的状态结构。LangGraph允许我们创建可以保存各种类型信息的复杂状态:

from typing import TypedDict, Annotated
from langchain_core.messages import HumanMessage, AIMessageclass ComplexState(TypedDict):count: intmessages: Annotated[list[HumanMessage | AIMessage], add_messages]

这个复杂的状态不仅跟踪计数,而且还维护消息列表。Annotated类型提供了LangGraph用于特殊处理消息列表(元组)的附加元数据。这个结构特别适用于:

  • 需要记住对话历史的聊天机器人
  • 在多个交互中维护上下文的人工智能助手
  • 需要跟踪定量(计数)和定性(消息)数据的系统

状态修改函数

一旦我们定义了状态结构,我们就需要修改它们的方法。在LangGraph中,我们通常创建新的状态对象,而不是修改现有的状态对象,并遵循不变性原则:

def increment_count(state: BasicState) -> BasicState:return BasicState(count=state["count"] + 1)def add_message(state: ComplexState, message: str, is_human: bool = True) -> ComplexState:new_message = HumanMessage(content=message) if is_human else AIMessage(content=message)return ComplexState(count=state["count"],messages=state["messages"] + [new_message])

这些函数演示了我们如何:

  • 在我们的基本状态增加计数器
  • 向我们的复杂状态添加新消息,区分人类和AI消息
  • 创建反映这些变化的新状态对象

简单图状态

现在我们已经了解了state的基础知识以及如何修改它,让我们看看如何在LangGraph中使用state:

from langgraph.graph import StateGraph, ENDdef create_simple_graph():workflow = StateGraph(BasicState)def increment_node(state: BasicState):return {"count": state["count"] + 1}workflow.add_node("increment", increment_node)workflow.set_entry_point("increment")workflow.add_edge("increment", END)return workflow.compile()

这个简单的图表展示了LangGraph工作流的基本结构:

  1. 我们使用BasicState创建一个StateGraph。
  2. 我们定义了一个节点函数(increment_node)来修改状态。
  3. 我们将这个节点添加到图中,并将其设置为入口点。
  4. 我们从我们的节点到图的END创建一条边。
  5. 最后,我们编译我们的工作流。

虽然这个图看起来很基本,但它可以作为更复杂工作流的基础。

复杂图状态

基于我们对简单图形的理解,让我们创建一个更高级的工作流:

def create_complex_graph():workflow = StateGraph(ComplexState)def process_message(state: ComplexState):last_message = state["messages"][-1].content if state["messages"] else "No messages yet"response = f"Received: {last_message}. Count is now {state['count'] + 1}"return {"count": state["count"] + 1,"messages": state["messages"] + [AIMessage(content=response)]}workflow.add_node("process", process_message)workflow.set_entry_point("process")workflow.add_edge("process", END)return workflow.compile()

这个更复杂的图表展示了我们如何:

  • 使用我们的ComplexState来维护计数和消息历史
  • 处理传入消息并生成响应
  • 在每一步用新的信息更新我们的状态

这种类型的图形可以构成一个简单的聊天机器人或人工智能助手的基础,展示了LangGraph中状态的强大和灵活性。

在LangGraph中理解和有效地使用状态为创建复杂的、上下文感知的人工智能系统开辟了一个可能性的世界。从简单的计数器到复杂的会话代理,状态的概念允许我们构建可以轻松处理多步骤流程的人工智能工作流。

完整实战案例

改示例是使用 LangGraph实现状态管理的完整教学示例,包含 状态定义状态修改函数图(workflow)构建 的核心逻辑。

from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_core.messages import HumanMessage, AIMessage# Step 1: Basic State Definition
class BasicState(TypedDict):count: int# Step 2: More Complex State
class ComplexState(TypedDict):count: intmessages: Annotated[list[HumanMessage | AIMessage], add_messages]# Step 3: State Modification Functions
def increment_count(state: BasicState) -> BasicState:return BasicState(count=state["count"] + 1)def add_message(state: ComplexState, message: str, is_human: bool = True) -> ComplexState:new_message = HumanMessage(content=message) if is_human else AIMessage(content=message)return ComplexState(count=state["count"],messages=state["messages"] + [new_message])# Step 4: Simple Graph with State
def create_simple_graph():workflow = StateGraph(BasicState)def increment_node(state: BasicState):return {"count": state["count"] + 1}workflow.add_node("increment", increment_node)workflow.set_entry_point("increment")workflow.add_edge("increment", END)return workflow.compile()# Step 5: More Complex Graph with State
def create_complex_graph():workflow = StateGraph(ComplexState)def process_message(state: ComplexState):last_message = state["messages"][-1].content if state["messages"] else "No messages yet"response = f"Received: {last_message}. Count is now {state['count'] + 1}"return {"count": state["count"] + 1,"messages": state["messages"] + [AIMessage(content=response)]}workflow.add_node("process", process_message)workflow.set_entry_point("process")workflow.add_edge("process", END)return workflow.compile()# Interactive Session
def run_interactive_session():print("Welcome to the Interactive LangGraph State Lesson!")print("\nStep 1: Basic State")basic_state = BasicState(count=0)print(f"Initial basic state: {basic_state}")print("\nStep 2: More Complex State")complex_state = ComplexState(count=0, messages=[])print(f"Initial complex state: {complex_state}")print("\nStep 3: State Modification")modified_basic = increment_count(basic_state)print(f"Modified basic state: {modified_basic}")modified_complex = add_message(complex_state, "Hello, LangGraph!")print(f"Modified complex state: {modified_complex}")print("\nStep 4: Simple Graph with State")simple_graph = create_simple_graph()result = simple_graph.invoke(BasicState(count=0))print(f"Simple graph result: {result}")print("\nStep 5: Complex Graph with State")complex_graph = create_complex_graph()initial_state = ComplexState(count=0, messages=[HumanMessage(content="Hello, LangGraph!")])result = complex_graph.invoke(initial_state)print(f"Complex graph result: {result}")if __name__ == "__main__":run_interactive_session()

这段代码是使用 LangGraph(一个开源框架)实现状态管理的完整教学示例,包含 状态定义状态修改函数图(workflow)构建 的核心逻辑。以下是逐段详细解释:

在这里插入图片描述

1. 导入必要的模块

from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_core.messages import HumanMessage, AIMessage
  • TypedDict: 定义结构化的字典类型(类似数据类)。
  • Annotated: 类型注解工具,用于增强类型约束(如 messages 字段必须包含特定类型的消息)。
  • StateGraph, END: LangGraph 核心组件,用于构建状态图。
  • add_messages: 装饰器,标记可添加消息的字段。
  • HumanMessage, AIMessage: 表示人类用户消息和 AI 生成的响应消息。

2. 定义基本状态(BasicState)

class BasicState(TypedDict):count: int
  • 简单状态类,仅包含一个整数 count,用于演示基础状态管理。

3. 定义复杂状态(ComplexState)

class ComplexState(TypedDict):count: intmessages: Annotated[list[HumanMessage | AIMessage], add_messages]
  • 复杂状态类,包含:
    • count: 整数计数器。
    • messages: 一个消息列表,存储交互记录(人类消息或 AI 响应)。
    • Annotated[list[...], add_messages]: 类型注解,强制 messages 字段遵循 LangGraph 的消息规范。

4. 状态修改函数

(1) increment_count 函数
def increment_count(state: BasicState) -> BasicState:return BasicState(count=state["count"] + 1)
  • 输入一个 BasicState,将 count 加 1 并返回新状态。
(2) add_message 函数
def add_message(state: ComplexState, message: str, is_human: bool = True) -> ComplexState:new_message = HumanMessage(content=message) if is_human else AIMessage(content=message)return ComplexState(count=state["count"],messages=state["messages"] + [new_message])
  • 输入 ComplexState 和消息内容,根据 is_human 参数判断消息类型(人类或 AI),将新消息追加到 messages 列表中。

5. 构建简单状态图(create_simple_graph)

def create_simple_graph():workflow = StateGraph(BasicState)def increment_node(state: BasicState):return {"count": state["count"] + 1}workflow.add_node("increment", increment_node)workflow.set_entry_point("increment")workflow.add_edge("increment", END)return workflow.compile()
  • 目标: 创建一个仅包含 count 增加的简单流程。
  • 节点 (increment_node): 处理输入状态,将 count +1。
  • 入口点: 默认从 increment 节点开始。
  • : 直接连接到结束节点 END
  • 编译: 将流程图转换为可执行的逻辑。

6. 构建复杂状态图(create_complex_graph)

def create_complex_graph():workflow = StateGraph(ComplexState)def process_message(state: ComplexState):last_message = state["messages"][-1].content if state["messages"] else "No messages yet"response = f"Received: {last_message}. Count is now {state['count'] + 1}"return {"count": state["count"] + 1,"messages": state["messages"] + [AIMessage(content=response)]}workflow.add_node("process", process_message)workflow.set_entry_point("process")workflow.add_edge("process", END)return workflow.compile()
  • 目标: 创建处理消息并维护对话历史的复杂流程。
  • 节点 (process_message):
    • 读取当前最新消息(last_message)。
    • 生成响应(包含 count +1 的结果)。
    • 更新 count 和追加 AI 响应到 messages
  • 流程: 每次调用 process 节点后直接结束。

7. 交互式会话运行

def run_interactive_session():print("Welcome to the Interactive LangGraph State Lesson!")# 分步骤演示 BasicState 和 ComplexState 的操作# ...(省略中间打印语句)# 调用简单图和复杂图simple_result = simple_graph.invoke(BasicState(count=0))complex_result = complex_graph.invoke(ComplexState(count=0, messages=[HumanMessage(content="Hello, LangGraph!")]))print(f"Simple graph result: {simple_result}")print(f"Complex graph result: {complex_result}")
  • 功能: 运行教学示例,展示不同状态和流程的实际效果。
  • 简单图调用: 初始状态为 count=0,执行后结果为 count=1
  • 复杂图调用: 初始包含一条人类消息,处理后生成 AI 响应并更新 count

最后总结

LangGraph的状态管理是其构建上下文感知AI系统的核心机制。状态作为系统“内存”,贯穿工作流始终,确保信息在不同阶段间连贯传递。通过TypedDict定义结构化状态(如BasicState追踪计数、ComplexState维护消息历史),开发者能够灵活处理简单数值统计与多模态交互场景。状态的修改遵循函数式编程原则——每次操作均生成新状态对象而非直接修改旧状态,保障数据一致性与可追溯性。

实际应用中,开发者可通过构建简单图(如计数器递增)验证基础逻辑,再进阶到复杂图(如消息处理与动态响应),模拟对话机器人或自动化流程。例如,制造业中的设备预测性维护场景中,状态可整合设备运行数据与历史故障记录,驱动智能决策;而政务服务领域的政策咨询机器人则依赖状态维护用户提问轨迹与政策匹配结果。代码实践部分通过完整的Python示例(包括基础/复杂状态定义、工作流构建与交互式运行),为开发者提供了可直接复用的模板,降低了从理论到落地的门槛。

LangGraph的状态管理不仅解决了多步骤流程中的上下文丢失问题,还通过类型注解、不可变状态等设计,增强了系统的可靠性与扩展性,是构建高效AI代理的关键支撑。

相关文章:

LangGraph系列教程:基于状态构建上下文感知的AI系统

本文深入探讨LangGraph中的“状态”概念及其在AI工作流中的核心作用。通过基础状态(如计数器)和复杂状态(含消息历史)的定义,结合代码示例,演示如何通过函数式编程实现状态的不可变修改。然后进一步解析了如…...

图像处理、数据挖掘、数据呈现

目录 图像处理方法 阈值分割 图像处理方法 图像平滑 图像锐化 图像增强 阈值分割 边缘检测 阈值分割 特征提取 提取边界 区域提取 主成分压缩 POI 多源数据 数据挖掘 多源数据提取 关联度提取 位置集群, 新闻事件, 权限 个人喜好 历史…...

利用python和gpt写一个conda环境可视化管理工具

最近在学习python,由于不同的版本之间的差距较大,如果是用环境变量来配置python的话,会需要来回改,于是请教得知可以用conda来管理,但是conda在管理的时候老是要输入命令,感觉也很烦,于是让gpt帮…...

sort_values、sort 和 sorted 的区别与用法详解

sort_values、sort 和 sorted 是 Python 中用于排序的工具,但它们的适用场景和行为有所不同。以下是它们的区别和用法详解: 1. sort_values 适用对象 Pandas 的 Series 或 DataFrame。 功能 对 Pandas 数据结构中的值进行排序。 特点 专为 Pandas 设…...

银行系统功能架构设计元模型

1. 元模型核心目标 ​规范性:定义功能模块的标准化描述方式,便于跨团队协作。​可复用性:抽象通用组件,减少重复开发。​可扩展性:支持未来业务创新和技术升级(如开放银行API集成)。​2. 元模型层级结构 采用分层架构模式,分为以下核心层级: ​**(1) 业务功能层** ​…...

rabbitmq 延时队列

要使用 RabbitMQ Delayed Message Plugin 实现延时队列,首先需要确保插件已安装并启用。以下是实现延时队列的步骤和代码示例。 1. 安装 RabbitMQ Delayed Message Plugin 首先,确保你的 RabbitMQ 安装了 rabbitmq-delayed-message-exchange 插件。你可…...

idea + Docker + 阿里镜像服务打包部署

一、下载docker desktop软件 官网下载docker desktop,需要结合wsl使用 启动成功的画面(如果不是这个画面例如一直处理start或者是stop需要重新启动,不行就重启电脑) 打包成功的镜像在这里,如果频繁打包会导致磁盘空间被占满,需…...

Vue 3 零基础入门:从计数器应用开始你的工程化之旅 - 深入理解 Vue 3 响应式系统

引言 欢迎来到 Vue 3 + 现代前端工程化 系列技术博客! 本系列博客旨在通过每日构建一个小项目,帮助您深入学习 Vue 3 的各项核心特性,并掌握现代前端工程化的实践技能。 在接下来的系列文章中,我们将从零开始,由浅入深,逐步构建一系列实用的小型应用。 今天,作为本系列…...

批量将手机照片修改为一寸白底证件照的方法

生活中经常需要用到一寸白底证件照,但每次去照相馆拍摄既费时又麻烦。其实,利用手机拍照和批量证件照生成工具,就能轻松批量修改手机照片为一寸白底证件照。 首先,在电脑浏览器中打开【报名电子照助手】,找到“批量证件…...

【Docker基础】理解 Docker:本质、性质、架构与核心组件

文章目录 Docker 本质Docker 的引擎迭代Docker 和虚拟机的区别Docker 为什么比虚拟机资源利用率高,速度快?Docker 和 JVM 虚拟化的区别Docker 版本1. LXC (Linux Containers)2. libcontainer3. Moby4. docker-ce5. docker-ee总结: Docker 架构…...

LeetCodehot 力扣热题100 全排列

这段代码的目的是计算给定整数数组的所有全排列(permutations),并返回一个包含所有排列的二维数组。 思路解析 在这段代码中,采用了 深度优先搜索(DFS) 和 回溯 的方法来生成所有的排列。 关键步骤&#xf…...

SQL笔记#数据更新

一、数据的插入(INSERT语句的使用方法) 1、什么是INSERT 首先通过CREATE TABLE语句创建表,但创建的表中没有数据;再通过INSERT语句向表中插入数据。 --创建表ProductIns CREATE TABLE ProductIns (product_id CHAR(4) NOT NULL,product_name VARCHAR(1…...

GCC 和 G++的基本使用

GCC 和 G 命令 GCC 和 G 命令GCC(GNU C 编译器)基本用法常用选项示例 G(GNU C 编译器)基本用法常用选项示例 GCC 与 G 的区别选择使用 GCC 还是 G C编译流程1. 预处理(Preprocessing)2. 编译(Co…...

Maven中一些基础知识点

早些时候只知道创建或者开发springboot项目时候,有一个叫pom.xml的文件可以用来管理项目所需的依赖/第三方工具。 索性稍微深入了解了一下,然后把自己认为重要的记录下来。 首先我们要引入新的依赖自然是在dependencies下写dependency,这个…...

论文阅读笔记:Deep Face Recognition: A Survey

论文阅读笔记:Deep Face Recognition: A Survey 1 介绍2 总览2.1 人脸识别组件2.1.1 人脸处理2.1.2 深度特征提取2.1.3 基于深度特征的人脸对比 3 网络结构和损失函数3.1 判别损失函数的演化3.1.1 基于欧式距离的损失3.1.2 基于角度/余弦边距的损失3.1.3 Softmax损失…...

JVM生产环境问题定位与解决实战(三):揭秘Java飞行记录器(JFR)的强大功能

提到飞行记录器,或许你的脑海中并未立刻浮现出清晰的画面,但一说起“黑匣子”,想必大多数人都能恍然大悟,知晓其重要性及用途。在航空领域,黑匣子作为不可或缺的设备,默默记录着飞行过程中的每一项关键数据…...

爬虫框架与库

爬虫框架与库是用于网络数据抓取的核心工具,帮助开发者高效地从网页中提取结构化数据。 Requests:用于发送HTTP请求。 BeautifulSoup:用于解析HTML和XML。 Scrapy:强大的爬虫框架,适合大规模爬取。 Selenium&#…...

PyTorch常用函数总结(持续更新)

本文主要记录自己在用 PyTorch复现经典模型 过程中遇到的一些函数及用法,以期对 常见PyTorch函数 更加熟练~ 官方Docs:PyTorch documentation — PyTorch 2.6 documentation 目录 数据层面 torch.sign(tensor) torch.tensor(np.eye(3)[y]) torch.on…...

代码异常(js中push)NO.4

1. 环境 Vue3,Element Plsu 2. 示例代码 const { updateBy, updateTime, ...curObj } form.valuecurObj.id props.tableData.length 1var newTableData props.tableData.push(curObj)updateTableData(newTableData)3. 情景描述 newTableData变成了整数&#…...

Anaconda 2025 最新版安装与Python环境配置指南(附官方下载链接)

一、软件定位与核心功能 Anaconda 2025 是Python/R数据科学集成开发平台,预装1500科学计算库,新增AI模型可视化调试、多环境GPU加速等特性。相较于传统Python安装,其优势包括: 环境隔离:通过conda工具实现多版本Pyth…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...