概述

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

用法

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

生产环境

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

自定义代理记忆

您可以通过创建带有状态模式的自定义中间件来扩展代理状态。自定义状态模式可以使用中间件中的 stateSchema 参数传递。建议使用 StateSchema 类进行状态定义(也支持纯 Zod 对象)。

常见模式

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

裁剪消息

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

删除消息

从 LangGraph 状态中永久删除消息

总结消息

总结历史中的早期消息并用摘要替换它们

自定义策略

自定义策略(例如,消息过滤等)
这使代理能够跟踪对话而不超过 LLM 的上下文窗口。

裁剪消息

大多数 LLM 都有最大支持的上下文窗口(以 token 计量)。 决定何时截断消息的一种方法是计算消息历史中的 token 数,并在接近该限制时进行截断。如果您正在使用 LangChain,可以使用裁剪消息工具,并指定要从列表中保留的 token 数量,以及用于处理边界的 strategy(例如,保留最后的 maxTokens)。 要在代理中裁剪消息历史,请使用带有 beforeModel 钩子的 createMiddleware:

删除消息

您可以从图状态中删除消息以管理消息历史。 当您想要删除特定消息或清除整个消息历史时,这非常有用。 要从图状态中删除消息,您可以使用 RemoveMessage。为了让 RemoveMessage 生效,您需要使用带有 messagesStateReducer 归约器 的状态键,例如 MessagesValue。 要删除特定消息:
删除消息时,请 确保 结果消息历史记录是有效的。请检查您正在使用的 LLM 提供商的限制。例如:
  • 一些提供商期望消息历史以 user 消息开头
  • 大多数提供商要求带有工具调用的 assistant 消息后面必须跟相应的 tool 结果消息。

总结消息

如上所示,裁剪或删除消息的问题在于,您可能会因裁剪消息队列而丢失信息。 因此,一些应用程序受益于使用聊天模型来总结消息历史的更复杂方法。 总结 要在代理中总结消息历史,请使用内置的 summarizationMiddleware:
更多配置选项请参阅 summarizationMiddleware。

访问记忆

您可以通过几种方式访问和修改代理的短期记忆(状态):

工具

在工具中读取短期记忆

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

从工具写入短期记忆

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

提示

在中间件中访问短期记忆(状态),以创建基于对话历史或自定义状态字段的动态提示。

模型调用前

模型调用后