短期记忆

短期记忆主要是指将对话消息进行存储,用作下一次对话的记忆来源

短期记忆开启

短期记忆在开发环境中可以使用ImMemorySaver来存储,其数据是存储在内存中,应用重启则清空.
在生产环境中则是需要使用数据库来实现.

ImMemorySaver方案

from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver 


agent = create_agent(
    "gpt-5.4",
    tools=[get_user_info],
    checkpointer=InMemorySaver(), # 创建一个内存记忆体
)

agent.invoke(
    {"messages": [{"role": "user", "content": "Hi! My name is Bob."}]},
    {"configurable": {"thread_id": "1"}}, # 此步骤很重要,对于同一个对话上下文,thread_id要保持一致,不然将无法使用历史消息
)

持久存储的记忆

在使用前需要安装对应的数据库模块,如pip install langgraph-checkpoint-postgres

  • 使用
from langchain.agents import create_agent

from langgraph.checkpoint.postgres import PostgresSaver  


DB_URI = "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
    checkpointer.setup() # auto create tables in PostgreSQL
    agent = create_agent(
        "gpt-5.4",
        tools=[get_user_info],
        checkpointer=checkpointer,
    )

消息处理

过长的对话内容会影响输出质量以及增加消耗,过段则会让模型忘记上下文,因此对于消息处理有如下几种方案:

消息裁剪

此方案主要是移除消息列表中的部分消息,例如移除前几条消息,或者后几条消息.
消息移除需要使用Command来更新runtime.state['messages']中的消息,其中使用RemoveMessage来移除消息,可以使用REMOVE_ALL_MESSAGES来表示移除所有的消息.

  • 示例代码:
from langchain.messages import RemoveMessage
from langgraph.graph.message import REMOVE_ALL_MESSAGES
from langgraph.checkpoint.memory import InMemorySaver
from langchain.agents import create_agent, AgentState
from langchain.agents.middleware import before_model
from langgraph.runtime import Runtime
from langchain_core.runnables import RunnableConfig
from typing import Any

# 在模型处理前对消息做裁剪
@before_model
def trim_messages(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    """Keep only the last few messages to fit context window."""
    messages = state["messages"]

    if len(messages) <= 3:
        return None  # No changes needed

    first_msg = messages[0]
    recent_messages = messages[-3:] if len(messages) % 2 == 0 else messages[-4:]
    # 保留第一条消息
    new_messages = [first_msg] + recent_messages

    return {
        "messages": [
            RemoveMessage(id=REMOVE_ALL_MESSAGES),
            *new_messages
        ] # 此步骤的含义是,先将所有的历史消息清空,然后用裁剪后的消息列表来代替之前的消息列表
    }

agent = create_agent(
    your_model_here,
    tools=your_tools_here,
    middleware=[trim_messages],
    checkpointer=InMemorySaver(),
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}

agent.invoke({"messages": "hi, my name is bob"}, config)
agent.invoke({"messages": "write a short poem about cats"}, config)
agent.invoke({"messages": "now do the same but for dogs"}, config)
final_response = agent.invoke({"messages": "what's my name?"}, config)

final_response["messages"][-1].pretty_print()
"""
================================== Ai Message ==================================

Your name is Bob. You told me that earlier.
If you'd like me to call you a nickname or use a different name, just say the word.
"""

消息过滤

消息过滤是指删除特定的消息,也是使用RemoveMessage函数实现

from langchain.messages import RemoveMessage  

def delete_messages(state):
    messages = state["messages"]
    if len(messages) > 2:
        # remove the earliest two messages
        return {"messages": [RemoveMessage(id=m.id) for m in messages if 'password' in m.context]}

消息总结

对消息使用模型进行压缩总结,可以使用lanchain自带的SummarizationMiddleware模块
示例:

from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware
from langgraph.checkpoint.memory import InMemorySaver
from langchain_core.runnables import RunnableConfig


checkpointer = InMemorySaver()

agent = create_agent(
    model="gpt-5.4",
    tools=[],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=("tokens", 4000),
            keep=("messages", 20)
        )
    ],
    checkpointer=checkpointer,
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}
agent.invoke({"messages": "hi, my name is bob"}, config)
agent.invoke({"messages": "write a short poem about cats"}, config)
agent.invoke({"messages": "now do the same but for dogs"}, config)
final_response = agent.invoke({"messages": "what's my name?"}, config)

final_response["messages"][-1].pretty_print()
"""
================================== Ai Message ==================================

Your name is Bob!
"""

状态数据的读取

对于状态(runtime.state)中的数据,可以用作对话级别的数据缓存,即在一次对话里,其数据是互通的.

  • 示例
from langchain_core.messages import ToolMessage
from langchain.agents import AgentState, create_agent
from langchain.tools import tool
from langgraph.prebuilt import  ToolRuntime
from langgraph.types import Command

class CustomAgentState(AgentState):
    user_name: str | None # 添加 user_name 字段,并允许为 None

@tool
def recharge(phone:str, amount:int, runtime: ToolRuntime[None, CustomAgentState])->Command:
    """
    账号充值
    :param phone:需要充值的手机号
    :param amount: 需要充值的金额(单位为分)
    :param runtime: 工具上下文
    :return: 充值后的结果文案
    """
    print('[recharge]')
    return Command(
        update={
            'user_name': '小张',
            'messages': [
                ToolMessage(
                    content=f"充值成功。",
                    tool_call_id=runtime.tool_call_id,
                )
            ],
        }
    )

@tool
def query_user_balance(phone:str, runtime: ToolRuntime[None, CustomAgentState])->int:
    """
    查询用户余额
    :param phone:手机号
    :return: 余额(分)
    """
    print('[query_user_balance]', runtime.state.get('user_name'))
    return 2000

agent = create_agent(model, tools=[recharge,query_user_balance], state_schema=CustomAgentState,system_prompt="你是一个助手。每次只执行一个工具调用。在执行完充值操作后,请等待用户的进一步指令或观察状态变化后再进行查询。")

agent.invoke({"messages":[{'role':'user', 'content':"请为手机号1234567890充值10元,然后查询充值完成后的余额"}]})
  • 输出
[recharge]
[query_user_balance] 小张
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容