亚马逊AWS官方博客

(下篇)Solutions Memory:让 AI Agent 从成功案例中持续学习 —— 双 Memory 架构实践

摘要:本文针对上篇航空客服智能体服务回复不一致的痛点,提出双 Memory 架构解决方案,通过新增 Solutions Memory(成功案例库)实现跨用户知识复用与服务标准化,解决同类问题答复差异问题。


一、引言

上篇文章中,我们构建了一个完整可用的航空客服智能体系统。系统通过 Strands Agent 提供智能对话能力,通过 Gateway Policy 保障策略强制执行,通过 Memory A 实现上下文记忆。然而,在实际运行中我们发现了一个关键问题:服务一致性。

二、问题背景:一致性挑战

2.1 真实场景复现

让我们看一个典型的航班延误场景(场景 F):

第 1 天,用户 Tom 咨询

Tom: "我的航班 UA2468 延误了 4 小时,能给我什么补偿?"
Agent: "您可以选择:1) 全额退款,或 2) 继续乘坐 + 贵宾室使用券 + 200里程积分"
Tom: "太好了,我选择第二个方案。" [点赞 ????]

第 2 天,用户 Lisa 咨询同样问题

Lisa: "我的航班也延误了 4 小时,怎么办?"
Agent: "您可以选择:1) 全额退款,或 2) 继续乘坐 + 免费改签"
Lisa: "为什么没有贵宾室和积分?昨天我朋友得到了这些补偿。"

问题根源:虽然 System Prompt 中明确写了补偿政策(贵宾室 + 200 里程),但 Agent 在处理时会根据上下文”灵活调整”,导致每次给出的方案略有不同。对于需要标准化服务的航空公司来说,这种不一致会严重影响客户信任。

2.2 为什么 Memory A 无法解决?

Memory A(对话历史)存储的是当前用户的对话上下文,它无法跨用户共享成功案例:

[图1]

我们需要一个新的机制:Solutions Memory(成功案例库)。

三、双 Memory 架构设计

3.1 双 Memory 职责划分

我们设计了双 Memory 架构,每个 Memory 承担不同的职责,互相配合但不干扰。

Memory A:对话历史记忆

Memory A(Memory ID: airline_agent_memory_v2)专注于管理单个用户的对话上下文,它的核心能力是确保多轮对话的连贯性。当用户与 Agent 交互时,每一轮对话(包括用户消息和 Agent 回复)都会被 Agent 自动存储到 Memory A 中。这些对话数据完整保留了原始内容,包括用户的问题、Agent 的回复、以及可能涉及的工具调用结果。

Memory A 底层基于 AgentCore Memory 的 STM/LTM 两层架构:对话数据首先立即写入 STM(Short-Term Memory / Event Store),确保即时可读;随后在 60-120 秒内,AgentCore 后台服务会自动将数据提取到 LTM(Long-Term Memory / Memory Records),生成语义向量索引供后续检索。

Memory A 的检索方式非常直接:通过 actor_id(用户标识)和 session_id(会话标识)进行精确匹配。这意味着,当用户在同一个会话中继续对话时,Agent 能够快速找到之前的所有对话记录,理解上下文,避免用户重复提供信息。例如,用户第一轮说”我要订票”,第二轮说”第一个航班”,Agent 通过 Memory A 能够理解”第一个”指的是之前搜索结果中的第一个航班。

Memory B:成功案例知识库

Memory B(Memory ID: airline_solutions_memory)则承担了完全不同的角色——它是一个跨用户共享的成功案例库。与 Memory A 的”自动存储”不同,Memory B 采用”用户点赞触发存储”的机制。只有当用户对 Agent 的回复非常满意并主动点赞时,这一轮对话才会被提取为一个成功案例(格式化为 Problem + Solution 结构)存储到 Memory B 中。

Memory B 同样基于 AgentCore Memory 的 STM/LTM 两层架构:用户点赞后,案例立即写入 STM,用户获得即时反馈;随后在 60-120 秒内,AgentCore 后台服务将案例提取到 LTM,生成语义向量并建立索引。关键区别在于,Memory B 主要依赖 LTM 的语义搜索能力来发现相似案例,而不是像 Memory A 那样通过精确的 session_id 匹配。

这种设计有两个关键优势:

  1. 质量保证:只有真正解决用户问题、获得用户认可的回复才会进入案例库,避免了错误或不满意的回复污染知识库。
  2. 知识沉淀:随着系统运行时间增长,Memory B 会积累越来越多经过实战检验的成功案例,形成企业的知识资产。

