首页 / 文章

智能体记忆类型解析:工作记忆、情景记忆、语义记忆和程序记忆

一名智能体两次修复了同一个错误,因为没有任何机制能保留修复结果。工作记忆、情景记忆、语义记忆与程序记忆——它们各自存储什么,又会如何出错。

发布者:REACTAPP.TOP阅读约 13 分钟2888 词

来源: **Agent Memory Explained: Working, Episodic, Semantic & Procedural**

有一个编程智能体曾连续两轮修复了同一个漏洞。并非有人指示它这么做,而且模型本身也没有任何问题。

在第一轮中,该智能体处理了BUG-142工单,将故障原因追溯到迁移操作的执行顺序,修改了代码,运行集成测试并确认测试通过。随后那一轮就结束了。

在下一轮开始之前,系统为了降低令牌成本会清除对话历史记录。这是个明智的选择,因为不断增长的对话记录不仅会增加费用、导致延迟,还会让提示信息变得混乱。但消失的并不仅仅是对话记录——那些通过测试的结果仅保存在旧的任务上下文窗口中。没有记录显示该漏洞已被解决,任务跟踪系统仍将BUG-142列为未完成状态。

第二轮会话开始后,我看到了一个未处理的工单,便按照工单要求进行了操作。我进行了调查,得出了相同的结论,并应用了同样的修复方案。

该模型并没有忘记如何解决这个问题,只是系统未能记录下问题已经得到解决的这一事实。

这一缺陷使得常规问题需要重新定义。与其思考如何为智能体赋予记忆,不如先探讨哪些类型的信息应该能够跨越会话持续存在。回答这个问题会引出四项独立的任务:

  • 工作记忆:当前正在处理的任务。
  • 情景记忆:发生了什么以及何时发生的。
  • 语义记忆:已被确认为真实的信息。
  • 程序记忆:做事的正确方法。

内存并非单一概念,至少承担着四项功能,而大多数内存错误都源于将它们混淆。这种划分借鉴了认知科学,在诸如CoALA(用于语言智能体的认知架构)之类的研究中有所体现,该研究从模块化内存、结构化动作以及决策过程的角度来描述语言智能体。

在依次探讨这四项功能之前,还有两个概念需要与内存本身区分开来:上下文窗口以及应用程序的权威状态。

上下文窗口即工作台

上下文指的是模型在单次推理过程中能够获取的所有信息。通常包括系统指令、工具定义、最新消息、检索到的文档、正在编辑的文件、工具输出以及当前计划。它就是智能体的活跃工作区。

这也只是暂时的。当会话结束,或者为了控制令牌使用量而压缩对话内容或删除旧消息时,除非应用程序特意将其保存到其他地方,否则这些内容就会消失。模型不会记住之前的对话记录。要么由应用程序将信息重新输入,要么将模型连接到外部存储中。

这就是为什么较大的上下文窗口并不等同于长期记忆。更大的上下文窗口只是更广阔的工作台,而非文件柜。在智能体工作期间会有更多内容显示出来,但一旦工作台被清空,上面的所有内容都会消失,除非有人先将重要部分保存下来。

在那个事件中,正确的解决方案就放在工作台上,但却没有得到重视。即便如此,仅仅保存完整的对话记录也无法解决问题,因为还有另一个关键点被忽视了。

内存并非系统的当前真实状态

比较以下两句话。一句是内存中的记录:“BUG-142已在昨天的会议中修复。”另一句则是应用程序的状态:该工单的状态字段显示为“已完成”。

二者虽有关联,但属于不同类型的信息。前者是记录某事件已发生的历史记录,后者则是跟踪系统当前的真实状态来源。内存记录的是过去发生的事情,而状态记录的是此刻的实际状况。

这种差异很重要,因为记忆会逐渐过时、不完整,甚至出现错误。想象一下,智能体检索到一条记录,上面写着BUG-142尚未解决。这条记录在撰写时可能是正确的,但无法证明今天的情况。在据此采取行动之前,智能体应先查询跟踪系统、查看代码仓库、运行相关测试或尝试重现问题。检索到的记忆只是对过去的陈述,而非关于现在的证据。

