> **来源:[研报客](https://pc.yanbaoke.cn)** # 上下文工程 # 会话和记忆 作者:Kimberly Milam and Antonio Gulli 译者:架构师之道 日期:2025年12月3日 # 目录 1 引言 2 2上下文工程 4 3 会话 (Sessions) 9 代码片段1:多轮对话调用Gemini的Python示例 10 3.1 不同框架和模型如何实现会话 ..... 10 3.2 多智能体系统中的会话管理 ..... 12 3.3 智能体会话的生产环境考量 16 3.4 长上下文对话的管理:权衡与优化 ..... 17 3.5 记忆生成:从对话中提炼持久知识 ..... 19 4 记忆 (Memory) 20 表 1: RAG 引擎与记忆管理器对比 ..... 22 4.1 记忆的类型 ..... 23 4.2 记忆生成:提取与整合 30 4.3 记忆溯源 (Memory Provenance) 36 4.4 触发记忆生成 ..... 38 4.5 记忆检索 (Memory Retrieval) 41 4.6 基于记忆的推理 (Inference with Memories) 44 4.7 程序性记忆 (Procedural Memories) 46 4.8 测试与评估 (Testing and Evaluation) 47 4.9 记忆系统的生产环境考量(Production Considerations for Memory)……48 4.10隐私与安全风险(Privacy and security risks) 50 5结论 51 6 参考文献 52 如果您对此白皮书感兴趣,可以关注我的微信公众号,一起探讨技术不亦快哉! # 1 引言 有状态、个性化的 AI,始于上下文工程。 本白皮书探讨了会话(Sessions)与记忆(Memory)在构建有状态、智能化的大语言模型(LLM)智能体中的关键作用,旨在帮助开发者打造更强大、更个性化且具备持久性的AI体验。 要让大语言模型能够“记住”用户、“学习”偏好,并实现个性化的交互,开发者必须在其有限的上下文窗口中,动态地组织和管理相关信息——这一过程被称为上下文工程(Context Engineering)。 以下是本白皮书涉及的几个核心概念: - 上下文工程(Context Engineering):指在大语言模型的上下文窗口内,动态组装和管理信息的过程,目的是赋予智能体“有状态”和“智能化”的能力。 - 会话(Sessions):一次完整人机对话的容器,不仅记录对话的完整时间线,还保存智能体在当前交互中的“工作记忆”(working memory)。 - 记忆(Memory):实现长期信息留存的机制。它能从多次会话中提取并整合关键信息,使 AI 智能体在不同时间点与用户互动时,仍能保持连贯性和个性化体验。 译者注:大语言模型本身是“无记忆”的——每次对话对它来说都像第一次见面。正是通过上下文工程、会话管理和记忆系统,我们才能让 AI 表现出“记得你”、“了解你”的能力,从而迈向真正的 Agentic AI。 # 2上下文工程 大语言模型(LLM)本质上是“无状态”的——除了训练数据之外,它们的推理和认知能力完全受限于单次 API 调用中所提供的“上下文窗口”内的信息。这带来了一个根本性挑战:要让 AI 智能体真正发挥作用,它必须清楚三件事: 1. 自己能做什么(有哪些操作权限); 2. 依据什么事实进行推理(有哪些证据或知识); 3. 当前任务是什么(用户此刻在问什么)。 而这些信息并不会自动出现在模型面前。为了让智能体具备“记忆”、“学习”和“个性化交互”的能力,开发者必须在每一次对话轮次中,主动为模型构建合适的上下文。这种动态组装和管理信息的过程,就叫做上下文工程(Context Engineering)。 上下文工程可以看作是传统“提示工程(Prompt Engineering)”的升级版。 - 提示工程关注的是如何写出最优的、通常是静态的系统指令(比如“你是一个乐于助人的助手”)。 - 而上下文工程则着眼于整个输入载荷(payload),根据用户身份、对话历史和外部数据,动态构建一个具备状态感知能力的完整提示。 它的核心在于:精准选择、适当摘要、适时注入不同类型的信息,在最大化相关性的同时,尽量减少噪声干扰。 这些上下文信息通常由外部系统提供,例如: - 基于检索增强生成(RAG)的知识库, - 会话存储系统, - 记忆管理模块。 而智能体框架的任务,就是协调这些系统,把所需信息“拼装”成最终发送给大语言模型的提示。 你可以把上下文工程想象成厨师做菜前的“备菜”(法语叫 mise en place)——这是烹饪前最关键的一步:把所有食材洗净切好,工具摆齐,调料备妥。 如果只给厨师一份菜谱(相当于只给模型一个提示),他可能只能用厨房里随便找到的东西凑合做一顿饭。 但如果你提前为他准备好新鲜的食材、专用的厨具、以及对菜品风格的清晰理解,他就能稳定地做出一道量身定制的美味佳肴。 上下文工程的目标正是如此:确保模型拿到的信息不多不少,刚好是完成当前任务最相关、最精炼的内容。 译者注:上下文工程的本质是“状态外化”。LLM的无状态性是其根本限制,上下文工程实际上是:将本应内化的状态管理,通过外部系统显式实现。这有点类似于计算机架构中的“内存层次结构”:寄存器(当前上下文) $\rightarrow$ 缓存(会话) $\rightarrow$ 主存(记忆) $\rightarrow$ 外存(知识库)。 一次完整的上下文载荷通常包含三大类信息: 1)指导推理的上下文。它定义智能体的基本行为模式和可用能力: - 系统指令(System Instructions):设定智能体的角色、能力边界和行为准则(例如“你是一个医疗顾问,不能提供诊断”)。 - 工具定义(Tool Definitions):描述智能体可调用的外部功能(如查询天气、发送邮件的API接口规范)。 - 少量示例(Few-Shot Examples):通过几个精心挑选的例子,引导模型学会如何完成特定任务(属于“上下文内学习”,in-context learning)。 2)用于推理的事实与证据。这是智能体做判断所依赖的“原材料”: - 长期记忆(Long-Term Memory):跨多次会话积累的关于用户或主题的关键信息(比如“用户对花生过敏”)。 - 外部知识 (External Knowledge):通过 RAG 等技术从数据库或文档中实时检索的信息。 - 工具输出(Tool Outputs):调用外部工具后返回的数据(如“当前北京气温 $5^{\circ}$ C”)。 - 子智能体输出(Sub-Agent Outputs):由专门负责某项子任务的其他智能体返回的结果。 - 工件(Artifacts):与用户或会话相关的非文本数据,如上传的图片、PDF文件等。 3)当前对话的即时信息。让智能体“锚定”在当前交互场景中: - 对话历史(Conversation History):本次会话中用户与智能体一来一回的完整记录。 - 状态/草稿板 (State / Scratchpad):智能体在当前推理过程中临时使用的中间变量或计算步骤。 - 用户当前提问 (User's Prompt):用户刚刚输入的具体问题。 上下文不是静态的。例如,记忆需要根据新交互动态更新和选择性调用;少量示例也应匹配当前任务,而不是死板地复用固定模板;外部知识则要根据用户当前问题,通过RAG工具实时检索。 更重要的是,随着对话越来越长,上下文会“膨胀”。虽然理论上大语言模型支持超长上下 文窗口(如 128K tokens),但实践中会遇到两个问题: 1. 成本与延迟上升:输入越长,计算越贵、响应越慢; 2. 上下文衰减(Context Rot):模型在超长上下文中容易“注意力涣散”,忽略关键信息。 译者注:LLM的“上下文衰减”问题比表面看起来更严重,其实际表现为: 1. 位置偏见:模型对开头和结尾内容更敏感; 2. 信息淹没:关键细节在长文本中容易被忽略; 3. 关联断裂:跨长距离的语义关联能力下降。 因此,上下文工程必须采用智能压缩策略,例如: - 对旧对话进行摘要, - 选择性删除无关内容, - 或使用其他上下文精简技术。 这样既能保留核心信息,又能控制 token 数量,最终实现更稳定、更个性化的 AI 体验。 译者注:关于上下文优先级设计,建议采用分层策略。 P0: 系统指令 + 当前问题 (必需) P1: 关键记忆 + 工具定义 (重要) P2:对话历史 + 示例 (辅助) P3:扩展知识 (可选) 译者注:关于上下文压缩的技术路线,除了使用摘要,还有:1)提取式压缩,保留关键句子;2)抽象式压缩,重写为精炼版本;3)结构化压缩,转为表格或列表格式。 译者注:另外还要主意高级压缩策略会产生额外的LLM调用成本。1)简单截断:成本 $= 0$ ,但信息损失大;2)关键词提取:成本 $=$ 小模型调用;3)递归摘要:成本 $=$ 多次大模型调用;4)智能压缩:成本 $=$ 压缩模型 $+$ 验证模型。实际应根据会话价值和预算动态选择。 在每一次对话轮次中,智能体都会执行一个标准的上下文管理流程: 图1:智能体的上下文管理流程 1. 获取上下文(Fetch Context):智能体首先根据用户当前提问和元数据,从记忆库、RAG系统、最近对话记录等来源拉取所需信息。 2. 准备上下文(Prepare Context):框架将所有信息动态组装成最终提示。虽然后续的 LLM 调用可能是异步的,但上下文准备是“关键路径”上的阻塞操作——必须等它完成,才能继续。 3. 调用大语言模型与工具(Invoke LLM and Tools):智能体反复调用 LLM 和必要工具(如搜索、计算),直到生成最终回答。过程中产生的工具输出或中间结果会被追加到上下文中。 4. 上传上下文(Upload Context):本轮新产生的信息(如用户偏好、结论、文件)会被写入持久化存储。这通常作为后台任务异步执行,不影响主流程响应速度,便于后续进行记忆整合等操作。 译者注:从系统工程的视角来看,这个流程实际上构成了一个完整的控制论反馈系统:获取 $\rightarrow$ 准备 $\rightarrow$ 执行 $\rightarrow$ 更新,每个环节都需要精心设计,特别是错误处理和回滚机制。 译者注:关于错误恢复机制,上下文工程必须考虑:1)降级策略,当上下文过长或混乱时的备选方案;2)回滚机制,识别并移除“污染”上下文的错误信息;3)重试逻辑,基于修正后上下文的重新尝试。 这个流程的核心,是两个基础组件:会话(Session)和记忆(Memory)。 - 会话管理单次对话的逐轮状态,就像你为某个项目临时搭起的工作台:上面堆满了草稿、参考文档、工具和半成品——一切触手可及,但只是临时的。 - 记忆则负责长期留存,如同一个整理好的档案柜:项目结束后,你不会把整个乱糟糟的工作台塞进柜子,而是筛选出关键成果,丢掉废稿,归档精华。 正是这种“工作台 + 档案柜”的配合,让智能体既能灵活应对当前任务,又能在未来对话中“记得你、了解你”。 有了对上下文工程的整体理解,接下来我们将深入探讨它的两大支柱:会话机制与记忆系统。我们先从会话开始。 译者注:本章我产生了一些联想思考。上下文质量验证这一点 Google 没谈到。我认为它至少包含四点:1)相关性检查:检索的内容是否与问题相关;2)一致性检查:不同来源信息是否冲突;3)时效性检查:信息是否过时;4)完整性检查:关键信息是否缺失。 # 3 会话 (Sessions) 在上下文工程中,会话(Session)是一个基础性组件。它就像一次完整对话的“快照”,封装了当前交互的全部历史记录和智能体在本次对话中的临时工作记忆。 每个会话都与特定用户绑定,是独立且自包含的。即使同一个用户发起多次对话,每一次都会生成一个全新的会话——彼此之间互不干扰,就像你每次打开一个新的聊天窗口。 会话包含了两样东西: 1. 事件日志(Events):按时间顺序记录对话中的每一个动作; 2. 工作状态 (State) : 一个结构化的“草稿板”, 存放当前任务所需的临时数据。 译者注:事件日志是不可变的、仅追加的审计轨迹,用于重放和调试;工作状态是可变的数据结构,存储当前处理结果。 事件是构成对话的基本单元。常见的事件类型包括: - 用户输入:用户发送的消息(可以是文字、语音、图片等); - 智能体回复:AI智能体对用户的回应; - 工具调用:智能体决定使用某个外部工具(比如查天气、发邮件); - 工具输出:工具执行后返回的数据,供智能体继续推理。 你可以把“事件”想象成聊天记录里的每一条消息,但比普通聊天更丰富——它还能记录“谁做了什么”“调用了哪个功能”。 译者注:上面列出的事件类型是基础,实际复杂系统需要更多事件类型,比如:系统事件,记录框架内部决策;元事件,描述事件之间的关系;异常事件,记录失败和降级;控制事件,改变会话流程。 除了聊天记录,会话通常还包含一个结构化的工作记忆,也就是“状态”。它用来保存当前任务相关的临时信息。 例如: - 用户正在购物,状态里就可能存着“购物车中有3件商品”; - 用户在订机票,状态里可能记录“出发地:北京,目的地:上海,日期:明天”。 随着对话推进,智能体会不断向会话中追加新事件,并根据逻辑更新状态。 译者注:上面的状态示例(购物车、机票信息)过于简单,真实状态设计需要考虑比如任务特定数据、用户画像(从记忆加载)、智能体自身状态(如思考步骤)、系统级信息(token计数、成本)、临时计算中间结果等等。 许多大语言模型(如 Google 的 Gemini)接收的输入是一个由“角色”和“内容”组成的列表。这种结构与“事件”高度对应。 # 代码片段1:多轮对话调用Gemini的Python示例 下面是一个多轮对话调用 Gemini 的 Python 示例: ```javascript #构建多轮对话的上下文(即“事件”序列) contents $= [$ {"role": "user", #角色:用户"parts": ["text":"法国的首都是哪里?"] #内容:用户提问},{"role": "model", #角色:模型(即智能体)"parts": ["text":"法国的首都是巴黎。"] #内容:模型回答} #调用Gemini模型生成新回复response $=$ client.models.create_content(model="gemini-2.5-flash",contents $\equiv$ contents #将整个对话历史作为上下文传入 ``` 这里的 contents 列表本质上就是一次会话中的“事件日志”,每一项对应一个对话轮次。 在生产环境中,智能体的运行环境通常是无状态的——也就是说,每次请求处理完后,系统不会自动保留任何数据。 如果不将会话保存下来,下一次用户再说话时,智能体就会“失忆”,仿佛第一次见面。为了提供连贯体验,必须将会话数据写入持久化存储(如数据库)。 - 开发阶段:可以用内存临时存储(简单快捷); - 生产环境:应使用可靠的数据库或托管服务(如 Google 的 Agent Engine Sessions)来管理会话。 译者注:每次对话生成全新会话,在实际中需要更精细的定义。比如:策略1,基于时间窗口,30分钟内视为同一会话;策略2,基于主题连续性,话题明显切换时创建新会话;策略3,基于用户显式操作,“新话题”按钮;策略4,混合策略,结合时间、语义、用户意图。要注意,会话边界不应该是机械的,而应基于语义连续性智能判断。 # 3.1 不同框架和模型如何实现会话 虽然核心思想一致,但不同智能体框架对“会话”、“事件”、“状态”的实现方式各不相同。 智能体框架的核心职责是: - 维护对话历史和状态; - 根据这些信息构建大语言模型能理解的请求; - 解析模型的响应,并更新会话。 图2:智能体上下文管理流程 译者注:智能体上下文管理流程如下: 1. 用户提问 $\rightarrow$ 智能体框架:用户输入问题(User Query)进入系统,智能体框架接收到请求后,开始启动上下文构建流程。 2. 智能体框架 $\leftrightarrow$ 会话存储:无翻译(no translation)直接访问,框架和存储之间有强契约(strong contract),意味着它们使用相同的内部数据格式。智能体框架可以直接读取/写入会话存储中的对话历史和状态,无需额外转换。 3. 智能体框架 $\leftrightarrow$ 记忆管理器:轻量级翻译(lightweight translation)连接,仅在生成阶段需要少量转换,通常只涉及“获取记忆”或“上传新记忆”。记忆管理器专注于长期记忆的维护,比如从多个会话中提炼关键信息并存入“记忆银行”。 4. 智能体框架 $\leftrightarrow$ 模型服务:翻译(translate)连接,智能体框架将自己内部的数据结构(如事件列表、状态)转换成模型服务所需的格式,模型服务再将这些请求转发给底层的大语言模型。 5. 模型服务 $\leftrightarrow$ 大语言模型:翻译(translate)连接,模型服务层作为中间人,负责调用大语言模型 API,并处理响应结果。它屏蔽了模型的具体实现细节,使得智能体框架无需关心底层是 Gemini 还是其他模型。 6. 智能体框架 $\leftrightarrow$ 其他数据源:无翻译(no translation)直接访问,智能体框架可以直接调用 RAG 引擎、云存储等外部系统,获取实时信息。虽然这些系统可能有不同的 API,但框架通常内置了适配器来统一处理。 更重要的是,框架为你屏蔽了底层大语言模型的接口差异。你只需用框架提供的统一数据结构编写逻辑,框架会自动将其转换成目标模型所需的格式(比如 Gemini 的 List[Content]、OpenAI 的 messages 等)。 这种抽象让你的代码不依赖特定厂商,避免“被锁死”在某一家模型上。以 Google ADK 和 LangGraph 框架为例: 1) Google ADK (Agent Development Kit) - 明确定义了一个 Session 对象; - 包含两个部分: 。一个事件列表(Eventobjects) $\rightarrow$ 存放对话历史; 。一个独立的状态对象(state) $\rightarrow$ 存放工作内存。 - 类比:像一个文件柜,一个抽屉放聊天记录,另一个放临时笔记。 # 2) LangGraph - 没有显式的“会话”对象; - 整个 状态(state) 本身就是会话; - 这个状态不仅包含对话历史(以 Message 对象列表形式),还包含所有其他工作数据; - 关键区别:状态是可变的 (mutable),可以被修改、压缩甚至重写。 当对话太长、token 快超限时,LangGraph 可以自动对历史进行摘要或删减,从而控制上下文长度——这在处理超长对话时非常实用。 译者注:会话的本质是什么?会话不是简单的聊天记录,而是智能体完成当前任务所需的“临时工作台”。它既要忠实记录发生了什么(事件),又要灵活管理正在处理什么(状态)。而不同的框架提供了不同的“工作台设计”——有的分格清晰(如ADK),有的高度集成(如LangGraph),开发者可根据需求选择。 接下来,我们将探讨一个更深层的问题:当多个智能体一起协作时,会话该如何设计?这将引出“多智能体会话”的新挑战。 # 3.2 多智能体系统中的会话管理 在多智能体系统(multi-agent system)中,多个AI智能体协同工作,每个智能体专注于一个更小、更专业的任务。为了高效协作,这些智能体必须共享信息。如下图所示,系统的架构定义了它们用于信息共享的通信模式。该架构的一个核心组成部分,是如何处理会话历史(session history)——即所有交互行为的持久化日志。 图3:多智能体系统的不同架构模式 # 译者注:理解图3的六种架构模式 - 单智能体:仅包含一个智能体,其内部集成一个大语言模型(LLM)和若干工具。是最基础的智能体形式;所有决策由单一LLM驱动;工具调用在本地完成,无外部协作;类似于“功能增强型聊天机器人”。适用于简单任务,如信息查询、文本生成等。缺乏复杂协作能力,但实现简单、调试方便。 - 网络型:多个智能体以对等(peer-to-peer)方式连接,形成网状拓扑。每个智能体可与其他任意智能体通信;无中心控制器;支持去中心化协作;可用于分布式推理或共识机制。适合需要高度灵活性和容错性的场景,例如社交网络模拟、群体决策系统。但可能面临消息冲突、循环依赖等问题。 - 监督者型:一个中央智能体(Supervisor)作为协调者,管理多个下属智能体。中央智能体负责调度任务、分配角色;下属智能体执行具体工作;具有清晰的上下级关系;常见于任务分解与流程控制。类似于“项目经理 + 团队成员”的组织结构。适用于多阶段任务(如规划→执行→验证)。优点是逻辑清晰,缺点是中心节点可能成为瓶颈。 - 监督者即工具:一个LLM将其他智能体当作“工具”来调用。主LLM决定何时使用哪个智能体;被调用的智能体返回结果后即结束;不参与长期对话或状态维护;实现了“智能体即工具”(Agent-as-a-Tool)模式。这是将智能体封装为可调用服务的经典模式。例如:主智能体调用“搜索智能体”获取数据,再调用“总结智能体”生成摘要。适合模块化任务处理。 - 层级型:具有多层嵌套结构,顶层智能体指挥中间层,中间层再指挥底层智能体。支持复杂任务的分层拆解;上层负责策略制定,下层负责执行细节;可扩展性强,适合大规模系统;类似于企业组织架构。适用于需要精细分工的任务,如自动驾驶中的感知 $\rightarrow$ 决策 $\rightarrow$ 控制流程。每一层可以独立优化,提高整体效率与稳定性。 - 自定义型:没有固定规则,智能体之间的连接关系完全由设计者定义。完全灵活,可根据特定需求定制;支持非线性、异步、反馈环路等复杂交互;通常结合状态机或图神经网络建模;需要较强的设计能力和工程实现。适用于高度复杂的任务,如科学研究协作、动态环境适应等。虽然强大,但也增加了开发难度和调试成本。 在探讨管理会话历史的架构模式之前,有必要明确区分“会话历史”与传递给大语言模型的“上下文”。 - 会话历史是整个对话的完整、不可删减的永久记录; - 上下文则是为单次模型调用精心构造的信息载荷。 智能体在构造上下文时,可能会从会话历史中选取相关片段,或添加特定格式(如引导性前缀)以引导模型生成期望的响应。本节关注的是智能体之间传递的信息内容,而非最终发送给大语言模型的具体上下文。 目前,智能体框架在多智能体系统中处理会话历史主要采用两种方式: 1. 共享统一历史(shared, unified history):所有智能体共用一个中央日志; 2. 独立个体历史(separate, individual histories):每个智能体维护自己的私有历史。 选择哪种模式,取决于任务性质以及期望的智能体协作方式。 # 3.2.1 共享统一历史模式 在此模式下,系统中所有智能体都从同一个会话历史中读取信息,并将自身产生的所有事件(包括消息、工具调用、观察结果等)按时间顺序追加到这一中央日志中。该模式适用于紧密耦合、高度协作的任务,例如多步骤问题求解场景——其中一个智能体的输出直接作为下一个智能体的输入。 即使采用共享历史,子智能体在将日志传递给大语言模型前,仍可对其进行预处理。例如,过滤出与当前任务相关的事件,或为每条事件添加标签以标识其来源智能体。 若使用ADK的LLM驱动委托机制(LLM-driven delegation)将任务交由子智能体处理,则子智能体的所有中间事件都会写入与根智能体相同的会话中。 ```txt 代码片段2:跨多个智能体框架的A2A通信 from google.adk.agents import Ll mAgent #子智能体可访问Session,并向其中写入事件 sub_agent_1 = Ll mAgent(...) #可选:子智能体可将其最终响应文本(或结构化输出) #保存到指定的状态键中,供后续使用 sub_agent_2 = Ll mAgent( ``` ```txt output_key="final_result" #指定输出存储位置 ) #父智能体(根智能体) root_agent $=$ LlmAgent(,sub Agents $\equiv$ [sub_agent_1,sub_agent_2] #委托给子智能体 ``` # 3.2.2 独立个体历史模式 在此模式下,每个智能体维护自己的私有会话历史,对外表现为一个“黑盒”。其内部过程(如中间推理、工具调用、思考步骤等)均保留在私有日志中,不对其他智能体可见。智能体之间的通信仅通过显式消息进行——即只共享最终输出,而非内部过程。 这种交互通常通过以下两种方式实现: - 智能体即工具(Agent-as-a-Tool):一个智能体像调用普通工具一样调用另一个智能体,传入输入并接收一个自包含的最终输出; - 智能体间协议(Agent-to-Agent, A2A Protocol):智能体通过结构化的协议进行直接消息传递。 我们将在下一节中深入探讨 A2A 协议。 # 3.2.3 跨智能体框架的互操作性 图4:使用不同框架的多个智能体之间的A2A通信 每个智能体框架通常采用其内部的数据表示形式,这在多智能体系统架构中引入了一个关键权衡:正是这种将智能体与大语言模型解耦的抽象机制,也导致了不同框架智能体之间的隔离。 这种隔离在持久化层尤为明显。会话 (Session) 的存储模型通常将数据库结构与框架内部对象(如 Event、Message)紧密绑定,从而形成一种刚性且难以移植的对话记录格式。因 此,一个基于 LangGraph 构建的智能体无法原生解析由 ADK 框架持久化的 Session 和 Event 对象,导致无缝任务交接几乎不可能。 目前,一种新兴的架构模式——智能体间通信(Agent-to-Agent,A2A)——被用于协调这些相互隔离的智能体。然而,尽管 A2A 支持消息交换,它并未解决共享丰富上下文状态的核心难题。由于每个智能体的会话历史都以其框架特有的内部 schema 编码,任何包含会话事件的 A2A 消息若要被其他框架理解,都必须经过翻译层(translation layer)处理。 更稳健的互操作性架构是:将共享知识抽象为一个与框架无关的数据层——即“记忆”(Memory)。 与会话存储(Session store)不同,记忆层不保存原始的、框架专属的对象(如 Events 或 Messages),而是存储经过处理的、标准化的信息,例如: - 对话摘要 - 提取出的实体 - 关键事实 这些信息通常以字符串或字典形式存储,其数据结构不依赖于任何单一框架的内部表示,因而可作为通用的共享认知资源。通过这一模式,异构智能体无需定制翻译器,即可实现真正的协同智能(collaborative intelligence)。 # 3.3 智能体会话的生产环境考量 当将一个智能体部署到生产环境中时,其会话管理系统必须从简单的日志记录演进为健壮、企业级的服务。关键考量主要集中在三个核心维度:安全性与隐私保护、数据完整性以及性能与可扩展性。像Agent Engine Sessions这样的托管式会话存储服务,正是为满足这些生产级需求而设计的。 # 3.3.1 安全性与隐私保护 会话中往往包含高度敏感的信息,因此对其保护是不可妥协的基本要求。 - 严格隔离(Strict Isolation)是最关键的安全原则。每个会话归属于单一用户,系统必须通过访问控制列表(ACL)等机制,确保任何用户都无法访问他人的会话数据。 - 所有对会话存储的请求都必须经过身份认证(Authentication)和权限授权(Authorization),并与会话所有者绑定。 处理个人身份信息(PII)的最佳实践是:在写入存储前即进行脱敏(redaction)。这是一种根本性的安全措施,能显著降低数据泄露事件的“影响范围”(blast radius)。通过使用如Model Armor等工具确保敏感数据永不持久化,不仅能简化对GDPR、CCPA等隐私法规的合规工作,还能增强用户信任。 # 3.3.2 数据完整性与生命周期管理 生产系统必须对会话数据的存储与维护制定清晰的规则: - 会话不应永久保留。应实施生存时间(TTL, Time-to-Live)策略,自动删除长期不活跃的会话,以控制存储成本并减轻数据管理负担。 - 需要制定明确的数据保留策略,规定会话在归档或永久删除前应保留多长时间。 此外,系统必须保证所有操作以确定性顺序追加到会话历史中。维持事件的正确时间序列,是保障对话日志完整性的基础。 # 3.3.3 性能与可扩展性 会话数据位于每次用户交互的“热路径”(hot path)上,其性能直接影响用户体验: - 读写会话历史必须极其高效,以确保响应迅速。 - 智能体运行时通常是无状态的(stateless),因此每轮对话开始时,都需要从中央数据库完整拉取会话历史,这会引入网络传输延迟。 为缓解延迟,减少传输数据量至关重要。一种关键优化手段是在将会话历史发送给智能体之前,对其进行过滤或压缩(compaction)。例如,可移除当前对话状态已不再需要的旧函数调用结果。 下文将详细介绍多种会话压缩策略,以有效管理长上下文对话。 # 3.4 长上下文对话的管理:权衡与优化 在简单架构中,会话被视为用户与智能体之间对话的不可变日志。但随着对话延长,所消耗的 token 数量持续增长。尽管现代大语言模型支持较长上下文,但在对延迟敏感的应用场景中仍存在明显限制: 1. 上下文窗口限制:每个大语言模型都有最大处理文本长度(即上下文窗口)。若历史超过该限制,API调用将失败。 2. API 成本:大多数大语言模型服务商按输入/输出 token 数计费。更短的历史意味着更低的每轮成本。 3. 延迟(速度):向模型发送更多文本会增加处理时间,导致用户响应变慢。压缩可保持智能体的快速响应感。 4. 生成质量:随着 token 增多,上下文中噪声增加,可能引发自回归错误,反而降低输出质量。 类比:管理长对话如同一位精明的旅行者为长途旅行打包行李。 - 行李箱 = 模型的上下文窗口 - 衣物与物品 = 对话中的信息片段 - 若一股脑塞入所有物品,行李箱会过重且杂乱,难以快速找到所需之物——正如超载的上下文会推高成本、拖慢响应; - 若打包过少,则可能遗漏护照或保暖衣物,危及整个旅程——正如智能体丢失关键上下文,导致回答无关或错误。 - 成功的关键不在于能带多少,而在于只带必需之物。 压缩策略(Compaction Strategies)通过智能裁剪对话历史,在保留关键上下文的同时,使其适配模型的上下文窗口,从而降低API成本与延迟。 那么,如何判断哪些内容可以安全丢弃而不损失有价值信息?常见策略从简单截断到高级压缩不等: - 保留最近 N 轮对话(Keep the last N turns):最简单的策略。仅保留最近 N 轮对话(“滑动窗口”),丢弃更早内容。 - 基于 token 限制的截断:从最新消息开始反向累加 token 数,直至接近预设上限(如 4000 tokens),超出部分直接截断。 - 递归摘要(Recursive Summarization):用大语言模型对较早的对话段落生成摘要。随着对话增长,智能体定期调用LLM将最旧消息压缩为摘要,并将其作为浓缩历史置于近期原始消息之前。 示例:在ADK中,可通过内置插件轻松实现“仅保留最近N轮”的上下文限制。注意:此操作不会修改会话存储中的原始事件,仅影响发送给模型的上下文。 代码片段3:使用ADK仅保留最近N轮对话 ```python from google.adk.apps import App from google.adkplugins.context_filterPlugin import ContextFilterPlugin app $=$ App( name $\equiv$ 'hello_world_app', root_agent $\equiv$ agent, plugins $\coloneqq$ [ # 保留最近10轮对话 $^+$ 最新的用户查询 ContextFilterPlugin(num_invocations_to_keep=10), ], ``` 由于高级压缩策略(如递归摘要)涉及额外LLM调用,成本较高,因此必须: - 异步执行:在后台运行,避免阻塞用户请求; - 持久化结果:将生成的摘要存入存储,防止重复计算。 通常由智能体的记忆管理器(Memory Manager)负责摘要的生成与持久化。同时,系统需记录哪些原始事件已被纳入摘要,以避免将冗余的详细事件再次发送给大语言模型。 此外,智能体还需决定何时触发压缩。常见触发机制包括: - 基于计数的触发(Count-Based Triggers):当对话轮数或 token 总量超过阈值时触发。这是管理上下文长度的“够用就好”策略。 - 基于时间的触发(Time-Based Triggers):在用户长时间无交互(如15或30分钟)后,后台自动执行压缩。 - 基于事件的触发(Event-Based Triggers):当智能体检测到某个子任务、目标或话题已结束时,主动触发压缩。 示例:ADK 支持通过 EventsCompactionConfig 配置,在指定轮数后自动触发基于 LLM 的摘要压缩。 代码片段4:使用ADK通过摘要进行会话压缩 ```python from google.adk.apps import App from google.adk.apps.app import EventsCompactionConfig app = App( name='hello_world_app', root_agent=agent, events_compaction_config=EventsCompactionConfig( compaction_interval=5, #每5轮触发一次压缩 overlap_size=1, #保留1轮重叠内容,确保上下文连贯), ``` # 3.5 记忆生成:从对话中提炼持久知识 记忆生成(Memory Generation)是指从冗长、嘈杂的数据源中提取持久化知识的能力。本节讨论的会话压缩正是这一能力的典型应用:它将完整的逐字对话记录提炼为关键事实与摘要,同时剔除无意义的寒暄或冗余信息。 在会话压缩的基础上,下一节将进一步探讨记忆的生成与管理。我们将介绍多种创建、存储和检索记忆的方式,以构建智能体的长期知识库,支撑更复杂的 Agentic AI 行为。 # 4 记忆 (Memory) 记忆(Memory)与会话(Session)之间存在深度共生关系: - 会话是生成记忆的主要数据源; - 记忆则是管理会话规模的关键策略。 所谓“记忆”,是指从对话或数据源中提取出的、具有意义的信息快照。它是一种浓缩表示,保留了关键上下文,从而在未来的交互中仍具价值。通常,记忆会跨会话持久化存储,以提供连续、个性化的用户体验。 作为一种专用且解耦的服务,“记忆管理器”(Memory Manager)构成了多智能体互操作性的基础。记忆管理器通常采用与框架无关的数据结构(如字符串、字典等),使得基于不同框架(如ADK、LangGraph)构建的智能体都能连接到同一个记忆存储库,从而共建一个共享知识库——任何接入的智能体均可从中受益。 注意,某些框架可能将“会话”或逐字对话记录称为“短期记忆”(short-term memory)。但在本白皮书中,“记忆”特指经过提炼的信息,而非原始的逐轮对话文本。 构建复杂、智能的AI智能体离不开高效的记忆系统。一个健壮的记忆机制能将基础聊天机器人转变为真正的Agentic AI,解锁以下核心能力: # 1)个性化(Personalization) 最常见的应用场景:记住用户的偏好、事实和历史交互,以定制未来响应。例如:记住用户支持的体育队伍,或其偏好的飞机座位,可显著提升服务体验的贴心度。 # 2) 上下文窗口管理(Context Window Management) 随着对话延长,完整历史可能超出大语言模型的上下文窗口限制。记忆系统可通过生成摘要或提取关键事实来压缩历史,在不发送数千 token 的前提下保留必要上下文,从而降低 API 成本与延迟。 # 3)数据挖掘与洞察 (Data Mining and Insight) 在聚合且隐私合规的前提下,分析海量用户的记忆可从噪声中提炼洞察。例如:零售客服智能体发现大量用户询问某商品的退货政策,可能预示产品描述存在误导。 # 4)智能体自优化与适应(Agent Self-Improvement and Adaptation) 智能体可通过创建程序性记忆(procedural memories)学习自身表现——记录哪些策略、工具或推理路径曾带来成功结果。这使其能逐步构建“有效解决方案手册”,持续提升问题解决能力。 在AI系统中,记忆的创建、存储与使用是一个多方协作过程。各组件职责分明: 1) 用户: 提供记忆的原始数据源。在某些系统中, 用户也可直接提交记忆 (如通过表单)。 2)智能体(开发者逻辑):决定“记什么”和“何时记”,并协调调用记忆管理器。 - 简单架构:始终检索 + 始终触生成生; - 高级架构:将记忆作为“工具”(memory-as-a-tool),由大语言模型动态决定是否检索或生成记忆。 3)智能体框架(如ADK、LangGraph):提供记忆交互的基础设施(“管道”)。 - 定义如何访问会话历史; - 定义如何将检索到的记忆注入上下文窗口; - 但不负责长期存储本身。 4)会话存储(如 Agent Engine Sessions、Spanner、Redis):存储逐轮对话的原始记录。这些数据将被送入记忆管理器,用于生成记忆。 5)记忆管理器(如 Agent Engine Memory Bank、Mem0、Zep):负责记忆的存储、检索与压缩管理,是支撑智能体持续认知与决策的关键组件。该模块承担从潜在记忆识别到全生命周期管理的完整职责,其具体实现机制依赖于所采用的后端记忆服务提供商。 - 提取(Extraction):从源数据中提炼关键信息; - 整合 (Consolidation) : 合并重复实体, 去重归一; - 存储(Storage):持久化至数据库; - 检索(Retrieval):为新交互召回相关记忆。 译者注:记忆的生命周期管理包括如何创建(自动提取 vs. 手动标注)、更新(合并冲突、修正错误)、检索(基于元数据、向量相似度、混合搜索)、遗忘(主动删除、被动衰减)。 图5:会话、记忆与外部知识之间的信息流动 这种职责分离使开发者能专注于智能体的核心业务逻辑,而无需从零构建复杂的记忆持久化与管理基础设施。 要注意,记忆管理器是一个主动系统,而非被动的向量数据库。虽然它可能使用相似性搜索进行检索,但其核心价值在于随时间智能地提取、整合与维护记忆。 像 Agent Engine Memory Bank 这类托管式记忆服务,完整覆盖记忆的生成、存储与演化,让开发者得以聚焦于智能体本身的逻辑设计。 记忆常被拿来与另一重要架构模式——检索增强生成(RAG,Retrieval-Augmented Generation)——进行比较,但二者基于不同的设计原则。做一个形象比喻,RAG是智能体的“研究型图书管理员”,在浩瀚公共图书馆(百科、文档)中查找权威事实,回答“客观问题”,但不了解用户个人情况。而记忆管理器是智能体的“私人助理”,随身携带私密笔记本,记录每位用户的偏好、历史对话与目标演变,专精于“这个人是谁”。 表 1: RAG 引擎与记忆管理器对比 <table><tr><td>对比维度</td><td>RAG 引擎</td><td>记忆管理器</td></tr><tr><td>核心目标</td><td>向对话上下文注入外部事实性知识</td><td>打造个性化、带状态的交互体验。记录用户信息、适配使用习惯,维护长对话上下文</td></tr><tr><td>数据来源</td><td>静态、预索引的外部知识库(如PDF、维基百科、文档、API)</td><td>用户与智能体的对话内容</td></tr><tr><td>隔离级别</td><td>通常为共享模式。知识库多为全局只读资源,支持所有用户访问,以保证回答的事实一致性</td><td>高度隔离:记忆通常按用户独立划分,避免数据泄露</td></tr><tr><td>信息类型</td><td>静态、事实性、权威性信息,包含领域专属数据、产品详情或技术文档</td><td>动态且(通常)是用户专属的信息。由对话内容生成,天然存在一定的不确定性</td></tr><tr><td>写入模式</td><td>批量处理由离线的管理员操作触发</td><td>事件驱动处理按固定频率触发(如每轮对话后、会话结束时),或“记忆即工具”模式(由智能体主动生成记忆)</td></tr><tr><td>读取模式</td><td>几乎是“工具式读取”:当用户查询需要外部信息时,由智能体主动检索</td><td>两种常见模式:·“记忆即工具”:需补充用户(或其他身份)信息时检索·静态检索:每轮对话开始时自动读取</td></tr><tr><td>数据格式</td><td>自然语言“文本块”</td><td>自然语言片段或结构化用户画像</td></tr><tr><td>数据预处理</td><td>文本分块与索引:将源文档拆分为更小的文本块,转换为向量嵌入后存储,便于快速检索</td><td>提取与整合:从对话中提取关键信息,确保内容无重复、无矛盾</td></tr><tr><td>更新频率</td><td>低频(依赖外部知识库更新)</td><td>高频(随每次交互演进)</td></tr></table> 真正智能的Agentic AI既需要RAG,也需要记忆——前者赋予其世界知识,后者赋予其用户理解。二者相辅相成,共同支撑智能体在复杂任务中实现既精准又贴合语境的决策与响应。 下一节将深入剖析“记忆”的核心构成要素,包括: - 存储的信息类型; - 组织模式; - 存储与生成机制; - 作用范围的策略定义; - 对多模态数据与纯文本的处理方式。 # 4.1 记忆的类型 智能体的记忆可根据信息存储方式与捕获机制进行分类。这些不同类型的记忆协同工作,共同构建对用户及其需求的丰富上下文理解。 译者注:根据信息存储方式与捕获机制进行分类,白皮书并未展开讲,这里做一个补充。 按信息存储方式分类,指的是记忆内容在数据库或系统中的物理或逻辑组织形式,直接影响检索效率和应用场景。可分为: 1. 嵌入向量记忆:将记忆的文本内容通过嵌入模型转换为高维向量,存储在向量数据库中。优势在于支持语义搜索。智能体可以提出一个问题(如“用户对座位有什么要求?”),系统会查找与之语义相近的记忆向量(如包含“靠窗”、“过道”、“前排”的记忆)。这是实现“联想”、“模糊匹配”能力的基础,尤其适用于非结构化、描述性的记忆内容。 2. 结构化记忆:使用键值对、关系型数据库表或文档型数据库来存储。记忆内容被提炼为结构化的字段。优势在于精确查询和高效管理。例如,将用户偏好存储为 {"favorite_airline": "Delta", "seat Preference": "Aisle", "meal Preference": "Vegetarian"}。这允许系统瞬间回答“用户最喜欢的航空公司是什么?”这类精确问题。它通常用于存储明确的事实(实体记忆)。 3. 图记忆:以知识图谱的形式存储,记忆成为“节点”,记忆之间的关系成为“边”。优势在于表达和推理复杂关系。例如,记忆“用户A” $\rightarrow$ (购买了) $\rightarrow$ “产品B”;“产品B” $\rightarrow$ (属于类别) $\rightarrow$ “电子产品”。这种存储方式不仅存储事实,还显式地存储了事实间的联系,使智能体能够进行多跳推理(“用户A购买过电子产品,那么新款的平板电脑他可能感兴趣”)。 4. 时序/事件流记忆:以时间序列或事件日志的形式按序存储。优势在于保留事件的因果和上下文关系。它忠实记录交互的原始顺序:“用户询问机票 -> 助手推荐航班 -> 用户选择航班 A -> 用户询问酒店”。这对于理解对话流程、诊断问题、以及构成“情景记忆”至关重要。它通常作为最底层的原始数据源。 按捕获机制分类,指的是记忆是如何从原始交互数据中被识别、提取和创建的,决定了记忆的质量和丰富度。 1. 显式捕获:智能体直接询问用户以获取关键信息,并明确将其存入记忆。示例,助手问:“为了将来更好地为您服务,可以告诉我您偏爱的舱位吗?”用户回答:“头等舱。”助手随后创建一条结构化记忆:{“preferred_class”: “First”}。优点是准确性高,意图明确。缺点是交互生硬,可能打断对话流。 2. 隐式/自动提取:通过后台的自然语言处理模型自动分析对话内容,提取关键实体、情感、偏好或摘要。示例,用户在聊天中说:“上次那个靠窗的座位让我整个旅程都很舒服。”NLP模型自动识别并提取“偏好:靠窗座位”,并创建记忆。优点是无缝、自动化,能捕捉用户无意中流露的信息。缺点是可能存在提取错误或歧义,需要置信度评估。 3. 推断生成:基于已有的记忆和当前交互,通过推理模型生成新的、隐含的记忆。示例,用户多次在周五晚上预订餐厅,且常选择川菜馆。系统可能推断生成一条记忆:“用户可能在周五晚上有社交聚餐的惯例,且偏爱川菜。”优点是能产生深层次、有洞察的记忆,实现个性化跃迁。缺点是推断结果具有不确定性,必须明确标记为“推测”,并与事实性记忆区分开。 4. 反馈驱动捕获:从用户的显式反馈(如点赞/点踩)或隐式反馈(如任务是否最终成功完成)中学习,并转化为程序性或陈述性记忆。示例,用户纠正了助手的一次错误操作,这次纠正的步骤序列可以被提炼为“如何正确执行X任务”的程序 性记忆。优点是形成了学习闭环,记忆系统能够持续优化。缺点是反馈信号可能稀疏或嘈杂。 核心原则:所有记忆均为描述性(descriptive),而非预测性(predictive)。即:记忆记录“发生了什么”或“用户说了什么”,而非“未来会怎样”。 译者注:记忆系统的职责是忠实记录历史,而不是充当预测模型。这避免了记忆系统与推理/决策模型的功能混淆,保证了记忆的“事实性”基础。在AI伦理与可解释性日益重要的今天,这一原则有助于界定责任边界——决策由推理引擎基于记忆做出,而非记忆本身。 一个“记忆”是由记忆管理器返回、供智能体使用的原子化上下文单元。尽管具体格式可能不同,但通常包含两个核心部分: 1)内容(Content):从源数据(如会话原始对话)中提取的核心信息。 - 框架无关:使用简单数据结构(如字典、字符串),便于任何智能体解析。 - 可为结构化(如 {"seat Preference": "Window"}) 或非结构化(如自然语言句子:“用户偏好靠窗座位”)。 译者注:“框架无关”的理想是内容对任何智能体都“可读”,而“标准格式”是实现这一理想的“协议”。在实际工程中,必须定义一个强制的、版本化的内容模式(Schema)。否则,不同团队或不同时期开发的智能体可能因为对同一个字典(如{"seat Preference":"Window")的字段理解不同而产生混乱。“框架无关”应建立在“团队或生态内部约定的统一数据契约”之上。 2)元数据(Metadata):描述记忆本身的上下文信息,通常以字符串形式存储。包括: - 唯一标识符 (ID) - 所属用户 ID - 标签 (如来源、主题、数据类型) 此定义清晰区分了“内容”与“元数据”,符合现代记忆系统设计(如Zep、Mem0)。但需注意:“框架无关”不等于“无格式”——实际系统常采用JSON Schema或Protobuf等标准格式保证互操作性。 译者注:将内容与元数据分离,使得:1)检索高效,可通过元数据(如标签、用户ID)快速筛选记忆;2)管理灵活,可以独立更新元数据(如打新标签)而不影响核心内容;3)互操作性强:标准化的元数据格式是不同系统间交换记忆的关键。这完全对应了向量数据库(存储内容嵌入)与传统数据库(存储元数据)结合的混合检索架构,也是Zep、Mem0等项目的核心理念。 译者注:还要注意记忆的时效性、强度与关联性维度。 - 时效性:记忆是否有有效期?用户的“当前项目偏好”和“童年梦想”重要性显然不同。记忆系统需要支持记忆衰减、过期或显式失效的机制。 - 强度/置信度:记忆是否都有相同的可信度?来自用户明确声明的记忆(“我讨厌苹果”)与智能体推测的记忆(“用户可能喜欢咖啡,因为常提咖啡馆”)应有不同的强度或置信度标签。这影响检索权重和使用时的谨慎程度。 - 关联性:记忆原子之间是孤立的吗?现实中,记忆是网络状的。“预订了去巴黎的机票”与“用户喜欢法国印象派绘画”这两个记忆原子之间存在潜在关联。高级的记忆系统会尝试建立记忆间的链接,形成知识图谱,从而支持更复杂的联想与推理。 # 4.1.1 记忆信息的类型 超越基本结构,记忆还可按其所代表的知识本质分类。这一区分源自认知科学,对理解智能体如何使用记忆至关重要: 1)陈述性记忆(Declarative Memory)一“知道是什么” - 存储事实、数据、事件; - 可被显式陈述(“declare”); - 回答“What”类问题。 - 子类: 。语义记忆(Semantic):通用世界知识(如“巴黎是法国首都”); ○ 实体/情景记忆(Entity/Episodic):特定用户事实(如“张三的生日是5月1日”)。 2)程序性记忆(Procedural Memory)一“知道怎么做” - 存储技能、流程、操作序列; - 指导智能体隐式执行任务; - 回答“How”类问题(如“预订机票的正确工具调用顺序”)。 译者注:陈述性记忆让智能体“有知识”,是进行对话、问答、个性化服务的基础;而程序性记忆让智能体“有技能”,是掌握复杂、多步骤工具调用工作流的核心。例如,一旦通过程序性记忆“学会”了“预订机票-选座-付款”的可靠流程,它就能稳定、重复地执行该任务,无需每次都重新推理步骤。这指出了智能体进化的一个方向——从仅有“事实库”的聊天机器人,向兼具“技能库”的自主任务执行者演变。 # 4.1.2 记忆的组织模式 创建记忆后,需决定其组织方式。主流模式有三种: # 模式 # 集合模式 (Collection) # 特点 将同一用户的多个自然语言记忆组织为松散集合;每个记忆为独立事件/观察;支持按主题检索。 # 适用场景 长期交互、多目标对话(如客服历史) <table><tr><td>模式</td><td>特点</td><td>适用场景</td></tr><tr><td>结构化用户画像(Structured User Profile)</td><td>类似“联系人卡片”,持续更新稳定事实(姓名、偏好、账号)。</td><td>快速查找关键信息(如登录态、支付方式)</td></tr><tr><td>滚动摘要(Rolling Summary)</td><td>将所有信息压缩为单个动态演化的自然语言摘要;每次更新覆盖前一版本。</td><td>会话压缩、上下文窗口管理</td></tr></table> 译者注:组织模式的三种类型(集合、结构化、滚动摘要)实际上代表了信息粒度与查询效率的权衡。滚动摘要是解决大语言模型有限上下文窗口的经典工程方案,其核心思想是用信息的“分辨率”换取“覆盖率”。白皮书未提及混合模式(如“结构化主干 + 非结构化补充”),这在实践中更常见。在实际系统中,结构化用户画像(如键值对)作为主干,用于存储核心、稳定的身份与偏好信息,保证快速精准查询。非结构化的集合/滚动摘要作为枝叶,用于记录动态的、描述性的交互历史。二者通过用户ID关联,在检索时融合(例如,先查画像获得核心偏好,再用此偏好增强对历史摘要的语义查询),这才是最强大的模式。 # 4.1.3 存储架构 存储架构决定记忆的检索效率与智能程度。主流方案有: 1)向量数据库(Vector Databases) - 基于语义相似性检索; - 将记忆转为嵌入向量,匹配最相近查询; - 擅长处理非结构化自然语言记忆(如“用户上周抱怨物流慢”)。 2)知识图谱(Knowledge Graphs) - 将记忆表示为实体-关系网络(节点-边); - 支持关系推理(如“用户 $\mathsf{A} \rightarrow$ 喜欢 $\rightarrow$ 产品 $\mathsf{B} \rightarrow$ 属于 $\rightarrow$ 品类 $\mathsf{C}$ ”); - 适合结构化、关联性强的查询。 3) 混合架构 (Hybrid) - 在知识图谱的实体上附加向量嵌入; - 同时支持关系遍历与语义搜索; - 被视为“最佳实践”。 译者注:向量数据库擅长处理“模糊查询”,知识图谱擅长处理“精确推理”。混合架构之所以是“最佳实践”,是因为现实世界的查询往往是两者混合的。 # 4.1.4 记忆的创建机制 按用户意图分: - 显式记忆(Explicit):用户直接指令(如“记住我生日是10月26日”); - 隐式记忆(Implicit):智能体从对话中推断(如“我下周结婚” $\rightarrow$ 提取“婚礼日期”)。 按系统架构分: <table><tr><td>类型</td><td>说明</td><td>优缺点</td></tr><tr><td>内部记忆(Internal Memory)</td><td>记忆逻辑内置于智能体框架(如 LangChain 的 ConversationBufferMemory)</td><td>快速上手功能有限,难扩展</td></tr><tr><td>外部记忆(External Memory)</td><td>专用服务(如 Agent Engine Memory Bank、Zep)通过 API 提供记忆能力</td><td>支持语义搜索、实体抽取、自动摘要解耦、可复用</td></tr></table> 生产环境应优先采用外部记忆服务,避免重复造轮子。 译者注:记忆即服务(Memory-as-a-Service)和外部记忆的倡导,体现了现代软件工程的解耦思想。将记忆能力独立为服务,有利于实现高可用、独立扩展、功能专业化(如集成更优的嵌入模型、实现记忆去重等)。 # 4.1.5 记忆的作用域 作用域决定记忆的归属与可见性: <table><tr><td>作用域</td><td>说明</td><td>示例</td><td>注意事项</td></tr><tr><td>用户级(User-Level)</td><td>绑定用户 ID,跨会话持久化</td><td>“用户偏好中间座位”</td><td>最常用,需严格隐私隔离</td></tr><tr><td>会话级(Session-Level)</td><td>仅限单次会话的压缩摘要</td><td>“本次会话:用户计划11月7-14日纽约→巴黎,偏好直飞+中间座”</td><td>≠原始对话日志,仅为提炼洞察</td></tr><tr><td>应用级(Application-Level)</td><td>全局共享,所有用户可见</td><td>“项目代号 XYZ指代‘智能客服升级’”</td><td>必须脱敏!禁止包含用户私有数据</td></tr></table> 译者注:作用域隔离是数据安全与隐私保护的铁律。它不仅是技术设计,更是产品伦理。混淆作用域会导致灾难性的数据泄露。 # 4.1.6 多模态记忆 处理图像、音频、视频等非文本信息的关键在于区分: <table><tr><td>概念</td><td>说明</td></tr><tr><td>多模态来源 (Multimodal Source)</td><td>输入为多模态(如语音、图片),但记忆内容为文本(经转录/描述)</td></tr><tr><td>多模态内容 (Multimodal Content)</td><td>记忆本身直接包含非文本数据(如嵌入图片)</td></tr></table> 当前绝大多数记忆系统(包括 Google Agent Engine)仅支持多模态来源 $\rightarrow$ 文本记忆。原因是非文本数据的存储、索引、检索成本高;缺乏统一的多模态嵌入与相似性度量标准。 译者注:文本为王的原则是对当前技术生态的务实判断。文本的存储、索引、检索技术最成熟,且大语言模型本身是文本理解的专家。将多模态信息蒸馏(Distill)为高质量的文本描述,是目前性价比最高、最可行的方案。 代码片段 5: Google Agent Engine Memory Bank 的多模态记忆生成 ```python from google.genai import types client = vertexai.Client.project=..., location=... response = client(agent Engines.memories_generate( name=agent.engine_name, direct_contents_source={ "events": [ "content": types.Content( role="user", parts=[ # 纯文本上下文 types.Part.from_text("This is context about the multimodal input.") # 二进制数据(如图片/音频字节流) types.Part.from_bytes( data=CONTENT_AS_BYTES, # ← 多模态输入:字节数据 mime_type=MIME_TYPE # ← 如 "image/jpeg", ] # 或从 URI 加载文件 types.Part.from_url(file_url="file/path/to/content", mime_type=MIME_TYPE ] ] }, ``` 代码说明: - from_bytes / from_url: 支持传入图像、音频等二进制或多模态数据; - 但返回的记忆仍是文本:系统内部会调用多模态模型(如 Gemini)生成文本描述; - scope: 确保记忆归属正确用户,符合隐私要求。 译者注:RAG + Memory 双引擎:智能体的“外脑”与“内脑”,这一总结极为精辟。RAG 为智能体接入一个庞大、实时、可信的外部世界知识库(如产品文档、最新新闻),解决其“无知”和“幻觉”问题。而 Memory 则为智能体构建了一个持续演进、高度个性化的内部用户模型与技能库,解决其“健忘”和“不个性化”问题。二者协同工作,共同构成了智能体认知能力的双支柱。 # 4.2 记忆生成:提取与整合 记忆生成能够自动将原始对话数据转化为结构化、有意义的洞察,其核心作用相当于一个由大语言模型驱动的ETL(提取、转换、加载)流程,专门用于提取和凝练记忆。这一ETL流程正是记忆管理器区别于RAG引擎和传统数据库的关键特征——无需开发者手动指定数据库操作,记忆管理器会通过大语言模型智能判断何时添加、更新或合并记忆。这种自动化能力是记忆管理器的核心优势:它封装了数据库内容管理、大语言模型调用链构建、数据处理后台服务部署等复杂工作。 译者注:将记忆生成比作LLM驱动的ETL流程极为恰当。1)提取(Extract):从非结构化的对话流中识别“信号”而非“噪音”;2)转换(Transform):将识别出的信息转化为规范的记忆表示;3)加载(Load):将处理后的记忆持久化到适当存储中。这个比喻强调了记忆管理器与传统数据库的本质区别:前者是声明式的(告诉系统“需要什么主题”),后者是命令式的(需要精确指定“如何增删改查”)。 图6:记忆生成的高层级算法,从新数据源提取记忆并与现有记忆整合 尽管不同平台(如 Agent Engine Memory Bank、Mem0、Zep)的具体算法存在差异,但记忆生成的高层级流程通常包含以下四个阶段: 1)数据摄入:当客户端向记忆管理器提供原始数据源(通常是对话历史)时,整个流程正式启动。 2)提取与筛选:记忆管理器通过大语言模型从数据源中提取有价值的内容。关键在于,该大语言模型不会提取所有信息,只会捕获符合预定义“主题定义”的内容。如果摄入的数据中没有与这些主题匹配的信息,则不会生成任何记忆。 3)整合处理:这是最复杂的阶段,记忆管理器在此完成冲突解决和去重操作。它会执行“自我编辑”流程:通过大语言模型将新提取的信息与现有记忆进行比对。为确保用户知识库的连贯性、准确性,并基于新信息持续演进,管理器会做出以下决策: - 将新洞察合并到现有记忆中; - 若现有记忆已失效,则将其删除; - 若为全新主题,则创建一条全新的记忆。 译者注:白皮书中描述的整合过程——LLM对比新旧记忆并决定操作类型——这实际上是记忆系统的推理引擎。它解决了信息系统中经典的数据一致性问题:通过识别冗余避免存储膨胀;通过冲突解决维护知识一致性;通过信息演进实现用户认知的渐进式精炼。这个“自我编辑”机制让记忆系统具备了自维护能力,这是传统数据库完全不具备的特性。 4)存储持久化:最终,新生成或更新后的记忆会被持久化到可靠的存储层(如向量数据库或知识图谱),以便在未来的交互中快速检索。 像 Agent Engine Memory Bank 这样的托管式记忆管理器,会将整个流程完全自动化。它们提供了一套统一、连贯的系统,能将对话中的无效信息转化为结构化知识,让开发者无需自行构建和维护底层数据基础设施,可专注于智能体逻辑的开发。例如,通过 Memory Bank 触发记忆生成仅需一个简单的 API 调用: 代码片段6:使用Agent Engine Memory Bank生成记忆 ```python 导入Google Cloud的Vertex AI SDK from google.cloud import vertexai #初始化Vertex AI客户端(需替换为实际项目ID和区域) client = vertexaiClient(project="你的项目ID", location="你的区域") #调用记忆生成接口 client(agent Engines.memories_generate( #记忆管理器的资源名称(需替换为实际资源路径) name="projects/你的项目ID/Locations/你的区域/reasoningEngines/你的推理引擎ID", #记忆的作用范围(指定关联的用户ID) scope={'user_id":"123'}, #直接指定内容来源(传入对话事件列表) direct_contents_source={'events":[...] #此处填写实际的对话事件数据(如消息记录、交互日志等)} ), #生成配置 config={' #关键配置:设置为异步执行(后台运行记忆生成,不阻塞当前流程) "wait_for Completion":False} ``` 1 记忆生成的过程可类比为一位勤奋的园丁打理花园:提取阶段如同收到新的种子和幼苗(来自对话的新信息),园丁不会随意将它们撒在地里,而是通过整合处理环节:拔除杂草(删除冗余或冲突数据)、修剪过密的枝条以促进现有植物健康生长(优化和总结现有记忆),然后将新幼苗精心栽种在最合适的位置。这种持续、用心的打理确保花园始终保持健康有序、不断繁茂,而非变得杂乱无章、无法利用。整个过程以异步方式在后台运行,确保每次“到访”(交互)时,花园(知识库)都处于最佳状态。 接下来,我们深入探讨记忆生成的两个关键步骤:提取与整合。 # 4.2.1 深度解析:记忆提取 记忆提取的核心目标是回答一个基础问题:“这场对话中,哪些信息足够有意义,值得被留存为记忆?”这并非简单的内容总结,而是一个定向、智能的筛选过程——要从“噪音”(寒暄、填充性文字)中分离出“有效信号”(关键事实、偏好、目标)。 “有意义”并非通用概念,它完全由智能体的用途和场景决定。客服智能体需要记忆的内容(比如订单号、技术问题),和个人健康教练需要记忆的内容(比如长期目标、情绪状态),本质上截然不同。因此,自定义需留存的信息类型,是打造真正高效智能体的关键。 记忆管理器的大语言模型会依据一套精心设计的程序化约束与指令(通常嵌入复杂的系统提示词中),决定要提取的内容。这套提示词通过“主题定义”明确了“有意义”的标准,常见的提取方式包括: - 基于 Schema 与模板的提取:给大语言模型指定预定义的 JSON 结构,或利用大语言模型的结构化输出能力设计模板,让模型从对话中提取对应信息并填充到 JSON 里; ○ 译者注:适用于高度结构化、可枚举的信息(如日期、产品 ID、状态码)的场景。优点是精确度高,易解析;缺点是灵活性差,需预定义所有字段。 - 基于自然语言的主题定义:用简单的自然语言描述主题,引导大语言模型识别相关内容; ○译者注:适用于概念性、描述性的主题(如“用户体验反馈”、“技术问题”)的场景。优点是表达能力强,易理解;缺点是可能产生歧义,需要精心设计的提示词。 - 少样本提示提取:给大语言模型提供“输入文本-理想记忆”的示例,让模型从示例中学习提取模式——这种方式对难以用 schema 或简单定义描述的定制化、细粒度主题尤为有效。 ○译者注:适用于复杂、模糊、领域特定的概念(如“客户不满的微妙迹象”)的场景。优点是可从示例中学习复杂模式;缺点是需要标注数据,可能过拟合。 译者注:最佳实践通常是混合使用:用 Schema 处理确定性信息,用少样本提示处理模糊概念。 整合阶段的算法复杂性被低估。 多数记忆管理器默认会识别通用主题(比如用户偏好、关键事实、目标),同时也支持开发者自定义主题,让提取流程适配特定领域。例如,你可以通过自定义主题定义和少样本示例,设置 Agent Engine Memory Bank 需留存的“有意义信息”: 代码片段 7:自定义 Agent Engine Memory Bank 需留存的有意义信息 ```python from google.genai.types import Content, Part #更多信息参考:https://cloud.google.com/agent-builder/agent-engine/memory- bank/set-up #配置记忆库的自定义规则 memory_bank_config = { "customizationconfigs": [ { #自定义配置列表 "memory_topics": [ #要提取的记忆主题 #内置主题:用户个人信息 {"managed_memory_topic": {"managed_topic今天我们,} #自定义主题:咖啡店相关反馈 { "custom_memory_topic": { "label": "business_feedback", #主题标识 "description": ""用户对咖啡店体验的具体反馈,包括对饮品、食物、糕点、氛 围、员工友好度、服务速度、卫生情况的评价,以及任何改进建议。 } ], #少样本示例:告诉模型如何从对话中提取记忆 "generate_memories/examples": { "conversationSource": { #示例对话来源 "events": [ #对话事件列表 { "content": Content(#模型发出的消息 role="model", parts=[Part(text="欢迎回到The Daily Grind!我们很想听听您的光顾 体验。") }, { "content": Content(#用户的反馈 role="user", parts=[Part(text="嗨,今天的滴滤咖啡有点温,这点不太满意。另外店 里的音乐太吵了,我几乎听不清朋友说话。") } }, "generatedMemories": [ #对应提取出的记忆 ``` ```python {"fact":"用户反馈今天的滴滤咖啡温度偏温。"},{"fact":"用户觉得店内音乐音量过大。"}] 1 1] } # 创建配置好记忆库的智能体引擎 agent.engine $=$ client(agent_engines.create(config={'将记忆库配置关联到智能体的上下文规范中"context_spec": {"memory_bank_config": memory_bank_config}}) ``` 尽管记忆提取本身不是“总结”,但算法会融入总结能力来提炼信息。为提升效率,很多记忆管理器会在记忆提取提示词中加入对话的“滚动摘要”(参考: https://arxiv.org/html/2504.19413v1)。这份浓缩的对话历史能为提取最新交互的关键信息提供必要上下文,避免每次都重复处理冗长的完整对话来维持上下文连贯性。 当信息从数据源中提取完成后,就需要通过“整合”环节,将新信息更新到已有的记忆库中。 译者注:记忆提取不是简单的关键词匹配或情感分析,而是基于目标导向的信息过滤。通过预定义主题(无论是内置通用主题还是自定义业务主题),记忆系统实现了:1)注意力机制,只关注与智能体功能相关的信息;2)语义理解,能捕捉相同概念的不同表达方式(如“NYC”和“纽约”);3)上下文关联:结合滚动摘要理解信息的完整含义。这实际上是在对话流上部署了一个持续运行的实体/关系抽取和分类模型,但使用LLM作为通用理解引擎。 # 4.2.2 深度解析:记忆整合 在从冗长对话中提取出记忆后,整合环节需要将新信息融入知识库,使其保持连贯、准确并持续演进。这可以说是记忆生命周期中最复杂的阶段——它能把零散的事实集合,转化为对用户的系统化认知。如果没有整合,智能体的记忆会迅速变成杂乱、矛盾、不可靠的信息日志。这种“自我整理”通常由大语言模型实现,也是记忆管理器区别于普通数据库的核心优势。 整合环节主要解决对话数据带来的几类核心问题: - 信息重复:用户可能在不同对话中以多种方式提及同一事实(比如“我要订去NYC的航班”和“我计划去纽约旅行”),若仅做简单提取会生成两条冗余记忆; - 信息冲突:用户的状态会随时间变化,缺乏整合的话,智能体记忆会包含矛盾的事实; - 信息演进:简单事实会变得更具体——比如初始记忆“用户对营销感兴趣”,可能演变为“用户正主导Q4客户获取的营销项目”; - 记忆相关性衰减:并非所有记忆都永远有用,智能体需要“遗忘”——主动清理过时、陈旧或低置信度的记忆,保持知识库的相关性与高效性。实现遗忘的方式包括:在整合时让大语言模型优先采用新信息,或通过“存活时间(TTL)”自动删除记忆。 整合流程是由大语言模型驱动的工作流,会将新提取的信息与用户已有的记忆做比对,具体步骤如下: 1)检索相似记忆:先从现有记忆库中检索与新提取记忆相似的内容,这些内容会作为整合的候选对象。若现有记忆与新信息矛盾,可能会被删除;若新信息是对现有记忆的补充,则可能被更新; 2)决策操作类型:将现有记忆与新信息同时输入大语言模型,让模型分析并确定要执行的操作,核心操作包括: - 更新(UPDATE):用新信息或修正后的信息修改现有记忆; - 创建(CREATE):若新信息是完全新颖、与现有记忆无关的内容,则创建新记忆; - 删除/失效(DELETE / INVALIDATE):若新信息让旧记忆完全无关或错误,则删除或标记其失效。 3)执行存储更新:记忆管理器将大语言模型的决策转化为事务操作,更新记忆存储库。 译者注:整合阶段的算法复杂性被低估 白皮书描述的整合流程(检索-决策-执行)虽然正确,但实际实现中隐藏着诸多挑战: 1)挑战1:相似性检索的局限性 纯粹的向量相似性检索可能错失逻辑关联但语义不相似的信息。例如:“我讨厌咖啡”和“我喜欢茶”语义相反,但都指向“饮料偏好”。解决方案:混合检索策略(向量检索 + 关键词检索 + 基于知识图谱的关联检索)。 2)挑战2:冲突解决需要元数据支撑 当新旧信息冲突时,仅凭内容难以决策。需要附加:时间戳、信息源置信度、用户确认次数等元数据。例如:显式声明(“记住我的生日是X”)应比隐式推断(“下周我过生日”)优先级更高。 3)挑战3:操作的原子性与回滚 整合操作应该是事务性的,但LLM的决策可能不一致。例如:先删除旧记忆,再创建新记忆,如果第二步失败会导致数据丢失。解决方案:实现操作日志和回滚机制,或在决策阶段生成完整的事务脚本。 译者注:遗忘机制需要更系统的设计 资料提到了TTL和基于新旧优先的遗忘,但这仅是冰山一角。完整的遗忘机制应考虑: <table><tr><td>遗忘策略</td><td>原理</td><td>适用场景</td></tr><tr><td>时间衰减</td><td>基于最后访问时间或创建时间</td><td>时效性信息(如“用户正在旅行”)</td></tr><tr><td>使用频率</td><td>很少被检索或引用的记忆</td><td>偶然提及但不重要的细节</td></tr><tr><td>相关性网络</td><td>当核心记忆被删除时,连带删除相关记忆</td><td>维护知识图谱的一致性</td></tr><tr><td>用户显式指令</td><td>用户要求忘记某些信息</td><td>隐私合规要求</td></tr><tr><td>置信度阈值</td><td>低于一定置信度的记忆自动清理</td><td>清理低质量推断</td></tr></table> # 4.3 记忆溯源 (Memory Provenance) 机器学习领域有句经典格言:“垃圾进,垃圾出”(garbage in, garbage out),这对大语言模型而言尤为关键——其结果往往是“输入垃圾,输出自信满满的垃圾”(garbage in, confident garbage out)。要让智能体做出可靠决策,让记忆管理器有效整合记忆,就必须能批判性地评估自身记忆的质量。而这种可信度,直接来源于记忆的“溯源信息”(provenance)——一份记录记忆来源与演变历程的详细档案。 图7:数据源与记忆间的信息流向。单个记忆可源自多个数据源,单个数据源也可能为多个记忆提供支撑 记忆整合(memory consolidation)是将多源信息融合为单个动态演化记忆的过程,这一过程催生了对记忆谱系(lineage)的追踪需求。如上图所示,单个记忆可能是多个数据源的融合产物,而单个数据源也可能被拆分到多个记忆中。 为评估记忆的可信度,智能体必须追踪每个数据源的关键细节,例如来源类型(source type)和时效性(“新鲜度”,freshness)。这些细节至关重要,原因有二:一是它们决定了各数据源在记忆整合过程中的权重;二是它们指导智能体在推理阶段对该记忆的依赖程度。 来源类型是决定可信度的核心因素之一,数据源主要分为三类: - 预置数据(Bootstrapped Data):从内部系统预加载的信息(如客户关系管理系统 CRM)。这类高可信度数据可用于初始化用户记忆,解决“冷启动问题”——即智能体在首次与用户交互时,如何提供个性化体验的挑战。 - 用户输入 (User Input) : 包括用户明确提供的数据(如通过表单提交,可信度高),或从对话中隐式提取的信息(可信度通常较低)。 - 工具输出(Tool Output):外部工具调用返回的数据。不建议基于工具输出生成长期记忆,因为这类记忆往往稳定性差、易过时,更适合用于短期缓存。 # 4.3.1 记忆管理中的谱系追踪 这种多源动态的记忆构建方式,给记忆管理带来了两大核心运营挑战:冲突解决(conflict resolution)和衍生数据删除(deleting derived data)。 记忆整合过程中难免出现数据源冲突的情况。记忆的溯源信息使记忆管理器能够为各信息源建立可信度层级。当不同来源的记忆相互矛盾时,智能体需依据该层级采用冲突解决策略,常见策略包括:优先采用可信度最高的来源、青睐最新信息,或寻找多个数据点的交叉验证。 记忆管理的另一大挑战是记忆删除。由于单个记忆可能源自多个数据源,当用户撤销对某个数据源的访问权限时,基于该数据源生成的衍生数据也应被移除。直接删除所有“接触过”该数据源的记忆可能过于激进,更精准(尽管计算成本更高)的方式是:仅利用剩余的有效数据源,重新生成受影响的记忆。 除了静态的溯源信息,对记忆的可信度评估也需动态演化:当多个可信来源提供一致信息时,可信度会通过交叉验证得到提升。同时,高效的记忆系统必须通过“记忆修剪”(memory pruning)主动筛选现有知识——即识别并“遗忘”不再有用的记忆。触发修剪的因素主要包括: - 时效性衰减(Time-based Decay):记忆的重要性会随时间降低。例如,两年前的会议记忆可能远不如上周的会议记忆相关。 - 低可信度(Low Confidence):基于薄弱推理生成、且从未经其他来源验证的记忆,可能被修剪。 - 无关性(Irrelevance):随着智能体对用户的理解不断深化,可能会判定部分早期琐碎记忆与用户当前目标不再相关,进而将其修剪。 通过将“被动整合流水线”与“主动修剪机制”相结合,记忆管理器确保智能体的知识库并非简单堆砌所有过往信息的日志,而是经过筛选、准确且贴合用户需求的深度理解。 # 4.3.2 推理阶段的谱系考量 除了在知识库筛选过程中考虑记忆谱系,推理阶段也需纳入记忆的可信度评估。智能体对记忆的可信度不应是静态的,而需根据新信息的出现和时间推移动态调整:通过多源交叉验证可提升可信度;反之,随着旧记忆过时,可信度会逐渐衰减,且当出现矛盾信息时,可信度也会下降。最终,系统可通过归档或删除低可信度记忆实现“遗忘”。 这种动态可信度评分在推理阶段至关重要:记忆及其可信度评分(若有)不会直接展示给用户,而是被注入提示词(prompt)中,使大语言模型能够评估信息可靠性,做出更精准细腻的决策。 整个可信度框架服务于智能体的内部推理过程:记忆及其可信度评分通常不直接呈现给用户,而是通过注入系统提示词,让大语言模型能够权衡证据、考量信息可靠性,最终做出更具深度和可信度的决策。 # 4.4 触发记忆生成 尽管记忆管理器会在生成触发后自动完成记忆提取与整合,但智能体仍需决定何时尝试启动记忆生成流程。这是一项关键的架构设计选择,需要在数据时效性、计算成本与延迟之间找到平衡。该决策通常由智能体的逻辑层管控,可采用多种触发策略。记忆生成可基于以下各类事件启动: - 会话结束 (Session Completion):在多轮对话会话结束时触生成成; - 轮次间隔(TurnCadence):在特定对话轮次后执行生成流程(例如每5轮触发一次); - 实时触发(Real-Time):每一轮对话结束后立即生成记忆; - 显式指令 (Explicit Command) : 响应用户的直接指令触发生成(例如“记住这段内容”)。 触发方式的选择直接关乎成本与记忆保真度的权衡: - 高频生成(如实时触发)可确保记忆高度详实且时效性强,能捕捉对话的每一处细节,但会产生最高的大语言模型调用成本与数据库操作成本,若处理不当还会引入延迟; - 低频生成(如会话结束时触发)成本效益显著更高,但由于大语言模型需一次性总结大段对话内容,可能导致记忆保真度降低。此外,需注意避免记忆管理器重复处理同一事件,否则会产生不必要的成本损耗。 # 4.4.1 记忆即工具 (Memory-as-a-Tool) 一种更精细化的方案是让智能体自主决定何时创建记忆。在该模式下,记忆生成功能被封装为工具(即create_memory工具);工具定义中需明确哪些类型的信息应被判定为具有留存价值。智能体可分析对话内容,当识别到值得持久化的信息时,自主决定调用该工具。这一设计将“识别有价值信息”的责任从外部记忆管理器转移至智能体本身(最终由开发者把控)。 例如,借助 ADK(Agent Development Kit)可实现该方案:将记忆生成代码封装为工具,当智能体判定对话内容值得留存时,自行调用该工具。你可将会话数据发送至记忆库(Memory Bank),由记忆库从对话历史中提取并整合记忆: # 代码片段 8:ADK 智能体通过自定义工具触发记忆生成 # (记忆由记忆库完成提取与整合) ```python from google.adk.agents import Ll mAgent from google.adk/memory import VertexAiMemoryBankService from google.adk.runners import Runner from google.adk.tools import ToolContext def generate_memories tool_context: ToolContext): ""触发记忆生成以留存会话内容 Args: tool_context:工具上下文对象,包含会话、用户等核心上下文信息 Returns: 包含执行状态的字典 "" #方案1:通过ADK记忆服务从完整对话历史中提取记忆 #注:session需确保已从上下文或外部传入,此处为简化示例未展示赋值逻辑 tool_context._invocation_context-memory_service.add_session_to_memory( session) #方案2:仅从最后一轮对话中提取记忆 #调用AgentEngine的记忆生成接口 client(agent Engines.memories_generate( #指定推理引擎的完整资源名称 name="projects/../locations/../reasoningEngines/..", #数据源:仅传入最后一轮用户输入的内容 direct相关内容_source $=$ { "events":[ {"content":tool_context._invocation_context.user_content} ] }, #作用域:指定记忆归属的用户与应用 scope $=$ { "user_id":tool_context._invocation_context.user_id, "app_name":tool_context._invocation_context.app_name }, #配置:后台异步生成记忆(不阻塞用户响应) config $=$ {"wait_for Completion":False} ) return {"status":"success"} #初始化智能体,注册记忆生成工具 agent $=$ LlmAgent( #省略模型配置、系统提示词等其他参数 ..., tools $=$ [generate_memories] #将自定义的记忆生成工具注入智能体 ) #初始化运行器,关联记忆服务 runner $=$ Runner( agent $\equiv$ agent, ``` ```python app_name=APP_NAME, # 应用名称(需提前定义) session_service=session.service, # 会话服务实例(需提前初始化) # 配置Vertex AI记忆库服务 memory_service=VertexAiMemoryBankService( agent_engine_id=AGENTENGINE_ID, # Agent Engine的ID project=PROJECT, # GCP项目ID location=LOCATION # 部署区域(如us-central1) ``` 另一种方案是利用内部记忆机制:由智能体主动决定从对话中留存哪些信息。在该流程中,智能体负责提取关键信息;可选地,这些提取出的记忆可被发送至 Agent Engine Memory Bank,与用户已有的记忆进行整合: 代码片段9:ADK智能体通过自定义工具提取对话记忆,并触发与Agent Engine记忆库的整合 (与片段 8 不同: 记忆提取由智能体完成, 而非记忆库) ```python def extract_memories(query: str, tool_context: ToolContext): ""触发记忆生成以留存用户相关信息 Arguments: query: 从对话中提取的、值得持久化的用户相关关键信息 tool_context: 工具上下文对象,提供用户/应用等上下文信息 Returns: 包含执行状态的字典 # 调用 Agent Engine 记忆生成接口,直接整合已提取的记忆 client(agent Engines.memories_generate( # 指定推理引擎的完整资源名称 name="projects/../locations/../reasoningEngines/../", # 直接传入已提取的记忆(无需再从对话内容解析) direct_memories_source={{"fact": query}} # fact为记忆事实内容 ), # 作用域:指定记忆归属的用户与应用 scope={{"user_id": tool_context._invocation_context.user_id, "app_name": tool_context._invocation_context.app_name}}, # 异步执行:避免阻塞用户交互 config={{"wait_for_completion": False}} ) return {"status": "success"} ``` # 4.4.2 后台操作 vs. 阻塞式操作 记忆生成属于高成本操作,需调用大语言模型并执行数据库写入。对于生产环境中的AI智能体,记忆生成几乎都应作为后台进程异步处理(23)。 智能体向用户返回响应后,记忆生成流水线可并行运行,不会阻塞用户体验。这种解耦设计是保证智能体响应快速、交互流畅的关键:若采用阻塞式(同步)方案,用户需等待记忆写入完成后才能收到回复,将导致无法接受的慢速体验与用户挫败感。这就要求记忆生成功能部署在架构上独立于智能体核心运行时的服务中。 # 4.5 记忆检索 (Memory Retrieval) 在搭建好记忆生成机制后,核心工作可转向至关重要的检索环节。一套智能的检索策略是智能体性能的关键保障,它需要明确两大核心决策:应检索哪些记忆,以及何时执行检索。 检索策略的设计高度依赖记忆的组织形式: - 对于结构化用户档案(structured user profile),检索通常是直接的查询操作——要么获取完整档案,要么提取特定属性; - 而对于非结构化或半结构化的记忆集合(collection of memories),检索则是更为复杂的搜索问题:需从海量数据中挖掘与当前场景最相关、概念最契合的信息。本节探讨的策略,正是为解决记忆集合的复杂检索挑战而设计。 记忆检索的核心目标是为当前对话匹配最具相关性的记忆。一套高效的检索策略至关重要:提供无关记忆会干扰大语言模型的判断、降低响应质量;而精准匹配到关键上下文,则能让交互体验变得异常智能。检索的核心挑战在于:在严格的延迟预算内,平衡记忆的“实用性”。 先进的记忆系统不止步于简单搜索,而是通过多维度评分筛选最优记忆,核心维度包括: - 相关性(语义相似度,Relevance):该记忆与当前对话的概念契合度如何? - 时效性(Recency):该记忆的创建时间距今多久? - 重要性(Significance):该记忆的整体关键程度如何?与相关性不同,“重要性”可在记忆生成时预先定义。 仅依赖基于向量的相关性检索是常见误区——相似度分数可能筛选出概念相似但过时或无关紧要的记忆。最有效的策略是“混合评分法”:综合上述三个维度的得分进行决策。 译者注:混合评分法是现代检索系统的标准范式,白皮书提出了三维评分体系:1)相关性:解决”语义匹配”问题(“用户说了什么?”);2)时效性:解决”信息新鲜度”问题(“这是什么时候的信息?”);3)重要性:解决”价值密度”问题(“这个信息有多关键?”)。这三个维度共同构成了一个记忆价值评估框架,实际上对应了人类记忆的三个特性:联想性、时间标签、情感强度。 对于准确性要求极高的场景,可通过以下方法优化检索效果,但需注意其计算成本与延迟代价(不适用于多数实时应用): - 查询重写 (query rewriting) : 利用大语言模型优化搜索查询(如将模糊输入转化为精准查询,或扩展为多维度查询以覆盖主题全貌),虽能提升初始搜索质量,但会增加一次大语言模型调用的延迟; - 重排序(reranking):先通过相似度搜索获取大量候选记忆(如Top50结果),再利用大语言模型重新评估并排序,生成更精准的最终列表(24); - 专用检索器微调(specialized retrievers):通过微调训练定制化检索器,但需依赖标注数据,且会显著增加成本。 若需使用这些复杂算法,且记忆不易过时,可通过缓存层缓解延迟问题:将高成本的检索结果临时存储,后续相同请求可直接复用,避免重复计算。 最终,最优检索策略的根基是“高质量记忆生成”——确保记忆库内容优质、无无关信息,是保证检索结果有效的最核心手段。 # 4.5.1 检索时机 (Timing for Retrieval) 检索环节的最后一项架构决策是“何时执行检索”,主要分为两种方案: 译者注:主动检索 vs 被动检索的对比不是简单的“好与坏”,而是不同工程约束下的优化选择。主动检索牺牲每次调用的固定开销,换取确定的上下文完备性;而被动检索将检索决策权交给智能体,实现按需加载,但增加决策复杂度。这本质上是在预计算成本与运行时决策成本之间的权衡。 # 方案1:主动检索(ProactiveRetrieval) 在每轮对话开始时自动加载记忆,确保上下文随时可用,但会为无需访问记忆的轮次引入不必要的延迟。由于单轮对话中记忆内容保持不变,可通过高效缓存减轻性能损耗。 例如,在ADK中可通过内置的PreLoadMemoryTool或自定义回调函数实现主动检索: 代码片段 10: 使用 ADK 的内置工具或自定义回调, 在每轮对话开始时检索记忆 ```txt 方案1:使用内置的PreloadMemoryTool(每轮通过相似度搜索自动检索记忆)from google.adk.tools.preload_memory_tool import PreloadMemoryToolagent $=$ LlmAgent(#省略模型配置、系统提示词等其他参数...,tools $\coloneqq$ [PreloadMemoryTool()] #注入内置预加载记忆工具) ``` ```txt 方案2:使用自定义回调函数,更灵活地控制记忆检索逻辑 def retrieve_memories_callback(callback_context, llm_request): ""自定义回调函数:在调用大语言模型前检索记忆并注入上下文 Args: callback_context:回调上下文对象,包含调用相关元信息 ``` ```python llm_request:大语言模型请求对象,用于修改请求配置 ``` #从上下文获取用户ID和应用名称(确定记忆归属) user_id = callback_context._invocation_context.user_id app_name = callback_context._invocation_context.app_name #调用Agent Engine的记忆检索接口 response = client(agent Engines.memories.retrieve( #指定推理引擎的完整资源名称 name="projects/../locations/../reasoningEngines/... #检索范围:限定当前用户和应用的记忆 scope={{"user_id":user_id, "app_name":app_name} } ) #格式化检索到的记忆(转为"* 记忆事实"的列表形式) memories = [f"* {memory/memory.fact}" for memory in list(response)] if not memories: #无匹配记忆,不修改系统提示词 return #将格式化后的记忆追加到系统提示词中,供大语言模型参考 llm_request.config.systeminstruction += "\n以下是你已掌握的用户相关信息:\n" llm_request.config.systeminstruction += "\n".join(memories) #初始化智能体,绑定前置回调函数(检索记忆) agent = LlmAgent( ... before_model_callback=retrieve_memories_callback, #调用模型前执行检索 ``` # 方案2:被动检索(Reactive Retrieval,“记忆即工具”) 为智能体提供记忆查询工具,由智能体自主决定何时检索上下文。该方案更高效、稳健,但需额外调用一次大语言模型,会增加延迟与成本;不过仅在必要时执行检索,延迟代价的发生频率更低。 此外, 智能体可能不清楚是否存在相关记忆可检索——可通过在工具描述中明确记忆类型 (如自定义工具的说明文档), 帮助智能体做出更合理的检索决策。 代码片段 11:配置 ADK 智能体,通过内置或自定义工具自主决定检索时机 ```python #方案1:使用内置的LoadMemory工具 from google.adk.tools.load_memory_tool import LoadMemoryTool agent = LlmAgent( ..., tools=[LoadMemoryTool(), #注入内置记忆加载工具) #方案2:使用自定义工具(可明确描述可用记忆类型,提升智能体决策准确性) ``` ```python def load_memory(query: str, tool_context: ToolContext): ""检索用户相关记忆 工具说明:告知智能体当前可查询的记忆类型,辅助其判断是否调用该用户可能存储以下类型的信息: * 用户偏好(如喜爱的食物、常用设置等) * 历史交互记录(如之前提到的需求、已完成的操作等) * 个人属性(如职业、联系方式等,需符合隐私规范) ...(可根据实际场景补充) Args: query: 检索关键词(由智能体根据对话生成) tool_context: 工具上下文对象,提供检索相关能力 Returns: 检索到的记忆列表 # 通过相似度搜索检索记忆(tool_context 内置 search_memory 方法) response = tool_context.search_memory(query) return response.memories # 返回记忆列表供智能体使用 # 初始化智能体,注入自定义记忆检索工具 agent = LlAgent( ... tools=[load_memory], ) ``` # 4.6 基于记忆的推理 (Inference with Memories) 在检索到相关记忆后,最后一步是将这些记忆策略性地融入模型的上下文窗口。这是至关重要的环节:记忆的嵌入方式会显著影响大语言模型的推理过程、运营成本,最终决定回答的质量。 记忆的呈现方式主要有两种——追加至系统指令中,或注入对话历史;实际应用中,混合策略往往效果最佳: - 系统提示词(system prompt)适用于承载稳定的“全局记忆”(如用户档案),这类记忆需全程参与交互; - 对话注入或“记忆即工具”模式则适用于临时的“场景化记忆”(仅与当前对话上下文相关)。 这种设计既能满足持久化上下文的需求,又能兼顾即时信息检索的灵活性。 译者注:系统指令注入会影响模型的身份认知和长期行为倾向;对话历史注入会影响模型的短期注意力和上下文理解。这对应了认知科学中的工作记忆与长期记忆的区别。 # 4.6.1 系统指令中的记忆嵌入 将记忆追加至系统指令是一种简单的推理阶段应用方式。该方法通过在系统提示词后附加检索到的记忆(搭配引导语),将其定义为整个交互的基础上下文,同时保持对话历史的整洁。例如,可通过 Jinja 模板动态将记忆嵌入系统指令: 代码片段 12:基于检索到的记忆构建系统指令 ```python from jinja2 import Template # 定义 Jinja 模板:将系统指令与记忆拼接,结构化呈现用户相关信息 # 注:原代码模板末尾多了一个“}”,已修正 template = Template(""); ``` 将记忆纳入系统指令的优势在于: 1. 赋予记忆较高的权重(大语言模型会将系统指令视为核心准则); 2. 清晰区分上下文与对话内容,避免混淆; 3. 适配用户档案等稳定的“全局信息”。 但该方式存在“过度影响”风险:智能体可能会强行将所有话题与核心指令中的记忆关联,即便这种关联并不恰当。 此外,该架构模式还存在以下约束: - 要求智能体框架支持每轮调用大语言模型前动态构建系统提示词(部分框架未原生支持此功能); - 与“记忆即工具”模式不兼容——系统提示词需在大语言模型决定调用记忆检索工具前确定,无法动态调整; - 对非文本类记忆的支持性差:多数大语言模型仅接受文本格式的系统指令,难以直接嵌入图片、音频等多模态内容。 # 4.6.2 对话历史中的记忆嵌入 这种方式是将检索到的记忆直接注入逐轮对话流中,可选择放置在完整对话历史的开头,或紧邻最新的用户查询前。 该方法的弊端在于:- 易引入冗余信息,增加 Token 消耗;若检索到无关记忆,还可能干扰大语言模型的判断;- 核心风险是“对话注入混淆”:模型可能误将记忆当作真实发生的对话内容;- 需严格把控记忆的视角——例如,若使用“用户”角色注入用户级记忆,需采用第一人称表述。 对话历史注入的特殊场景是“通过工具调用检索记忆”:记忆会作为工具输出的一部分直接融入对话,无需额外处理。 代码片段 13:将记忆检索封装为工具,直接将记忆插入对话历史 ```python def Load_memory(query: str, tool_context: ToolContext): ""检索用户记忆并直接插入对话历史 Args: query: 检索关键词(由智能体根据当前对话生成) tool_context: 工具上下文对象,提供记忆检索、对话操作等能力 Returns: 检索到的用户记忆列表(会自动作为工具输出插入对话) # # 基于关键词检索用户记忆(tool_context 内置的相似度检索方法) response = tool_context.search_memory(query) # 返回记忆列表:工具调用结果会直接追加至对话历史,供大语言模型参考 return response/memoryes # 初始化智能体:将记忆检索工具注入,由智能体自主决定何时调用 agent = LlAgent( # 省略模型配置、系统提示词等其他参数 ... tools = [load_memory], # 注册自定义记忆检索工具 ``` # 4.7 程序性记忆 (Procedural Memories) 本文档此前主要聚焦于陈述性记忆(declarative memories)——这与当前商业记忆领域的发展现状一致。大多数记忆管理平台的架构设计均围绕陈述性记忆展开,擅长提取、存储和检索“是什么”(事实、历史记录、用户数据等)。 然而,这些系统并未针对程序性记忆(procedural memories)进行优化——这类记忆是智能体优化工作流程与推理能力的核心机制。存储“如何做”并非简单的信息检索问题,而是推理增强问题。管理这种“技能型知识”需要一套完全独立的专业化算法生命周期,尽管其高层级结构与陈述性记忆相似: 1. 提取(Extraction):程序性记忆的提取需要专用提示词设计,核心目标是从成功的交互中提炼出可复用的策略或“操作手册”(playbook),而非仅捕捉单一事实或有价值信息; 2. 整合(Consolidation):陈述性记忆的整合是合并相关事实(“是什么”),而程序性记忆的整合则是对工作流程本身(“如何做”)进行筛选优化——包括将新的成功方法与现有“最佳实践”融合、修补已知方案中的缺陷步骤、修剪过时或无效的流程; 3. 检索(Retrieval):核心目标并非检索数据以回答问题,而是获取指导智能体执行复杂任务的方案。因此,程序性记忆的数据结构可能与陈述性记忆存在差异。 智能体这种“自我进化”逻辑的能力,自然让人联想到一种常见的适配方法:微调(finetuning)——通常通过基于人类反馈的强化学习(Reinforcement Learning from Human Feedback, RLHF)实现。两者虽均以提升智能体行为表现为目标,但机制与应用场景存在本质区别: <table><tr><td>特性</td><td>微调(Fine-tuning)</td><td>程序性记忆(Procedural Memory)</td></tr><tr><td>实现方式</td><td>离线训练,修改模型权重</td><td>在线动态适配,注入提示词</td></tr><tr><td>响应速度</td><td>较慢(需完整训练周期)</td><td>快速(即时注入,无需等待)</td></tr><tr><td>适配机制</td><td>模型参数级更新</td><td>上下文学习(in-context learning)</td></tr><tr><td>资源消耗</td><td>高(需大量数据与计算资源)</td><td>低(仅需提示词注入,无需微调)</td></tr></table> 程序性记忆通过将正确的“操作手册”动态注入提示词,借助上下文学习引导智能体,实现了无需微调的快速在线适配。 # 4.8 测试与评估 (Testing and Evaluation) 当你构建好具备记忆能力的智能体后,需通过全面的质量与评估测试验证其行为表现。智能体记忆的评估是一个多层级过程,核心需验证三点: 1. 记忆质量:智能体是否记住了正确的信息; 2. 检索效果:智能体能否在需要时精准找到目标记忆; 3. 实用价值:使用这些记忆是否真的有助于智能体达成目标(任务成功率)。 学术界的评估重点在于可复现的基准测试,而工业界的评估核心则是记忆对生产环境中智能体性能与可用性的直接影响。 # 4.8.1 记忆生成质量指标 (Memory Generation Quality Metrics) 评估记忆本身的内容质量,核心回答“智能体是否记住了正确的信息?”。通常通过将智能体生成的记忆与人工构建的“理想记忆黄金集”(golden set)进行对比来衡量: - 精确率(Precision):智能体生成的所有记忆中,准确且相关的比例。高精确率可避免“过度活跃”的记忆系统向知识库中注入无关噪声; - 召回率(Recall):在源数据中所有应被记住的相关事实中,智能体成功捕捉的比例。高召回率确保智能体不会遗漏关键信息; - F1 分数(F1-Score):精确率与召回率的调和平均数,提供单一、均衡的质量衡量指标。 # 4.8.2 记忆检索性能指标 (Memory Retrieval Performance Metrics) 评估智能体在正确时间找到正确记忆的能力: - 前 K 召回率(Recall@K):当需要某一记忆时,正确的记忆是否出现在前 K 个检索结果中?这是检索系统准确性的核心衡量指标; - 延迟(Latency):检索处于智能体响应的“关键路径”(hot path)中。整个检索过程必须在严格的延迟预算内完成(例如200毫秒以内),避免影响用户体验。 # 4.8.3 端到端任务成功指标 (End-to-End Task Success Metrics) 这是最终的核心测试,回答“记忆是否真的能帮助智能体更好地完成工作?”。通过评估智能体在下游任务中使用记忆后的表现来衡量——通常由大语言模型“裁判”(judge)将智能体的最终输出与黄金答案对比,判断回答是否准确,进而量化记忆系统对最终结果的贡献度。 评估并非一次性事件,而是持续改进的引擎。上述指标提供了识别系统弱点的关键数据,支持对记忆系统进行系统性优化。这一迭代过程包括:建立基准性能、分析失败案例、调整系统参数(如优化提示词、调整检索算法)、重新评估以衡量改进效果。 除质量指标外,生产环境就绪性还依赖性能表现。对于每个评估维度,必须衡量底层算法的延迟及其在负载下的扩展能力: - 关键路径上的记忆检索需满足严格的亚秒级延迟预算; - 记忆生成与整合虽多为异步操作,但需具备足够的吞吐量以应对用户需求。 最终,一个成功的记忆系统必须兼具智能性、高效性与稳健性,以适配真实世界的应用场景。 # 4.9 记忆系统的生产环境考量 (Production Considerations for Memory) 除性能外,将具备记忆能力的智能体从原型推向生产环境,还需重点关注企业级架构设计问题——包括可扩展性、韧性与安全性。生产级系统的设计不仅要保障智能性,更要满足企业级的稳健性要求。 # 4.9.1 核心架构原则:解耦记忆处理与业务逻辑 为避免计算成本高昂的记忆生成过程阻塞用户体验,稳健的架构必须将记忆处理与主应用逻辑解耦。尽管这是一种事件驱动模式,但通常通过直接调用专用记忆服务的非阻塞API实现,而非依赖自管理的消息队列。具体流程如下: 1. 智能体推送数据:当相关事件触发(如会话结束)后,智能体应用向记忆管理器发起非阻塞API调用,将原始源数据(如对话记录)“推送”至记忆服务进行处理; 2. 记忆管理器后台处理:记忆管理器服务立即确认请求,并将生成任务放入其内部托管队列。随后由该服务独立负责异步执行耗时操作——包括调用大语言模型完成记忆的提取、整合与格式化。管理器可能会等待一段无活动期后再处理事件(以避免高频重复处理); 3. 记忆持久化存储:服务将最终生成的记忆(可能是新条目或对现有记忆的更新)写入专用的高可用数据库。对于托管型记忆管理器(如 Agent Engine Memory Bank),存储功能已内置; 4. 智能体检索记忆:当需要为新的用户交互获取上下文时,主智能体应用可直接查询该记忆存储。 这种基于服务的非阻塞架构确保:记忆流水线中的故障或延迟不会直接影响面向用户的应用,大幅提升系统韧性。同时,该架构也为生成策略选择提供了灵活性: - 在线(实时)生成:适合保障对话时效性; - 离线(批量)处理:适合从历史数据中初始化系统。 # 4.9.2 关键生产环境需求 # 1. 可扩展性与并发控制 随着应用规模增长,记忆系统必须能够处理高频事件且不发生故障。面对并发请求,当多个事件试图修改同一记忆时,系统需防止死锁或竞态条件(race conditions): - 可通过事务型数据库操作或乐观锁(optimistic locking)缓解竞态条件; - 但这可能导致多个请求修改同一记忆时出现排队或限流(throttling); - 需部署稳健的消息队列缓冲高量事件,避免记忆生成服务被压垮。 # 2. 故障处理(Failure Handling) 记忆服务必须能抵御瞬时错误: - 若大语言模型调用失败,系统应采用带指数退避(exponential backoff)的重试机制; - 将持续失败的任务路由至死信队列(dead-letter queue),以便后续分析排查。 # 3. 全球可用性(Global Availability) 对于全球部署的应用,记忆管理器必须使用支持多区域复制(multi-region replication)的数据库,以确保低延迟与高可用性。客户端侧复制不可行——因为记忆整合需要单一的事务一致性数据视图,以避免冲突。因此,记忆系统需在内部处理复制逻辑,向开发者呈现统一的逻辑数据存储,同时确保底层知识库的全球一致性。 # 4.托管型记忆系统的优势 托管型记忆系统(如 Agent Engine Memory Bank)可帮助开发者解决上述生产环境考量,使其能够专注于智能体核心逻辑的开发,无需投入大量资源处理架构层面的稳健性问题。 # 4.10隐私与安全风险 (Privacy and security risks) 记忆源自用户数据且包含用户信息,因此需要严格的隐私与安全管控。一个形象的类比是:将系统记忆视为由专业档案管理员管理的企业机密档案库——档案管理员的核心职责是在保护企业安全的前提下,妥善保存有价值的知识。 该档案库的首要原则是数据隔离(data isolation):正如档案管理员绝不会将不同部门的机密文件混放,记忆必须在用户或租户(tenant)级别实现严格隔离。服务于某一用户的智能体绝不能访问其他用户的记忆,这一规则需通过严格的访问控制列表(Access Control Lists, ACLs)强制执行。此外,用户必须拥有对自身数据的程序化控制权,包括明确的记忆生成退出选项(opt-out),或要求从档案库中删除所有个人数据的权利。 档案管理员在归档任何文件前,会执行两项关键安全步骤: 1. 逐页仔细审查,脱敏敏感个人信息(Personally Identifiable Information,)——确保在保存知识的同时,避免产生法律风险; 2. 识别并丢弃伪造或故意误导性文件——这是防范记忆污染(memory poisoning)的重要保障。 同理,系统在将信息写入长期记忆前,必须进行验证与净化处理,以防止恶意用户通过提示词注入(prompt injection)破坏智能体的持久化知识。系统需集成 Model Armor 等安全防护机制,在信息写入长期记忆前完成验证与净化(29)。 此外,当多个用户共享同一组记忆时(如程序性记忆——用于指导智能体“如何做”的记忆),存在信息泄露风险。例如,若将某一用户的程序性记忆作为示例共享给其他用户(类似企业内部全员共享备忘录),档案管理员必须先执行严格的匿名化处理,防止敏感信息跨用户边界泄露。 # 5 结论 本文档深入探讨了上下文工程(Context Engineering)这一专业领域,重点聚焦其两大核心组件:会话(Sessions)与记忆(Memory)。从简单的单轮对话到具备持久化、可操作性的智能,这一转化过程正是由上下文工程驱动——通过将所有必要信息(包括对话历史、记忆、外部知识)动态整合到大语言模型的上下文窗口中实现。整个流程依赖两个独立但相互关联的系统:即时性的“会话”与长期性的“记忆”。 会话 (Session) : 管控“当下”。会话是单轮对话的低延迟时序容器,核心挑战集中在性能与安全性: - 性能层面:需确保低延迟访问,同时通过基于 Token 的截断(token-based truncation)、递归摘要(recursive summarization)等提取技术,压缩会话历史或单个请求的有效载荷,避免上下文窗口溢出与延迟升高; - 安全层面:会话数据持久化前必须对敏感个人信息(PII)进行脱敏处理,这是不可妥协的底线。 记忆(Memory):驱动长期个性化。记忆是实现跨会话持久化的核心机制,也是长期个性化的引擎。它超越了RAG(检索增强生成)的能力边界——RAG让智能体成为“事实专家”,而记忆让智能体成为“用户专家”。记忆是一个由大语言模型驱动的主动ETL流水线,负责完成以下核心工作: 1. 提取 (Extraction) : 从对话历史中提炼最关键的信息, 形成核心记忆点; 2. 整合(Consolidation):将新信息与现有知识库筛选整合,解决冲突、删除冗余,确保知识体系的一致性; 3. 检索 (Retrieval):在需要时精准匹配相关记忆,为智能体推理提供支撑。 为保障流畅的用户体验,记忆生成必须在智能体向用户返回响应后,以异步后台进程的形式运行。通过追踪记忆溯源信息(provenance)并部署记忆污染等风险的防护机制,开发者能够构建出可信、自适应的智能助手——这类助手能够真正实现与用户共同学习、共同成长。 # 6 参考文献 1. https://cloud.google.com/use-cases/retrieval-augmented-generation?hl=en 2. https://arxiv.org/abs/2301.00234 3. https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/sessions/overview 4. https://langchain-ai.github.io/langgraph/concepts/multi_agent/#message-passing-between-agents 5. https://google.github.io/adk-docs/agents/multi-agents/ 6. https://google.github.io/adk-docs/agents/multi-agents/#c-explicit-invocation-agenttool 7. https://agent2agent.info/docs/concepts/test 8. https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/ 9. https://cloud.google.com/security-command-center/docs/model-armor-overview 10. https://ai.google.dev/gemini-api/docs/long-context#long-context-limitations 11. https://huggingface.co/blog/Kseniase/memory 12. https://langchain-ai.github.io/langgraph/concepts/memory/#semantic-memory 13. https://langchain-ai.github.io/langgraph/concepts/memory/#semantic-memory 14. https://arxiv.org/pdf/2412.15266 15. https://arxiv.org/pdf/2412.15266 16. https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#sample-requests-text-gen-multimodal-prompt 17. https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/memory-bank/generate-