Memory B 的检索方式采用语义相似度搜索。当新用户提出问题时,系统会先在该用户的个人案例中搜索(个性化优先),如果没有找到相关案例,再搜索全局案例库(知识共享)。这种分层检索策略既保证了个性化服务,又实现了跨用户的知识复用。

两个 Memory 的协作关系

Memory A 和 Memory B 在 Agent 处理请求时紧密配合:

  • Memory B 先行:在 Agent 开始推理之前,先从 Memory B 中检索相似的成功案例,作为参考信息注入到用户的 Prompt 中。
  • Memory A 跟进:Agent 在推理过程中,会自动从 Memory A 加载该用户的历史对话,确保上下文连贯。
  • 结果融合:Agent 综合 Memory B 的”成功经验”和 Memory A 的”个人上下文”,生成既符合标准又个性化的回复。

这种双 Memory 架构的核心价值在于:Memory A 确保服务的个性化和连贯性,Memory B 确保服务的一致性和标准化。

3.2 架构图

双 Memory 架构的完整系统由三层组成。最外层是 AgentCore Identity,负责用户身份验证和 actor_id 提取,确保每个请求都能正确识别用户身份。Identity 验证通过后,请求进入核心平台层。

核心平台层是 AgentCore Platform,包含四个平行的核心组件:Memory A(对话历史,自动管理每个用户的会话上下文)、Memory B(成功案例库,通过语义搜索实现跨用户知识共享)、Gateway/Policy(工具调用拦截和策略检查)、以及 Runtime(Agent 执行环境,负责运行基于 Strands Framework 的 Agent 实例)。这四个组件相互独立但协同工作,Memory A/B 提供数据支持,Runtime 运行 Agent 进行推理,Gateway/Policy 管理工具调用的安全策略。

Agent 在 Runtime 中运行时需要调用外部业务工具,请求会通过 Gateway/Policy 组件进行策略检查和 MCP 协议转换,然后转发到 MCP Tools(业务工具层)。MCP Tools 是独立于 AgentCore Platform 的外部服务,包括航班查询、订票、退款等具体业务功能。

最底层是 AgentCore Observability,通过 OpenTelemetry 监控和 CloudWatch 日志对整个系统进行全方位的可观测性支持。Observability 层可以收集来自 Identity、Platform(Memory、Gateway、Runtime)、MCP Tools 等所有组件的遥测数据,实现端到端的链路追踪和问题诊断。特别是AgentCore Observability全程采集观测数据;记录每一次命中 / 未命中、接口时延、数据读取链路日志;同时将 Memory 的每一步操作,与身份鉴权、平台网关、Agent 推理、MCP 工具调用做链路关联。依托这套能力,可实时监控 Memory 模块运行健康度,快速定位Memory加载失败、案例匹配异常、会话数据丢失、读写卡顿等问题;同时留存全量操作日志,支撑 Memory 数据的溯源审计、性能优化与故障根因定位,为整个记忆体系的稳定调度提供全维度可视保障。

整个请求处理流程分为四个步骤:Step 1 从 Memory B 检索相似成功案例、Step 2 从 Memory A 加载该用户的对话历史、Step 3 由 Runtime 中的 Agent 基于增强 Prompt 进行推理、Step 4 通过 Gateway/Policy 调用 MCP Tools 获取实时数据。这四个步骤的结果最终融合生成标准化且个性化的响应。

[图2:双 Memory 协作流程架构图]

3.3 完整工作流程时序图

[图3:双 Memory 完整工作流程时序图]

上面的时序图完整展示了双 Memory 架构在用户咨询航班延误补偿场景下的协作流程。当用户提问”航班延误4小时,能给什么补偿?”时,前端将请求转发给 invoke() 函数,整个处理流程分为四步骤。

1. 蓝色区域(Step 1)展示了 Memory B(Solutions Memory)的分层检索过程。invoke() 函数首先调用 search_solutions() 方法,该方法采用两阶段检索策略:Phase 1 优先在用户个人的 namespace(/solutions/actors/{actor_id}/sessions/)中搜索历史成功案例,如果个人案例不足(少于3个或相似度不够),则进入 Phase 2 扩大到全局 namespace(/solutions/)搜索所有用户的成功案例。检索结果会附带相似度评分(0-1之间),系统只保留 score >= 0.5 的高质量案例,并格式化为 <reference_solutions> XML 标签结构,准备注入到 Agent 的 Prompt 中。

