想象一下,你正试图与一个瞬间就忘记你所说一切的人交谈。每句话都将是一个全新的开始,使得任何有意义的交流都无法进行。大型语言模型(LLM)代理,如果没有办法记住近期互动,也将面临类似的挑战。我们所说的“记住近期事件”的能力,在LLM代理的背景下,就是短期记忆。它是一个基本组成部分,允许代理在持续的操作或对话中保持上下文。为什么代理需要记录与LLM静态的预训练知识不同,短期记忆是动态的。它涉及当前正在处理的特定任务或当前的交互会话。可以将其视为代理的草稿本,它在上面记下刚刚发生的事情。这并非永久学习新事实,比如LLM已经知道的法国首都。相反,它是关于记住你刚刚在这段对话中询问了飞往巴黎的航班,这样当你接着问“那里的酒店呢?”时,代理就能明白“那里”指的是巴黎。如果没有这种记忆,与代理的每次交互都将是孤立的。代理将无法做到:理解后续问题。引用对话中较早提供的信息。执行需要多步骤且前一步骤的上下文很必要的任务。在整个交互过程中保持连贯的“个性”或状态。本质上,短期记忆赋予了代理一种连续感。它允许代理在先前的交流基础上进行,使交互更顺畅、更有效。短期记忆的工作方式(一个简单视角)在基本层面,LLM代理的短期记忆通常涉及保留近期交互的日志或历史记录。此历史记录通常包含:用户的输入。代理自身的响应或行动。当代理需要处理用户的新输入时,它不仅仅是孤立地查看那一条信息。相反,它(或控制它的系统)不仅向LLM提供新输入,还提供部分或全部近期历史记录。这种组合信息形成了一个更丰富的提示,为LLM提供生成相关且充分响应所需的上下文。例如,如果你正在与一个代理交互:你:“将‘买牛奶’添加到我的待办事项列表。”**代理(记录在记忆中):**用户说“将‘买牛奶’添加到我的待办事项列表”。代理回应“好的,‘买牛奶’已添加。”你:“也添加‘打电话给约翰’。”**代理(处理“也添加‘打电话给约翰’”时):**LLM收到“也添加‘打电话给约翰’”以及关于牛奶的先前交互记忆。这有助于它理解“也添加”指的是待办事项列表。以下图描绘了短期记忆如何融入代理的运行流程:digraph G { rankdir=TB; graph [fontname="sans-serif"]; node [shape=box, style="filled,rounded", fillcolor="#e9ecef", fontname="sans-serif"]; edge [fontname="sans-serif"]; UserInput [label="用户输入", fillcolor="#a5d8ff"]; AgentCore [label="代理核心\n(结合输入 + 记忆)", fillcolor="#ffd8a8"]; LLM [label="大型语言模型", fillcolor="#b2f2bb"]; AgentResponse [label="代理对用户的响应", fillcolor="#a5d8ff"]; Memory [label="短期记忆\n(例如:对话历史)", fillcolor="#ffc9c9", shape=cylinder]; UserInput -> AgentCore [label="新信息"]; Memory -> AgentCore [arrowhead=vee, label="提供上下文"]; AgentCore -> LLM [arrowhead=vee, label="形成的提示\n(输入 + 上下文)"]; LLM -> AgentCore [arrowhead=vee, label="LLM输出"]; AgentCore -> AgentResponse [arrowhead=vee, label="交付给用户"]; AgentCore -> Memory [arrowhead=vee, label="用新一轮更新\n(输入 + 输出)"]; }此图描绘了用户输入与现有短期记忆如何结合,为LLM形成完整提示的循环。LLM的输出随后被用于回应用户,并同时更新短期记忆以备后续交互。保持“短期”“短期”这个词有其含义。LLM在一次处理的文本量上存在限制(常称为“上下文窗口”)。如果对话历史变得太长,可能会超出这个限制。因此,短期记忆的实际实现方式通常涉及以下策略:只保留对话的最后几轮。总结对话中较旧的部分。使用更精细的技术来获取过去的相关信息(我们将在后续章节中会涉及)。目前,需要理解的是,代理需要某种机制来记住近期事件,以便智能地运作。这种能力,即使是最简单的形式,也能将LLM从无状态的文本生成器转变为一个更有用、更具交互性的助手。当我们构建第一个代理时,我们会看到即使是基本的记忆也能产生很大的作用。在第六章“LLM代理记忆:信息回顾”中,我们将更详尽地研究这些机制。