最初的故障已经两次失败。没有保留任何关于问题已解决的有用记录,权威的任务状态也从未更新。明确了这些情况后,我们就能弄清楚智能体究竟需要保留什么信息。

工作记忆:当前的任务

工作记忆仅存储智能体完成当前任务所需的信息,除此之外别无他物。对于BUG-142而言,其中可能包括任务本身、当前的假设(依赖关系表初始化过晚)、当前步骤(运行集成测试套件)、最新的观察结果(三项迁移测试失败)以及正在编辑的文件。

它用于回答实际问题:目标是什么?当前正在进行哪一步?上一个工具调用返回了什么结果?哪些文件发生了变化?还有哪些任务未完成?

在实践中,这些信息存储在提示语中、智能体状态对象里、工作流检查点中,或是生命周期较短的会话存储中。它们是临时的,仅与单个任务相关,并非用于记录系统所学的一切内容的持久日志。IBM对短期记忆的描述类似:即用于即时决策和保持对话连贯性的最新信息。

工作记忆也与其他三种记忆类型不同。情景记忆、语义记忆和程序记忆可以跨会话持续存在,而工作记忆则描述当前正在处理的内容,无论这些内容是暂时存储在内存中还是暂时保存在附近。

它的短暂寿命并非缺陷。一旦任务完成,就很少有理由保留所有的中间假设、未写完的片段、失败的指令或被放弃的思路。问题出现在重要结果仅存在于工作记忆中时。在那次事件中,有两样东西消失了:测试通过的结果以及BUG-142已被修复的事实。该系统将重要的结果当作可随意丢弃的临时空间。

工作记忆用于支持任务的执行,它绝不应成为已完成工作的唯一记录。

情景记忆:事件的记录

情景记忆存储具体的经历。一个情景不仅仅是事实,它发生在特定的情境中,通常包含时间、行为和结果。

对于BUG-142,一个有用的情景记录可以写成如下简短的结构化内容:

  • 事件:在迁移初始化过程中重现了BUG-142。
  • 背景:服务启动时依赖关系表不可用。
  • 采取的措施:改变了迁移执行的顺序。
  • 结果:集成测试通过。
  • 证据:提交记录a7f43d2。
  • 时间:2026年9月8日14:20。

这样的记录能够告知未来的智能体这种情况此前已经出现过。它有助于避免重复工作,提供示例,并显示之前的尝试哪些有效、哪些无效。CoALA将情景记忆与语义记忆区分开来,因为一次经历的记录与通用知识的作用不同。

情景记录也与聊天历史不同。聊天记录可能包含数百条消息、工具输出、推测、修正内容以及重复信息。在经过提炼的情景记录旁,可以加上简短的说明,例如“我们或许应该检查初始化顺序”,其内容为:重新排序依赖项的初始化解决了BUG-142问题,且在a7f43d2版本提交后测试全部通过。后者更易于检索,在后续任务中也更有用。

情景记忆仍可能以两种方式出错。系统可能会记住动作但忘记结果。仅留下“尝试过:已更改迁移顺序”的记录,会让未来的智能体不确定是否要再次尝试。或者,在架构发生变化后,智能体仍可能检索到六个月前的成功案例。情景记忆用于保存过去的信息,并不描述当下情况,正因如此,每个情景都应包含其发生的时间、背景、证据及结果。

语义记忆:智能体所掌握的知识

情景记录了发生的事情,而语义记忆则记录从中学到的知识。

BUG-142这个情景可以提炼出一个可重复使用的事实:迁移服务在启动初始化之前需要依赖表存在。这已不再局限于某一次调试过程,而是关于该系统的一个通用结论。

