亚马逊AWS官方博客
让 Agent拥有「跨终端长期记忆」——基于 Amazon Bedrock AgentCore Memory 的实践
摘要:无状态是 LLM 的天性,但「记不住」不该成为 Agent 的宿命。本文通过 HOOK+MCP Server 的方式,来使用 Amazon Bedrock AgentCore Memory,实现跨项目、跨终端、跨人员的团队记忆共享。记忆于是变成了一个独立的、可治理的服务层,不再跟着人、设备或某一个客户端走。本文也进一步分享了使用Amazon Bedrock AgentCore Memory的一些实操经验与技巧。
一、背景与设计理念
1.1 无状态带来的现实困扰
大语言模型天生是无状态的。模型每次只处理当前这段上下文,回复一生成完就结束,会话一关,上下文就被整段丢掉,下次再进来又是一张白纸。 而在日常开发中,尽管有很多实践,已通过提示词的渐进式披露、项目规范的团队共享以及 Agent 工具的本地记忆,一定程度上实现了大模型的状态存储与记忆管理,但是现有记忆是按机器、按项目、靠文件名的,而我们真正想要的,是一套能跨终端、跨项目、还能按语义去找的记忆,从而实现个人多终端/跨多项目的经验教训的自动积累,进而延伸到团队内的经验教训的自动积累与分享。
本文就以 Claude Code 为例,介绍一套基于 Amazon Bedrock AgentCore Memory 实现的多终端共享团队长期记忆的方案。
1.2 不替代,而是多加一层
我们的做法不是改造内置 auto-memory,而是在它上面叠一层云端语义记忆:
| 层级 | 系统 | 职责 | 存储 | 检索 | |
| 1 | 第一层 | Claude Code 内置 auto-memory | 项目级上下文、即时反馈 | 本地 Markdown | LLM 推断文件名 |
| 2 | 第二层 | AgentCore Memory MCP(本方案) | 跨设备知识、长期偏好、情景套路 | AWS 云端向量库 | 语义搜索 |
两层各管各的,互不打扰:本方案不去碰 ~/.claude/projects/*/memory/,内置记忆也感知不到 MCP Server 的存在。Claude 同时看着这两个信息源,自己判断什么时候该用哪个。本地这层图的是快,云端那层图的是记得久、跨得开。
而撑起云端这层的,正是 Amazon Bedrock AgentCore Memory。这是 AWS 在 2025 年推出的全托管 Agent 记忆服务。过去开发者得自己拼的那套基础设施,对话存储、向量库、检索逻辑,它都打包成了一个开箱即用的服务,并提供两类记忆。
一类是短期记忆,把原始对话以不可变事件(event)的形式,按 actorId 加 sessionId 存下来。哪怕服务重启了、用户隔天才回来,上下文都能原样恢复。另一类是长期记忆,它从原始事件里异步提取出结构化知识,包括事实、偏好和情景套路,跨会话长期保留下来,这样 Agent 不必把全部历史重放一遍,也能「记住」那些要紧的东西。 本文中的方案主要聚焦在长期记忆的使用。
二、整体架构
整个系统由三部分搭起来:一个 MCP Server,对外提供 5 个记忆工具;两个在后台静默运行的 Hook:UserPromptSubmit 在用户每次提交时实时抓下这条 user 输入,Stop 则在每轮回复结束时把本轮的 user 输入和 assistant 回复打包成一个多轮 event 写入;后端则是 Amazon Bedrock AgentCore Memory,托管了提取和存储。
[图1] |
数据是这样流动的:用户的输入和助手的回复,先由两个 Hook 静默写进 Amazon Bedrock AgentCore Memory,随后自动从中抽出事实、偏好和情景反思,等到后面再聊起相关话题,Claude 就能按语义把它们召回。多个终端之间,只要配上同一个 ActorID,用的就是同一套记忆。
2.1 记忆管道:从原始对话到结构化知识
短期记忆很直白,CreateEvent 同步写进去就可以了。真正有意思的是长期记忆背后那条异步管道,它能在不打断实时对话的前提下,把原始对话慢慢「消化」成可检索的结构化知识。我们先看图,再一步步拆开讲。
[图2] |
整条链路走的是「写入、异步触发、三阶段加工、落库、语义召回」这么一条路。中间那三个加工阶段,是整套机制的核心。
第一阶段是提取(Extraction)。事件一旦写进短期记忆,后台的 LLM 就会按配置好的策略去读这段对话,把该策略关心的信息抽出来,写成预定义 schema 的记忆记录。多个策略是并行跑的,互不阻塞,所以同一条事件可以被同时抽出好几条记忆。
第二阶段是整合(Consolidation),也是这套机制最见功力的地方。新记忆并不是简单地 append 进去:系统会先把相关的已有记忆检索出来,连同新记忆一起交给 LLM,由它来判定该做哪个动作——是 ADD(全新信息,新增一条)、UPDATE(补充或修正已有的),还是 NO-OP(信息重复,直接跳过)。它甚至能识别语义上的等价,「喜欢 pizza」和「爱吃 pizza」会被当成同一条,不会重复写。
第三阶段是反思(Reflection)。Episodic 策略会在前两步之上再加一层,跨多次交互归纳出更高阶的洞察和可复用的方法论。这部分下一节会用一个实测 Demo 展开讲。
2.2 本方案使用的三套策略
AgentCore Memory 靠记忆策略来控制「从对话里抽什么、又存到哪」。本方案配了三套:
| 策略类型 | 提取什么 | 命名空间 | |
| 1 | semanticMemoryStrategy | 陈述性事实与知识 | /facts/{actorId}/ |
| 2 | userPreferenceMemoryStrategy | 用户偏好与风格 | /preferences/{actorId}/ |
| 3 | episodicMemoryStrategy | 情景化的交互经验与可复用套路 | /reflect/{actorId}/ |
三个命名空间都是 actor 级别的,不带 {sessionId},也就是说,所有会话的记忆都汇进同一个 namespace。整合的时候,新记忆能看到之前任何一个 session 留下的旧记忆,于是就能跨 session 做 UPDATE:同一个事实可以被反复修正,比如从「风险待处理」改成「风险已解除」,旧的那条自动标记成 INVALID,不会残留下来碍事。
这里的 {actorId} 正是跨设备、跨团队共享的关键,后面讲解决方案时会专门展开。
这三套策略里,前两套 Semantic 和 Preference 比较好懂,第三套 Episodic 就特别一些,也最容易跟 Semantic 搞混。下一节我们专门拿一个实测 Demo 把它讲透。
2.3 Semantic vs Episodic:一个容易混淆的区别
刚接触时,很自然会冒出一个疑问:Semantic 不是已经能记事实了吗,Episodic 到底还多记了些什么?
一句话概括,Semantic 记的是「什么是真的」,Episodic 记的是「下次该怎么做」。前者抽取的是与时间无关的陈述性事实,每条都独立成立;后者则把一段「踩坑、诊断、解决」的交互过程,沉淀成带因果关系的经验,再跨多次交互提炼出可复用的处置套路。
| 维度 | Semantic(语义/事实) | Episodic(情景/套路) | |
| 1 | 抽取的内容 | 陈述性事实:「X 是 Y」 | 程序性经验:「遇到 X,先做 Y、别做 Z」 |
| 2 | 能否包含「不要做什么」 | 不能(事实没有褒贬) | 能——失败的尝试会作为教训留下 |
| 3 | 失败的试错分支 | 丢弃,只留最终结论 | 保留,正是经验的一部分 |
| 4 | 跨场景泛化 | 不会(关于 A 的事实就只关于 A) | 会——把套路抽象后迁移到没见过的场景 |
| 5 | 面对新问题 | 给你相关旧事实,要你自己判断 | 直接给出可执行的处置建议 |
这里有个简单的判断诀窍:凡是能压缩成一条事实的,Semantic 就够用了。Episodic 真正独有的价值,恰恰是 Semantic 表达不出来的那两样东西——失败的教训,以及能跨场景泛化的行为套路。下面这个实测 Demo,会把这条边界清清楚楚地显出来。
2.4 实测 Demo:Episodic 如何「学会套路再举一反三」
为了不停在概念上空谈,我拿一个独立的 actorId 跑了一组真实测试,模拟的是这么一个过程:同一类故障在多次会话里反复出现,看 Agent 能不能从中学到套路。 接下来,我们以一个 EMR 的 Demo 来演示整个过程。
[图3] |
第一步:喂三段会话(试错 → 复用 → 再验证)
我通过 create_event 写入了三段独立的会话。第一段是试错:一个 EMR Serverless 作业卡住了,driver 日志报 pip install 拉第三方包超时。助手起初猜是「资源不够」,建议把 executor 内存从 16GB 加到 32GB,结果失败了,症状一点没变;后来改判为网络隔离的问题——EMR Serverless 默认跑在隔离子网里,根本访问不了公网 PyPI——于是配上 VPC 加 NAT 网关、放开公网,这才成功。第二段是复用:另一个作业冒出同类症状,助手「按上次的经验」直接开了公网访问,一次就成。第三段是再验证:又来一个作业 pip 超时,照着解法套上去,再次成功。
第二步:等管道反思
写入之后,事实和偏好很快就抽好了。而 Episodic 的 /reflect/ 命名空间下的episodes和reflections,则需要等待更长时间才会生成。反思是最重的阶段,急不得。
最终产出的记录分两种结构:
一种是结构化的 episode,它把每次交互拆成 situation / intent / assessment / justification / reflection 几个字段(字段名以实际返回为准)。它如实地记下了那条失败的分支,还在 reflection 里点明了原委:
“最初把 pip install 超时归因为内存不足,是个推理错误——超时是网络 I/O 失败,不是内存问题,看到这类症状就该先怀疑网络出口。”
另一种是跨 episode 的 reflection,它在多个 episode 之上提炼出 title / use_cases / hints / confidence 这样的处置洞察(AgentCore 官方就管它叫 reflection)。其中一条的 confidence 高达 0.9:
“ Diagnosing Package Install Timeouts in Serverless/Managed Environments 先排查网络出口,再考虑资源;pip/包安装超时是网络 I/O 失败,不是内存或 CPU 问题……不要把「加大内存」当成首选动作。”
最关键的一点是,它的 use_cases 写的是「Serverless / Managed 环境」,并没有写死成 EMR——套路就这么被抽象出来了。
第三步:用一个全新的、跨服务的问题验证
我故意问了一个 episode 里从没出现过的服务、还带着错误前提的问题:
“ 我的 Lambda 函数调用外部 API 总是超时,我打算给它加内存,这样能解决吗?”
对两个命名空间分别做语义搜索,结果的分化非常明显。Semantic(/facts/)返回的全是 EMR 相关的旧事实,比如 “用户把 executor 内存从 16GB 加到 32GB,但没解决超时”。这些事实本身都没错,可它只是陈述发生过什么,至于 Lambda 这边该怎么办,它给不出答案。Episodic(/reflect/)则直接命中了那条 reflection: ”先查网络出口,别急着加内存”——套路从 EMR 自然而然迁移到了它从没见过的 Lambda 上,还顺带把我「加内存」的错误打算给纠正了。
这正是 Episodic 不可替代的地方:它学到的不是「EMR 要开公网」这一条死事实,而是「这类症状该怎么诊断」这套能迁移的经验。
什么场景适合用 Episodic?反复出现的排障和处置流程、需要慢慢攒出「最佳实践」的操作,还有团队希望把「踩过的坑」而不只是结论沉淀下来的那类知识。什么场景不适合?单纯记一条事实或一个配置值——那本来就是 Semantic 的活。
三、解决方案
三个组件正好对应「喂、消化、取」三个环节:Hook 负责采集,AgentCore Memory 负责提取和存储(上面已经展开过),MCP Server 则负责让 Claude 真正能调用到记忆。
3.1 记忆是怎么「喂」进去的:两种写入方式
在看具体组件之前,有件容易被忽略的事得先说清楚:记忆其实有两条写入路径,它们的触发方式和适用场景完全不同,但最终都汇进同一条托管管道。
| A | 方式 A:后台 Hook | 方式 B:memory_store 工具 | |
| 1 | 谁触发 | 系统自动(回车 / 回复结束) | 模型主动调用,或用户明确要求 |
| 2 | 写什么 | 用户输入 + 助手回复的原始全文 | 模型提炼后的一句话结论 |
| 3 | 判断重要性吗 | 不判断,先全收 | 判断——只存值得长期记的 |
| 4 | 比喻 | 录音机 | 编辑划重点 |
| 5 | 解决的问题 | 不漏 | 准 |
假设你在Claude Code里 讨论一个数据管道该怎么选型。
先说方式 A,你随手敲下一句话就回车了:
我们这个项目统一用 Python 3.12,部署在 us-west-2。
你什么额外的事都没做。UserPromptSubmit Hook 在你回车那一瞬间静默触发,把这句话写进短期记忆,几十秒后管道就自动从里面抽出了两条 fact。你压根没发出过任何「记一下」的指令,记忆却已经被收下了,这条路径管的就是「不漏」。
再看方式 B,主动精选。讨论继续往下走,模型给出了一个关键结论:
综合性能和成本,建议放弃 Glue,改用 EMR Serverless 7.12,并允许访问公网。
模型判断这是个值得长期沉淀的决策,于是主动调用了工具:
这次存进去的不是原始对话,而是模型精炼过的那句结论,这条路径管的是「准」。
两条路径最后都会通过 create_event 进入同一条管道,也都经过整合去重。等过几天,同事在另一台设备上配上相同的 actorId,问一句「这个项目的数据管道用的是什么、有哪些约束」,一次 memory_search 就能把这两条路径写进去的记忆一并召回。下面我们分别看看这两条路径背后各是什么组件。
3.2 后台 Hook采集信息
怎么才能把对话喂进记忆系统,又不打断使用体验、也不挤占对话的上下文?
答案是一个极简的 Hook。用户每次按回车提交,它就静默地调一次 create_event,把消息写进短期记忆,全程没有任何 stdout 输出,对 Claude 的上下文窗口零侵入。
不过,光抓用户输入会留下一个缺口。Episodic 的情景反思,需要一条完整的「我做了什么、结果如何」的弧线,而这条弧线的后半段,也就是助手的回复和给出的结论,单靠采集 user prompt 是拿不到的。只喂用户的问题、不喂模型的回答,反思就归纳不出可复用的处置经验。
所以我们又补了第二个 Hook,也就是 Stop。它在每轮回复结束时触发,把助手的回复文本(role=ASSISTANT)也写进同一个 session:
虽然两个Hook 创建的 Event 内容略有重叠,但这么做是值得的。UserPromptSubmit Hook作为兜底,实时存储 User 输入,这也是被认为最能代表事实、可靠性最高的数据。而Stop Hook是作为锦上添花,将一轮对话中的User 输入 + Assistant 回复,存入 Memory,最终期望转化为场景记忆(Episodes)和反思(Reflections)。
3.3 配置 Memory 资源
记忆的提取、向量化和存储,全都交给 AWS 托管管道。要创建一个配齐三套策略的资源,一次 API 调用就够了:
3.4 MCP Server —— 让 Claude 用上记忆
Claude Code 是通过 MCP 协议来调用外部工具的,如下代码中列出了 5 个 Tool:
| 工具 | 干什么 | |
| 1 | memory_search | 按语义搜索记忆(任务开始时、提到历史时调用) |
| 2 | memory_store | 统一写入入口:单条 USER 记一条事实/偏好,多轮 USER→ASSISTANT 喂 Episodic 反思(走管道,自动整合去重) |
| 3 | memory_list | 按时间段浏览(支持 this_week、7d 等) |
| 4 | memory_delete | 删除指定记忆 |
| 5 | memory_stats | 系统状态 |
memory_search 不指定类型时,会跨 facts / preferences / reflect 三个命名空间分别检索,合并后按相关度排序返回 Top-K。
MCP Server 相关代码如下:
最后,一条命令完成配置(包括Hook 的设置):
setup.py
重启 Claude Code,/mcp 能看到 agentcore-memory 和它的 5 个工具。
3.5 多终端共享,靠 actorId
回到最开始那个问题:怎么让一台设备上记下的东西,在另一台上也能想起来?
答案其实很简单。AgentCore Memory 的命名空间里有个 {actorId} 占位符,多个客户端只要配上相同的 actor-id,就会落进同一套命名空间、自动共享记忆;要是不指定,默认就用「用户名-主机名」,各台设备各自隔离。两种模式之间,一个参数就能切换。
[图4] |
共享模式下,客户端 A 存进去的事实,几十秒后就能在客户端 B 上被 memory_search 召回。而且要注意,这里画的已经不止 Claude Code 了,任何 MCP 客户端都能挂上来,这点我们留到结尾再展开。隔离模式下,每台设备各写各的 /facts/用户名-主机名/ 命名空间,彼此不会串台。
3.6 团队级共享
actorId 的设计空间,远不止个人多终端这一种用法。要是一个团队约定好都用同一个 actor-id,比如拿客户名或项目名来命名,那么每个人的 Claude Code,其实都是在向同一个「团队大脑」读写。 当前,也可以考虑改写 MCP Server 的实现逻辑,即使不同人员使用不同actorId, 也可以根据namespace前缀实现团队内的记忆共享。
举个场景就清楚了。架构师 A 跟 Claude 讨论时,确定了「VPC 放在 us-west-2、EMR Serverless 要通公网」这条约束;第二天架构师 B 接手数据库选型,memory_search 直接就把这条约束召回了,根本不用再去问人;再往后 其他工程师接手时,团队记忆里早已沉淀好了一整条决策脉络。
这本质上就是把 Memory as a Service 的理念,落到了真实的协作场景里:记忆成了一个独立的、可共享的服务,不再绑死在某个人的某台机器上。
四、总结和综述
无状态是 LLM 的天性,但「记不住」不该成为 Agent 的宿命。本文通过 HOOK+MCP Server 的方式,来使用 Amazon Bedrock AgentCore Memory,实现跨项目、跨终端、跨人员的团队记忆共享。记忆于是变成了一个独立的、可治理的服务层,不再跟着人、设备或某一个客户端走。本文也进一步分享了使用Amazon Bedrock AgentCore Memory的一些实操经验与技巧。
尽管本文是以 Claude Code 为例进行实现与分享,但无论是 Kiro,还是其它客户端 Agent,都可以参考本方案打造一个开箱即用,默认包含了 Agent Memory 最佳实践的方案。
➡️ 下一步行动:
相关产品:
- Amazon EFS — 弹性文件存储
- Amazon S3 — 适用于 AI、分析和存档的几乎无限的安全对象存储
- Amazon Bedrock — 用于构建生成式人工智能应用程序和代理的端到端平台
- Amazon VPC — 隔离云网络
- Amazon Bedrock AgentCore — 加快代理投入生产的速度
相关文章:
- 当 OpenClaw 学会”团队记忆”:一个面向多客户服务的企业级共享记忆系统设计
- 当 AI Agent 学会”忘记”:Amazon Bedrock AgentCore Memory 的记忆哲学”
- 向量存储成本降低 85%:用 Amazon S3 Vectors 构建企业级多平台统一知识库
- AI Agent 的迁移与现代化 — 使用 Amazon Bedrock AgentCore 将 OpenClaw 从单机改造为多租户 Serverless 架构 第三篇
- Amazon Bedrock模型推理的Serverless 异步架构 – 处理在线多模态高负载案例
五、参考资料
当 AI Agent 学会”忘记”:Amazon Bedrock AgentCore Memory 的记忆哲学
*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。
本篇作者
AWS 架构师中心:云端创新的引领者探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用 |
![]() |





