← 目录
← → / 空格:先走图示步骤,再翻页
记

Tech Notes · Amazon Bedrock AgentCore

AgentCore Memory
生命周期管理

博客方案拆解 · 新 API 能力 · Spike 实测结论

Blog · 2026-09-04 Spike · 2026-10-08 · us-east-1
01

Memory 模型

短期 Event / 长期 Record,异步抽取。

01 / 两层存储03

短期记忆 vs 长期记忆

Short-term · Event

原始对话,逐轮存储

  • 组织键:actorId + sessionId(支持 branch)
  • 写入:CreateEvent
  • 读取:ListEvents / ListSessions
  • 过期:eventExpiryDuration 3–365 天,服务端自动

Long-term · Memory Record

从事件中异步抽取的知识

  • 组织键:namespace 层级路径
  • 写入:策略自动抽取 / BatchCreate / IngestData
  • 读取:RetrieveMemoryRecords(语义检索)/ List
  • 过期:没有内置 TTL ← 本次主题
01 / 抽取链路04

Event → Record → Retrieve

01 / 最小调用05

最小调用

内置策略:semantic · userPreference · summary · episodic;另有 custom(override prompt / model)与 self-managed。

ctl.create_memory(name="SupportMemory", eventExpiryDuration=30,
    memoryStrategies=[{"semanticMemoryStrategy": {"name": "facts",
        "namespaceTemplates": ["support/actor/{actorId}"]}}])
dp.create_event(memoryId=mid, actorId="alice", sessionId="s1", payload=[...])
# 异步抽取,实测 110–125s
dp.retrieve_memory_records(memoryId=mid, namespace="support/actor/alice",
    searchCriteria={"searchQuery": "部署区域偏好", "topK": 5})
02

博客方案

Designing lifecycle policies for AgentCore memory
AWS ML Blog · 2026-09-04 · Sehwag / Sah / Albanese

业务问题 → 对照 Coding Agent → 方案总览 → ① 分级 → ② 策略 → ③ 架构 → ④ 质量合规 → 回顾

02 / 业务问题
07

业务问题

Agent 记得越久,越容易答错

场景:客服、销售、IT Helpdesk 等高频 Agent,与同一批用户持续对话数周到数月,记忆不断累积。低频 Agent(个人助理类)只需 TTL + GDPR。

痛点 1 · 答错

引用过期事实

客服 Agent 把 4 个月前已解决的账单争议当成仍未解决;运维 Agent 按已被替换的 runbook 给部署建议。根因:新旧事实并存,语义检索按相似度召回、不分新旧。

痛点 2 · 合规

删不掉、证不了

用户行使 GDPR 被遗忘权时,需要按用户删除全部记忆,并留下可审计的记录。

业务目标

该记的记住,该忘的忘掉

保留仍有价值的知识,清理陈旧内容;回答质量不下降,删除可证明。

02 / 对照
08

对照 · 没有 AgentCore Memory 时,Coding Agent 怎么做记忆

Claude Code / Codex:本机文件 + 人在回路

Claude CodeCodex
指令层
人写
CLAUDE.md:managed → ~/.claude → 项目 → CLAUDE.local.md,逐级拼接;.claude/rules/ 按路径加载;也可读 AGENTS.md AGENTS.md:~/.codex → Git root → cwd,逐级拼接;AGENTS.override.md 覆盖;合计上限 32 KiB
自动记忆
模型写
auto memory:~/.claude/projects/<repo>/memory/,MEMORY.md 索引 + 每条一文件(user / feedback / project / reference);启动只加载索引前 200 行或 25KB,正文按需读 memories(默认关闭):~/.codex/memories/;后台从空闲会话抽取,再做全局 consolidation;跳过短会话,脱敏 secrets
隔离粒度 会话上下文按 session 隔离(每个 session 全新上下文窗口);持久记忆按 repo 跨 session 共享(含 worktree),仅本机 会话上下文独立;memories 按本机 CODEX_HOME 跨会话共享,/memories 可让单个会话不读 / 不写
生命周期 无 TTL;写入时记 modified 时间戳;索引接近上限时提示模型合并 / 删除陈旧条目;不受 transcript 清理影响 文档未提 TTL;/memories 按会话控制读写;设置中一键 Delete Codex memories