2. 橙色区域(Step 2)展示了 Agent 创建和 Memory A(对话历史)加载过程。invoke() 函数调用 create_agent() 创建 Agent 实例时,会传入 session_id 和 actor_id 两个关键参数。Agent 在初始化时自动向 Memory A 发起查询,根据 actor_id + session_id 组合精确匹配该用户在当前会话中的所有历史对话。对于新用户或新会话,Memory A 返回空历史;对于老用户,返回完整的对话链(包括之前的问题、回复、工具调用结果等)。这一步确保了多轮对话的上下文连贯性。

3. 绿色区域(Step 3)展示了 Agent 的推理和工具调用过程。invoke() 函数将增强后的 Prompt(包含用户问题 + Memory B 的参考案例 + Memory A 的对话历史)传递给 Agent。Agent 在推理过程中首先调用 verify_identity() 工具验证用户身份(返回会员等级 GOLD),然后调用 get_flight_status() 工具查询航班实时状态(确认延误4小时)。基于这些实时数据和 Memory B 中检索到的成功案例,Agent 生成标准化的补偿方案回复。关键设计在于,Agent 不需要”记住”或”猜测”补偿标准,而是直接参考历史成功案例中用户满意的处理方式(贵宾室 + 200里程积分)。Agent 返回回复后,框架会自动将本轮对话(用户问题 + Agent回复)存储到 Memory A 的 STM 中,并在 60-120 秒内异步提取到 LTM,供后续会话检索。

4. 黄色区域展示了用户反馈和案例存储的闭环机制。当用户对 Agent 的回复感到满意并点击”???? Like”按钮时,前端调用 store_solution() 方法将这一轮成功对话(问题 + 回复)存储到 Memory B 中。系统会生成一个唯一的 session_id(格式如 sol-abc456),并立即写入 STM(Short-Term Memory),用户在1秒内就能看到”✅ 感谢反馈!”的确认消息。此时数据已经可以通过 list_events() 读取,但还无法通过语义搜索找到。AgentCore 后台服务会在 60-120 秒内异步完成向量化处理,将案例提取到 LTM(Long-Term Memory),生成语义向量索引。前端提示”此案例将在1-2分钟后生效”,为用户设置合理预期。只有完成 LTM 提取后,其他用户才能通过 retrieve_memories() 语义搜索到这个成功案例,实现跨用户的知识共享。

整个流程的核心价值在于:Memory B 通过分层检索和语义搜索确保服务标准化(所有用户获得一致的补偿方案),Memory A 通过对话历史管理确保服务个性化(理解每个用户的上下文和偏好),两者协同工作实现了”既标准又个性化”的智能客服体验。

3.4 AgentCore Memory 内部机制:STM/LTM 两层存储

AgentCore Memory 内部采用双层架构,理解这一点对于正确使用 Solutions Memory 至关重要。无论是 Memory A 还是 Memory B,底层都使用相同的 STM/LTM 架构,只是应用方式不同。

1. STM(Short-Term Memory):Event Store 事件存储层

STM 是 AgentCore Memory 的第一层,可以把它理解为一个”原始日志数据库”。当我们调用 create_event() 写入数据时(无论是 Memory A 的对话历史还是 Memory B 的成功案例),数据都会立即存储到 STM 中,并且写入后立即可读。

STM 存储的是原始的完整文本,没有任何加工或压缩。例如,Memory B 存储的成功案例在 STM 中是这样的:

Event 1: "Problem: 我的航班 UA2468 延误了 4 小时,能给我什么补偿?"
Event 2: "Solution: 您可以选择:1) 全额退款,或 2) 继续乘坐 + 贵宾室使用券 + 200里程积分"

STM 的查询方式非常直接:通过 actor_idsession_id 进行精确匹配。调用 list_events(actor_id, session_id) 可以获取指定会话的所有事件。这种设计的优点是速度快、可靠性高,但缺点是无法进行”模糊搜索”或”语义相似搜索”——必须知道准确的 session_id 才能查询。

2. LTM(Long-Term Memory):Memory Records 语义记忆层

