智能体
aws.amazon.com ·
@Akarsha Sehwag
为Amazon Bedrock AgentCore设计记忆生命周期策略
本文介绍如何为长期运行的AI代理设计记忆生命周期策略,包括对代理记忆进行评分、整合和修剪。该方案通过AWS Step Functions夜间工作流实现,并提供可部署的AWS CDK代码栈。
AI推荐理由 长期运行的AI智能体会因记忆过期或混乱而质量下降,也面临数据合规风险;这套以夜间自动化流程对记忆打分、整合和修剪的方案,给了工程团队一套可落地的治理范本,降低人工维护成本并提升长时任务的可靠性。
83
正文
记忆生命周期策略通过系统性地管理智能体(Agent)记住和遗忘的内容,帮助在 Amazon Bedrock AgentCore 上运行的长期智能体保持高效。您的智能体会从每次对话中生成记忆。如果您不主动管理这些记忆,智能体将积累过时的上下文,这可能会降低响应质量,并为您的部署带来合规风险。经过数月的生产使用后,问题就会出现。我们观察到,一个客户支持智能体引用了一个四个月前已解决的账单争议,并将其视为当前问题。另一个智能体重复给出过时的部署建议,因为其记忆中仍包含一份已被取代的操作手册。在本文中,我们介绍 AI 智能体的记忆生命周期管理:即随着时间推移,系统性地对智能体记忆进行评分、整合和修剪的实践。我们使用 AgentCore 记忆(Amazon Bedrock AgentCore 的一项功能)、AWS Step Functions 和 Amazon Bedrock 来运行夜间生命周期工作流,逐步构建一个可部署的架构。最后,您将获得一个 AWS Cloud Development Kit (AWS CDK) 堆栈和一个将智能体记忆作为托管资源进行管理的框架。完整代码可在 GitHub 仓库中获取。此解决方案针对在数周或数月内积累大量交互数据的智能体,例如客户支持智能体、销售顾问和 IT 帮助台机器人。对于个人助理等低流量智能体,您可能只需从生存时间(TTL)过期和通用数据保护条例(GDPR)合规开始。所有阈值均可配置,以满足您的智能体需求。解决方案概述 此解决方案结合了共享记忆分类法与三个生命周期策略,这些策略作为夜间工作流运行。我们首先介绍塑造这些策略的记忆类型。记忆类型 在设计生命周期策略之前,我们需要一个共享词汇来描述智能体记住的内容。我们将智能体记忆分为三种类型,每种类型具有不同的保留要求。情景记忆:情景记忆捕捉发生了什么,是过去对话的记录。这些记忆带有时间戳、绑定会话且数量庞大。AgentCore 记忆将此信息存储在两种策略中:摘要和情景。两种策略都将记忆存储为绑定到特定智能体-用户会话的单独条目。情景和摘要提供短期连续性,但随着时间的推移,它们各自的相关性会降低。在设计生命周期策略时,优先考虑这些记忆的过期。语义记忆:语义记忆是从交互中提取的提炼事实和偏好,但与任何单一对话解耦。例如,“用户更喜欢美国东部(弗吉尼亚北部)AWS 区域(us-east-1)进行部署。”这些记忆持久、高价值且紧凑。在生命周期策略中,语义记忆的保留时间应长于情景记忆。它们是整合的主要候选对象,您可以将多个情景观察合并为单一权威事实。程序性记忆:程序性记忆编码了学习到的工作流程和工具使用模式。例如,“当用户询问成本时,先查询 AWS Cost Explorer API,然后总结。”这些代表了智能体的操作专业知识。程序性记忆数量较少,但对于某些用例来说是最有价值的类型。它们具有最长的保留期和最高的修剪标准。AgentCore 记忆将程序性知识存储为与情景记忆绑定的反思。更多信息请参阅情景记忆深入探讨博客。随着流程的发展,您应该检查这些记忆的有效性。生命周期策略 有了我们的分类法,我们可以设计三个互补的生命周期策略。每个策略针对无界记忆的不同故障模式。策略 1:基于 TTL 的过期 第一个策略自动删除超过配置 TTL 的记忆。我们默认情景记忆为 90 天。TTL 不考虑记忆是否仍然有用,但它为积累提供了硬性上限,并且对于合规性至关重要。在生产中,按记忆类型区分 TTL。将摘要记忆配置为 30-60 天后过期,语义记忆为 6-12 个月,并考虑对程序性记忆不设置 TTL。本文提供了一个可配置的 memoryTtlDays 参数作为起点。TTL 过期在评分或整合之前运行,这有助于避免将计算浪费在应该已经消失的记忆上。AgentCore 记忆不提供内置的自动删除 TTL。但是,它公开了系统生成的时间戳字段,这些字段支持 ListMemoryRecords 上的 BEFORE 和 AFTER 过滤器运算符。我们的修剪器使用 x-amz-agentcore-memory-createdAt 和 BEFORE 过滤器仅检索早于配置 TTL 的记录,然后删除它们。cutoff = (now - timedelta(days=ttl_days)).isoformat() response = client.list_memory_records( memoryId=memory_id, namespace=agent_id, metadataFilters=[{ "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"}, "operator": "BEFORE", "right": {"metadataValue": {"dateTimeValue": cutoff}}, }], ) 策略 2:相关性衰减评分 并非所有记忆都以相同的速度老化。昨天访问过的记忆比数周未触碰的记忆更相关。我们使用一个三项加权公式对每条记忆进行评分,该公式结合了创建新近度、上次访问新近度和访问频率:score = W_RECENCY * exp(-decay_rate * days_since_creation) + W_ACCESS * exp(-decay_rate * days_since_last_access) + W_FREQUENCY * min(access_count / MAX_ACCESS_BASELINE, 1.0) 我们不公开原始衰减常数,而是提供一个直观的参数:pruneDays,即未访问记忆的分数降至相关性阈值以下的大致天数:import math def decay_rate_from_prune_days(prune_days: int, threshold: float) -> float: """将 pruneDays 转换为指数衰减率。decay_rate = -ln(threshold) / prune_days """ if prune_days = 1: raise ValueError( f"threshold must be in the open interval (0, 1), got:
{threshold}" ) return -math.log(threshold) / prune_days 使用默认值(pruneDays = 45,threshold = 0.3),这给出 decay_rate ≈ 0.02676。该公式产生 0.0–1.0 之间的分数。当记忆分数低于您配置的阈值时,系统会根据您的策略设置将其标记为整合或修剪。该公式平衡了三个直觉:最近的记忆很重要,最近使用的记忆更重要,频繁检索的记忆携带额外信号。指数衰减意味着分数在最初几周内急剧下降,然后趋于平稳。一个旧但最近频繁访问的记忆仍然可以获得高分。三个权重可配置,让操作员可以根据智能体的工作负载强调不同的信号:W_RECENCY(默认 0.4):创建新近度的权重。较高的值有利于较新的记忆。W_ACCESS(默认 0.35):上次访问新近度的权重。较高的值有利于最近检索的记忆。W_FREQUENCY(默认 0.25):访问频率的权重。较高的值有利于经常检索的记忆。MAX_ACCESS_BASELINE(默认 50):频率项饱和为 1.0 时的访问次数。将此设置为“大量使用”的记忆在您的回看窗口中积累的大致访问次数。当三个权重之和为 1.0 时,分数将落在 [0.0, 1.0] 范围内。操作员可以调整权重以匹配其智能体的需求。例如,对于频繁访问的记忆最有价值的智能体(例如,反复引用同一故障排除手册的支持机器人),增加 W_FREQUENCY;或者对于新鲜度最重要的智能体(例如,实时交易助手),增加 W_RECENCY。正确的 pruneDays 值取决于您的智能体用例。下表为常见智能体原型提供了推荐的起点:智能体类型 pruneDays 理由 实时支持机器人 7 工单在数小时/天内解决。不需要旧上下文 销售/入职智能体 21 交易在数周内完成。过时的线索污染上下文 通用助手 45 混合工作负载的平衡保留 IT 帮助台/运维智能体 90 事件模式按季节重复 法律/合规顾问 180 先例在数月内保持相关 以下评分函数来自我们的 Memory Scorer AWS Lambda 函数(code/lambdas/memory_scorer/handler.py):def compute_relevance_score( created_at: datetime, last_accessed_at: datetime, access_count: int, decay_rate: float, now: datetime, w_recency: float = 0.4, w_access: float = 0.35, w_frequency: float = 0.25, max_access_baseline: int = 50, ) -> float: """使用三项加权衰减公式计算相关性分数。score = w_recency * exp(-decay_rate * days_since_creation) + w_access * exp(-decay_rate * days_since_last_access) + w_frequency * min(access_count / max_access_baseline, 1.0) 当权重之和为 1.0 时,返回 [0.0, 1.0] 范围内的浮点数。如果 max_access_baseline 为零或负数,则引发 ValueError。""" if max_access_baseline <= 0: raise ValueError( f"max_access_baseline must be a positive integer, got: {max_access_baseline}" ) days_since_creation = max((now - created_at).total_seconds() / 86400, 0.0) days_since_last_access = max((now - last_accessed_at).total_seconds() / 86400, 0.0) recency_term = w_recency * math.exp(-decay_rate * days_since_creation) access_term = w_access * math.exp(-decay_rate * days_since_last_access) frequency_term = w_frequency * min(access_count / max_access_baseline, 1.0) score = recency_term + access_term + frequency_term return score 基于 AWS CloudTrail 的访问跟踪 AgentCore 记忆 API 在其 MemoryRecordSummary 中不包含 lastAccessedAt 字段。为了获取真实的访问数据,我们使用 AWS CloudTrail。CDK 堆栈配置了一个带有高级事件选择器的跟踪,用于捕获 GetMemoryRecord 数据事件。您的 CloudTrail 配置记录每次记忆检索及其 memoryRecordId 和时间戳,然后将日志传送到您的 Amazon Simple Storage Service (Amazon S3) 存储桶。在每次评分调用开始时,Memory Scorer 列出过去 25 小时的 CloudTrail 日志文件,解压缩它们,并将 GetMemoryRecord 事件聚合为每条记录的上次访问时间戳和访问计数的查找表。为了在调用之间维护累积的访问历史,评分器在 Amazon S3 中持久化访问分类账。每次运行将新的 CloudTrail 计数与历史计数合并,使频率项获得真实的生命周期信号,而不是狭窄的每日快照。策略 3:基于 LLM 的整合 在修剪低分记忆之前,我们给它们最后一次机会。整合使用 Amazon Bedrock 将相关记忆合并为单个紧凑的语义条目。关于部署偏好的五个情景记忆变成一个权威事实。在此步骤中,大型语言模型 (LLM) 总结其自身的记忆。整合提示指示模型保留基本事实、删除冗余并输出置信度分数:CONSOLIDATION_PROMPT_TEMPLATE = """您是一个记忆整合助手。给定以下智能体记忆,创建单个简洁摘要,保留基本事实、用户偏好和可操作知识。删除冗余和过时信息。记忆:{memory_contents} 输出一个 JSON 对象,包含:- "summary":整合后的记忆文本 - "confidence":0.0-1.0 之间的浮点数,表示整合质量 - "key_facts":保留的关键事实列表""" 系统将整合后的记忆存储回 AgentCore 记忆,然后删除原始记忆。如果 Amazon Bedrock 失败,系统将保留原始记忆不变。系统记录失败的删除以供手动审查。整合本质上有损。LLM 将五个记忆总结为一个可能会丢失一些细微差别。模型返回的置信度分数有助于标记低质量整合以供人工审查。对于高风险领域,请考虑将原始记忆存档到冷存储而不是删除。对于生产部署,配置
Amazon Bedrock Guardrails 以过滤有害内容,并使用接地检查来验证整合后的记忆是否忠实于源材料。这些控制是生产要求,而不是可选添加。架构图 下图显示了夜间生命周期工作流架构。Amazon EventBridge 触发 AWS Step Functions 状态机,该状态机按顺序编排五个 Lambda 函数。图 1:由 Amazon EventBridge 和 AWS Step Functions 编排的夜间记忆生命周期工作流 无障碍文本描述:Amazon EventBridge 规则每晚触发 Step Functions 状态机。状态机按顺序调用 Lambda 函数:Memory Pruner(TTL 过期)、Memory Scorer(使用 CloudTrail 访问数据进行相关性评分)、Memory Consolidator(通过 Amazon Bedrock 进行基于 LLM 的合并)、Metrics Emitter(Amazon CloudWatch 指标)和 Run Output Writer(S3 持久化)。失败路由到 Amazon Simple Notification Service (Amazon SNS) 主题以发出警报。工作流按以下步骤进行:TTL 过期:Memory Pruner 查询 AgentCore 记忆,查找早于配置 TTL(默认:90 天)的记录并删除它们。评分记忆:Memory Scorer 从 CloudTrail 日志构建每条记录的访问查找表,将其与持久化 S3 分类账合并,计算相关性分数,并返回低于阈值的记忆。整合:工作流将低分记忆分批(默认大小:10)发送到 Memory Consolidator,后者调用 Amazon Bedrock 将它们合并为紧凑的语义条目并删除原始记忆。发出指标:Metrics Emitter 将工作流指标(处理的记忆、整合的记忆、修剪的记忆)发布到 CloudWatch。写入运行输出:Run Output Writer 将工作流结果持久化到 S3 以供审计。如果任何步骤失败,Catch 块将路由到失败处理程序,该处理程序将错误详细信息发布到 Amazon SNS 主题。先决条件 在部署解决方案之前,请确认您具备以下条件:一个 AWS 账户,具有创建 Lambda 函数、Step Functions 状态机、Amazon EventBridge 规则、SNS 主题、CloudWatch 仪表板、CloudTrail 跟踪和 S3 存储桶的权限。已安装 AWS CDK v2(npm install -g aws-cdk)。Node.js 18+ 和 npm。Python 3.12 和 pip。已在您的目标区域启用 Amazon Bedrock 模型访问权限,用于 Claude Sonnet 4.5(anthropic.claude-sonnet-4-5-20250929-v1:0)。请参阅 Amazon Bedrock 中按 AWS 区域支持模型以验证可用性。Amazon Bedrock AgentCore 至少配置了一个启用记忆的智能体。AWS Command Line Interface (AWS CLI) 配置了适当的凭证。克隆仓库并安装依赖项:cd code npm install 解决方案演练 我们将整个生命周期编排为夜间 AWS Step Functions 工作流,由 Amazon EventBridge 触发。工作流按顺序运行五个阶段:TTL 过期、评分、整合、指标发出和运行输出写入。CDK 堆栈演练 单个 CDK 堆栈(code/lib/memory-lifecycle-stack.ts)定义了整个基础设施。以下是关键部分。Lambda 函数定义:每个处理程序使用 Python 3.12 并具有最低权限 IAM 权限。堆栈将共享代码部署为 Lambda Layer,并将可配置参数作为环境变量传递:// 共享 Python 模块(常量、模型)的 Lambda Layer const sharedLayer = new lambda.LayerVersion(this, 'SharedLayer', { code: lambda.Code.fromAsset( path.join(__dirname, '..', 'lambdas', 'shared'), { bundling: { image: lambda.Runtime.PYTHON_3_12.bundlingImage, command: [ 'bash', '-c', 'mkdir -p /asset-output/python/shared && cp -r . /asset-output/python/shared/', ], }, }, ), compatibleRuntimes: [lambda.Runtime.PYTHON_3_12], description: 'Shared constants and models for memory lifecycle Lambdas', }); const memoryScorerFn = new lambda.Funct
查看原文(中文正文为 AI 翻译)
Memory lifecycle policies help long-running agents on Amazon Bedrock AgentCore stay effective by systematically managing what they remember and forget. Your agent generates memories from every conversation it conducts. If you don’t actively manage these memories, your agents will accumulate outdated context, which can degrade response quality and create compliance risks for your deployment. After months of production use, problems emerge. We observed a customer support agent reference a billing dispute resolved four months earlier, treating it as active. Another agent repeated outdated deployment advice because its memory still contained a superseded runbook. In this post, we introduce memory lifecycle management for AI agents: the practice of systematically scoring, consolidating, and pruning agent memories over time. We walk through a deployable architecture using AgentCore memory (a capability of Amazon Bedrock AgentCore), AWS Step Functions, and Amazon Bedrock to run a nightly lifecycle workflow. By the end, you will have an AWS Cloud Development Kit (AWS CDK) stack and a framework for managing agent memory as a managed resource. The complete code is available in the GitHub repository. This solution targets agents that accumulate high volumes of interaction data over weeks or months, such as customer support agents, sales advisors, and IT helpdesk bots. For lower-volume agents like personal assistants, you might start with time-to-live (TTL) expiration and General Data Protection Regulation (GDPR) compliance alone. All thresholds are configurable to match your agent’s needs. Solution overview This solution combines a shared memory taxonomy with three lifecycle policies that run as a nightly workflow. We begin with the memory types that shape those policies. Memory types Before designing lifecycle policies, we need a shared vocabulary for what agents remember. We categorize agent memory into three types, each with different retention requirements. Episodic memory: Episodic memories capture what happened, it’s the record of past conversations. These are timestamped, session-bound, and high-volume. Agentcore memory stores this information in two strategies, Summary and Episodic. Both strategies store memories as individual entries tied to specific agent-user sessions. Episodes and Summary provide short-term continuity but individually they become less relevant as time progresses. When designing your lifecycle policies, prioritize these memories for expiration first. Semantic memory: Semantic memories are distilled facts and preferences extracted from interactions but decoupled from any single conversation. “The user prefers the US East (N. Virginia) AWS Region (us-east-1) for deployments.” These are durable, high value, and compact. In your lifecycle policies, retain semantic memories longer than episodic memories. These are prime candidates for consolidation, where you merge multiple episodic observations into a single, authoritative fact. Procedural memory: Procedural memories encode learned workflows and tool-use patterns. “When the user asks about costs, query the AWS Cost Explorer API first, then summarize.” These represent the agent’s operational expertise. Procedural memories are lower volume but the most valuable type for certain use cases. They have the longest retention and the highest bar for pruning. AgentCore memory stores procedural knowledge as reflections tied to episodic memory. Read more about it in Episodic memory deep dive blog. You should check these for validity as your procedures evolve. Lifecycle policies With our taxonomy in place, we can design three complementary lifecycle policies. Each targets a different failure mode of unbounded memory. Policy 1: TTL-based expiration The first policy automatically deletes memories older than a configured TTL. We default to 90 days for episodic memories. TTL does not consider whether a memory is still useful, but it provides a hard ceiling on accumulation and is essential for compliance. In production, differentiate TTL by memory type. Configure your summary memories to expire after 30–60 days, semantic memories after 6–12 months, and consider setting no TTL for procedural memories. This post delivers a single configurable memoryTtlDays parameter as a starting point. TTL expiration runs first, before scoring or consolidation, which helps avoid wasting compute on memories that should already be gone. AgentCore memory doesn’t provide a built-in auto-delete TTL. However, it exposes system-generated timestamp fields that support BEFORE and AFTER filter operators on ListMemoryRecords. Our pruner uses x-amz-agentcore-memory-createdAt with a BEFORE filter to retrieve only records older than the configured TTL, then deletes them. cutoff = (now - timedelta(days=ttl_days)).isoformat() response = client.list_memory_records( memoryId=memory_id, namespace=agent_id, metadataFilters=[{ "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"}, "operator": "BEFORE", "right": {"metadataValue": {"dateTimeValue": cutoff}}, }], ) Policy 2: Relevance decay scoring Not all memories age at the same rate. A memory accessed yesterday is more relevant than one untouched for weeks. We score each memory using a three-term weighted formula that combines creation recency, last-access recency, and access frequency: score = W_RECENCY * exp(-decay_rate * days_since_creation) + W_ACCESS * exp(-decay_rate * days_since_last_access) + W_FREQUENCY * min(access_count / MAX_ACCESS_BASELINE, 1.0) Rather than exposing a raw decay constant, we provide one intuitive parameter: pruneDays, the approximate number of days after which an unaccessed memory’s score drops below the relevance threshold: import math def decay_rate_from_prune_days(prune_days: int, threshold: float) -> float: """Convert pruneDays to an exponential decay rate. decay_rate = -ln(threshold) / prune_days """ if prune_days = 1: raise ValueError( f"threshold must be in the open interval (0, 1), got: {threshold}" ) return -math.log(threshold) / prune_days With the defaults (pruneDays = 45, threshold = 0.3), this gives decay_rate ≈ 0.02676. The formula produces a score between 0.0–1.0. When memories score below your configured threshold, the system flags them for consolidation or pruning based on your policy settings. The formula balances three intuitions: recent memories matter, recently used memories matter even more, and frequently retrieved memories carry additional signal. The exponential decay means scores drop sharply in the first few weeks, then level off. A memory that is old but accessed recently and frequently can still score well. The three weights are configurable, letting operators emphasize different signals depending on their agent’s workload: W_RECENCY (default 0.4): Weight for creation recency. Higher values favor newer memories. W_ACCESS (default 0.35): Weight for last-access recency. Higher values favor recently retrieved memories. W_FREQUENCY (default 0.25): Weight for access frequency. Higher values favor memories that are retrieved often. MAX_ACCESS_BASELINE (default 50): The access count at which the frequency term saturates at 1.0. Set this to the approximate number of accesses a “heavily used” memory accumulates in your lookback window. When the three weights sum to 1.0, the score will fall in [0.0, 1.0]. Operators can adjust weights to match their agent’s needs. For example, increase W_FREQUENCY for agents where frequently accessed memories are most valuable (for example, a support bot that repeatedly references the same troubleshooting runbook), or increase W_RECENCY for agents where freshness matters most (for example, a real-time trading assistant). The right pruneDays value depends on your agent’s use case. The following table provides recommended starting points for common agent archetypes: Agent type pruneDays Rationale Real-time support bot 7 Tickets resolve in hours/days. Old context is not needed Sales / onboarding agent 21 Deals close in weeks. Stale leads pollute context General assistant 45 Balanced retention for mixed workloads IT helpdesk / ops agent 90 Incident patterns repeat seasonally Legal / compliance advisor 180 Precedents stay relevant for months The following scoring function comes from our Memory Scorer AWS Lambda function (code/lambdas/memory_scorer/handler.py): def compute_relevance_score( created_at: datetime, last_accessed_at: datetime, access_count: int, decay_rate: float, now: datetime, w_recency: float = 0.4, w_access: float = 0.35, w_frequency: float = 0.25, max_access_baseline: int = 50, ) -> float: """Compute relevance score using the 3-term weighted decay formula. score = w_recency * exp(-decay_rate * days_since_creation) + w_access * exp(-decay_rate * days_since_last_access) + w_frequency * min(access_count / max_access_baseline, 1.0) Returns a float in [0.0, 1.0] when weights sum to 1.0. Raises ValueError if max_access_baseline is zero or negative. """ if max_access_baseline <= 0: raise ValueError( f"max_access_baseline must be a positive integer, got: {max_access_baseline}" ) days_since_creation = max((now - created_at).total_seconds() / 86400, 0.0) days_since_last_access = max((now - last_accessed_at).total_seconds() / 86400, 0.0) recency_term = w_recency * math.exp(-decay_rate * days_since_creation) access_term = w_access * math.exp(-decay_rate * days_since_last_access) frequency_term = w_frequency * min(access_count / max_access_baseline, 1.0) score = recency_term + access_term + frequency_term return score AWS CloudTrail-based access tracking The AgentCore memory API does not include a lastAccessedAt field in its MemoryRecordSummary. To get real access data, we use AWS CloudTrail. The CDK stack configures a trail with advanced event selectors that capture GetMemoryRecord data events. Your CloudTrail configuration logs every memory retrieval with its memoryRecordId and timestamp, then delivers the logs to your Amazon Simple Storage Service (Amazon S3) bucket. At the start of each scoring invocation, the Memory Scorer lists CloudTrail log files from the past 25 hours, decompresses them, and aggregates GetMemoryRecord events into a per-record lookup of last-access timestamps and access counts. To maintain cumulative access history across invocations, the scorer persists an access ledger in Amazon S3. Each run merges fresh CloudTrail counts with historical counts, giving the frequency term a true lifetime signal rather than a narrow daily snapshot. Policy 3: LLM-based consolidation Before pruning low-scoring memories, we give them one last chance. Consolidation uses Amazon Bedrock to merge related memories into a single, compact semantic entry. Five episodic memories about deployment preferences become one authoritative fact. In this step, a large language model (LLM) summarizes its own memories. The consolidation prompt instructs the model to preserve essential facts, remove redundancy, and output a confidence score: CONSOLIDATION_PROMPT_TEMPLATE = """You are a memory consolidation assistant. Given the following agent memories, create a single concise summary that preserves essential facts, user preferences, and actionable knowledge. Remove redundancy and outdated information. Memories: {memory_contents} Output a JSON object with: - "summary": the consolidated memory text - "confidence": a float 0.0-1.0 indicating consolidation quality - "key_facts": list of preserved key facts""" The system stores the consolidated memory back in AgentCore memory, then deletes the originals. If Amazon Bedrock fails, the system retains the originals unchanged. The system logs failed deletions for your manual review. Consolidation is lossy by nature. An LLM summarizing five memories into one can drop some nuance. The confidence score returned by the model helps flag low-quality consolidations for human review. For high-stakes domains, consider archiving originals to cold storage instead of deleting them. For production deployments, configure Amazon Bedrock Guardrails to filter harmful content and use grounding checks to verify consolidated memories remain faithful to the source material. These controls are production requirements, not optional additions. Architecture diagram The following diagram shows the nightly lifecycle workflow architecture. Amazon EventBridge triggers an AWS Step Functions state machine that orchestrates five Lambda functions in sequence. Figure 1: Nightly memory lifecycle workflow orchestrated by Amazon EventBridge and AWS Step Functions Text description for accessibility: An Amazon EventBridge rule triggers a Step Functions state machine nightly. The state machine invokes Lambda functions in sequence: Memory Pruner (TTL expiration), Memory Scorer (relevance scoring using CloudTrail access data), Memory Consolidator (LLM-based merging through Amazon Bedrock), Metrics Emitter (Amazon CloudWatch metrics), and Run Output Writer (S3 persistence). Failures route to an Amazon Simple Notification Service (Amazon SNS) topic for alerts. The workflow proceeds as follows: TTL Expiration: The Memory Pruner queries AgentCore memory for records older than the configured TTL (default: 90 days) and deletes them. Score Memories: The Memory Scorer builds a per-record access lookup from CloudTrail logs, merges it with a persistent S3 ledger, computes relevance scores, and returns memories below the threshold. Consolidate: The workflow batches low-scoring memories (default size: 10) and sends them to the Memory Consolidator, which invokes Amazon Bedrock to merge them into compact semantic entries and deletes the originals. Emit Metrics: The Metrics Emitter publishes workflow metrics (memories processed, consolidated, pruned) to CloudWatch. Write Run Output: The Run Output Writer persists workflow results to S3 for auditability. If any step fails, a Catch block routes to a failure handler that publishes error details to an Amazon SNS topic. Prerequisites Before deploying the solution, confirm you have the following: An AWS account with permissions to create Lambda functions, Step Functions state machines, Amazon EventBridge rules, SNS topics, CloudWatch dashboards, CloudTrail trails, and S3 buckets. AWS CDK v2 installed (npm install -g aws-cdk). Node.js 18+ and npm. Python 3.12 with pip. Amazon Bedrock model access enabled for Claude Sonnet 4.5 (anthropic.claude-sonnet-4-5-20250929-v1:0) in your target Region. See Supported models by AWS Region in Amazon Bedrock to verify availability. Amazon Bedrock AgentCore with at least one agent configured with memory enabled. AWS Command Line Interface (AWS CLI) configured with appropriate credentials. Clone the repository and install dependencies: cd code npm install Solution walkthrough We orchestrate the entire lifecycle as a nightly AWS Step Functions workflow triggered by Amazon EventBridge. The workflow runs five stages in sequence: TTL expiration, scoring, consolidation, metrics emission, and run output writing. CDK stack walkthrough A single CDK stack (code/lib/memory-lifecycle-stack.ts) defines the entire infrastructure. Here are the key sections. Lambda function definitions: Each handler uses Python 3.12 with least-privilege IAM permissions. The stack deploys shared code as a Lambda Layer and passes configurable parameters as environment variables: // Lambda Layer for the shared Python module (constants, models) const sharedLayer = new lambda.LayerVersion(this, 'SharedLayer', { code: lambda.Code.fromAsset( path.join(__dirname, '..', 'lambdas', 'shared'), { bundling: { image: lambda.Runtime.PYTHON_3_12.bundlingImage, command: [ 'bash', '-c', 'mkdir -p /asset-output/python/shared && cp -r . /asset-output/python/shared/', ], }, }, ), compatibleRuntimes: [lambda.Runtime.PYTHON_3_12], description: 'Shared constants and models for memory lifecycle Lambdas', }); const memoryScorerFn = new lambda.Funct