Coding Agent 的前提

单用户 · 本机文件 · 规模小 · 人可直接审阅和编辑 → 生命周期靠模型自觉 + 人工清理即可。会话隔离只管上下文,累积发生在跨会话的持久层

自建 Agent(AgentCore Memory 的场景)

多租户海量 actor · 服务端自动抽取 · 语义检索 · 无人逐条审阅 → 需要策略化的 TTL / 打分 / 合并 / GDPR。隔离由开发者设计:Event 按 actorId / sessionId,Record 按 namespaceTemplates

来源:code.claude.com/docs/en/memory · learn.chatgpt.com/docs/customization/memories · learn.chatgpt.com/docs/agent-configuration/agents-md(2026-10 查阅)

02 / 方案总览
09

方案总览 · 博客给自建 Agent 的记忆治理方案

博客方案:一条每晚运行的记忆治理流水线

每晚一次的 Step Functions 流水线:先按 TTL 硬删 → 再按衰减分排序 → 低分记录用 LLM 合并为 semantic;用回归评测守质量,用 GDPR 删除 + 审计守合规。

①

分级

episodic / semantic / procedural 不同保留期

②

三条策略

TTL 过期→衰减打分→LLM 合并

先删、再排、后压缩

③

架构

EventBridge + Step Functions + 5 Lambda,CDK 部署

④

质量合规

AgentCore Evaluations · GDPR 删除 · 审计

02 / ① 分级
10

① 记忆分级:不同类型,不同保留期

Episodic · 情节

30–60 天

Summary / Episodic 策略产出,与 session 绑定。量大、时效短 → 最先过期。

Semantic · 事实

6–12 个月

“偏好 us-east-1 部署”。紧凑、耐久 → 合并的目标形态。

Procedural · 流程

可不过期

Episodic 的 reflection,“问成本先查 Cost Explorer”。剪枝门槛最高,需随流程变更复核。

注:这是博客的推荐值;sample 代码只暴露单一 memoryTtlDays(默认 90)。

02 / ② 策略
11

② 三条策略:总览

示意数据;score 按博客默认参数计算(pruneDays=45, threshold=0.3)。下面三页分别展开 ②a / ②b / ②c。

02 / ②a TTL
12

②a TTL 过期:硬上限

# memory_pruner(按博客描述整理)
cutoff = (datetime.now(timezone.utc) - timedelta(days=ttl_days)).isoformat()
resp = client.list_memory_records(memoryId=memory_id, namespace=agent_id, metadataFilters=[
    {"left": {"metadataKey": "x-amz-agentcore-memory-createdAt"},
     "operator": "BEFORE", "right": {"metadataValue": {"dateTimeValue": cutoff}}}])
for r in resp["memoryRecordSummaries"]:
    client.delete_memory_record(memoryId=memory_id, memoryRecordId=r["memoryRecordId"])

为什么自建

AgentCore 只有 Event 级 eventExpiryDuration;长期记录无自动过期,但系统时间字段支持 BEFORE / AFTER。

为什么先跑

不为本该删除的记录花打分和 LLM 合并的算力;也是合规上的硬上限。

参数

memoryTtlDays 默认 90;不看有用与否,只看年龄。

02 / ②b 公式
13

②b 打分公式:三个信号加权

总分= 0.40×新鲜度+ 0.35×活跃度+ 0.25×热度

新鲜度 · W_RECENCY

衰减( 创建了几天 )

越新越接近 1

活跃度 · W_ACCESS

衰减( 距上次被读几天 )

最近被读过越接近 1;没被读过 → 按创建时间算

热度 · W_FREQUENCY

min( 被读次数 ÷ 50 , 1 )

读满 50 次 = 1,封顶

例:算一条记录

创建 60 天 · 3 天前被读过 · 累计被读 20 次 (pruneDays = 45 → r = 0.974)

新鲜度= 衰减(60) = 0.97460= 0.20
活跃度= 衰减(3) = 0.9743= 0.92
热度= min(20 ÷ 50, 1)= 0.40
总分= 0.40×0.20 + 0.35×0.92 + 0.25×0.40= 0.50

0.50 ≥ 0.3 → 保留 若 60 天里从没被读过:0.40×0.20 + 0.35×0.20 + 0 = 0.15 → 合并