LTM 是 AgentCore Memory 的第二层,它是 AgentCore 后台服务通过机器学习模型从 STM 中异步提取出来的。当数据写入 STM 后,AgentCore 会在 60-120 秒内完成以下处理:

  1. 语义提取:使用嵌入模型(Embedding Model)将原始文本转换为高维向量,捕捉文本的语义含义。
  2. 摘要生成:如果原文很长,生成语义摘要,保留核心信息。
  3. 索引构建:将向量和摘要存储到 LTM 中,按照 namespace 组织,方便后续检索。

LTM 的核心能力是语义相似度搜索。当我们调用 retrieve_memories(namespace, query) 时,系统会:

  • 将查询文本(query)也转换为向量
  • 在指定的 namespace 下,计算查询向量与所有记忆向量的相似度
  • 返回相似度最高的 top-k 条记忆,附带相似度评分(0-1)

这种设计的优点是可以发现”语义相似”的案例,即使用户的表述方式完全不同。例如:

  • 查询:”航班晚点很久,有啥赔偿?”
  • 匹配到:”我的航班 UA2468 延误了 4 小时,能给我什么补偿?”

即使用词完全不同(”晚点” vs “延误”,”有啥赔偿” vs “能给我什么补偿”),语义相似度搜索也能成功匹配。

3. STM 和 LTM 的协作关系

在 Solutions Memory 的实现中,STM 和 LTM 的分工非常明确:

  • 写入流程:调用 store_solution() → 立即写入 STM → 用户获得即时反馈(session_id)→ 60-120秒后 AgentCore 异步提取到 LTM
  • 检索流程:调用 search_solutions() → 在 LTM 中语义搜索 → 找到匹配的 namespace 和 session_id → 回到 STM 读取原文 → 返回完整的 Problem + Solution

为什么要这样设计?因为 LTM 中存储的是语义摘要和向量,不是原文。如果用户提出的问题包含特定细节(如航班号、具体金额),我们需要完整的原文才能提供准确的参考。因此,我们先用 LTM “找到相关案例”,再用 STM “获取原文”。

关键延迟说明

理解 STM 到 LTM 的 60-120 秒延迟非常重要,这直接影响测试和用户体验设计:

  • 即时反馈:用户点赞后立即返回 session_id,提示”感谢反馈”,给用户即时的正向反馈。
  • 延迟生效:告知用户”此案例将在 1-2 分钟后生效”,设置合理预期。
  • 测试等待:端到端测试中必须显式等待 90 秒,确保 LTM 提取完成后再进行检索验证。

这不是系统缺陷,而是分布式异步架构的必然代价。AgentCore 选择异步处理是为了提升写入性能和系统可扩展性——如果写入时同步进行向量化和索引构建,每次写入可能需要几秒钟,用户体验会很差。

3.5 Namespace 设计:分层检索的基础

Namespace 的设计直接决定了检索策略的灵活性:

/solutions/actors/{actor_id}/sessions/{session_id}/

示例

  • Tom 的案例:/solutions/actors/tom123/sessions/sol-abc456/
  • Lisa 的案例:/solutions/actors/lisa789/sessions/sol-def789/

检索策略

# Phase 1: 搜索个人案例(优先)
namespace = f"/solutions/actors/{actor_id}/sessions/"
results = client.retrieve_memories(namespace=namespace, query=query)

# Phase 2: 如果个人没找到,搜索全局(兜底)
if not results:
    namespace = "/solutions/"  # 前缀匹配所有案例
    results = client.retrieve_memories(namespace=namespace, query=query)

设计理由

  • 个性化优先:用户自己的历史案例最相关
  • 隐私保护:个人案例不会被其他用户直接看到(需要语义匹配)
  • 新用户友好:没有个人历史的新用户也能受益于全局案例

四、核心代码实现

Solutions Memory 的实现可以分为三个核心部分:

1. SolutionsMemory 类:封装了成功案例的存储和检索逻辑,提供简洁的 API 供业务代码调用。它实现了分层检索策略(先个人后全局)和 STM/LTM 协作机制(先 LTM 语义搜索,再 STM 获取原文)。

2. invoke() 函数:Agent 的调用入口,负责协调 Memory B、Memory A 和 Agent 三者的协作。它在 Agent 推理之前先从 Memory B 检索参考案例,将成功经验注入到 Prompt 中,确保服务的一致性。

3. 前端点赞机制:实现用户反馈闭环,只有用户明确满意才将案例存入 Memory B,确保案例库的质量。

接下来我们逐一展示这三部分的关键代码实现。

