langgraph的 MessagesState 解读
MessagesState是 LangGraph 预置的状态类专门为对话历史 工具调用这类场景设计。它的本质就是一个内置了messages字段、且该字段用add_messages作为 reducer 的TypedDict# MessagesState 在源码中大致等价于classMessagesState(TypedDict):messages:Annotated[list[AnyMessage],add_messages]文章目录一、最基本用法作为 StateGraph 的状态二、add_messages 的三个核心行为三、继承 MessagesState 扩展自定义字段四、多轮对话 记忆持久化五、⚠️ 三个最容易踩的坑这意味着你不用自己写Annotated[...]那串样板直接拿来用就行 。下面把关键用法拆开讲。一、最基本用法作为 StateGraph 的状态fromlanggraph.graphimportStateGraph,START,END,MessagesStatefromlangchain_core.messagesimportHumanMessage,AIMessagedefchatbot_node(state:MessagesState):# 节点内通过 state[messages] 读取完整历史last_user_msgstate[messages][-1]replyf你说了{last_user_msg.content}# 只返回新增的部分框架会用 add_messages 合并return{messages:[AIMessage(contentreply)]}builderStateGraph(MessagesState)builder.add_node(chatbot,chatbot_node)builder.add_edge(START,chatbot)builder.add_edge(chatbot,END)graphbuilder.compile()resultgraph.invoke({messages:[HumanMessage(content你好)]}) 注意MessagesState是状态 schema不是普通的 class 实例。不要写成MessagesState(messages[...])而是在调用图时传{messages: [...]}或继承它来扩展字段 。二、add_messages 的三个核心行为add_messages这个 reducer 决定了messages字段怎么合并它比简单的list list聪明得多 追加新消息没有 id 或 id 不匹配时# 旧: [msg1, msg2] 节点返回 [msg3]# 结果: [msg1, msg2, msg3]按 id 替换已有消息流式输出场景必备fromlangchain_core.messagesimportAIMessagefromlanggraph.graph.messageimportadd_messages existing[AIMessage(content它是5,idmsg-2)]correction[AIMessage(content它是4,idmsg-2)]# 同 idresultadd_messages(existing,correction)# 结果: [AIMessage(content它是4, idmsg-2)]# 长度还是 1没有重复如果换成operator.add错误答案和正确答案会并排在列表里 。用RemoveMessage删除消息裁剪历史以控制 tokenfromlangchain_core.messagesimportRemoveMessage# 节点返回这个id 对应的消息会从列表中移除return{messages:[RemoveMessage(idmsg-2)]}三、继承 MessagesState 扩展自定义字段如果你的 Agent 还需要追踪其他状态当前工具、迭代次数、用户信息等直接继承fromlanggraph.graphimportMessagesStateclassAgentState(MessagesState):current_tool:striteration:intuser_info:dictdefchatbot(state:AgentState):# messages 字段依然享受 add_messages 的全部能力replyAIMessage(content处理中...)return{messages:[reply],current_tool:search,iteration:state[iteration]1}这是多智能体协作、RAG、带业务上下文的对话 Agent 最常用的模式 。四、多轮对话 记忆持久化配合MemorySaver或SqliteSaver做 checkpoint用thread_id区分不同会话fromlanggraph.checkpoint.memoryimportMemorySaver checkpointerMemorySaver()graphbuilder.compile(checkpointercheckpointer)config{configurable:{thread_id:conversation-1}}# 第一轮graph.stream({messages:[{role:user,content:广州天气怎么样}]},config,stream_modevalues)# 第二轮不需要手动拼历史框架自动从 checkpoint 恢复graph.stream({messages:[{role:user,content:那明天呢}]},config,stream_modevalues)messages字段会自动累积thread_id不同的会话互不干扰 。五、⚠️ 三个最容易踩的坑坑 1原地修改state[messages]# ❌ 错误直接 append 会破坏 LangGraph 的不可变更新契约defbad_node(state):state[messages].append(AIMessage(contenthi))return{}# ✅ 正确返回增量让 reducer 合并defgood_node(state):return{messages:[AIMessage(contenthi)]}原地修改会导致浅拷贝下多节点共享引用引发竞态丢失 。坑 2自定义 TypedDict 忘了加add_messagesreducer# ❌ 错误没有 reducer新值会直接覆盖整个列表历史全丢classBadState(TypedDict):messages:list[AnyMessage]# ✅ 正确classGoodState(TypedDict):messages:Annotated[list[AnyMessage],add_messages]这也正是为什么直接用MessagesState更安全 。坑 3条件分支里有的路径返回messages、有的不返回如果route_to_tool分支里工具路径返回了{messages: [...]}而直接响应路径只返回{messages: [ai_msg]}会造成历史断裂。确保所有分支都按统一方式返回消息增量 。总的来说MessagesState就是 LangGraph 给你的一把对话状态瑞士军刀开箱即用管理消息历史、自动处理追加/更新/删除、还能继承扩展。只要是涉及聊天、工具调用、多轮对话的 Agent直接用它就对了只有当你需要非常特殊的合并逻辑比如滑动窗口只保留最近 N 条时才需要回到自定义的TypedDict 自定义 reducer 。如果你是在具体的 Agent 架构里用比如 ReAct Agent、多智能体协作、或者带 RAG 的对话告诉我场景我可以给到更贴合的代码示例。

