- 短期记忆,或线程范围记忆,通过维护会话内的消息历史来跟踪正在进行的对话。LangGraph将短期记忆作为代理状态的一部分进行管理。状态通过检查点持久化到数据库中,以便线程可以随时恢复。短期记忆在图被调用或步骤完成时更新,并在每个步骤开始时读取状态。
- 长期记忆存储跨会话的用户特定或应用程序级数据,并在对话线程之间共享。它可以在任何时候和任何线程中被召回。记忆的范围可以是任何自定义命名空间,而不仅仅是单个线程ID。LangGraph提供存储(参考文档),让您可以保存和召回长期记忆。

短期记忆
短期记忆让您的应用程序可以记住单个线程或对话中的先前交互。线程在一个会话中组织多个交互,类似于电子邮件将消息分组到一个对话中。 LangGraph将短期记忆作为代理状态的一部分进行管理,并通过线程范围的检查点进行持久化。此状态通常可以包括对话历史以及其他有状态数据,例如上传的文件、检索到的文档或生成的工件。通过将这些数据存储在图的状态中,机器人可以访问给定对话的完整上下文,同时保持不同线程之间的分离。管理短期记忆
对话历史是短期记忆最常见的形式,而长对话对当今的LLM来说是一个挑战。完整的历史可能无法完全适应LLM的上下文窗口,从而导致不可恢复的错误。即使您的LLM支持完整的上下文长度,大多数LLM在长上下文下的表现仍然不佳。它们会被陈旧或偏离主题的内容“分心”,同时还会导致响应时间变慢和成本升高。 聊天模型通过消息接受上下文,其中包括开发者提供的指令(系统消息)和用户输入(人类消息)。在聊天应用程序中,消息在人类输入和模型响应之间交替,导致消息列表随着时间增长。由于上下文窗口有限且富含令牌的消息列表可能成本高昂,许多应用程序可以受益于使用技术来手动删除或遗忘陈旧信息。
长期记忆
LangGraph 中的长期记忆允许系统在不同的对话或会话中保留信息。与短期记忆(它是线程范围的)不同,长期记忆存储在自定义“命名空间”中。 长期记忆是一个复杂的挑战,没有一劳永逸的解决方案。但是,以下问题提供了一个框架来帮助您驾驭不同的技术:- 记忆的类型是什么?人类使用记忆来记住事实(语义记忆)、经验(情景记忆)和规则(程序记忆)。AI代理也可以以同样的方式使用记忆。例如,AI代理可以使用记忆来记住用户的特定事实以完成任务。
- 您何时要更新记忆?记忆可以作为代理应用程序逻辑的一部分进行更新(例如,“在热路径中”)。在这种情况下,代理通常在响应用户之前决定记住事实。或者,记忆可以作为后台任务进行更新(在后台/异步运行并生成记忆的逻辑)。我们将在下面的部分解释这些方法之间的权衡。
语义记忆
语义记忆,无论是人类还是AI代理,都涉及对特定事实和概念的保留。在人类中,它可能包括在学校学到的信息以及对概念及其关系的理解。对于AI代理,语义记忆通常用于通过记住过去交互中的事实或概念来个性化应用程序。语义记忆不同于“语义搜索”,后者是一种使用“意义”(通常是嵌入)来查找相似内容的技术。语义记忆是心理学中的一个术语,指的是存储事实和知识,而语义搜索是一种根据意义而不是精确匹配来检索信息的方法。
配置文件
记忆可以是一个单一的、持续更新的“配置文件”,其中包含关于用户、组织或其他实体(包括代理本身)的范围明确的特定信息。配置文件通常只是一个 JSON 文档,其中包含您选择的各种键值对,以表示您的领域。 在记住配置文件时,您需要确保每次都更新配置文件。因此,您需要传入之前的配置文件并要求模型生成一个新配置文件(或应用于旧配置文件的某些 JSON 补丁)。随着配置文件变大,这可能会变得容易出错,并且可能受益于将配置文件拆分为多个文档或在生成文档时进行严格解码,以确保记忆模式保持有效。
集合
或者,记忆可以是一个文档集合,随着时间的推移不断更新和扩展。每个独立的记忆范围更窄,更容易生成,这意味着您随着时间推移丢失信息的可能性更小。对于 LLM 来说,为新信息生成新对象比将新信息与现有配置文件协调更容易。因此,文档集合倾向于导致更高的下游召回率。 然而,这使得记忆更新的复杂性有所增加。模型现在必须删除或更新列表中的现有项目,这可能很棘手。此外,一些模型可能会默认过度插入,而另一些模型可能会默认过度更新。请参阅 Trustcall 包,了解一种管理此问题的方法,并考虑使用评估(例如,使用 LangSmith 等工具)来帮助您调整行为。 处理文档集合还将复杂性转移到对列表进行记忆搜索。Store 当前支持语义搜索和按内容过滤。 最后,使用记忆集合可能会使向模型提供全面上下文变得具有挑战性。虽然单个记忆可能遵循特定的模式,但这种结构可能无法捕捉记忆之间的完整上下文或关系。因此,当使用这些记忆生成响应时,模型可能缺乏统一配置文件方法中更容易获得的重要上下文信息。 
情景记忆
情景记忆,无论是人类还是AI代理,都涉及回忆过去的事件或行为。CoALA 论文对此进行了很好的阐述:事实可以写入语义记忆,而经验可以写入情景记忆。对于AI代理,情景记忆通常用于帮助代理记住如何完成任务。 实际上,情景记忆通常通过少样本示例提示来实现,即代理从过去的序列中学习以正确执行任务。有时“展示”比“告诉”更容易,而LLM通过示例学习效果很好。少样本学习允许您通过使用输入-输出示例更新提示来“编程”您的LLM,以说明预期的行为。虽然可以使用各种最佳实践来生成少样本示例,但通常的挑战在于根据用户输入选择最相关的示例。 请注意,记忆存储只是存储数据作为少样本示例的一种方式。如果您希望有更多的开发者参与,或者将少样本示例更紧密地与您的评估工具结合起来,您还可以使用 LangSmith 数据集来存储您的数据。然后,可以开箱即用地使用动态少样本示例选择器来实现相同的目标。LangSmith 将为您索引数据集,并根据关键词相似性检索与用户输入最相关的少样本示例。 有关 LangSmith 中动态少样本示例选择的示例用法,请参阅此操作指南视频。此外,请参阅这篇博客文章,展示了少样本提示如何提高工具调用性能,以及这篇博客文章,使用少样本示例使 LLM 与人类偏好保持一致。程序记忆
程序性记忆,在人类和人工智能代理中,都涉及记住执行任务的规则。在人类中,程序性记忆就像是执行任务的内在知识,例如通过基本运动技能和平衡骑自行车。另一方面,情景记忆涉及回忆特定经验,例如第一次成功骑自行车没有辅助轮,或者一次难忘的风景优美的自行车之旅。对于人工智能代理,程序性记忆是模型权重、代理代码和代理提示的组合,它们共同决定了代理的功能。 实际上,代理修改其模型权重或重写其代码的情况相当罕见。然而,代理修改其自身提示的情况更为常见。 完善代理指令的一种有效方法是通过“反思”或元提示。这涉及使用其当前指令(例如系统提示)以及最近的对话或明确的用户反馈来提示代理。然后,代理根据此输入完善其自身指令。此方法对于指令难以预先指定的任务特别有用,因为它允许代理从其交互中学习和适应。 例如,我们构建了一个推文生成器,使用外部反馈和提示重写来为 Twitter 生成高质量的论文摘要。在这种情况下,特定的摘要提示很难先验地指定,但用户可以相当容易地批评生成的推文并提供有关如何改进摘要过程的反馈。 下面的伪代码展示了您如何使用 LangGraph 记忆存储实现这一点,使用存储来保存提示,update_instructions 节点来获取当前提示(以及从与用户对话中捕获的反馈,存储在state["messages"]中),更新提示,并将新提示保存回存储。然后,call_model 从存储中获取更新后的提示并使用它来生成响应。
写入记忆
代理写入记忆主要有两种方法:“在关键路径中”和“在后台”。
在关键路径中
在运行时创建记忆既有优点也有挑战。积极的一面是,这种方法允许实时更新,使新记忆立即可用于后续交互。它还实现了透明性,因为可以在创建和存储记忆时通知用户。 然而,这种方法也带来了挑战。如果代理需要新工具来决定将什么提交到记忆中,它可能会增加复杂性。此外,推理要保存到记忆中的过程可能会影响代理的延迟。最后,代理必须在记忆创建和其他职责之间进行多任务处理,这可能会影响创建记忆的数量和质量。 例如,ChatGPT 使用 save_memories 工具以内容字符串的形式插入记忆,并决定是否以及如何使用此工具处理每条用户消息。请参阅我们的 memory-agent 模板作为参考实现。在后台
将记忆创建作为独立的后台任务提供了诸多优势。它消除了主应用程序中的延迟,将应用程序逻辑与记忆管理分离,并允许代理更专注于任务完成。这种方法还在时间安排上提供了灵活性,以避免重复工作。 然而,这种方法也有其自身的挑战。确定记忆写入的频率至关重要,因为不频繁的更新可能会导致其他线程缺乏新上下文。决定何时触发记忆形成也很重要。常见的策略包括在设定的时间段后安排(如果发生新事件则重新安排)、使用 cron 计划或允许用户或应用程序逻辑手动触发。 请参阅我们的 memory-service 模板作为参考实现。记忆存储
LangGraph 将长期记忆存储为 JSON 文档,位于存储中。每个记忆都组织在一个自定义的namespace 下(类似于文件夹)和一个独特的 key(像文件名)。命名空间通常包括用户或组织 ID 或其他标签,以便更轻松地组织信息。这种结构支持记忆的分层组织。然后,通过内容过滤器支持跨命名空间搜索。
以编程方式连接这些文档到 Claude、VSCode 等,通过 MCP 获取实时答案。