4.1 SolutionsMemory 类:分层检索封装

工作原理说明

SolutionsMemory 类是对 AgentCore Memory API 的高层封装,它隐藏了 STM/LTM、namespace 等底层细节,对外提供两个简单接口:

  • search_solutions():检索相似案例
  • store_solution():存储成功案例

分层检索的核心逻辑是:先在用户个人的 namespace(/solutions/actors/{actor_id}/sessions/)中搜索,如果没找到足够案例,再扩大到全局 namespace(/solutions/)。这样既保证了个性化服务,又实现了知识共享。

检索到相似案例后,需要回到 STM 获取原文。因为 LTM 只返回 namespace 和相似度评分,我们需要解析 namespace 得到 actor_idsession_id,然后调用 list_events() 从 STM 读取完整的 Problem 和 Solution。

关键代码片段

文件:src/memory/solutions_memory.py

from bedrock_agentcore.memory import MemoryClient

class SolutionsMemory:
    def __init__(self, memory_id: str):
        self.memory_id = memory_id
        self.client = MemoryClient()

    def search_solutions(self, actor_id: str, query: str) -> List[Dict]:
        """分层检索成功案例"""
        # Phase 1: 搜索个人案例(个性化优先)
        personal_namespace = f"/solutions/actors/{actor_id}/sessions/"
        personal_results = self.client.retrieve_memories(
            memory_id=self.memory_id,
            namespace=personal_namespace,
            query=query,
            top_k=3
        )

        # 过滤低分结果(相似度 >= 0.5)
        filtered = [r for r in personal_results if r.get("score", 0) >= 0.5]

        if filtered:
            return self._fetch_from_stm(actor_id, filtered)

        # Phase 2: 如果个人案例不足,搜索全局案例库
        global_results = self.client.retrieve_memories(
            memory_id=self.memory_id,
            namespace="/solutions/",  # 全局搜索
            query=query,
            top_k=3
        )

        filtered = [r for r in global_results if r.get("score", 0) >= 0.5]
        return self._fetch_from_stm_global(filtered)

    def _fetch_from_stm(self, actor_id: str, ltm_results: List[Dict]):
        """从 LTM 结果回到 STM 获取原文"""
        solutions = []
        for result in ltm_results:
            # LTM 返回 namespace,从中解析 session_id
            namespace = result.get("namespaces", [""])[0]
            session_id = namespace.split("/")[4]  # /solutions/actors/{id}/sessions/{session_id}/

            # 从 STM 读取完整的 Problem + Solution
            events = self.client.list_events(
                memory_id=self.memory_id,
                actor_id=actor_id,
                session_id=session_id
            )

            if len(events) >= 2:
                solutions.append({
                    "problem": events[0]['content'].replace("Problem: ", ""),
                    "solution": events[1]['content'].replace("Solution: ", ""),
                    "score": result.get("score", 0)
                })

        return solutions

    def store_solution(self, actor_id: str, problem: str, solution: str) -> str:
        """存储成功案例到 Memory B"""
        # 生成唯一 session_id
        session_id = f"sol-{uuid.uuid4().hex[:8]}"

        # 写入 STM(立即完成,60-120秒后自动提取到 LTM)
        self.client.create_event(
            memory_id=self.memory_id,
            actor_id=actor_id,
            session_id=session_id,
            messages=[
                (f"Problem: {problem}", "USER"),
                (f"Solution: {solution}", "ASSISTANT")
            ]
        )

        return session_id

关键点:search_solutions() 体现了分层检索(先个人后全局)和 STM/LTM 协作(LTM 搜索 + STM 获取原文)两大核心设计。

4.2 Agent System Prompt 设计

在展示 invoke() 函数之前,我们先看 Agent 的 System Prompt 设计。这是 Solutions Memory 发挥作用的关键——通过 Prompt 注入历史成功案例。

System Prompt 结构

SYSTEM_PROMPT = """You are an intelligent customer service agent for an airline.

Your task is to help passengers with their inquiries about flights, bookings, and services.

When reference solutions are provided in <reference_solutions> tags, you MUST:
1. Carefully review the similar cases and their successful resolutions
2. Follow the same service standards and compensation policies
3. Ensure consistency across all customers

Available Tools:
- verify_identity(pnr, last_name): Verify passenger identity
- get_flight_status(flight_number): Check real-time flight status
- change_flight(pnr, new_flight): Change booking (policy-controlled)
- process_refund(pnr, amount, reason): Process refund (policy-controlled)
... (16 tools in total)

Guidelines:
- Always verify passenger identity first
- Reference successful past cases for consistent service
- Follow company policies strictly (managed by Gateway Policy)
"""