典型的条目包括服务使用的数据库、API调用速率限制、要求客户标识信息不得出现在日志中的规则、存储库的架构模式、用户对简练技术答案的偏好,以及迁移脚本需保持向后兼容性的要求。语义记忆涵盖事实、概念、约束条件、关系以及偏好设置。它通常具有较长的存续时间,但由于事实和偏好会发生变化,因此必须能够随时被修改。

它与情景记忆的区别很微妙,但值得牢记。情景记忆会记录“BUG-142是昨天发生的,因为启动时缺少依赖关系表”;而语义记忆则会说明“初始化过程要求该表必须先存在”。前者记住的是具体经历,后者记住的是其中的经验教训。

其典型的缺陷在于信息过时。假设团队后来采用了不再依赖该表格的新初始化机制,而内存系统只是简单地添加新事实,那么智能体可能会同时获取到这两个信息:一个表明表格必须先存在,另一个则称这已无关紧要。这样一来,内存就失去了清晰性。过时的信息甚至可能比没有信息更糟糕,因为智能体会满怀信心地依据它行事。

因此,语义记忆需要一条修正路径,即需要一些问题的答案。必须有人负责对事实进行更新,它需要有明确的来源说明以及最后验证日期。当出现更新版本时,旧版本应被标记为已被替换,随后要么删除,要么作为历史记录保留。这些都属于内存工程的内容。目前而言,关键在于语义记忆是用来保存可重复使用的知识,而不仅仅是事件的记录。

程序性记忆:任务如何完成

程序性记忆告诉智能体如何执行任务。它存储着技能、工作流程、操作规则以及可重复的方法。

针对某个缺陷,团队可以制定出相应的流程:在运行迁移初始化之前,先确认依赖关系表已存在;接着运行迁移集成测试,记录测试结果;更新任务跟踪系统;附上代码提交引用;最后确认该问题不再出现。

那并非事实,尽管它源于某种事实。从语义层面来看,事实是必须在初始化之前创建该表。而从程序规则而言,则是在初始化前先验证其是否存在。语义记忆负责说明什么是真实的,而程序记忆则规定该做些什么。其他例子包括:回滚失败的部署、调查支付失败问题、在关闭缺陷前必须通过哪些测试、如何审查拉取请求、何时需要人工审批,以及在操作生产数据之前必须使用哪种工具。

实现方式多种多样,从简明的指令和分版本的操作手册,到打包好的技能、工作流定义、纯代码或从实践中总结出的模式。CoALA为这些程序规则在智能体记忆中提供了专属位置,使其既与模型的能力相关联,也与智能体的显式代码相绑定。

正因如此,流程应当像软件一样进行版本管理,而非像聊天记录那样堆积起来。如果某个组织改变了其部署流程,自动化工具就不应去检索五个旧版本的操作步骤并试图判断哪个是当前有效的。任何在生产环境中运行的内容都应明确说明其负责人、所在版本、生效时间、覆盖范围、被替代的版本,以及如何确认其仍能正常运行。

在这起事件中,缺失的操作流程直接导致了问题。自动化工具虽然修复了代码,但并没有相应规则要求它将这一修复结果转化为更新后的应用状态。缺失的并非整个对话记录,而是一条明确的指令,类似“测试通过后需记录结果并关闭工单”。这正是流程上的漏洞。

一个缺陷,五种表述方式

通过用五种不同的方式描述同一个缺陷,最能清晰地体现这种分类体系。

  • 工作记忆:“目前正在修复BUG-142,下一步是进行集成测试。”它用于维持当前的运行状态。
  • 情景记忆:“在第一次会话中,通过调整依赖顺序修复了BUG-142,且测试通过。”它用于保存特定经历。
  • 语义记忆:“迁移服务在初始化前需要依赖关系表。”它用于保存可重复使用的知识。
  • 程序记忆:“在初始化迁移之前,需先验证表结构并运行集成测试。”它用于保存可重复执行的方法。
  • 权威状态:状态为已完成,提交编号为a7f43d2,测试结果为通过。它记录了应用程序认定的真实信息。

