LangChain核心组件之Short-term memory

概述

记忆是一种用于记录先前交互信息的系统。对于 AI Agent(智能体)而言,记忆至关重要——它使智能体能够记住过往对话、从用户反馈中学习,并适应用户的偏好。随着智能体处理的任务越来越复杂、交互轮次越来越多,这种能力对提升效率和用户体验变得不可或缺。

短期记忆允许你的应用在单个线程(thread)或一次会话(conversation)中记住之前的交互内容。

注:
一个 线程(thread) 用于组织一次会话中的多次交互,类似于电子邮件中将多条消息归为同一对话的方式。

最常见的短期记忆形式就是对话历史。然而,长对话对当前的大语言模型(LLM)构成了挑战:完整的对话历史可能超出 LLM 的上下文窗口(context window),导致上下文丢失或出错。

即使你的模型支持超长上下文,大多数 LLM 在处理过长上下文时表现依然不佳——它们容易被陈旧或无关的内容“干扰”,同时还会带来响应变慢和成本上升的问题。

聊天模型通过 消息(messages) 接收上下文,这些消息包括指令(system message)和用户输入(human message)。在聊天应用中,消息通常在用户输入与模型回复之间交替出现,随着时间推移形成一个不断增长的消息列表。由于上下文窗口有限,许多应用都需要采用一些策略来移除或“遗忘”过时的信息。

使用方法

要为智能体添加短期记忆(即线程级别的持久化能力),你需要在创建智能体时指定一个 checkpointer。

说明:
LangChain 的智能体将短期记忆作为其状态(state)的一部分进行管理。
通过将这些状态存储在图(graph)中,智能体可以在保持不同线程隔离的同时,访问特定会话的完整上下文。
状态通过 checkpointer 持久化到数据库(或内存)中,使得线程可以在任意时刻恢复。
每次调用智能体或完成一个步骤(如工具调用)后,短期记忆会被更新;而在每个步骤开始时,状态会被读取。

fromlangchain.agentsimportcreate_agentfromlanggraph.checkpoint.memoryimportInMemorySaver agent=create_agent("gpt-5",tools=[get_user_info],checkpointer=InMemorySaver(),)agent.invoke({"messages":[{"role":"user","content":"Hi! My name is Bob."}]},{"configurable":{"thread_id":"1"}},)
在生产环境中

在生产环境中,应使用基于数据库的 checkpointer:

pipinstalllanggraph-checkpoint-postgres
fromlangchain.agentsimportcreate_agentfromlanggraph.checkpoint.postgresimportPostgresSaver DB_URI="postgresql://postgres:postgres@localhost:5442/postgres?sslmode=disable"withPostgresSaver.from_conn_string(DB_URI)ascheckpointer:checkpointer.setup()# 自动在 PostgreSQL 中创建所需表agent=create_agent("gpt-5",tools=[get_user_info],checkpointer=checkpointer,)

自定义智能体记忆

默认情况下,智能体使用 AgentState 来管理短期记忆,特别是通过 messages 键保存对话历史。

你可以通过继承 AgentState 来添加自定义字段。自定义的状态结构(state schema)可通过 create_agent 的 state_schema 参数传入。

fromlangchain.agentsimportcreate_agent,AgentStatefromlanggraph.checkpoint.memoryimportInMemorySaverclassCustomAgentState(AgentState):user_id:strpreferences:dictagent=create_agent("gpt-5",tools=[get_user_info],state_schema=CustomAgentState,checkpointer=InMemorySaver(),)# 调用时可传入自定义状态result=agent.invoke({"messages":[{"role":"user","content":"Hello"}],"user_id":"user_123","preferences":{"theme":"dark"}},{"configurable":{"thread_id":"1"}})

常见模式

启用 短期记忆 后,长对话仍可能超出 LLM 的上下文窗口。常见解决方案包括:

移除最前或最后 N 条消息(在调用 LLM 前) 从 LangGraph 状态中永久删除消息 将早期消息摘要后替换原消息 自定义策略(如消息过滤等)
这些方法可帮助智能体在不超出上下文限制的前提下,持续跟踪对话上下文。