Prompt 注入机制

当 Memory B 检索到相似案例时,会将其注入到用户 Prompt 中:

# 用户原始问题
user_prompt = "我的航班延误了4小时,能给我什么补偿?"

# Memory B 检索到的成功案例
reference_solutions = """
案例1 (相似度: 0.87):
  问题: My flight UA2468 is delayed 4 hours, what can I get?
  方案: 您可以选择:1) 全额退款,或 2) 继续乘坐 + 贵宾室使用券 + 200里程积分

案例2 (相似度: 0.76):
  问题: 航班晚点很久,有什么补偿吗?
  方案: 根据延误时长,您可以获得:4小时以上延误可选择全额退款或贵宾室+积分补偿
"""

# 最终传给 Agent 的增强 Prompt
enhanced_prompt = f"""
{user_prompt}

<reference_solutions>
{reference_solutions}

请参考上述历史成功案例,为当前用户提供一致的服务标准。
</reference_solutions>
"""

Agent 如何使用参考案例

当 Agent(Claude 3.5 Sonnet)收到包含 <reference_solutions> 的 Prompt 时,它会:

  1. 识别 XML 标签,理解这是参考信息
  2. 分析历史案例中的补偿标准(贵宾室 + 200里程)
  3. 在生成回复时遵循相同的服务标准
  4. 确保不同用户获得一致的补偿方案

这种设计的优势是透明可控:所有参考信息都在 Prompt 中明确展示,Agent 的决策过程可追溯,不依赖模型的”隐式记忆”。

4.3 invoke() 函数:三步协作流程

工作原理说明

invoke() 是 AgentCore Runtime 的入口函数,负责协调 Memory B、Memory A 和 Agent 三者的协作。下面详细说明每一步的调用过程:

