langchain langgraph历史会话的 json序列化

你说得非常对!使用 langchain_core.messages 提供的工具函数确实是最佳实践。这种方式既官方又可靠,能正确处理所有消息类型和内部结构。

为什么这是最好的方式:

1. 官方支持,未来兼容性好

from langchain_core.messages import (
    message_to_dict,      # 单个消息转换
    messages_to_dict,     # 消息列表转换
    messages_from_dict,   # 反向转换
    HumanMessage, AIMessage, SystemMessage
)

2. 处理所有消息类型

import json
from langchain_core.messages import (
    HumanMessage, AIMessage, SystemMessage,
    ToolMessage, FunctionMessage,
    messages_to_dict, messages_from_dict
)

# 创建各种类型的消息
messages = [
    HumanMessage(content="Hello"),
    AIMessage(content="Hi there!", additional_kwargs={"tool_calls": [...]}),
    SystemMessage(content="You are a helpful assistant"),
    ToolMessage(content="result", tool_call_id="123"),
    FunctionMessage(content="data", name="some_function")
]

# 正确序列化
message_dicts = messages_to_dict(messages)
json_str = json.dumps(message_dicts, indent=2)
print(json_str)

# 完美恢复
restored_messages = messages_from_dict(message_dicts)
print(type(restored_messages[0]))  # <class 'langchain_core.messages.human.HumanMessage'>

3. 在 LangGraph 中的完美集成

from langgraph.graph import StateGraph, END
from typing import TypedDict, List
import json
from langchain_core.messages import (
    BaseMessage, HumanMessage, AIMessage,
    messages_to_dict, messages_from_dict
)

# State 定义 - 存储为字典
class ChatState(TypedDict):
    messages: List[dict]  # 存储序列化后的消息
    metadata: dict

def human_node(state: ChatState):
    """处理用户输入"""
    # 1. 将字典转换回消息对象
    messages = messages_from_dict(state["messages"])
    
    # 2. 处理业务逻辑
    last_message = messages[-1] if messages else None
    if last_message:
        response = AIMessage(content=f"Echo: {last_message.content}")
        messages.append(response)
    
    # 3. 转换回字典存储
    state["messages"] = messages_to_dict(messages)
    return state

def ai_node(state: ChatState):
    """AI处理节点"""
    # 转换为消息对象
    messages = messages_from_dict(state["messages"])
    
    # 添加AI响应
    ai_message = AIMessage(
        content="I'm thinking about your question...",
        additional_kwargs={"reasoning": "User needs assistance"}
    )
    messages.append(ai_message)
    
    # 存回state
    state["messages"] = messages_to_dict(messages)
    return state

# 创建图
workflow = StateGraph(ChatState)
workflow.add_node("human", human_node)
workflow.add_node("ai", ai_node)

workflow.set_entry_point("human")
workflow.add_edge("human", "ai")
workflow.add_edge("ai", END)

app = workflow.compile()

# 使用
initial_state = {
    "messages": messages_to_dict([HumanMessage(content="Hello world!")]),
    "metadata": {"user_id": "123"}
}

result = app.invoke(initial_state)
print("Final messages:", result["messages"])

4. 完整的工作流示例

from langchain_core.messages import messages_to_dict, messages_from_dict
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
import json

# 定义State
class AgentState(TypedDict):
    messages: List[dict]  # 序列化的消息
    context: str
    status: str

# 工具函数:在State和Message对象间转换
def state_to_messages(state: AgentState) -> List[BaseMessage]:
    """从state中恢复消息对象"""
    return messages_from_dict(state["messages"])

def messages_to_state(messages: List[BaseMessage], state: AgentState) -> AgentState:
    """将消息对象存回state"""
    state["messages"] = messages_to_dict(messages)
    return state

# 节点函数
def process_input(state: AgentState):
    """处理用户输入节点"""
    # 获取消息对象
    messages = state_to_messages(state)
    
    # 创建LLM调用
    llm = ChatOpenAI(model="gpt-3.5-turbo")
    
    # 添加系统消息
    from langchain_core.messages import SystemMessage
    system_msg = SystemMessage(content="You are a helpful assistant.")
    all_messages = [system_msg] + messages
    
    # 调用LLM
    response = llm.invoke(all_messages)
    
    # 添加响应到消息列表
    messages.append(response)
    
    # 更新state
    state = messages_to_state(messages, state)
    state["status"] = "processed"
    
    return state