裁剪消息(Trim messages)

大多数 LLM 都有最大上下文长度限制(以 token 计)。

一种判断何时裁剪消息的方法是:统计消息历史中的 token 数量,当接近上限时进行截断。如果你使用 LangChain,可以借助内置的 trim messages 工具,指定保留多少 token,并选择裁剪策略(例如保留最近的 max_tokens)。

要在智能体中裁剪消息历史,可使用 @before_model 中间件装饰器:

fromlangchain.messagesimportRemoveMessagefromlanggraph.graph.messageimportREMOVE_ALL_MESSAGESfromlanggraph.checkpoint.memoryimportInMemorySaverfromlangchain.agentsimportcreate_agent,AgentStatefromlangchain.agents.middlewareimportbefore_modelfromlanggraph.runtimeimportRuntimefromlangchain_core.runnablesimportRunnableConfigfromtypingimportAny@before_modeldeftrim_messages(state:AgentState,runtime:Runtime)->dict[str,Any]|None:"""仅保留最近几条消息,以适配上下文窗口。"""messages=state["messages"]iflen(messages)<=3:returnNone# 无需修改first_msg=messages[0]recent_messages=messages[-3:]iflen(messages)%2==0elsemessages[-4:]new_messages=[first_msg]+recent_messagesreturn{"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. """
删除消息(Delete messages)

你可以从图状态中删除消息,以管理消息历史。这在需要移除特定消息或清空整个历史时非常有用。

要删除消息,需使用 RemoveMessage。

注意:RemoveMessage 要求状态键使用 add_messages 这个 reducer(归约器)。

默认的 AgentState 已经提供了该功能。

  1. 删除特定消息:
fromlangchain.messagesimportRemoveMessagedefdelete_messages(state):messages=state["messages"]iflen(messages)>2:# 删除最早的两条消息return{"messages":[RemoveMessage(id=m.id)forminmessages[:2]]}
  1. 删除全部消息:
fromlanggraph.graph.messageimportREMOVE_ALL_MESSAGESdefdelete_messages(state):return{"messages":[RemoveMessage(id=REMOVE_ALL_MESSAGES)]}

警告:
删除消息时,请确保剩余的消息历史仍然有效。请参考你所用 LLM 提供商的限制,例如:
某些提供商要求消息历史必须以 user 消息开头;
大多数提供商要求带有工具调用的 assistant 消息后必须紧跟对应的 tool 结果消息。

示例:

# 使用 @after_model 中间件在模型调用后删除旧消息@after_modeldefdelete_old_messages(state:AgentState,runtime:Runtime)->dict|None:messages=state["messages"]iflen(messages)>2:return{"messages":[RemoveMessage(id=m.id)forminmessages[:2]]}returnNone# ...(后续调用略)

输出示例显示:随着新消息加入,旧消息被逐步移除,但关键信息(如用户名)仍被保留。

摘要消息(Summarize messages)
上述裁剪或删除消息的方法可能导致重要信息丢失。因此,某些应用更适合采用更高级的策略:使用 LLM 对历史消息进行摘要。

LangChain 提供了内置的 SummarizationMiddleware 来实现这一功能:

fromlangchain.agentsimportcreate_agentfromlangchain.agents.middlewareimportSummarizationMiddlewarefromlanggraph.checkpoint.memoryimportInMemorySaver agent=create_agent(model="gpt-4o",tools=[],middleware=[SummarizationMiddleware(model="gpt-4o-mini",trigger=("tokens",4000),# 当 token 数超过 4000 时触发摘要keep=("messages",20)# 保留最近 20 条消息)],checkpointer=InMemorySaver(),)config={"configurable":{"thread_id":"1"}}agent.invoke({"messages":"hi, my name is bob"},config)# ... 多轮交互后final_response=agent.invoke({"messages":"what's my name?"},config)final_response["messages"][-1].pretty_print()""" ================================== Ai Message ================================== Your name is Bob! """

更多配置选项请参阅 SummarizationMiddleware 文档。

访问记忆

你可以通过多种方式访问和修改智能体的短期记忆(即状态):

在工具(Tools)中
  1. 读取短期记忆

在工具函数中,可通过 runtime 参数(类型为 ToolRuntime)访问当前状态。

该参数对模型不可见(不会出现在工具签名中),但工具内部可读取状态。

fromlangchain.agentsimportcreate_agent,AgentStatefromlangchain.toolsimporttool,ToolRuntimeclassCustomState(AgentState):user_id:str@tooldefget_user_info(runtime:ToolRuntime)->str:"""Look up user info."""user_id=runtime.state["user_id"]return"User is John Smith"ifuser_id=="user_123"else"Unknown user"agent=create_agent(model="gpt-5-nano",tools=[get_user_info],state_schema=CustomState,)result=agent.invoke({"messages":"look up user information","user_id":"user_123"})print(result["messages"][-1].content)# > User is John Smith.
  1. 写入短期记忆

工具可通过返回 Command 对象直接更新智能体状态,适用于保存中间结果或供后续步骤使用。

fromlangchain.toolsimporttool,ToolRuntimefromlangchain_core.runnablesimportRunnableConfigfromlangchain.messagesimportToolMessagefromlangchain.agentsimportcreate_agent,AgentStatefromlanggraph.typesimportCommandfrompydanticimportBaseModelclassCustomState(AgentState):user_name:strclassCustomContext(BaseModel):user_id:str@tooldefupdate_user_info(runtime:ToolRuntime[CustomContext,CustomState],)->Command:"""Look up and update user info."""user_id=runtime.context.user_id name="John Smith"ifuser_id=="user_123"else"Unknown user"returnCommand(update={"user_name":name,# update the message history"messages":[ToolMessage("Successfully looked up user information",tool_call_id=runtime.tool_call_id)]})@tooldefgreet(runtime:ToolRuntime[CustomContext,CustomState])->str|Command:"""Use this to greet the user once you found their info."""user_name=runtime.state.get("user_name",None)ifuser_nameisNone:returnCommand(update={"messages":[ToolMessage("Please call the 'update_user_info' tool it will get and update the user's name.",tool_call_id=runtime.tool_call_id)]})returnf"Hello{user_name}!"agent=create_agent(model="gpt-5-nano",tools=[update_user_info,greet],state_schema=CustomState,context_schema=CustomContext,)agent.invoke({"messages":[{"role":"user","content":"greet the user"}]},context=CustomContext(user_id="user_123"),)
在提示词(Prompt)中

通过中间件动态生成系统提示词,可基于对话历史或自定义状态字段构建个性化 prompt。

fromlangchain.agentsimportcreate_agentfromtypingimportTypedDictfromlangchain.agents.middlewareimportdynamic_prompt,ModelRequestclassCustomContext(TypedDict):user_name:strdefget_weather(city:str)->str:"""Get the weather in a city."""returnf"The weather in{city}is always sunny!"@dynamic_promptdefdynamic_system_prompt(request:ModelRequest)->str:user_name=request.runtime.context["user_name"]system_prompt=f"You are a helpful assistant. Address the user as{user_name}."returnsystem_prompt agent=create_agent(model="gpt-5-nano",tools=[get_weather],middleware=[dynamic_system_prompt],context_schema=CustomContext,)result=agent.invoke({"messages":[{"role":"user","content":"What is the weather in SF?"}]},context=CustomContext(user_name="John Smith"),)formsginresult["messages"]:msg.pretty_print()
在模型调用前(@before_model)

可在模型调用前处理消息,例如裁剪、过滤或注入上下文。

fromlangchain.messagesimportRemoveMessagefromlanggraph.graph.messageimportREMOVE_ALL_MESSAGESfromlanggraph.checkpoint.memoryimportInMemorySaverfromlangchain.agentsimportcreate_agent,AgentStatefromlangchain.agents.middlewareimportbefore_modelfromlangchain_core.runnablesimportRunnableConfigfromlanggraph.runtimeimportRuntimefromtypingimportAny@before_modeldeftrim_messages(state:AgentState,runtime:Runtime)->dict[str,Any]|None:"""Keep only the last few messages to fit context window."""messages=state["messages"]iflen(messages)<=3:returnNone# No changes neededfirst_msg=messages[0]recent_messages=messages[-3:]iflen(messages)%2==0elsemessages[-4:]new_messages=[first_msg]+recent_messagesreturn{"messages":[RemoveMessage(id=REMOVE_ALL_MESSAGES),*new_messages]}agent=create_agent("gpt-5-nano",tools=[],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. """
在模型调用后(@after_model)

可在模型生成回复后进行后处理,例如过滤敏感内容:

fromlangchain.messagesimportRemoveMessagefromlanggraph.checkpoint.memoryimportInMemorySaverfromlangchain.agentsimportcreate_agent,AgentStatefromlangchain.agents.middlewareimportafter_modelfromlanggraph.runtimeimportRuntime@after_modeldefvalidate_response(state:AgentState,runtime:Runtime)->dict|None:"""Remove messages containing sensitive words."""STOP_WORDS=["password","secret"]last_message=state["messages"][-1]ifany(wordinlast_message.contentforwordinSTOP_WORDS):return{"messages":[RemoveMessage(id=last_message.id)]}returnNoneagent=create_agent(model="gpt-5-nano",tools=[],middleware=[validate_response],checkpointer=InMemorySaver(),)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1120134.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何有效降低论文AI痕迹?我的真实降AI经验分享

在高校越来越严格的AIGC检测环境下&#xff0c;论文的AI率成为了毕业、答辩的重要门槛。特别是知网AI率检测日益精细&#xff0c;许多同学的论文初稿AI率都偏高&#xff0c;面临被退回甚至重写的风险。作为一名研究生&#xff0c;我也遇到了论文AI率过高的问题&#xff0c;在尝…

基于ADMM的车辆路径问题与时间窗口(VRPTW)的问题分解方案附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

环境仿真软件:SWAT_(6).SWAT在农业与水资源管理中的应用

SWAT在农业与水资源管理中的应用 1. 农业与水资源管理的基本概念 在农业与水资源管理领域&#xff0c;环境仿真软件如SWAT&#xff08;Soil and Water Assessment Tool&#xff09;发挥着重要作用。SWAT是一种分布式流域模型&#xff0c;用于模拟水文循环、水质、农作物生长和土…

智能降重软件使用体验分享:如何有效降低论文AI率

"## 近年来&#xff0c;随着AIGC技术在论文写作中的广泛应用&#xff0c;许多高校对论文AI率的检测标准也越来越严格&#xff0c;尤其是知网的AI率检测系统。作为一名长期关注论文降重和查AI率的学生&#xff0c;我最近试用了两款智能降重软件——【嘎嘎降AI】和【比话降…

【资料】基于模型预测算法的含储能微网双层能量管理模型

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

LangChain核心组件之Messages

在 LangChain 中&#xff0c;消息&#xff08;Messages&#xff09; 是模型上下文的基本单元。它们代表了模型的输入与输出&#xff0c;既包含实际内容&#xff0c;也携带元数据&#xff0c;用于在与大语言模型&#xff08;LLM&#xff09;交互时完整表达对话状态。 消息对象包…

论文重复率修改:如何有效降低论文AI率?

在当前高校论文写作中&#xff0c;AI生成内容&#xff08;AIGC&#xff09;检测成为越来越严格的门槛。面对知网、万方等权威平台的AI率检测&#xff0c;很多同学和老师都难免会遇到论文重复率过高的问题。本文结合真实使用体验&#xff0c;介绍两款我在实际论文降重过程中效果…

PHP 使用 Redis

PHP 使用 Redis 引言 Redis 是一款高性能的键值存储系统,常用于缓存、会话存储、消息队列等场景。PHP 作为一种流行的服务器端脚本语言,与 Redis 的结合使用非常广泛。本文将详细介绍 PHP 使用 Redis 的方法、技巧以及注意事项。 Redis 简介 Redis 是一种基于内存的键值存…

元服务一站式平台:告别碎片化,开启All in One一站式经营新纪元

为了给元服务开发者提供更聚焦、更高效的管理体验&#xff0c;我们在AppGallery Connect平台上正式推出了元服务一站式平台。为何打造专属一站式平台&#xff1f; 随着元服务能力不断丰富&#xff0c;相关功能分布在平台的多个模块中。为了帮助您更便捷地查找和使用所需功能&am…

【滤波跟踪】基于量测非线性模型进行仿真;通过对比分析EKF,UKF和PF粒子滤波的性能附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1…

AI写作降重体验分享:论文降AI率的实用方法

"## 随着AI辅助写作技术的普及&#xff0c;论文AI率&#xff08;即论文中的AI生成内容比例&#xff09;问题也日益严峻。尤其是在高校严格的AIGC检测环境下&#xff0c;如知网AIGC检测&#xff0c;论文AI率过高极有可能导致学术不合格甚至退回重写。因此&#xff0c;掌握…

用户选择静态 IP 时最关心的6个核心问题

#静态IP#在跨境电商、社媒多账号运营、广告投放等场景中&#xff0c;静态IP被越来越多的用户所关注。相比较动态IP&#xff0c;静态IP在稳定性和可控性方面具有一定的优势&#xff0c;但是否适合我们呢&#xff1f;仍然需要结合具体的应用场景。下面小编为大家总结了6个用户选择…

【AI+教育】被 “高考不考,坚决不搞” 毁掉的创新力:衡水中学让我复盘半生应试路

应试教育只给了我‘术’,而生活教会了我‘道’。从衡水模式到职场觉醒,这是一个‘标准答案’受害者的十年自救报告。 一、现状:职场失意时,仍会梦回高考考场 如今的我早已步入职场,却仍会被一段关于高考的记忆反复纠缠。 只要工作中遇到不顺心的事,我就会做同一个类型的…

论文降重平台推荐及真实体验分享

"## 在当前高校对论文原创性要求越来越高的背景下&#xff0c;AIGC检测及论文AI率成为大家关注的重点。尤其是当使用知网等权威系统检测时&#xff0c;高AI率不仅会影响论文的合格与否&#xff0c;也直接关系到毕业、答辩等重要环节。作为一名学生&#xff0c;我最近使用了…

鸿蒙开发者12月社区声望值月度榜单揭晓!

亲爱的鸿蒙开发者们&#xff0c; 【HarmonyOS开发者社区】“成长徽章”计划历经两个月的暂停调整&#xff0c;现正式重启评奖活动&#xff01;感谢大家在暂停期间依然坚守分享初心&#xff0c;以技术传递价值&#xff0c;用热忱共建生态&#xff0c;让社区始终保持蓬勃的技术活…

基于粒子群算法PSO融合动态窗口法DWA的无人机三维动态避障路径规划研究附MATLAB代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

全网最全专科生必备AI论文写作软件TOP10测评

全网最全专科生必备AI论文写作软件TOP10测评 一、不同维度核心推荐&#xff1a;10款AI工具各有所长 对于专科生而言&#xff0c;论文写作是一个复杂而多环节的过程&#xff0c;从开题、初稿撰写到查重、降重和排版&#xff0c;每个阶段都需要合适的工具辅助。在实际测评过程中…

【例4-6】香甜的黄油(信息学奥赛一本通- P1345)

【题目描述】农夫John发现做出全威斯康辛州最甜的黄油的方法&#xff1a;糖。把糖放在一片牧场上&#xff0c;他知道N&#xff08;1≤N≤500&#xff09;只奶牛会过来舔它&#xff0c;这样就能做出能卖好价钱的超甜黄油。当然&#xff0c;他将付出额外的费用在奶牛上。农夫John…

【路径规划】基于信息的RRT方法在非完整系统中的应用——车辆泊车辅助附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1…

基于微信小程序的校友管理系统设计与实现(毕设源码+文档)

课题说明随着高校校友网络建设需求的提升&#xff0c;传统校友管理模式存在信息传递滞后、联络渠道分散、资源共享不足、活动组织繁琐等问题&#xff0c;难以满足校友间交流互动与母校情感联结的需求。本课题聚焦高校校友管理的核心痛点&#xff0c;设计并实现一款基于微信小程…