LangGraph之State的定义

在 LangGraph(LangChain 生态中的一个用于构建状态机和有向无环图工作流的库)中,State(状态)是整个工作流的核心数据结构。它用于在节点(Node)之间传递信息、维护上下文,并驱动整个图的执行流程。


LangGraph 中 State 的定义主要有以下几种方式,每种适用于不同的使用场景和复杂度需求:

一、TypedDict(推荐方式)

这是 LangGraph 官方最推荐的方式,尤其适用于 Python 3.8+(需安装typing_extensions)。

特点:

  • 类型安全:通过类型注解明确每个字段的数据类型。
  • 可读性强:清晰地表达状态结构。
  • 支持部分更新(Partial Update):在节点函数中只需返回需要更新的字段,LangGraph 会自动合并到全局状态中。
  • 与 Pydantic 兼容性好(虽然不是必须用 Pydantic)。

示例:

fromtypingimportTypedDict,ListclassAgentState(TypedDict):messages:List[str]current_step:struser_query:strresult:str

然后在构建图时:

fromlanggraph.graphimportStateGraph graph=StateGraph(AgentState)

⚠️ 注意:所有字段都必须有类型注解,否则 LangGraph 无法正确处理状态更新。


为什么推荐使用 TypedDict?

LangGraph 需要知道:

  • 状态有哪些字段?
  • 每个字段的类型是什么?(用于调试、序列化、工具调用等)
  • 哪些字段可以被节点更新?

TypedDict__annotations__属性正好提供了这些元信息:

print(AgentState.__annotations__)# 输出:# {'messages': list[str], 'user_query': str, 'current_step': str, 'result': typing.Optional[str]}

LangGraph 在构建图时会读取这些注解,从而:

  • 验证节点返回的更新是否合法(不能返回未定义的字段)
  • 支持 IDE 自动补全和类型检查(如 PyCharm、VS Code + Pylance)
  • 实现安全的部分状态合并(partial update)

✅ 所有字段都必须有类型注解!否则 LangGraph 会报错或忽略该字段。


messages字段的更新机制

假设我们这样定义状态:

fromtypingimportTypedDict,Annotated,Sequencefromlangchain_core.messagesimportBaseMessageclassState(TypedDict):messages:Annotated[Sequence[BaseMessage],...]# 注意这里用了 Annotated

💡 实际项目中,messages通常用list[BaseMessage]Sequence[BaseMessage],并配合Annotated来定制更新行为。


更新机制 1:覆盖式更新(Replace)

这是默认行为:节点返回一个新列表,完全替换原有messages

defadd_greeting(state:State)->dict:return{"messages":[HumanMessage(content="Hi!")]}

✅ 效果:原 messages 被清空,只保留新列表。
⚠️ 风险:容易丢失历史消息!


更新机制 2:追加式更新(Append)—— 推荐!

LangGraph 支持通过operator.add或自定义 reducer 实现“追加”而非“覆盖”。

方法 A:使用Annotated+operator.add
fromoperatorimportaddfromtypingimportAnnotated,Sequencefromlangchain_core.messagesimportBaseMessageclassState(TypedDict):messages:Annotated[Sequence[BaseMessage],add]

现在,当节点返回{"messages": [new_msg]}时,LangGraph 会执行:

state["messages"]=add(state["messages"],[new_msg])# 等价于:state["messages"] + [new_msg]

✅ 效果:新消息被追加到末尾,历史保留!
✅ 这是构建多轮对话 Agent 的标准做法。

方法 B:自定义 Reducer 函数

可以定义更复杂的合并逻辑:

defmerge_messages(old:list,new:list)->list:# 例如:去重、截断、过滤等combined=old+newreturncombined[-10:]# 只保留最近10条classState(TypedDict):messages:Annotated[list[BaseMessage],merge_messages]

更新机制 3:部分更新 + 追加组合

你可以在一个节点中同时更新多个字段,其中messages追加,其他字段覆盖:

