前面我们讲的智能体都是没有记忆的,也就是前面问的话,后面第二次聊天调用就忘了,不能连接
Agent的记忆:
· 短期记忆(short-term memory):当前任务或会话的上下文
· 长期记忆(long-term memory):跨任务或会话的经验与知识
一、短期记忆 -- 内存存储
在LangChain短期记忆是通过AgentState实现的,而会话历史(也就是消息列表)是AgentState的一部分。
LangChain提供了Checkpointer对象来保存AgentState,每一次用户与AI的交互都会生成一个快照,记录为一个Checkpoint。可以回退到任意一次对话的位置,同一会话的多个Checkpoint形成一个组,用同一个thread_id来标记
接下来就是创建短期记忆了,依旧到了熟悉的步骤:读langchain官方文档
这就是官方给出的短期记忆的文档,我来拆解一下,首先就是引入一个包,然后在创建的agent里示例化一个checkpointer对象用来存储当前agent的短期记忆,再创建编号,在每一段相同话题的对话的时指定引入这个编号
from langchain_core.messages import HumanMessage thread_config = {"configurable": {"thread_id": "1"}} response = agent.invoke( {"messages": [HumanMessage(content="西安的天气怎么样")]}, thread_config, )["messages"][-1].content print(response) response = agent.invoke( {"messages": [HumanMessage(content="我刚刚问的是哪个地方的天气")]}, thread_config, )["messages"][-1].content print(response)回答:
西安今天天气晴朗,气温 25°C,挺舒适的,适合外出活动。
您刚刚问的是**西安**的天气。 西安今天是晴天,气温 25°C。
二、短期记忆 -- 持久存储
短期记忆都是把对话存储在内存的,如果内存不够就会溢出,所以大多情况下都会用数据库存储代替内存存储短期记忆。
还是读langchain文档短期记忆的In production的部分,有很多的数据库存储方法,我用sqlite举例阅读文章后拆解步骤就是:
· 导入依赖
· 初始化checkpointer
· 自动建表
· 创建Agent,指定checkpointer
import sqlite3 from langgraph.checkpoint.sqlite import SqliteSaver #连接sqlite connection = sqlite3.connect("./checkpoint.db",check_same_thread=False) #初始化checkpointer checkpointer = SqliteSaver(connection) #给checkpointer建表 checkpointer.setup() #创建Agent agent = create_agent( model=llm, tools=[get_weather], checkpointer=checkpointer ) config = {"configurable": {"thread_id": "2"}} response1 = agent.invoke( {"messages":[HumanMessage(content="今天上海天气怎么样")]}, config )["messages"][-1].content print(response1) response1 = agent.invoke( {"messages":[HumanMessage(content="我刚刚问的是哪个地区的天气")]}, config )["messages"][-1].content三、记忆管理策略
1、方法策略
多轮对话会导致消息越来越多,最终超出模型的上下文限制(DeepSeek的上下文不能超过128k),LangChain提供了一些记忆管理的策略来解决这个问题,包括:修剪、删除、总结摘要、自定义(如根据用户的问题筛选历史消息)
修剪:拿到消息历史后,先移除前N条或后N条消息,再调用模型。有记忆消失的风险
删除:永久删除AgentState的快照,回滚不了,风险大
总结摘要:先总结历史消息中的早期消息,得到消息摘要。用消息摘要和最近的消息形成消息列表,再调用模型
2、具体实现(看langchain官网文档)
具体参数看文档解释
from langchain.agents import create_agent from langchain.agents.middleware import SummarizationMiddleware from langgraph.checkpoint.memory import InMemorySaver from langchain_core.runnables import RunnableConfig from langchain_core.messages import HumanMessage from langchain.chat_models import init_chat_model from langchain.tools import tool from dotenv import load_dotenv import os llm = init_chat_model( model="deepseek-chat", model_provider="openai", api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com", temperature = 0.7 ) @tool def get_weather(location:str)->str: """ 获取天气 """ return f"{location}的天气是晴朗" checkpointer = InMemorySaver() agent = create_agent( model=llm, tools=[get_weather], middleware=[ SummarizationMiddleware( model=llm, trigger=("messages", 3), keep=("messages", 1) ) ], checkpointer=checkpointer, ) config: RunnableConfig = {"configurable": {"thread_id": "1"}} agent.invoke({"messages": [HumanMessage(content='我喜欢的动物是小猫。')]}, config) agent.invoke({"messages": [HumanMessage(content='我喜欢的运动是游泳。')]}, config) agent.invoke({"messages": [HumanMessage(content='我的名字叫张飞?')]}, config) final_response = agent.invoke({"messages": "你认识我吗?"}, config) final_response["messages"][-1].pretty_print()回答:你好,张飞!是的,我记得你的信息——你喜欢小猫,也喜欢游泳。😊