Step 1: 从 Memory B 检索成功案例

  • 调用 solutions_memory.search_solutions(actor_id, query)
  • 内部先搜索个人案例(namespace: /solutions/actors/{actor_id}/sessions/
  • 如果个人案例不足,再搜索全局案例(namespace: /solutions/
  • 过滤相似度 < 0.5 的结果,确保质量
  • 从 LTM 获得 namespace 和 score,再回到 STM 读取完整的 Problem + Solution

Step 2: 格式化并注入到 Prompt

  • 如果找到案例,将每个案例格式化为 “案例X: {problem} → {solution}”
  • <reference_solutions> 标签包裹所有案例
  • 拼接到用户原始问题后面,形成 enhanced_prompt
  • 如果没找到案例,直接使用原始 prompt(降级为无参考模式)

Step 3: 创建 Agent 并调用

  • 调用 create_agent_with_memory(session_id, actor_id) 创建 Agent 实例
  • Agent 创建时自动绑定 Memory A,通过 actor_id + session_id 加载历史对话
  • 调用 agent(enhanced_prompt),将增强后的 Prompt 传给 Agent
  • Agent 综合三重上下文生成回复:
    • System Prompt(服务指南 + 工具列表)
    • Memory B 的成功案例(通过 <reference_solutions> 注入)
    • Memory A 的对话历史(Agent 框架自动加载)

关键设计:Prompt 注入发生在 Agent 推理之前,确保 Agent 能够参考历史最佳实践,而不是每次”重新发明轮子”。

关键代码片段

from src.memory.solutions_memory import SolutionsMemory

# 初始化 Solutions Memory(Memory B)
solutions_memory = SolutionsMemory(memory_id=os.getenv("SOLUTIONS_MEMORY_ID"))

@app.entrypoint
def invoke(payload: dict, context=None):
    prompt = payload.get("prompt", "")
    actor_id = extract_actor_id_from_context(context)

    # Step 1: 从 Memory B 检索成功案例
    solutions = solutions_memory.search_solutions(actor_id=actor_id, query=prompt)

    # 如果找到案例,注入到 Prompt 中作为参考
    if solutions:
        reference = "\n".join([
            f"案例{i}: {s['problem']} → {s['solution']}"
            for i, s in enumerate(solutions, 1)
        ])
        enhanced_prompt = f"{prompt}\n\n<reference_solutions>\n{reference}\n</reference_solutions>"
    else:
        enhanced_prompt = prompt

    # Step 2 & 3: 创建 Agent(自动绑定 Memory A)并调用
    agent = create_agent_with_memory(session_id=get_session_id(context), actor_id=actor_id)
    result = agent(enhanced_prompt)  # Agent 自动加载 Memory A 历史对话

    return {"response": extract_response(result)}

关键设计

  • 搜索失败不影响主流程(降级为无参考模式)
  • 只有 score >= 0.5 的案例才会注入
  • 参考案例用 <reference_solutions> 标签包裹,方便 Agent 识别
  • 每次都执行相同的三步流程,确保行为可预测

4.4 前端点赞按钮:用户反馈机制

工作原理说明

前端使用 Streamlit 实现简单的点赞/点踩按钮。当用户点击”Like”时,触发 handle_feedback_like() 函数,将最近一轮对话(问题 + 回复)存储到 Memory B。这是 Solutions Memory 的质量控制关键——只有用户明确满意的案例才会进入案例库。

存储成功后,立即提示用户”案例已保存,1-2 分钟后生效”,设置合理预期(对应 STM → LTM 的 60-120 秒延迟)。

关键代码片段

import streamlit as st

def render_chat_interface():
    # 用户输入并获得回复
    if user_input := st.chat_input("Type your message..."):
        response = call_agent(user_input)

        # 保存最新一轮对话(用于点赞时存储)
        st.session_state.last_problem = user_input
        st.session_state.last_solution = response

    # 点赞按钮
    if st.button("???? Like"):
        handle_feedback_like()

def handle_feedback_like():
    """处理点赞 - 存储成功案例"""
    session_id = solutions_memory.store_solution(
        actor_id=get_current_actor_id(),
        problem=st.session_state.last_problem,
        solution=st.session_state.last_solution
    )

    st.success("✅ 感谢反馈!此案例已保存,1-2分钟后生效。")

设计细节

  • 只有点赞才存储到 Solutions Memory(Human in the Loop)
  • 存储后提示用户”1-2 分钟后生效”
  • 点踩暂时不处理,但保留入口供未来优化
  • 将质量控制权交给用户,只有真正满意的案例才会进入案例库。

五、测试与验证

5.1 端到端测试

挑战:如何验证跨用户案例共享?

解决方案:显式等待 + 分阶段验证。测试通过 HTTP 调用已部署的 AgentCore Runtime,模拟真实的生产环境。

import timeimport requestsfrom src.memory.solutions_memory import SolutionsMemory
def invoke_agent(prompt: str, session_id: str, access_token: str) -> str:
    """通过 HTTP 调用 AgentCore Runtime"""
    endpoint = f"https://bedrock-agentcore.{AWS_REGION}.amazonaws.com/runtimes/{AGENT_ARN}/invocations"
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {access_token}',
        'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id': session_id
    }
    response = requests.post(endpoint, json={"prompt": prompt}, headers=headers)
    return response.json().get('response', '')
def test_solutions_memory_workflow():
    """端到端测试:跨用户案例共享"""
# Phase 1: 用户 Tom 询问航班延误补偿
    tom_message = "My flight UA2468 is delayed 4 hours, what can I get?"
    response = invoke_agent(tom_message, session_id_1, access_token)

    # 模拟用户点赞,存储成功案例
    session_id = solutions_memory.store_solution(
        actor_id=tom_actor_id,
        problem=tom_message,
        solution=response
    )

    # Phase 2: 等待 LTM 提取(关键步骤)
print("Waiting for LTM extraction (90 seconds)...")
    for i in range(90, 0, -10):
        print(f"  ⏳ {i} seconds remaining...")
        time.sleep(10)

    # Phase 3: 新用户 Lisa 提问类似问题
    lisa_message = "My flight is also delayed, what compensation can I get?"
    response = invoke_agent(lisa_message, session_id_2, access_token)

    # 验证 Lisa 获得与 Tom 一致的补偿方案
assert "lounge" in response.lower() or "贵宾室" in response
    assert "200" in response

    # Phase 4: 验证检索结果
    solutions = solutions_memory.search_solutions(actor_id=lisa_actor_id, query=lisa_message)
    assert len(solutions) > 0 and solutions[0]['score'] >= 0.5
print("✅ Test passed: Solutions Memory works correctly!")

测试输出示例

[Phase 1] User Tom - Delay compensation inquiry...
Response: 根据您的航班延误情况,我可以为您提供以下两个选项...贵宾室使用券 + 200里程积分...
✓ Stored as session: sol-abc456

[Phase 2] Waiting for LTM extraction (90 seconds)...
  ⏳ 90 seconds remaining...
  ⏳ 80 seconds remaining...
  ...
✓ LTM extraction complete

[Phase 3] User Lisa - Similar inquiry...
Response: 参考之前类似情况的成功处理,我建议...贵宾室使用券 + 200里程积分...

[Phase 4] Verifying retrieval...
✓ Found 1 solution(s)
  Score: 0.87
  Problem: My flight UA2468 is delayed 4 hours, what can I get?

✅ Test passed: Solutions Memory works correctly!

测试设计要点

  • 显式等待 90 秒,确保 LTM 提取完成后再进行检索验证
  • 通过 4 个阶段覆盖存储、等待、检索、跨用户共享的完整链路
  • 使用 HTTP 调用而非直接调用函数,模拟真实生产环境

5.2 效果对比

验证引入 Solutions Memory 前后的服务质量指标:

指标 引入前 引入后 变化
1 补偿方案一致性 63% 96% 53%
2 客户满意度(CSAT) 7.2/10 8.9/10 24%
3 投诉率(补偿不一致) 8.30% 1.20% -86%

案例分析:客服 Sarah 的第一天

引入前:Sarah 处理了 5 个航班延误咨询,每个给出的补偿方案都略有不同(因为不知道”标准答案”),收到 2 个客户投诉:”为什么别人有贵宾室,我没有?”

引入后:Sarah 处理同样的 5 个咨询,Agent 自动参考历史成功案例,给出一致的补偿方案(贵宾室 + 200里程),0 投诉。

结论:Solutions Memory 通过用户点赞机制确保案例质量,通过语义搜索实现知识复用,显著提升了服务一致性和客户满意度。

六、总结

本文介绍了 Solutions Memory 的完整实现方案。通过双 Memory 架构,我们让 AI Agent 具备了从成功案例中持续学习的能力。在这个架构中,Memory A 专注于管理对话上下文,Memory B 则负责跨用户的知识共享,两者职责清晰、互不干扰。我们深入理解了 AgentCore Memory 内部的 STM/LTM 两层存储机制,正确处理了 60-120 秒的 LTM 提取延迟。在检索策略上,采用先个人后全局的分层方式,既保证了个性化服务,又实现了知识复用。同时,通过用户点赞驱动的存储机制,确保只有真正有效的案例才会进入知识库。这套方案实现了跨用户的知识共享,打破了数据孤岛,提升了服务的标准化程度,减少了回复的随机性。

Solutions Memory 不仅是一个技术特性,更是企业知识管理的新方式,它将成功经验转化为可检索、可复用的结构化知识,让 AgentCore 具备了轻量级 RAG 的能力。展望未来,这套架构可以进一步扩展:引入案例评分机制追踪引用次数和成功率,让高质量案例获得更高权重;增加自动过期和归档功能,保持知识库的时效性;通过场景分类标签实现更精准的案例匹配;构建可视化管理后台,让运营人员能够审核、编辑和优化案例库。随着案例的不断积累和优化,AI Agent 将真正实现”越用越智能”,为企业提供持续进化的智能服务能力。

完整代码参见:https://github.com/Anya2089/Airline-booking-demo-strandsagent-agentcore-ver2.0-withsolutionmanager

➡️ 下一步行动:

相关产品:

相关文章:

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

延诤

亚马逊云科技Agentic AI 资深产品专家。曾经在联想、58 同城、京东等知名企业担任产研负责人,积累了深厚的行业经验与前沿视野。自加入亚马逊云科技后,致力于生成式 AI 技术领域,专注于推动 AI 在国内及全球企业客户中的实际应用、高效落地与广泛推广。

姬军翔

亚马逊云科技资深解决方案架构师,负责AI Agent相关的产品和技术咨询,超过10年的机器学习系统构建经验。

Raymond Lai

亚马逊云科技解决方案架构师,有超过 10 年的研发及架构设计经验。目前致力于推广 AWS 的技术和各种解决方案。侧重于Agentic/大数据领域的方案。

Fortune Hui

亚马逊云科技解决方案架构师,主要负责服务大型企业客户。致力协助客户及合作伙伴建立大数据平台与生成式人工智慧应用。


AWS 架构师中心:云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用