Cloudflare推出Agent Memory,实现AI代理持久记忆
Cloudflare AI··作者 Rob Sutter
关键信息
Agent Memory采用有明确设计意图的API和基于检索的架构——避免直接访问数据库,以确保成本效益、性能,并支持时间逻辑等复杂推理。资料档案是跨会话和用户访问的隔离内存存储。
资讯摘要
随着AI代理变得越来越复杂,高效管理上下文变得更加困难。Cloudflare的Agent Memory通过将代理对话中的重要信息存储在结构化资料档案中来解决这个问题,从而在需要时提供信息而不填满上下文窗口。该系统支持摄入(批量存储)、记住(即时存储)、回忆(检索+合成)和遗忘操作。
与其他给予模型原始数据访问权限的解决方案不同,Agent Memory在后台处理提取和检索,减少令牌使用并提高可靠性。它特别适合在真实代码库和系统上运行数周甚至数月的代理,因为这些代理需要长时间保持记忆的有效性。

资讯正文
作为开发人员在Cloudflare上构建越来越复杂的代理时,他们面临的一个最大挑战是如何在正确的时间将正确的信息放入上下文中。模型生成结果的质量直接取决于其操作的上下文质量,但即便上下文窗口大小已超过一百万(1M)个标记,上下文衰减问题仍未解决。一种自然的矛盾由此产生:要么把所有内容都保留在上下文中,导致质量下降;要么激进地裁剪,又可能丢失代理稍后需要的信息。
今天,我们宣布推出Agent Memory的私有测试版,这是一项托管服务,能够从代理对话中提取信息,并在需要时提供访问,而不会填满上下文窗口。
它为AI代理提供了持久记忆能力,使其能够记住重要的内容、遗忘无用的信息,并随着时间推移变得越来越智能。在本文中,我们将解释它的运作原理——以及它能帮助你构建什么。
代理记忆的现状
代理记忆是人工智能基础设施领域发展最快的领域之一,几乎每周都有新的开源库、托管服务和研究原型发布。这些产品在存储内容、检索方式以及适配的代理类型方面差异很大。像LongMemEval、LoCoMo和BEAM这样的基准测试提供了有用的横向对比,但也容易让人构建出仅针对特定评估表现良好但在生产环境中崩溃的系统。
现有方案在架构上也各不相同。一些是托管服务,在后台处理信息提取与检索;另一些则是自托管框架,你需要自行运行记忆处理流水线。有些提供受限的专用API,将记忆逻辑排除在代理主上下文之外;而另一些则让模型直接访问数据库或文件系统,由模型自行设计查询策略,从而在存储和检索策略上消耗大量标记,而非专注于实际任务。有些尝试将全部内容塞入上下文窗口,必要时通过多个代理分片存储;而另一些则利用检索机制只呈现相关内容。
Agent Memory是一项带有明确API和基于检索架构的托管服务。我们仔细权衡了各种替代方案,认为这种组合对大多数生产工作负载来说都是最佳默认选择。更紧密的摄入和检索流程优于赋予代理对文件系统的原始访问权限。除了成本和性能的提升外,它们还为生产环境中所需的复杂推理任务提供了更好的基础,例如时间逻辑、覆盖关系和指令遵循能力。未来我们可能会开放数据供程序化查询使用,但我们预计这主要用于边缘场景,而非常见情况。
我们开发Agent Memory,是因为我们在平台上观察到的工作负载暴露了现有方法未能充分解决的空白。那些在真实代码库和生产系统上运行数周甚至数月的代理,需要一种随着规模增长依然保持实用性的记忆能力——而不仅仅是能在干净基准数据集上表现良好的记忆,后者可能完全适合新模型的上下文窗口。
它们需要快速摄入信息,需要在不阻塞对话的情况下进行检索,并且需要在模型上运行,以保持每次查询的成本合理。
如何使用它
Agent Memory 将记忆存储在名为“配置文件”的结构中,该配置文件通过名称访问。一个配置文件提供多种操作:摄入对话、记住特定内容、回忆所需信息、列出记忆或遗忘特定记忆。摄入是批量处理路径,通常在上下文压缩时调用。记住用于模型即时存储重要信息。回忆会运行完整的检索流程并返回合成的答案。
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// 获取一个配置文件——一个跨会话、代理和用户共享的隔离记忆存储
const profile = await env.MEMORY.getProfile("my-project");
// 摄入——从对话中提取记忆(通常在压缩时调用)
await profile.ingest([
{ role: "user", content: "用 React 和 TypeScript 设置项目。" },
{ role: "assistant", content: "已完成。搭建了一个面向 Workers 的 React + TS 项目。" },
{ role: "user", content: "使用 pnpm 而不是 npm。默认开启深色模式。" },
{ role: "assistant", content: "明白——默认使用 pnpm 和深色模式。" },
], { sessionId: "session-001" });
// 记住——显式存储单条记忆(由模型直接调用工具)
const memory = await profile.remember({
content: "在 4 月 10 日事件后,每个区域的 API 请求速率限制提升至每秒 10,000 次请求。",
sessionId: "session-001",
});
// 回忆——检索记忆并获得合成回答
const results = await profile.recall("用户偏好的包管理器是什么?");
console.log(results.result); // "用户更喜欢 pnpm 而不是 npm。"
return Response.json({ ok: true });
},
};
Agent Memory 可通过任何 Cloudflare Worker 中的绑定访问,也可通过 REST API 供不在 Workers 中运行的代理使用,其调用方式与其他 Cloudflare 开发者平台 API 一致。如果你使用 Cloudflare Agents SDK 构建应用,Agent Memory 服务可作为 Session API 中记忆部分的参考实现,无缝集成压缩、记忆和搜索功能。
你可以用它构建什么
Agent Memory 设计用于适配多种代理架构:
个体代理的记忆。无论你是使用 Claude Code 或 OpenCode 等编码代理,还是采用人类参与的协作模式;无论你使用自托管代理框架如 OpenClaw 或 Hermes 来代表你执行任务,或者接入 Anthropic 的托管代理等托管服务,Agent Memory 都可以作为持久化记忆层,无需修改代理核心逻辑。
定制代理框架的记忆。许多团队正在构建自己的代理基础设施,包括无需人工干预即可自主运行的后台代理。Ramp Inspect 是一个公开示例;Stripe 和 Spotify 也描述了类似的系统。这些框架同样可以从赋予代理跨会话持久化记忆的能力中受益,即使重启也能保留记忆。
代理记忆:让智能体记住一切
代理、人和工具之间的共享记忆。记忆档案并不一定只属于单个智能体。一个工程师团队可以共享一个记忆档案,这样一个人的编码智能体所学到的知识就能被所有人使用:编码规范、架构决策、目前存在于人们头脑中的部落知识,或者在上下文被修剪时丢失的信息。代码审查机器人和编码智能体可以共享记忆,使审查反馈能够影响未来的代码生成。智能体积累的知识不再转瞬即逝,而会变成团队持久的资产。
虽然搜索是记忆的一部分,但代理搜索和代理记忆解决的是不同的问题。AI搜索是我们用于在非结构化和结构化文件中查找结果的基本功能;代理记忆则用于上下文回忆。代理记忆中的数据不是以文件形式存在的;它源自会话。智能体可以同时使用两者,它们的设计目标就是协同工作。
你的记忆,归你所有
随着智能体能力越来越强,并深度嵌入企业流程中,它们积累的记忆变得真正有价值——不仅是作为运行状态,更是作为需要大量投入才能建立起来的机构知识。我们听到越来越多客户担忧:如果将这些资产绑定到单一供应商上,意味着什么?这种担忧是合理的。智能体学得越多,如果无法携带其记忆迁移,转换成本就越高。
代理记忆是一个托管服务,但你的数据始终属于你。每条记忆都可以导出,我们承诺确保你在Cloudflare上积累的智能体知识,在需求变化时也能随你离开。我们认为赢得长期信任的正确方式,是让离开变得容易,并持续打造足够好的产品,让你根本不想离开。
代理记忆如何运作
要理解上述API背后发生的事情,有助于拆解智能体如何管理上下文。一个智能体包含三个组成部分:
一个驱动模型重复调用、促进工具调用并管理状态的框架。
一个接收上下文并返回补全结果的模型。
包含当前上下文窗口及外部信息的状态:对话历史、文件、数据库、记忆。
智能体上下文生命周期中的关键时刻是压缩(compaction),此时框架决定缩短上下文以保持在模型限制之内或避免上下文退化。如今大多数智能体永久丢弃信息。代理记忆则在压缩时保留知识,而不是让它丢失。
代理记忆以两种方式融入这一生命周期:
在压缩时批量摄入。当框架压缩上下文时,它会将对话发送至代理记忆进行摄入。摄入过程从消息历史中提取事实、事件、指令和任务,与现有记忆去重后,存储为未来可检索的记忆。
模型直接使用工具。该模型能够获取工具,以直接与记忆进行交互,包括回忆(搜索特定信息)的能力。模型还可以记住(根据重要事项显式存储记忆)、遗忘(标记某条记忆不再重要或不再真实),以及列出(查看已存储的记忆)。这些操作轻量且无需模型设计查询或管理存储。主要代理永远不应因存储策略而消耗上下文。它所见的工具界面被刻意限制,确保记忆不会干扰实际任务。
数据摄入流程
当对话到达时,它会通过一个多阶段流程,提取、验证、分类并存储记忆。
第一步是确定性ID生成。每条消息都会获得一个内容地址ID——即会话ID、角色和内容的SHA-256哈希值,截断为128位。如果同一对话被重复摄入,每条消息都将解析为相同的ID,使重新摄入具有幂等性。
接下来,提取器并行运行两轮处理。一轮完整处理将消息大致按10,000字符分块,并保留两个消息的重叠部分,最多并发处理四个分块。每个分块都会生成带有角色标签、相对日期转换为绝对日期(如“昨天”变为“2026-04-14”)和行索引用于溯源的结构化转录文本。对于较长的对话(9条以上消息),还会同时运行一轮详细处理,使用重叠窗口专门提取诸如姓名、价格、版本号和实体属性等具体数值,这些在广义提取中容易被遗漏。这两组结果随后合并。
下一步是对每条提取的记忆与原始转录文本进行验证。验证器执行八项检查,涵盖实体身份、对象身份、地点上下文、时间准确性、组织背景、完整性、关系上下文,以及推断事实是否确实在对话中有依据。每一项都据此通过、修正或丢弃。
随后,系统将每条验证后的记忆归类为四种类型之一。
事实代表当前为真的原子性稳定知识,例如“项目使用GraphQL”或“用户偏好深色模式”。
事件记录特定时间发生的事情,比如部署或决策。
指令描述如何完成某事,如操作步骤、工作流程或运行手册。
任务追踪当前正在进行的工作,设计上具有短暂性。
事实和指令均带键值。每条都有标准化的主题键;当新记忆与现有记忆拥有相同键时,旧记忆会被覆盖而非删除,从而形成一条向前指针的版本链。任务完全不纳入向量索引,以保持其简洁,但仍可通过全文搜索发现。
最后,所有内容都会通过 INSERT OR IGNORE 语句写入存储,这样基于内容地址的重复项会被静默跳过。在向调用框架返回响应后,后台会异步运行向量化处理。嵌入文本会在记忆内容本身前加上分类过程中生成的3到5个搜索查询,从而弥合记忆写入方式(声明式:“用户偏好深色模式”)与搜索方式(疑问式:“用户想要什么主题?”)之间的差距。被覆盖的记忆向量会在新插入操作并行执行时一并删除。
检索流程
当代理搜索记忆时,查询会进入一个独立的检索流程。在开发过程中,我们发现没有单一的检索方法能适用于所有查询,因此我们会并行运行多种方法,并融合结果。
第一阶段同时进行查询分析和嵌入处理。查询分析器生成按优先级排序的主题关键词、带同义词的全文搜索词,以及HyDE(假设文档嵌入),这是一种以回答形式表述的声明性陈述。该阶段直接对原始查询进行嵌入,两种嵌入结果都会在后续步骤中使用。
第二阶段并行运行五个检索通道。使用Porter词干提取的全文搜索适用于那些知道确切术语但不熟悉上下文的查询,确保关键词精度;精确的事实键查找则返回查询能直接映射到已知主题键的结果;原始消息搜索通过全文搜索直接查询存储的对话消息,用于捕捉未分类对话片段中的细节,作为安全网,防止提取管道遗漏重要信息;直接向量搜索利用嵌入后的查询找到语义相似的记忆;而HyDE向量搜索则寻找与答案可能看起来相似的记忆,通常能发现直接嵌入无法捕捉的结果——尤其适用于抽象或需要多跳推理的查询,此时问题和答案使用的词汇往往不同。
第三阶段也是最后一个阶段,使用倒数排名融合(RRF)合并来自五个检索通道的结果,每个结果根据其在特定通道中的排名获得加权分数。事实键匹配得分最高,因为精确的主题匹配是最强信号。全文搜索、HyDE向量和直接向量各根据信号强度分配权重。最后,原始消息匹配也以低权重包含进来,作为安全网识别提取管道可能遗漏的候选结果。若存在并列情况,则按时间顺序决定优先级,较新的结果排在前面。
随后,该流程将最佳候选结果传递给合成模型,由其生成针对原始查询的自然语言回答。某些特定类型的查询会得到特殊处理。例如,时间计算通过正则表达式和算术运算确定性完成,而不是依赖大语言模型(LLM)。这些结果作为预计算的事实注入合成提示中。由于模型在日期计算等任务上不可靠,我们不会让它们来执行这类工作。
我们的Agent Memory初始原型非常轻量,包含一个基础的提取流程、向量存储和简单的检索机制。它足以证明概念,但还不足以投入实际使用。
因此,我们将其放入一个由代理驱动的循环中进行迭代。这个循环如下:运行基准测试,分析存在的差距,提出解决方案,由人类审核提案以选择那些能泛化而非过拟合的策略,让代理执行变更,然后重复这一过程。
这种方法效果不错,但也带来了一个特定挑战:即使将温度设置为零,大型语言模型(LLM)仍然具有随机性。这导致每次运行的结果不同,所以我们必须对多次运行取平均值(这对大型基准测试来说很耗时),同时结合趋势分析与原始分数来判断哪些改进真正有效。在此过程中,我们必须格外小心,避免在基准测试上过拟合,而这种过拟合并不会真正提升产品在一般情况下的表现。
随着时间推移,我们逐步达到了一个稳定的状态:每次迭代后基准分数都持续提升,并且形成了一个能够在真实世界中通用的架构。我们有意针对多个基准测试(包括LoCoMo、LongMemEval和BEAM)进行测试,以从不同角度推动系统优化。
为什么选择Cloudflare?
我们在Cloudflare上构建Cloudflare,Agent Memory也不例外。现有的强大且易于组合的基础组件让我们能在周末交付第一个原型,并在不到一个月内推出一个功能完整的内部生产版本。除了交付速度之外,Cloudflare还因为其他几个原因成为构建此类服务的理想场所。
底层实现上,Agent Memory是一个Cloudflare Worker,协调多个系统:
- Durable Object:存储原始消息和分类后的记忆
- Vectorize:提供嵌入记忆的向量搜索能力
- Workers AI:运行大型语言模型和嵌入模型
每个记忆上下文对应一个独立的Durable Object实例和Vectorize索引,确保不同上下文间数据完全隔离,同时也便于应对更高需求的扩展。
通过Durable Object实现计算隔离。每个记忆配置文件都拥有自己的Durable Object(DO),其后端是SQLite存储,从而在不增加任何基础设施开销的前提下实现租户间的强隔离。DO负责全文搜索索引、版本链和事务写入。DO的getByName()地址机制意味着,无论请求来自何处,都可以通过名称访问到正确的记忆配置文件,确保敏感记忆与其他租户严格隔离。
整个栈中的存储设计:记忆内容存储在基于SQLite的Durable Object中,向量存储在Vectorize中。未来,快照和导出将存入R2,以实现成本高效的长期存储。每个基础组件都是为其工作负载专门设计的,我们无需强行把所有东西塞进单一形态或数据库中。
本地模型推理通过 Workers AI 实现。整个提取、分类和合成流程都在 Cloudflare 网络上部署的 Workers AI 模型中运行。所有 AI 调用都携带一个会话亲和性头部信息,路由到特定的记忆配置文件名称,这样重复请求会命中相同的后端服务,从而获得提示缓存的优势。
我们在模型选择过程中发现了一个有趣的现象:更大的、更强大的模型并不总是更好。目前我们默认使用 Llama 4 Scout(170亿参数,16专家稀疏模型)进行提取、验证、分类和查询分析,而合成阶段则使用 Nemotron 3(1200亿参数稀疏模型,活跃参数120亿)。Scout 在结构化分类任务中效率很高,而 Nemotron 更大的推理能力提升了自然语言回答的质量。只有在合成阶段,增加参数数量能持续带来性能提升。其他所有环节,较小的模型在成本、质量和延迟之间达到了更优的平衡。
我们如何使用它
我们在 Cloudflare 内部将 Agent Memory 应用于自身的 workflows,既作为测试平台,也作为下一步开发灵感的来源。
编码代理记忆。我们使用一个内部 OpenCode 插件,将 Agent Memory 整合进开发流程。Agent Memory 提供了单次会话内及跨会话的记忆功能。更不明显的益处在于团队共享记忆:通过共享配置文件,代理知道团队其他成员已经学到了什么,从而避免重复提问已解答的问题,也避免犯过错误。
智能代码审查。我们将 Agent Memory 连接到内部的智能代码审查工具。可以说它学到的最有用的能力就是保持沉默。现在审查工具记得某条评论在过去审查中并不相关,某个模式曾被标记,但作者保留该模式是有合理原因的。随着时间推移,审查结果不仅变得更智能,噪音也减少了。
聊天机器人。我们也把记忆功能整合进一个内部聊天机器人,该机器人会摄入消息历史记录,然后默默记住新发送的消息。当有人提出问题时,机器人可以根据之前的对话给出回答。
此外,我们还有多个额外应用场景计划在未来几个月内在公司内部逐步推出,随着服务的不断优化和改进。
接下来做什么
我们仍在内部持续测试和优化 Agent Memory,改进提取流程,调整检索质量,并扩展后台处理能力。类似于人类大脑在睡眠期间通过重放和强化连接来巩固记忆,我们也看到了异步提升记忆存储潜力的机会,目前正在实施和测试多种策略以实现这一点。
我们计划很快将 Agent Memory 对外公开。如果你正在 Cloudflare 上构建代理并希望提前体验,请联系我们加入等待名单。
如果你想要深入了解架构细节,分享你正在构建的内容,或者跟随我们进一步开发的进度,请加入 Cloudflare Discord 或在 Cloudflare 社区中发帖。我们正在积极关注这两个平台,并且非常关心实际生产环境中代理工作负载的具体表现。
来源与参考
收录于 2026-04-18