衰减里的 r 是什么

每日保留率:价值每天打几折

r = 0.31/pruneDays

pruneDays 是业务配置:45 → r = 0.974,即每天打 97.4 折,45 天没人用正好跌到 0.3。7 天档 r = 0.842,180 天档 r = 0.993。

代码写作 exp(−λ·d),λ = −ln(0.3)/pruneDays,与 rd 等价;λ 不是 AWS Lambda

02 / ②b 曲线
14

②b 不同场景下的分数曲线

点按钮切换 pruneDays(每日保留率 r 随之变化),看三类记录的总分随创建天数怎么变化;跌破 0.3 的虚线即进入合并。

02 / ②b 调参
15

②b 参数怎么定、怎么调

调参前先知道 热度最多贡献 0.25,单靠“读得多”保不住一条记录;访问统计漏了 Retrieve 时,活跃度和热度基本为 0,打分退化为 ≈0.76 × pruneDays 的软 TTL → 先补访问统计,再调参数

参数管什么怎么定
pruneDays信息多久没人用算过时按业务周期:客服 7 / 销售 21 / 通用 45 / IT 运维 90 / 法务 180;用数据定:历史“创建 → 最后一次有效使用”间隔的 p90
threshold每晚多少记录进入合并先离线算得分分布,按可接受的合并量定(如每晚 ≤10–20%);合并有损,宁低勿高(博客写“从更高阈值起步以控制合并量”,方向相反:阈值越高,被合并的越多)
W_*三个信号各占多重时效性强调高新鲜度;runbook 反复用调高热度;三者之和 = 1
MAX_ACCESS_BASELINE读多少次算“常用”单条记录访问次数的 p90 / p95
# CDK context → Scorer Lambda 环境变量(PRUNE_DAYS / RELEVANCE_THRESHOLD / W_* / MAX_ACCESS_BASELINE),下次夜间运行生效
npx cdk deploy -c pruneDays=21 -c relevanceThreshold=0.25 -c wRecency=0.5 -c wAccess=0.3 -c wFrequency=0.2 -c maxAccessBaseline=30

1

补访问统计(Gateway 记录 Retrieve 命中)

→

2

离线跑分,看分布与合并比例

→

3

Evaluations 回归,对比前后质量

→

4

上线,持续看指标

02 / ②b 业务化
16

②b 打分器是可替换的:公式只是参考

层说明
编排复用TTL → 打分 → 合并 → 删除,与业务无关
打分接口复用输入一条记录 → 0–1 分 → 与 threshold 比较
打分算法参考只用时间 / 访问时间 / 访问次数,不知道记忆在业务上是否还成立
合并 prompt · 评测改写按业务改 prompt 和评测用例
验证复用固定业务问题集 → AgentCore Evaluations 前后对比 + 每晚合并 / 删除比例

自定义信号(可靠性从高到低)

1 业务事件

工单 closed、商机赢 / 输单、runbook 新版本 → 直接失效,不进打分

2 记录 metadata

写入时打 ticket_id / entity_status / mem_class / ts_epoch,用 metadataFilters 批量筛

3 真实使用

Retrieve 命中、命中后回答是否被采纳

4 时间衰减

兜底:博客公式

02 / ②c 合并
17

②c LLM 合并:删之前先压缩

# CONSOLIDATION_PROMPT_TEMPLATE(要点)
role    : memory consolidation assistant
keep    : essential facts / preferences / actionable
drop    : redundant / outdated
input   : {memory_contents}
output  : {
  "summary":    "...",
  "confidence": 0.0–1.0,
  "key_facts":  ["..."]
}

流程

低分记录每 10 条一批 → Bedrock(Claude Sonnet 4.5)→ 写回 1 条 semantic → 删除原记录

失败处理

Bedrock 失败:原记录不动;删除失败:记日志,人工处理

注意

合并有损;用 confidence 标记待人工复核;高风险领域原记录归档冷存储;生产必须加 Guardrails + grounding check

02 / ③ 架构
18

③ 落地架构:组件与数据流

IAM 按函数最小化:Scorer 仅 ListMemoryRecords;Consolidator 为 Get / BatchCreate / Delete + bedrock:InvokeModel。全部由一个 CDK stack 部署。