相关新闻

AI语音克隆准确率突破92.7%?深度拆解5大商用音频模型底层架构与合规红线

AI语音克隆准确率突破92.7%?深度拆解5大商用音频模型底层架构与合规红线

更多请点击: https://kaifayun.com 第一章:AI语音克隆准确率突破92.7%?深度拆解5大商用音频模型底层架构与合规红线 近期多项第三方基准测试(如VCTK-CloneBench v3.1与CommonVoice-ASR-Adversarial)显示,T…

2026/7/24 2:32:34阅读更多 →
LLM垃圾评论检测技术:从文本特征到行为分析的完整防护方案

LLM垃圾评论检测技术:从文本特征到行为分析的完整防护方案

在技术社区分享项目时,很多开发者都遇到过这样的困惑:明明精心准备的 Show HN 帖子,收到的互动却大多来自 LLM 生成的垃圾评论,真实用户的反馈寥寥无几。这种现象不仅影响了开源项目的健康发展,也让技术分享的价值大打…

2026/7/24 2:30:33阅读更多 →
KITTI数据集下载、处理与自动驾驶应用实战

KITTI数据集下载、处理与自动驾驶应用实战

1. KITTI数据集概述与核心价值KITTI数据集作为自动驾驶领域最具影响力的开源基准数据集,由德国卡尔斯鲁厄理工学院和芝加哥丰田技术学院联合发布。这个数据集采集自真实城市道路环境,包含立体视觉图像、激光雷达点云以及高精度GPS/IMU数据的三模态同步数…

2026/7/24 2:30:33阅读更多 →
C++与C#深度对比:内存管理、并发模型与实战选型指南

C++与C#深度对比:内存管理、并发模型与实战选型指南

1. 项目概述:为什么需要对比C与C#? 在技术社区里,关于C和C#孰优孰劣的讨论,几乎每隔一段时间就会掀起一波热潮。新手开发者常常会问:“我该学C还是C#?” 而资深工程师在技术选型时,也免不了要在…

2026/7/24 5:39:26阅读更多 →
mybatis的typeHandler 作用

mybatis的typeHandler 作用

在 MyBatis 中,TypeHandler(类型处理器)扮演着 **“翻译官”** 或 **“桥梁”** 的角色。它的核心作用是:**在 Java 数据类型和 JDBC 数据库数据类型之间进行相互转换。**因为 Java 的类型(如 String, Date, Enum, 自定…

2026/7/24 5:39:26阅读更多 →
深入解析TI BQ28Z610-R1电量计:阻抗追踪算法与智能BMS设计

深入解析TI BQ28Z610-R1电量计:阻抗追踪算法与智能BMS设计

1. 项目概述与核心价值在锂离子电池驱动的设备里,我们最怕两件事:一是用着用着突然没电关机,数据都没来得及保存;二是充电时管理不当,要么充不满影响体验,要么过充引发安全隐患。解决这些问题的核心&#x…

2026/7/24 5:39:26阅读更多 →
为什么92%的AI数字人项目卡在“最后一公里”?——打通CRM/ERP/知识库的4层集成架构图解

为什么92%的AI数字人项目卡在“最后一公里”?——打通CRM/ERP/知识库的4层集成架构图解

更多请点击: https://intelliparadigm.com 第一章:为什么92%的AI数字人项目卡在“最后一公里”? “最后一公里”并非指物理距离,而是从实验室原型到真实业务场景中稳定交付的关键跃迁——它涵盖实时语音驱动唇形同步精度、多模态…

2026/7/24 5:39:26阅读更多 →
从Excel报表到AI智能归因报告:一位CDO的转型实录——含12个真实失败案例、8个可复用指标树与审计留痕规范

从Excel报表到AI智能归因报告:一位CDO的转型实录——含12个真实失败案例、8个可复用指标树与审计留痕规范

更多请点击: https://codechina.net 第一章:从Excel报表到AI智能归因报告:一位CDO的转型实录 当首席数据官李薇第一次在季度经营会上展示“用户转化路径AI归因热力图”时,会议室里安静得能听见空调低鸣。三个月前,她还…

2026/7/24 5:39:26阅读更多 →
计算机毕业设计之基于SpringBoot的母婴用品购物平台设计与实现

计算机毕业设计之基于SpringBoot的母婴用品购物平台设计与实现

本世纪以来,随着越来越多的人使用网络,互联网得到了极大的发展,各种网络资源呈一个爆发性的增长,越来越多的人通过各种各样的网络工具,例如一些专业百度的官网,查询各种各样的信息,为了适应社会…

2026/7/24 5:37:26阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/23 18:58:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/23 18:58:18阅读更多 →