它们之间存在关联但不可互相替代。事件记录无法取代任务记录,而任务记录也未能保存事故处理过程中学到的所有信息。事实本身无法定义完整的调试流程,而调试流程也无法证明某个特定错误已被修复。工作记忆不可能持续到会话结束之后。

系统不仅未能记住某件事,还未能将已完成的工作转化为合适的持久形式。

每种类型都有其独特的故障表现

如果将所有信息都存放在同一个没有区分的存储空间中,诊断就会变得困难。此时最好先弄清楚是哪项信息处理失败了。

  • 当智能体在重置后丢失当前计划时,工作记忆就会失效,这通常是因为任务进度仅存储在窗口或本地进程中。
  • 当智能体重复实验或重做已完成的工作时,情景记忆会失效,因为先前的事件、动作或结果未被保存或无法被检索。
  • 当智能体自信地使用过时的信息时,语义记忆会失效,因为该信息已经发生变化,而旧版本从未被替换。
  • 当智能体完成技术工作却跳过某个操作步骤时,程序记忆会失效,因为相关工作流程缺失、过时、模糊或不可用。
  • 当智能体根据错误的任务状态采取行动时,权威状态机制会失效,因为真实信息来源的记录未被更新或未经过核实。
  • 每项工作都有其自身的规则,规定谁可以编写内容、如何获取数据、数据保存时长、如何修复错误以及如何评估质量。向量索引有助于检索多种类型的记忆数据,但无法决定内容的类型。一个可行的原则是:在选择存储技术之前先对信息进行分类。

    简短的分类检查清单

    当智能体遇到某条信息时,按顺序询问以下问题。

    1. 它是否仅当前任务所需?属于工作记忆。比如当前的计划、最新的工具检测结果或临时假设。
    2. 它是否是已经发生的特定事件?属于情景记忆。比如昨天失败的部署、未成功的修复尝试、用户拒绝的设计方案。
    3. 它是否是可重复使用的知识?属于语义记忆。比如架构、偏好设置、领域约束条件以及业务定义。
  • 它是工作流、规则还是技能?属于程序性记忆,比如部署流程、测试清单、工具使用政策或升级路径。
  • 它是当前的真实数据来源吗?即具有权威性的应用状态,如工单状态、账户余额、部署状态、库存情况以及审批状态。
  • 同一事件往往需要多种表达方式。一次失败的部署可能会产生一个事件描述(它在14:20失败)、一个事实陈述(服务X需要版本17的架构),一项操作流程(部署前需检查架构兼容性),以及一个状态变化记录(部署已回滚)。这并非浪费性的重复,因为每种表达方式都在回答不同的问题。

    该工具本应如何处理

    该上下文无需永远存在。工作流需要做的是在结束会话前确保重要结果得到保存:撰写相关内容,若存在事实则提取出来,补充或更新操作流程,并通过提交记录与测试证据来设定工单状态。

    如此一来,清除旧对话便是安全的。原始记录可以删除,因为所有值得保留的内容都已转化为必须留存的形式。上下文可以消失,但重要结果不应随之丢失。

    其带来的影响

    分类是起点,更复杂的工程问题则随之而来。哪些信息值得存储?每种类型应存储在何处,谁有权限修改它们?何时检索这些信息,它们如何进入系统视野?何时更新这些信息,又何时会过期?当两个记忆版本存在冲突时会发生什么,又该如何判断这些记忆是否真正提升了智能体的性能?

    这些问题共同构成了记忆工程,而在信息被分类之前,这些问题的任何一项都无法得到妥善解答。因此,在选择向量数据库、记忆框架或检索策略之前,先弄清楚智能体试图保存的是何种类型的信息。

    目标并非让智能体记住所有事物,而是确保有用的信息能够以适合其使用方式的格式被保存下来。接下来是记忆所遵循的生命周期:体验、提取、决定保留什么、存储、检索、注入到上下文中、验证、执行动作,最后是更新或遗忘。