02 / ④ 质量
19

④ 质量验证:用回答质量间接衡量记忆治理

AgentCore Evaluations 的评估器评的是 Agent 的 trace(回答、模型调用、工具调用),不直接评 Memory 记录。思路是:用一组固定问题,在 lifecycle 前后各问一次 Agent,回答质量下降 = 治理可能伤到了记忆。

博客 sample 的写法 概念示意

invoke_agent_runtime(agentId, inputText)
evaluate(agentResponse, expectedCriteria)
→ qualityScore;post ≥ min 即 PASS

博客示例:0.82 → 0.85、0.74 → 0.71,均 PASS

参数与真实 API 不符(真实为 Evaluate(evaluatorId, evaluationInput, …)、InvokeAgentRuntime(agentRuntimeArn, payload, …)),照原样调用会参数校验失败

真实落地:Dataset evaluation(preview)

  • 开 Observability:Runtime 或 Strands / LangGraph + ADOT,trace 进 CloudWatch
  • 建 dataset:问题 + ground truth,以具体 actorId 提问,答案必须依赖该用户的记忆
  • 选评估器:博客的 expected_criteria → 自定义 LLM-as-judge 指令;或内置评估器
  • 前后各跑一次 dataset runner → 按评估器对比分数,CI 设门槛

局限与补充

  • 只能发现问题,不能定位是哪条记录被误删 / 误合并
  • 补确定性检查:关键事实能否被 RetrieveMemoryRecords 检索到(代码型评估器或单独测试)
  • 配合 CloudWatch 里每晚的合并 / 删除比例一起看

来源:sample test/test_regression_suite.py;Evaluations 能力见 devguide Evaluations 章节(evaluators / dataset evaluations);API 参数按 boto3 1.43.6 模型核对。

02 / ④ 合规
20

④ 合规:GDPR 删除与审计留痕

GDPR 删除 · 博客做法

按需调用 Lambda:ListMemoryRecords(namespace=user_id)(翻页取全)→ 逐条 DeleteMemoryRecord → 返回 deleted_count / failed_memory_ids 供重试

需要补齐

  • 只删长期记录,漏了短期 Event → 补 ListSessions → ListEvents → DeleteEvent(spike 已验证)
  • namespace 设计要对齐:按 user_id 前缀匹配,若记录在 agent_id/…/user_id 下会匹配不到(推断)
  • 合并后的记录写回 [agent_id],按用户删不到(源码推断)
  • 回执校验用 GetMemoryRecord:List 约 60s 才收敛(实测)

审计留痕 · 博客做法

  • 每次变更(打分 / 合并 / 删除 / GDPR)写结构化 JSON 到 CloudWatch Logs:action、memoryId、ISO 时间
  • CloudTrail trail 开启 file validation,作不可篡改的审计记录
  • RunOutput 每次运行结果存 S3;Dashboard 看 processed / consolidated / pruned 与执行状态

可增强

  • 开 Memory Record Streaming:MemoryRecordDeleted 事件(含内置 consolidation 的删除)推 Kinesis,审计更完整
02 / 回顾 · 方法论
21

回顾:可复用的是方法论,不是算法

1 · 分级保留

博客:episodic 30–60d · semantic 6–12m · procedural 不过期

先按价值给记忆分类,不同类不同寿命

2 · 硬上限

博客:createdAt 超 90 天直接删

先做便宜、确定的清理;时间基准用业务时间

3 · 价值评估

博客:新鲜度 + 活跃度 + 热度衰减打分

用能反映“还有没有用”的信号,业务事件优先于时间

4 · 先压缩再删

博客:低分 10 条一批,LLM 合并为 semantic

低价值但有信息的内容先压缩,保留来源,必要时归档原文

5 · 编排与留痕

博客:每晚 Step Functions,Catch → SNS,指标 + S3 记录

定时或事件驱动;每一次删除都可追溯

6 · 质量与合规闸门

博客:Evaluations 前后对比,GDPR 按用户删

变更前后评测;按用户删全量(含短期 Event)

因场景而异 · 需要自己设计

分级维度:按记忆类型还是业务实体?时间基准:业务时间存在哪个 indexed key?失效信号:哪些业务事件让记忆直接作废? 打分算法与阈值:用哪些信号、权重多少?合并粒度:按用户 / 主题分组,写回哪个 namespace?删除还是归档:原文要不要留存、留多久?