def format_output(state: AgentState):
    """格式化输出节点"""
    messages = state_to_messages(state)
    
    # 只获取最后一个AI消息
    ai_messages = [msg for msg in messages if isinstance(msg, AIMessage)]
    if ai_messages:
        last_ai_message = ai_messages[-1]
        state["context"] = f"AI said: {last_ai_message.content}"
    
    return state

# 构建图
workflow = StateGraph(AgentState)
workflow.add_node("process", process_input)
workflow.add_node("format", format_output)

workflow.set_entry_point("process")
workflow.add_edge("process", "format")
workflow.add_edge("format", END)

app = workflow.compile()

# 序列化和反序列化整个状态
def save_state(state: AgentState, filepath: str):
    """保存状态到文件"""
    with open(filepath, 'w') as f:
        json.dump(state, f, indent=2)

def load_state(filepath: str) -> AgentState:
    """从文件加载状态"""
    with open(filepath, 'r') as f:
        return json.load(f)

# 使用示例
initial_messages = messages_to_dict([
    HumanMessage(content="What is the weather today?")
])

initial_state = {
    "messages": initial_messages,
    "context": "",
    "status": "initialized"
}

# 执行
result = app.invoke(initial_state)
print("Result:", result)

# 保存状态
save_state(result, "agent_state.json")

# 稍后可以加载继续执行
loaded_state = load_state("agent_state.json")
new_result = app.invoke(loaded_state)

关键优势:

  1. 标准化:使用LangChain官方提供的序列化方法
  2. 完整支持:处理所有消息类型和特殊字段(如additional_kwargstool_calls等)
  3. 易于调试:序列化的JSON结构清晰可读
  4. 跨版本兼容:降低LangChain版本升级带来的影响
<think>好的,我现在要回答用户关于在LangChain中存储本地会话记录的问题。首先,我需要回忆一下用户提供的引用内容,特别是引用[1]和引用[2],因为它们提到了ChatMessageHistory和结合buffer与summary memory的策略。 用户的问题是关于存储本地会话记录的方法和示例。根据引用[1],ChatMessageHistory类可以管理历史消息,这可能就是关键。我需要先确认这个类的基本用法,比如如何添加消息和保存到本地。然后,引用[2]提到了一种结合buffer和summary memory的策略,这可能涉及更高级的存储方式,比如定期总结历史记录以减少存储量。 接下来,我需要考虑用户可能需要具体的代码示例。例如,使用ChatMessageHistory时,如何初始化实例,添加用户消息和AI回复,然后将这些记录保存为文件。同时,可能需要提到不同的存储格式,比如JSON或文本文件。 另外,用户可能关心如何将这些会话记录持久化到本地文件中,而不仅仅是内存中的操作。因此,需要展示如何将消息列表转换为字典,再使用json库保存到磁盘。此外,结合buffer和summary memory的部分,可能需要引入ConversationSummaryBufferMemory类,并展示其配置方法,比如设置max_token_limit来控制缓冲区大小,并自动生成摘要。 还需要注意代码的正确性,确保导入正确的类,如from langchain.memory import ChatMessageHistory, ConversationSummaryBufferMemory。同时,示例需要简洁明了,让用户能够快速理解如何实现本地存储。 最后,要生成相关问题,可能需要涵盖性能优化、不同存储方式对比、会话历史的应用场景以及处理长对话的方法。这些问题可以帮助用户进一步探索相关主题。</think>在LangChain中存储本地会话记录可以通过`ChatMessageHistory`类实现,并结合文件存储实现持久化。以下是具体方法和示例: ### 方法一:基础会话存储 ```python from langchain.memory import ChatMessageHistory # 创建历史记录实例 history = ChatMessageHistory() # 添加用户消息和AI回复 history.add_user_message("如何学习Python?") history.add_ai_message("建议从基础语法开始,逐步实践项目") # 存储为本地文件(JSON格式) import json with open("chat_history.json", "w") as f: json.dump([msg.dict() for msg in history.messages], f) # 序列化消息对象 ``` ### 方法二:缓冲+摘要组合存储[^2] ```python from langchain.memory import ConversationSummaryBufferMemory memory = ConversationSummaryBufferMemory( llm=your_llm_instance, # 替换为实际LLM实例 max_token_limit=500 # 保留最近500token的原始对话 ) # 添加对话记录 memory.save_context( {"input": "什么是机器学习?"}, {"output": "通过数据训练模型的算法"} ) # 持久化存储方案 with open("summary_memory.json", "w") as f: # 同时保存原始缓冲和摘要 data = { "buffer": memory.chat_memory.messages, "summary": memory.moving_summary_buffer } json.dump(data, f) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

micro_cloud_fly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值