Skip to main content

概述

记忆是一个能够记住先前交互信息的系统。对于 AI 智能体来说,记忆至关重要,因为它让智能体能够记住先前的交互、从反馈中学习并适应用户偏好。随着智能体处理越来越复杂的任务和大量用户交互,这种能力对于效率和用户满意度变得不可或缺。 短期记忆让你的应用程序能够记住单个线程或对话中的先前交互。
线程组织单个会话中的多次交互,类似于电子邮件将消息分组在单个对话中。
对话历史是短期记忆最常见的形式。长对话对当今的 LLM 构成挑战;完整的历史可能无法放入 LLM 的上下文窗口,导致上下文丢失或错误。 即使你的模型支持完整的上下文长度,大多数 LLM 在长上下文中仍然表现不佳。它们会被陈旧或偏离主题的内容”分散注意力”,同时响应时间更慢、成本更高。 聊天模型使用消息接受上下文,包括指令(系统消息)和输入(人类消息)。在聊天应用程序中,消息在人类输入和模型响应之间交替,导致消息列表随时间增长。由于上下文窗口有限,许多应用程序可以从使用技术来移除或”遗忘”陈旧信息中受益。
需要对话记住信息?使用长期记忆跨不同线程和会话存储和召回用户特定或应用程序级别的数据。

用法

要为智能体添加短期记忆(线程级持久化),你需要在创建智能体时指定一个 checkpointer
LangChain 的智能体将短期记忆作为智能体状态的一部分进行管理。通过将这些存储在图的状态中,智能体可以访问给定对话的完整上下文,同时保持不同线程之间的隔离。状态使用检查点持久化到数据库(或内存),以便线程可以在任何时候恢复。短期记忆在智能体被调用或步骤(如工具调用)完成时更新,状态在每个步骤开始时读取。

在生产环境中

在生产环境中,使用由数据库支持的检查点:
有关更多检查点选项,包括 SQLite、Postgres 和 Azure Cosmos DB,请参阅持久化文档中的检查点库列表

自定义智能体记忆

默认情况下,智能体使用 AgentState 来管理短期记忆,特别是通过 messages 键管理对话历史。 你可以扩展 AgentState 来添加额外的字段。自定义状态模式通过 state_schema 参数传递给 create_agent

常见模式

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

修剪消息

移除前 N 条或后 N 条消息(在调用 LLM 之前)

删除消息

从 LangGraph 状态中永久删除消息

摘要消息

对历史中较早的消息进行摘要并用摘要替换它们

自定义策略

自定义策略(例如消息过滤等)
这允许智能体在不超出 LLM 上下文窗口的情况下跟踪对话。

修剪消息

大多数 LLM 有一个最大支持的上下文窗口(以 Token 为单位)。 一种决定何时截断消息的方式是计算消息历史中的 Token 数,并在接近该限制时截断。如果你使用 LangChain,你可以使用修剪消息工具并指定要从列表中保留的 Token 数以及处理边界的 strategy(例如保留最后 max_tokens 条)。 要在智能体中修剪消息历史,使用 @before_model 中间件装饰器:

删除消息

你可以从图状态中删除消息来管理消息历史。 这在你想要移除特定消息或清除整个消息历史时很有用。 要从图状态中删除消息,你可以使用 RemoveMessage 要使 RemoveMessage 工作,你需要使用带有 add_messages reducer 的状态键。 默认的 AgentState 提供了此功能。 要删除特定消息:
要删除所有消息:
删除消息时,确保生成的消息历史是有效的。检查你使用的 LLM 提供商的限制。例如:
  • 一些提供商要求消息历史以 user 消息开头
  • 大多数提供商要求带有工具调用的 assistant 消息后面跟着相应的 tool 结果消息。

摘要消息

如上所示,修剪或移除消息的问题在于你可能会因为消息队列的裁剪而丢失信息。 因此,一些应用程序受益于使用聊天模型对消息历史进行摘要的更复杂方法。 Summary 要在智能体中对消息历史进行摘要,使用内置的 SummarizationMiddleware
有关更多配置选项,请参阅 SummarizationMiddleware

访问记忆

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

工具

在工具中读取短期记忆

使用 runtime 参数(类型为 ToolRuntime)在工具中访问短期记忆(状态)。 runtime 参数对工具签名是隐藏的(模型看不到它),但工具可以通过它访问状态。

从工具写入短期记忆

要在执行期间修改智能体的短期记忆(状态),你可以直接从工具返回状态更新。 这对于持久化中间结果或使信息可供后续工具或提示词访问非常有用。

提示词

在中间件中访问短期记忆(状态),根据对话历史或自定义状态字段创建动态提示词。
输出

模型调用前

@before_model 中间件中访问短期记忆(状态),在模型调用之前处理消息。

模型调用后

@after_model 中间件中访问短期记忆(状态),在模型调用之后处理消息。