defprocess_step(state:State)->dict:new_msg=AIMessage(content="I'm processing your request.")return{"messages":[new_msg],# 因为用了 Annotated[add],所以是追加"current_step":"processing",# 覆盖"attempts":state.get("attempts",0)+1# 自增}

LangGraph 会分别对每个字段应用其对应的 reducer(默认是覆盖,除非用Annotated指定)。


更新机制 4:空更新或不更新

如果节点不返回messages,则保持原样:

deflog_step(state:State)->dict:print("Current step:",state["current_step"])return{}# messages 不变

最佳实践建议

✅ 1. 始终用Annotated[Sequence[BaseMessage], operator.add]定义 messages

fromtypingimportTypedDict,Annotated,Sequencefromlangchain_core.messagesimportBaseMessagefromoperatorimportaddclassAgentState(TypedDict):messages:Annotated[Sequence[BaseMessage],add]user_input:strstep:str

✅ 2. 节点函数只返回“变化的部分”

不要手动拼接整个 messages 列表,让 LangGraph 处理合并:

# ❌ 不推荐:手动拼接defbad_node(state):return{"messages":state["messages"]+[new_msg]}# ✅ 推荐:只返回新增消息defgood_node(state):return{"messages":[new_msg]}

✅ 3. 使用BaseMessage子类(如HumanMessage,AIMessage

这能让你的消息携带角色信息,便于 LLM 理解上下文:

fromlangchain_core.messagesimportHumanMessage,AIMessage# 在节点中return{"messages":[AIMessage(content="Hello! I'm an AI.")]}

完整示例:带消息追加的简单 Agent

fromtypingimportTypedDict,Annotated,Sequencefromlangchain_core.messagesimportBaseMessage,HumanMessage,AIMessagefromlanggraph.graphimportStateGraph,START,ENDfromoperatorimportaddclassState(TypedDict):messages:Annotated[Sequence[BaseMessage],add]defrespond(state:State)->dict:last_msg=state["messages"][-1].content reply=f"You said:{last_msg}"return{"messages":[AIMessage(content=reply)]}graph=StateGraph(State)graph.add_edge(START,"respond")graph.add_node("respond",respond)graph.add_edge("respond",END)app=graph.compile()# 运行result=app.invoke({"messages":[HumanMessage(content="Hi")]})print(result["messages"])# 输出包含 HumanMessage("Hi") 和 AIMessage("You said: Hi")

总结

关键点说明
TypedDict提供结构化、类型安全的状态定义,是 LangGraph 的基石
Annotated[T, reducer]允许为每个字段定制更新逻辑(如operator.add实现追加)
messages更新默认覆盖,但通过Annotated[..., add]可实现安全追加
节点返回值只需返回变化字段,LangGraph 自动合并

二、Pydantic BaseModel(实验性支持)

虽然 LangGraph 最初是围绕 TypedDict 设计的,但社区和官方也在逐步支持 Pydantic 模型。

特点:

  • 更强大的验证能力(如字段校验、默认值、嵌套模型等)。
  • 支持序列化/反序列化(对持久化状态很有用)。
  • 目前在 LangGraph 中的支持不如 TypedDict 成熟,可能存在兼容性问题(截至 LangGraph v0.1.x)。

示例:

frompydanticimportBaseModelfromtypingimportListclassAgentState(BaseModel):messages:List[str]=[]current_step:str="start"user_query:strresult:str=""

🔍 注意:使用 Pydantic 模型时,某些 LangGraph 功能(如 partial update)可能不会按预期工作,因为 LangGraph 内部依赖dict.update()行为,而 Pydantic 对象不是普通 dict。

建议:除非你有强验证或序列化需求,否则优先使用 TypedDict。


三、普通字典(不推荐)

理论上你可以直接用dict作为状态,但 LangGraph 要求状态类必须可被 introspect(内省),以便知道有哪些字段可以更新。

为什么不推荐?

  • 没有类型提示,容易出错。
  • 无法利用 LangGraph 的自动合并机制(因为不知道哪些是合法字段)。
  • 在大型项目中难以维护。

LangGraph 在内部会检查状态类是否为TypedDict或具有__annotations__,普通 dict 通常会导致运行时错误。


四、自定义类(带__annotations__

如果你不想用 TypedDict,也可以定义一个普通类并手动添加类型注解:

classAgentState:messages:list[str]current_step:struser_query:strresult:str

这种方式在技术上可行,因为 LangGraph 会读取AgentState.__annotations__来获取字段信息。

但存在风险:

  • 缺少 TypedDict 的语义保证(TypedDict 是专为结构化字典设计的)。
  • 无法直接实例化为字典,可能在节点函数中造成混淆。
  • 不符合官方最佳实践。

关键机制:Partial State Updates(部分状态更新)

无论使用哪种方式,LangGraph 的核心优势之一是允许节点只返回状态的一部分,系统会自动 merge 到全局状态中。

例如:

defstep_1(state:AgentState)->dict:return{"current_step":"processed","result":"hello"}

LangGraph 会将返回的 dict 合并到当前 state 中,其他字段保持不变。

✅ 这要求状态定义必须是“字段已知”的结构(如 TypedDict),否则无法安全合并。


总结对比表

方式类型安全部分更新支持官方推荐适用场景
TypedDict绝大多数 LangGraph 项目
Pydantic BaseModel✅✅⚠️(有限)需要强验证或 JSON 序列化的场景
普通dict不推荐
自定义类 + 注解⚠️✅(可能)特殊需求,不建议新手使用

自此,本文分享到此结束!!!

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

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

相关文章

【后端开发面试高频场景题设计题】深度解析(万字干货)| 面试通关必备

文章目录目录一、 前言:场景题&设计题的面试考察逻辑二、 高频场景题深度解析2.1 缓存三大问题:穿透、击穿、雪崩(面试最高频)问题描述分析思路参考答案面试考察点面试追问2.2 分布式事务的解决方案及适用场景问题描述分析思路…

基于MATLAB Simulink Simscape的倒立摆仿真控制器文档详解

MATLAB倒立摆仿真 simulink simscape 控制器 有文档刚上手倒立摆仿真时总觉得这玩意儿像在钢丝上跳舞——明明物理模型不复杂,但控制器稍微不听话整个系统就翻车。好在MATLAB的SimulinkSimScape组合给咱们配了把瑞士军刀,今天咱们边拆解边实操。先打开Si…

c盘红了怎么清理垃圾而不误删,教您一套安全又效率的清理方法!

“这是怎么回事啊?我的电脑C盘怎么爆满了?我记得自己没往C盘放过东西啊?怎么自己就红了啊?我想自己清理一下C盘,但是又不知道该从哪里入手,害怕删错了东西,那可就完犊子了,有谁知道C…

web自动化测试窗口框架与验证码登录处理

前言 selenium的作用域切换 selenium在处理元素时遇见新窗口、网页嵌套网页、网页的原生弹窗,无法进行直接处理作用域里元素的内容,需要通过切换作用域来处理此类问题。 selenium三种作用域切换: ①、window窗口切换 ②、iframe切换 ③、al…

探秘AI应用架构师的智能营销AI决策系统数据分析能力

探秘AI应用架构师的智能营销AI决策系统数据分析能力 1. 引入与连接:智能营销的变革与数据分析的核心作用 1.1 开场故事:营销困境与AI破局 场景: 2023年,某快消品牌市场总监李明正面临一个典型的营销困境——公司投入了数百万营销预算,却无法准确追踪哪些渠道带来了实际…

编程语言最核心的方面是什么?

编程语言最核心的区分要素及原理 编程语言的核心区别主要体现在以下几个方面,每个方面都有其独特的机制和原理: 一、核心区分要素 1. 编程范式 这是最根本的区别,决定语言如何组织和表达逻辑。 实例对比: # Python(多范…

rdd的持久化

在Apache Spark中,RDD(弹性分布式数据集)的持久化(Persistence)是一种优化技术,用于将RDD的计算结果存储在内存或磁盘中,避免重复计算。以下是关键要点:核心作用避免重复计算&#x…

[Windows] 局域网共享精灵v2025.11.10绿色版

[Windows] 局域网共享精灵v2025.11.10绿色版 链接:https://pan.xunlei.com/s/VOiI2bKifFbU2d-SbBTjWrfPA1?pwdpsbj# 局域网共享精灵是一款Windows环境下助力于局域网环境文件共享和打印机共享,帮助您快捷高效的在局域网内实现文件共享和打印机共享的操作&#xf…

强烈安利!继续教育必用TOP10 AI论文工具测评

强烈安利!继续教育必用TOP10 AI论文工具测评 2026年继续教育AI论文工具测评:为何需要这份权威榜单 在当前学术研究日益数字化的背景下,继续教育群体面临着前所未有的挑战。无论是撰写高质量论文,还是高效完成科研任务,…

介电强度试验仪解决材料在高压环境下的绝缘性能评估问题

介电强度试验仪主要解决材料在高压环境下的绝缘性能评估问题,具体包括以下几个方面:1. ‌评估材料的绝缘性能‌核心功能‌:通过施加直流或交流电压,模拟高压环境,测试材料在电场作用下的击穿电压,从而评估其…

UTS API插件,助力uniapp开发者快速实现人脸识别活体检测

HelloKitty-FaceAIFaceAI人脸识别,活体检测UTS API插件,支持iOS,Android 双端,助力uniapp开发者快速实现人脸识别活体检测。 后面我们会支持主题色定制等功能,更多可根据原生工程项目修改升级插件原生工程:…

【Linux命令大全】003.文档编辑之nl命令(实操篇)

【Linux命令大全】003.文档编辑之nl命令(实操篇) ✨ 本文为Linux系统文档编辑与文本处理命令的全面汇总与深度优化,结合图标、结构化排版与实用技巧,专为高级用户和系统管理员打造。 (关注不迷路哈!!&#…

【Linux命令大全】003.文档编辑之od命令(实操篇)

【Linux命令大全】003.文档编辑之od命令(实操篇) ✨ 本文为Linux系统文档编辑与文本处理命令的全面汇总与深度优化,结合图标、结构化排版与实用技巧,专为高级用户和系统管理员打造。 (关注不迷路哈!!&#…

小迪安全2023-2024|第12天-扩展整理:信息打点-Web应用企业产权指纹识别域名资产网络空间威胁情报_笔记|web安全|渗透测试|网络安全_2023-2024

小迪安全2023-2024|第12天:信息打点-Web应用&企业产权&指纹识别&域名资产&网络空间&威胁情报_笔记|web安全|渗透测试|网络安全_2023-2024 一、信息打点概述 在渗透测试和安全评估中,信息收集是整个…

【用友U8cloud】修改Server和Data Source 访问IP地址

访问路径 C:\U8CloudCERP5.1\U8CERP\bin 运行u8SysConfig配置修改完成后,点击保存 运行启动U8cloud这块启动时间稍微长一些,配置好的电脑可能1-3分钟左右,配置不好的可能更长

ITSM 现代化实践与智能化趋势:从传统运维到数智化服务的演进

摘要如今,IT 服务管理(ITSM)已不再仅仅是 IT 部门的内部流程规范,而是企业构建高效、稳定、可持续服务体系的核心支撑。随着云计算、大模型及自动化技术的爆发,传统的“流程驱动”模式正在向“价值驱动”与“智能驱动”…

小迪安全2023-2024|第10天:基础入门-HTTP数据包Postman构造请求方法请求头修改状_笔记|web安全|渗透测试|网络安全_2023-2024

第10天:基础入门-HTTP数据包&Postman构造&请求方法&请求头修改&状_笔记|web安全|渗透测试|网络安全_2023-2024 一、基础入门 1. 请求与返回过程00:25 基本流程:浏览器发送Request请求到服…

小迪安全2023-2024|第11天:基础入门-ChatGPT篇注册体验结合安全融入技术高效赋能拓_笔记|web安全|渗透测试|网络安全

第11天:基础入门-ChatGPT篇&注册体验&结合安全&融入技术&高效赋能&拓_笔记|web安全|渗透测试|网络安全_2023-2024 一、基础入门—ChatGPT篇&注册体验&结合安全&融入技术00:05 1. Cha…

吐血推荐9个AI论文网站,MBA轻松搞定毕业论文!

吐血推荐9个AI论文网站,MBA轻松搞定毕业论文! AI 工具助力论文写作,轻松应对学术挑战 在当前的学术环境中,MBA 学生面临着越来越高的论文要求,从选题到撰写、修改,每一个环节都充满挑战。而 AI 技术的快速发…

ITSM 运维管理平台:企业数字化转型的核心利器

摘要在数字化转型步入深水区的今天,IT 系统已不再是企业的后台辅助工具,而是支撑业务运转的核心引擎。无论是金融高频交易、制造自动生产线,还是互联网的实时交互,IT 系统的稳定性与响应速度直接决定了企业的竞争力和客户口碑。然…