博客方案成本参考(主要是 Bedrock 合并调用):1k 条记忆、20% 低分 ≈ $0.01–0.02 / 晚;10 万条 ≈ $50–100 / 月。

03

Spike:用博客原版代码
在真实 AWS 上跑一遍

Pruner → Scorer → Consolidator → GDPR
2026-10-09 · us-east-1 · 临时资源,测试后删除

03 / 实测设计23

实测设计:代码不改,只调参数

原样使用

  • sample 仓库的 4 个 Lambda handler:Pruner / Scorer(含 cloudtrail_query)/ Consolidator / GDPR,代码未修改,本地按 Step Functions 顺序调用
  • 真实资源:AgentCore Memory、S3 桶(trail 日志 + ledger)、CloudTrail trail(只记本 Memory 的 GetMemoryRecord)、Bedrock Claude Sonnet 4.5
  • 12 条记忆:alice / bob 各 6 条,混合主题;真实调用 GetMemoryRecord 10 次

只改参数(为什么)

  • MEMORY_TTL_DAYS=0:TTL 按整数天解析,createdAt 不能回填(写入时间由服务决定),几分钟内只能用 0 天演示“截止前全部过期”
  • RELEVANCE_THRESHOLD=0.95、MAX_ACCESS_BASELINE=10:几分钟内新鲜度 / 活跃度都≈1,靠热度把记录分开(读 ≥ 8 次才过线)
  • BEDROCK_MODEL_ID=us.anthropic.claude-sonnet-4-5-…:博客默认 ID 直接调用报 ValidationException

补充实验:原版 Consolidator 失败后,只给 JSON 解析加一处补丁(剥离 ```json),其余原样,观察合并与 GDPR 之后的行为。

03 / 实测视频24
03 / 实测结论25

实测结论:sample 原样不能直接上生产

环节实测结果证据
Pruner跑通按 createdAt 过滤 + 逐条删除符合预期删除 3 / 3;List 70s 后收敛
CloudTrail跑通data event 带 memoryRecordId;responseElements 为空(Retrieve 无法归因)10 条事件,投递等待 6 分钟
Scorer问题访问计数被放大 ×(UTC 小时+1):按小时循环却用“天”前缀,同一天日志重复读取真实读 2 次 → 计 14 次(UTC 6 点)
Consolidator问题原版必然失败:Sonnet 4.5 返回 ```json 代码块,json.loads 报错;失败安全,原记录保留Expecting value: line 1 column 1
合并(补丁后)问题不分主题、不分用户:alice + bob 的 8 条合成 1 条,写回 ["support-agent"]合并文本同时含 Alice 账单与 Bob 部署
GDPR问题按 "alice" 删不到;按完整前缀删后,合并记录与短期 Event 仍含 Alice 数据删除 0 条 / 2 条;合并记录存在;Event 1 条
模型 ID配置需改为 us. 跨区推理配置默认 ID 报 ValidationException
04 / Takeaways26

结论

① 长期记录没有原生 TTL,需要自建;博客的方法论(分级 → 硬上限 → 价值评估 → 压缩 → 留痕 → 质量闸门)可以复用。

② 打分算法、阈值、合并 prompt 要按业务场景自己设计,博客公式只是参考。

③ sample 代码不能原样上生产:访问计数被放大、合并必然失败;修复后又会跨用户合并、GDPR 删不净。

④ 落地时:时间基准用业务时间;按用户 / 主题分组合并并写回原 namespace;GDPR 同时删短期 Event 与合并记录。

04 / References27

References

Blogaws.amazon.com/blogs/machine-learning/designing-lifecycle-policies-for-agentcore-memory
Samplegithub.com/aws-samples/sample-memory-lifecycle-policies-for-bedrock-agentcore
Metadatadocs.aws.amazon.com/bedrock-agentcore/latest/devguide/long-term-memory-metadata.html
Streamingdocs.aws.amazon.com/bedrock-agentcore/latest/devguide/memory-record-streaming.html
IngestDatadocs.aws.amazon.com/bedrock-agentcore/latest/devguide/long-term-ingest-data.html