LLM 代理执行复杂任务和进行有意义交互的能力,很大程度上取决于其记忆。虽然底层的大型语言模型拥有一定量的预训练知识,但它在直接交互中本质上是无状态的。每次 API 调用通常都是独立的,除非明确提供,否则无法感知先前的交流。为了构建能够表现一致性、从经验中学习并在较长时间内保持上下文理解的代理,我们必须为它们配备专门的记忆机制。这些机制将代理的认知理解扩展到 LLM 即时上下文窗口之外。LLM 代理中记忆的重要性如果没有记忆,代理会将每次交互都视为第一次,无法回忆起之前的承诺、用户偏好或多步任务的演进状态。这种局限性严重限制了代理在任何需要连续性或个性化的应用中的实用性。有效的记忆系统满足以下多种需求:上下文感知:记忆使代理能够理解当前情况在更广泛的交互或任务历史中的位置。一致性:通过记住过去的陈述和行动,代理可以保持一致的形象并避免自相矛盾。学习与适应:存储过去行动的结果,使代理能够调整其行为,随着时间推移提高表现。个性化:记住用户特定信息,使代理能够定制响应和服务。克服上下文窗口限制:LLM 具有有限的上下文窗口。对于需要获取信息的长对话或任务,外部记忆对于存储和检索超出此窗口的相关数据非常重要。代理记忆的分类代理记忆大致可以分为两种主要类型:短期记忆和长期记忆,每种都有不同的功能并采用不同的实现策略。短期记忆(工作记忆)短期记忆,常称为工作记忆,存储与代理当前即时操作上下文相关的信息。它类似于人类的意识思维或计算机的 RAM,为 LLM 提供持续处理所需的数据。目的:维持对话的流畅性,追踪即时任务目标,存储计算或推理步骤的中间结果,并保存代理正在积极处理的瞬态数据。机制:对话缓冲区:存储代理与用户之间或代理之间最近的交流。常见策略包括:滑动窗口:保留最后 N 条消息或令牌。令牌限制:保留消息直到达到指定的令牌数量。摘要:定期总结对话中较旧的部分,以压缩信息并节省空间,并将摘要反馈到缓冲区中。草稿本:这些是临时存储区域,代理可以在其中记录中间思考、计算或计划,作为推理过程的一部分(例如,在 ReAct 或 Chain-of-Thought 提示中)。这有助于 LLM“逐步思考”并管理复杂任务。与 LLM 上下文窗口的交互:短期记忆通常直接格式化并插入到 LLM 的提示中。挑战在于有效地管理这些信息,以在 LLM 的上下文窗口限制内保持,同时保留重要上下文。长期记忆长期记忆使代理能够在较长时间内、跨多个会话或交互存储和回忆信息。这是代理的持久知识、学习到的经验和用户特定详情的所在地。目的:使代理能够构建持久的知识库,记住事实,回忆与用户的过去交互,存储用户偏好,并保留学习到的技能或程序。机制:向量数据库:这些是专门用于存储和搜索高维向量,特别是文本嵌入的优化数据库。当代理需要存储一段文本(例如,文档块、过去的对话片段)时,该文本会使用嵌入模型转换为数值向量(嵌入)。为了检索相关信息,代理的查询也会转换为嵌入,数据库会执行相似性搜索(例如,使用余弦相似度或点积)以找到语义最相似的存储向量。例子包括 Pinecone、Weaviate、Chroma 和 FAISS。结构化数据库:关系型数据库 (SQL):适用于存储定义明确的结构化数据,如用户档案、产品目录或交易历史。NoSQL 数据库(键值、文档、图):为各种数据类型提供灵活性。图数据库尤其擅长表示和查询实体之间的复杂关系,形成知识图谱。混合方法:通常,向量存储(用于非结构化文本的语义搜索)和结构化数据库(用于事实和关系数据)的组合,提供了一种全面的长期记忆解决方案。记忆系统架构精心设计的记忆架构确保代理能够有效访问和使用短期和长期信息。这两种类型的记忆并非孤立运行;它们不断交互。digraph G { rankdir=TB; node [shape=box, style="rounded,filled", fontname="Arial", fillcolor="#e9ecef", color="#495057"]; edge [fontname="Arial", color="#495057"]; subgraph cluster_agent { label = "LLM 代理记忆架构"; style="rounded"; bgcolor="#f8f9fa"; fontsize=14; LLM_Core [label="LLM 核心\n(处理与生成)", fillcolor="#a5d8ff", shape=Mdiamond]; subgraph cluster_stm { label = "短期记忆"; style="rounded,filled"; bgcolor="#f1f3f5"; ContextWindow [label="交互历史\n(例如:聊天缓冲区)", fillcolor="#d0bfff"]; Scratchpad [label="工作记忆\n(例如:中间步骤)", fillcolor="#d0bfff"]; } subgraph cluster_ltm { label = "长期记忆"; style="rounded,filled"; bgcolor="#f1f3f5"; VectorStore [label="向量存储\n(用于语义搜索的嵌入)", fillcolor="#96f2d7"]; StructuredDB [label="结构化数据库\n(关系型、图、键值)", fillcolor="#96f2d7"]; } Input [label="输入\n(查询、传感器数据、任务)", shape=ellipse, fillcolor="#ffec99"]; Output [label="输出\n(响应、行动)", shape=ellipse, fillcolor="#ffec99"]; Input -> LLM_Core; LLM_Core -> Output; LLM_Core -> ContextWindow [label=" 更新 "]; ContextWindow -> LLM_Core [label=" 提供上下文 "]; LLM_Core -> Scratchpad [label=" 写入/读取 ", dir=both, arrowhead=normal, arrowtail=normal]; LLM_Core -> VectorStore [label=" 查询 "]; VectorStore -> LLM_Core [label=" 检索结果 "]; LLM_Core -> StructuredDB [label=" 查询/存储 "]; StructuredDB -> LLM_Core [label=" 检索/确认 "]; ContextWindow -> VectorStore [label=" 摄入 (摘要/嵌入) ", style=dashed, color="#868e96", constraint=false]; ContextWindow -> StructuredDB [label=" 摄入 (结构化数据) ", style=dashed, color="#868e96", constraint=false]; } }LLM 代理的记忆系统,说明了 LLM 核心、短期记忆组件(如交互历史和工作记忆)与长期记忆存储(如向量存储和结构化数据库)之间的信息流。使用这种连接的一种常见模式是检索增强生成 (RAG)。在 RAG 配置中:当代理收到查询或需要执行任务时,它首先使用查询(可能用短期上下文增强)从其长期记忆(例如,向量存储)中检索相关信息。然后,这些检索到的信息与原始查询和任何其他相关的短期记忆(如最近的对话历史)结合,为 LLM 形成一个全面的提示。LLM 使用此增强的提示来生成响应或计划其下一步行动。检索时的考量包括:相关性:确保检索到的数据真正与当前上下文相关非常重要。不相关的信息会使 LLM 困惑或导致离题响应。延迟:从长期记忆中检索会增加延迟。系统必须优化以实现快速查找。数量:检索过多信息会使 LLM 的上下文窗口过载或淡化特定细节的重要性。通常采用重新排序检索到的块或对其进行摘要的策略。记忆操作:信息的生命周期管理代理的记忆涉及多种不同的操作:摄入这是将新信息添加到长期记忆的过程。信息可以通过以下方式摄入:手动:开发者或用户明确提供要存储的数据。自动:代理可以编程以处理文档、网页或其他数据源,提取相关信息并存储。从交互中:代理可能决定记住其对话或任务执行中的某些事实、用户偏好或结果。对于像向量存储这样的基于文本的长期记忆,摄入通常涉及:分块:将大段文本分解为更小、更易于管理的片段。嵌入:使用嵌入模型将每个块转换为数值向量。存储:在向量数据库中索引这些嵌入(通常还有原始文本块)。检索这是在需要时从记忆中获取相关信息的过程。有效的检索策略非常重要:查询制定:代理需要为其记忆系统制定有效查询。这可能涉及将用户的自然语言问题转换为更结构化的查询,或使用当前对话上下文的一部分作为语义搜索的基础。过滤与排序:检索到的结果通常需要在呈现给 LLM 之前进行过滤(例如,按日期、来源)并按相关性排序。合成信息检索后,必须将其合成并整合到代理的当前工作上下文中,通常通过适当格式化以包含在 LLM 提示中。这可能涉及:将检索到的块作为上下文呈现。总结多个检索到的信息片段。明确指示 LLM 如何使用检索到的数据。修改与遗忘记忆并非总是静态的。信息可能会过时、不相关或不正确。更新:修改现有记忆条目的机制很重要。遗忘:实现“遗忘”策略与记住同样重要。这可以防止记忆被无用数据 M 杂,并帮助代理保持最新状态。遗忘可以基于:基于时间的衰减:较旧的记忆可能被分配较低的相关性。相关性评分:不常访问或随着时间推移被认为相关性较低的记忆可能被存档或删除。明确删除:用户或其他系统可能触发删除特定信息。复杂代理的高级记忆考量随着我们设计更复杂的代理和多代理系统,记忆的作用和架构也变得更复杂。记忆与代理身份代理的长期记忆显著有助于其感知身份和形象。持续访问过去的交互、偏好和既定事实,使代理能够保持稳定的特性,并随着时间推移与用户建立良好关系。“健忘”的代理会迅速打破智能或连续性的假象。反思性记忆高级代理可以设计为反思存储在记忆中的过去经验。通过分析先前的行动、结果和反馈,代理可以从错误中学习,完善其策略,并随着时间推移提高表现。这可能涉及定期审查记忆日志以提取见解或识别模式。多代理团队中的记忆当多个代理协作时,记忆管理引入了新的维度:独立记忆与共享记忆:独立记忆:每个代理维护自己的私有记忆。这促进了自主性和专业化,但也可能导致信息孤岛。共享记忆:代理可以访问共同的记忆池。这有助于协调和共同理解,但需要仔细管理访问控制、一致性和潜在的争用。记忆共享机制:如果代理拥有独立记忆,它们需要协议来共享相关信息。这可以通过记忆片段的直接消息传递、查询指定的“记忆”代理或为共同知识库做出贡献来实现。成本与可伸缩性实现丰富的记忆系统会产生运营成本:存储:存储大量数据,特别是嵌入和原始文本,会产生费用。计算:生成嵌入、执行相似性搜索以及运行 LLM 调用以总结或处理记忆会消耗计算资源,如果使用第三方模型,可能会产生 API 费用。可伸缩性:记忆系统必须设计为能随代理数量、信息量和访问频率的增加而扩展。框架支持LangChain 和 LlamaIndex 等现代 LLM 开发框架提供了抽象和预构建组件,用于管理各种类型的代理记忆。例如,LangChain 提供了 BaseMemory 类(例如,ConversationBufferMemory、ConversationSummaryMemory、VectorStoreRetrieverMemory),简化了不同记忆策略集成到代理设计中。LlamaIndex 专注于数据索引和检索,提供了 StorageContext 和各种索引结构,这些结构作为代理长期知识的支撑。虽然这些工具提供了构建块,但对记忆架构原理的扎实理解对于根据特定多代理系统需求定制和优化记忆解决方案非常重要。通过精心设计和实现记忆机制,你将使你的 LLM 代理具备持续上下文感知、持续学习和个性化交互的能力,将它们从简单的响应者转变为更有能力、更智能的协作者。