首页 > 基础资料 博客日记
AI开发-python-LangGraph框架(3-30-LangGraph 「追加式消息状态」的原理与实践)
2026-04-22 11:00:05基础资料围观1次
LangGraph 状态管理实战:解锁追加式消息历史,打造流畅对话系统
一、追加式状态:对话系统的核心刚需
- 自动保留完整对话历史,无需手动维护消息列表
- 状态更新极简,节点只需返回新数据,无需处理历史拼接
- 状态流转清晰,符合对话系统的交互逻辑
- 扩展性强,多轮对话、长文本交互都能轻松支持
二、LangGraph 追加式状态的核心实现原理
Annotated 类型注解 + 运算符合并规则。1. 核心注解:Annotated 标记追加规则
Annotated 为状态字段绑定追加行为。这是告诉 LangGraph:这个字段的更新方式不是覆盖,而是追加。2. 关键运算符:add 实现列表合并
operator.add 运算符,让 LangGraph 知道如何处理新旧状态的合并 —— 对于列表类型,add 运算符等价于列表拼接,新消息会自动追加到原有消息列表的末尾,全程无需手动编写拼接逻辑。三、追加式状态的完整设计思路
1. 状态定义:区分追加与普通字段
- 消息历史字段:使用追加规则,自动保留所有用户与 AI 的消息,是对话的核心数据
- 辅助状态字段:使用普通覆盖规则,用于存储当前对话主题、状态标识等临时数据,每次更新直接覆盖
2. 节点函数:专注生成新数据,无需关心历史
- 每个节点只需要生成当前需要新增的一条 / 一组数据
- 直接返回新数据即可,框架会自动将其追加到原有状态中
- 无需读取历史消息、无需拼接列表,代码更简洁、可读性更强
3. 图流程:线性流转,完成对话闭环
四、追加式状态的核心优势总结
- 极简代码:告别手动列表拼接、状态合并,减少冗余代码
- 自动管理:框架自动处理消息追加,开发者专注业务逻辑
- 稳定可靠:避免因手动合并导致的消息丢失、顺序错乱问题
- 场景适配:完美匹配聊天机器人、对话系统、多轮交互等核心场景
- 易于扩展:新增节点、新增交互步骤,无需修改状态合并逻辑
五、适用场景与实践价值
- 智能客服机器人
- 多轮对话式助手
- 长文本交互应用
- 带记忆功能的 AI 应用
结语
Annotated + 运算符的优雅设计,解决了对话系统中历史状态保留的核心难题。它把复杂的状态合并逻辑交给框架,让开发者专注于业务流程与节点逻辑,是构建高质量对话应用的必备技巧。"""
📌 模式2: 消息历史追加
核心机制: Annotated[List, add] 实现自动追加(非覆盖)
适用场景: 聊天机器人、对话系统、需要保留完整历史的场景
"""
import asyncio
from typing import TypedDict, List, Annotated
from operator import add # 关键:列表追加操作符
from langgraph.graph import StateGraph, START, END
from langchain_core.messages import HumanMessage, AIMessage
# ===== 1. 状态定义(关键:Annotated + add)=====
class ChatState(TypedDict):
"""
聊天状态设计:
- messages: 使用 Annotated[List, add] → 自动追加新消息
- current_topic: 当前对话主题(普通字段,覆盖更新)
"""
messages: Annotated[List[HumanMessage | AIMessage], add] # ⚠️ 核心:add 操作符
current_topic: str
# ===== 2. 节点函数 =====
def user_input_node(state: ChatState) -> dict:
"""
用户输入节点: 追加用户消息
返回 {"messages": [新消息]} → 自动追加到历史
"""
print(f"\n[用户输入] 当前消息数: {len(state['messages'])}")
new_msg = HumanMessage(content="用户: 今天天气怎么样?")
return {
"messages": [new_msg], # 返回单元素列表
"current_topic": "天气查询"
}
def ai_response_node(state: ChatState) -> dict:
"""
AI回复节点: 追加AI消息
⚠️ 注意: 返回的 messages 会追加,不会覆盖历史!
"""
print(f"[AI回复] 当前消息数: {len(state['messages'])}")
new_msg = AIMessage(content="AI: 今天北京晴,25°C,适合外出")
return {
"messages": [new_msg], # 再次返回单元素列表
"current_topic": "天气详情"
}
def summary_node(state: ChatState) -> dict:
"""
总结节点: 展示完整对话历史
"""
print(f"\n[对话总结] 总消息数: {len(state['messages'])}")
for i, msg in enumerate(state['messages'], 1):
role = "👤" if isinstance(msg, HumanMessage) else "🤖"
print(f" {role} 消息{i}: {msg.content[:30]}...")
return {"current_topic": "对话结束"}
# ===== 3. 构建图 =====
def build_chat_graph():
builder = StateGraph(ChatState)
builder.add_node("user_input", user_input_node)
builder.add_node("ai_response", ai_response_node)
builder.add_node("summary", summary_node)
builder.add_edge(START, "user_input")
builder.add_edge("user_input", "ai_response")
builder.add_edge("ai_response", "summary")
builder.add_edge("summary", END)
return builder.compile()
# ===== 4. 执行演示 =====
async def main():
print("=" * 60)
print("🧠 模式2: 消息历史追加(Annotated + add)")
print("=" * 60)
graph = build_chat_graph()
# 画图
print(graph.get_graph().draw_ascii())
# 初始状态(必须初始化 messages 为空列表!)
initial_state = {
"messages": [], # ⚠️ 关键:必须初始化,否则合并失败
"current_topic": "初始"
}
print("\n【初始状态】messages 长度: 0")
# 执行图
final_state = await graph.ainvoke(initial_state)
print("\n【最终状态】")
print(f" messages 长度: {len(final_state['messages'])}")
print(f" current_topic: {final_state['current_topic']}")
if __name__ == "__main__":
asyncio.run(main())
结果输出:
============================================================
🧠 模式2: 消息历史追加(Annotated + add)
============================================================
+-----------+
| __start__ |
+-----------+
*
*
*
+------------+
| user_input |
+------------+
*
*
*
+-------------+
| ai_response |
+-------------+
*
*
*
+---------+
| summary |
+---------+
*
*
*
+---------+
| __end__ |
+---------+
【初始状态】messages 长度: 0
[用户输入] 当前消息数: 0
[AI回复] 当前消息数: 1
[对话总结] 总消息数: 2
👤 消息1: 用户: 今天天气怎么样?...
🤖 消息2: AI: 今天北京晴,25°C,适合外出...
【最终状态】
messages 长度: 2
current_topic: 对话结束
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:

