AWS Machine Learning Blog

Structured memory filtering with metadata in AgentCore Memory

6.9内容质量
Structured memory filtering with metadata in AgentCore Memory

TL;DR · AI 摘要

Structured memory filtering with metadata in AgentCore Memory Artificial Intelligence Structured memory filtering with m...

核心要点

  • 主题聚焦:Structured memory filtering with metadata in Age
  • 来源:AWS Machine Learning Blog,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#后端#安全#产品
打开原文

使用元数据在 AgentCore Memory 中实现结构化记忆过滤 | 人工智能

使用元数据在 AgentCore Memory 中实现结构化记忆过滤

假设您的客户支持代理询问“账单问题”,却收到了技术支援工单、存在收据问题的销售对话以及账单争议等混杂信息。当代理积累数周的交互历史后,团队会遇到检索精度的瓶颈:相似性搜索能找出语义上接近的信息,但无法限定到您实际需要的关键维度,例如问题类型、状态或时间。

Amazon Bedrock AgentCore Memory 是一项全托管的记忆服务,使 AI 代理能够跨对话记住并回忆信息。它通过命名空间将代理记忆记录组织成隔离的作用域(如 clients/client-123),确保每个实体的数据保持独立。您可以阅读关于《在 AgentCore Memory 中大规模组织代理记忆:命名空间设计模式》的博客,了解有关命名空间组织的更多信息。随着记忆数据增长,相关信号会被语义相似但上下文无关的结果淹没,仅靠命名空间的作用域无法将它们区分开。

元数据过滤弥补了这一差距。现在您可以在命名空间隔离的基础上,叠加基于属性的细粒度过滤器,从而在相似性搜索之前,按业务维度(如优先级、部门或时间范围)限定检索范围。在我们基于长期记忆基准(LoCoMo 风格多会话对话)构建的 151 个问题测试集评估中,该方法表现出显著提升。在所有问题类型启用元数据过滤后,整体问答(QA)准确率从 40% 提升至 64%。提升主要集中在依赖上下文边界的问题子集,例如时间限定查询、基于优先级的过滤或部门限定搜索。对于这些问题,准确率从 16% 跃升至 69%。

在本文中,您将学习元数据如何在配置、摄入和检索过程中工作,探索包括多代理和多租户架构在内的企业用例,并发现实施的最佳实践。

命名空间与元数据的结构化

AgentCore Memory 使用命名空间沿主要实体边界组织和隔离记忆。您可以将检索范围限定在特定命名空间(如 clients/client-123/sessionABC 或 patients/patient-456),从而防止代理意外检索到其他客户或患者的数据。命名空间提供了基础的隔离层。有关更多信息,请阅读《命名空间设计模式》博客。

随着部署规模扩大,命名空间内的语义搜索会遇到一些限制。考虑一个拥有每个客户独立命名空间的金融服务代理,其积累了六个月的交互历史。当关系经理要求代理回忆特定客户的“投资组合再平衡讨论”时,命名空间能正确限定搜索范围。但搜索结果会涵盖该客户历史中不同的投资策略、时间段和优先级。代理无法区分上周的高优先级再平衡对话与三个月前的常规咨询。这些信息语义相似,但上下文完全不同。

多租户环境清晰地展示了分层结构。命名空间已经为不同租户提供了完全的数据隔离。在每个租户的命名空间内,IT帮助台代理人员在搜索解决方案模式之前仍需要先筛选工单类型。命名空间在“谁”的维度上实现了逻辑隔离,而元数据过滤则在这些边界内处理更细粒度的分组:类别、解决状态、日期、优先级和标签。

AgentCore 内存中的元数据

AgentCore 内存中的元数据同时作用于短期和长期记忆,遵循包含三个阶段的生命周期:配置、摄入和检索。以下部分将逐步说明元数据在每个内存层级的工作方式,首先从短期记忆开始,然后深入探讨长期记忆的完整三阶段生命周期。

短期记忆中的元数据

在短期记忆层级,您会将基于字符串的键值对附加到事件中,用上下文信息标记交互内容。这些信息本身不属于对话内容,但对后续检索至关重要。

短期记忆元数据支持在事件上使用基于字符串的键值对,可用于过滤。这些标签在提取和整合过程中会传递到长期记忆,并成为可过滤的维度。

长期记忆中的元数据

长期记忆是元数据发挥完整作用的领域。下文描述的三个阶段让您能精确控制结构化上下文的声明、传播和查询方式。简而言之,在配置阶段您声明哪些键是重要的。在摄入阶段,您可以手动附加值或让模型推断值,检索阶段则基于这些键进行过滤。当会话中的多个事件携带相同键时,AgentCore 内存会根据您在 llmExtractionInstruction 中定义的解析行为,将它们合并为一个值。

#### 阶段 1:配置

创建内存资源时,您需要声明要为跨内存记录的快速过滤和检索建立索引的元数据键。在每个内存策略上定义元数据模式,指导 AgentCore 内存如何提取和解析元数据值。已建立索引的键以优化查询过滤的格式存储,而非索引键则与内存记录一起存储以供信息参考。

以下代码创建了一个带有元数据配置的客户支持内存资源:

python
# 示例代码保持原样不翻译
code
response = agentcore_client.create_memory(
    name="CustomerSupportMemory",
    eventExpiryDuration=30,
    indexedKeys=[
        {"key": "priority", "type": "STRING"},
        {"key": "agent_type", "type": "STRING"},
        {"key": "channel", "type": "STRING"},
        {"key": "ticket_id", "type": "STRING"}
    ],
    memoryStrategies=[{
            "semanticMemoryStrategy": {
                "name": "SupportSemanticStrategy",
                "description": "Captures support interaction details",
                "namespaces": ["support/{actorId}"],
                "memoryRecordSchema": {
                    "metadataSchema": [
                        {
                            "key": "priority",
                            "type": "STRING",
							"extractionType": "STRICTLY_CONSISTENT",
                            "extractionConfig": {
                                "llmExtractionConfig": {
                                    "definition": "Issue priority level based on customer impact.",
                                    "llmExtractionInstruction": "LATEST_VALUE",
                                    "validation": {
                                        "stringValidation": {
                                            "allowedValues": ["critical", "high", "medium", "low"]
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "key": "agent_type",
                            "type": "STRING",
							"extractionType": "STRICTLY_CONSISTENT",
                            "extractionConfig": {
                                "llmExtractionConfig": {
                                    "definition": "Support agent classification.",
                                    "llmExtractionInstruction": "Prefer the most specialized agent type. Hierarchy: specialist > tier3 > tier2 > tier1 > bot."
                                }
                            }
                        },
                        {
                            "key": "sentiment",
                            "type": "STRING",
							"extractionType": "STRICTLY_CONSISTENT",
                            "extractionConfig": {
                                "llmExtractionConfig": {
                                    "definition": " Customer sentiment during the interaction. ",
                                    "llmExtractionInstruction": "Classify the overall customer sentiment based on tone and language used.",
                                    "validation": {
                                        "stringValidation": {
                                            "allowedValues": ["positive", "neutral", "negative", "frustrated"]
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            }
    }]
)

每个模式条目中的extractionConfig在元数据提取过程中指导大型语言模型(LLM)。definition字段描述该字段的含义,而llmExtractionInstruction提供额外的提取指导和冲突解决行为。内置的LATEST_VALUE操作提供基于时间的新鲜度解决方式,而自定义自然语言指令处理领域特定逻辑。可选的validation字段对提取值进行约束,例如STRING和STRINGLIST的allowedValues、STRINGLIST的maxItems,或NUMBER的min-max范围。这可保持下游过滤的一致性。请注意(在前面的代码示例中),sentiment在模式中被定义但未声明为索引键。因此,LLM将完全根据对话内容推导其值,并将其填充到提取记录中,但不能在元数据过滤表达式中使用。

请注意,ticket_id在内存级别被声明为索引键,但未包含在策略的memoryRecordSchema中。此键不会被填充到提取的内存记录中。只有在策略的memoryRecordSchema中定义的键才会在提取后出现在记录中。未在模式中声明的索引键即使在原始事件中存在匹配值,也会被省略。如果需要某个键出现在提取记录中,必须在模式中有对应的条目。

您可以在AgentCore Memory文档中了解更多关于配置约束的信息。除了配置的元数据键外,系统生成的dateTimeValue字段(x-amz-agentcore-memory-createdAt和x-amz-agentcore-memory-updatedAt)支持基于时间的过滤(用于处理内存衰减,如适用),无需声明datetime索引键即可使用BEFORE和AFTER操作符。

#### 已知值的严格一致性元数据

某些元数据键是组织分类器,如department、compliance_level或interaction_type。这些键在事件创建时携带调用应用程序已知的值,必须严格按照提供的值出现在最终的内存记录中。LLM提取会为这些键引入变异性:同一对话可能在一条记录中生成"eng",在另一条记录中生成"Engineering",事件上提供的值可能在提取过程中被重新推断。AgentCore Memory通过STRICTLY_CONSISTENT提取类型(LLM_INFERRED提取类型的选项)解决此问题。当以这种方式配置键时,事件上提供的值在提取和合并过程中保持不变,LLM不会参与该键的处理。

code
"metadataSchema": [
    {
        "key": "department",
        "type": "STRING",
        "extractionType": "STRICTLY_CONSISTENT"
    },
    {
        "key": "priority",
        "type": "STRING",
        "extractionType": "STRICTLY_CONSISTENT"
    }
    {
        "key": "topic",
        "type": "STRING",
        "extractionType": "LLM_INFERRED"
        "extractionConfig": {
            "llmExtractionConfig": {
                "definition": "Primary topic of the conversation",
                "llmExtractionInstruction": "Identify the main topic discussed"
            }
        }
    }
]

STRICTLY_CONSISTENT键的作用不仅限于跳过推断。它们会划分提取过程。具有相同值的事件始终会被一起提取,并与具有不同值的事件隔离,因此不会出现关于哪个值属于哪条记录的歧义。

这种隔离机制也决定了记录的整合方式。由一组确定性值生成的记录只会与具有相同值的记录进行整合。携带 department: "billing" 的记录不会与携带 department: "engineering" 的记录合并,即使它们的内容在语义上非常相似。

考虑一个客户问题涉及多个部门的支持会话场景:

code
# 事件 1:初始账单咨询
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
                "content": {"text": "我在企业计划的上个月发票中看到了重复收费。"}}}],
    metadata={"department": {"stringValue": "billing"}, "priority": {"stringValue": "high"}}
)

# 事件 2:仍处于账单上下文
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
                "content": {"text": "这些费用是在我们上周从标准版升级到企业版后出现的。"}}}],
    metadata={"department": {"stringValue": "billing"}, "priority": {"stringValue": "high"}}
)

# 事件 3:升级至工程部门(技术根本原因)
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
                "content": {"text": "你们团队发现了一个配置错误,在层级迁移期间触发了重复收费。"}}}],
    metadata={"department": {"stringValue": "engineering"}, "priority": {"stringValue": "high"}}
)

如果没有确定性隔离,这三个事件将被合并提取。LLM可能会非确定性地将 department: "billing"、department: "engineering",甚至 department: "account_management" 分配给最终的事实。当在 department 字段配置了 STRICTLY_CONSISTENT 时:

  • 事件 1 和 2 共享相同的确定性值(department=billing,priority=high),会被合并提取。生成的记忆记录携带这些精确的值。
  • 事件 3 的确定性值不同(department=engineering,priority=high),会独立提取。其记录精确携带 department: "engineering"。

当账单代理使用 department=billing 查询时,只会检索到关于重复收费和层级升级的事实,而不会包含工程上下文中的配置错误细节。整合过程也遵循相同的隔离原则:账单记录和工程记录不会合并,即使它们的内容在语义上相关。

这使得确定性键成为合规隔离(如 HIPAA 与标准记录不混合)、组织路由(部门范围检索且无交叉污染)以及任何需要在事件发生时保留精确值的应用场景的理想选择。

配置为 STRICTLY_CONSISTENT 的键还必须在内存资源上声明为索引键。整合通过索引键的元数据过滤进行范围限定,这种限定正是防止不同确定性值记录合并的关键。对于缺少确定性元数据键值的事件,仍然会被处理,只是最终记录中该键会缺失。

AgentCore Memory 每个策略最多支持三个 STRICTLY_CONSISTENT 键。这些键中的每一个都会占用内存资源上的十个索引键槽位,且一旦添加索引键就无法删除。如果计划使用此功能,请提前预留槽位。

#### 第二阶段:数据摄入

配置完元数据模式后,下一步是通过附加元数据的方式摄入数据。元数据通过两条路径进入系统。事件驱动路径将元数据附加到事件上,AgentCore Memory 会根据提取指令自动通过提取和整合(基于提取指令)将其传播到长期记忆记录中:

code
# 初始接触事件
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-001",
    eventTimestamp="2024-01-23T10:00:00Z",
    payload=[{
            "conversational": {
                "role": "USER",
                "content": {"text": "I have a question about my bill"}
            }
    }],
    metadata={
        "priority": {"stringValue": "medium"},
        "channel": {"stringValue": "email"},
        "ticket_id": {"stringValue": "TKT-5001"}
    }
)

当会话中的多个事件对同一键具有不同值时,LLM 会使用该模式条目中的 llmExtractionInstruction 解决冲突。例如,如果后续的工单事件将优先级从 "medium" 升级为 "high",LATEST_VALUE 指令会保留 "high" 优先级值(图3)。像 agent_type 字段中的自定义层级会保留处理链中最专业的代理(图3)。请注意,只有在策略的 memoryRecordSchema 中定义的元数据键才会填充到最终的记忆记录中。不在模式中的事件元数据键在提取过程中会被忽略。

确定性键遵循不同的摄入路径。事件上提供的值会直接写入最终记录。由于 AgentCore Memory 在提取前会根据确定性键值对事件进行分组,因此不需要 LLM 推理或冲突解决。标记为 department: "engineering" 的事件和标记为 department: "finance" 的事件会以独立批次处理,整合操作在这些组内进行。因此,包含 compliance_level: "hipaa" 的记录不会与标记为 compliance_level: "standard" 的记录合并。这就是为什么确定性提取非常适合合规隔离和路由键。

如果事件未设置确定性键,则该事件的分组中会省略该键,最终记录中也不会包含该键。直接写入路径(BatchCreateMemoryRecords 和 BatchUpdateMemoryRecords)完全绕过提取过程,因此 STRICTLY_CONSISTENT 提取类型对其没有影响。请像目前对这些 API 的操作一样,直接提供元数据。

对于模式键的值生成,事件元数据不是严格必需的。当模式键在原始事件中没有匹配的元数据时,LLM 会完全根据对话内容,使用键的定义和 llmExtractionInstruction 推导出值。例如考虑一个包含三个键的模式;事件中未提供任何键:

code
# 在策略上定义的模式键
"metadataSchema": [
    {"key": "domain", "type": "STRING", "definition": "讨论的主要技术领域。。"},
    {"key": "tags", "type": "STRINGLIST", "definition": "引用的AWS服务。。"},
    {"key": "priority", "type": "NUMBER", "definition": "重要性等级1到10。。"}
]

# 创建无元数据的事件
agentcore_client.create_event(
    memoryId="mem-abc123",
    actorId="user-1",
    sessionId="session-001",
    payload=[{"conversational": {"role": "USER",
                "content": {"text": "如何在两个账户之间设置VPC对等连接?"}}}]

    # 无元数据参数
)

从内容中推断出的三个字段被填充到提取的内存记录中:

code
{
    "content": {"text": "用户询问如何在两个AWS账户之间设置VPC对等连接。"},
    "metadata": {
        "domain": {"stringValue": "Networking"},
        "tags": {"stringListValue": ["VPC"]},
        "priority": {"numberValue": 7.0}
    }
}

验证规则仍然适用:无论值来自事件元数据还是内容推断,LLM的输出都会受到您声明的allowedValues的限制。这种隐式提取对于仅存在于对话本身中的维度非常有用,例如主题分类、情感或重要性,而无需调用者在事件创建时提供这些信息。

对于直接创建内存记录的情况,例如导入知识库或从外部系统导入预处理记录时,您需要显式提供元数据:

code
agentcore_client.batch_create_memory_records(
    memoryId="mem-support-abc123",
    records=[{
            "requestIdentifier": "import-001",
            "namespaces": ["support/customer-456"],
            "content": {"text": "客户倾向于通过电话解决紧急账单问题"},
            "timestamp": "2024-01-15T10:00:00Z",
            "metadata": {
                "priority": {"stringValue": "high"},
                "agent_type": {"stringValue": "billing_agent"},
                "channel": {"stringValue": "phone"},
                "ticket_id": {"stringValue": "TKT-7890"}
            }
    }]
)

批量创建记录的元数据行为取决于您是否在每条记录上提供可选的memoryStrategyId。

当提供memoryStrategyId时,服务会将输入元数据与该策略的memoryRecordSchema进行过滤。只有在模式中定义的键会被存储在记录中。其他键会被静默丢弃,包括不在模式中的索引键和未在任何地方声明的键。这为您提供了模式强制的一致性,确保批量创建的记录与事件驱动提取生成的记录具有相同的元数据结构。

当省略memoryStrategyId时,服务会按原样将元数据键存储在记录中。这包括索引键、策略模式中的键以及既不是索引键也不是模式中键的键。然而,只有索引键可以被过滤。尝试对非索引键进行过滤会返回ValidationException。非索引键仍然可以在getMemoryRecord和listMemoryRecords响应中看到,但不能用于过滤表达式。

#### 第三阶段:检索

code

在您的记忆记录中元数据已建立索引并填充后,现在可以结合语义搜索与元数据过滤器来限定搜索结果范围。AgentCore Memory采用预过滤架构:元数据过滤器会在向量相似性搜索执行前应用。这首先缩小候选集范围,使K近邻(KNN)搜索能在更小且更相关的子集上运行。请注意下方示例中,结果先限定为仅包含今年的高优先级记录,再与"billing issues"进行语义匹配。

results = agentcore_client.retrieve_memory_records( memoryId="mem-support-abc123", namespace="support/customer-123", searchCriteria={ "searchQuery": "billing issues", "topK": 10, "metadataFilters": [{ "left": {"metadataKey": "priority"}, "operator": "EQUALS_TO", "right": {"metadataValue": {"stringValue": "high"}} }, { "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"}, "operator": "AFTER", "right": {"metadataValue": {"dateTimeValue": "2026-01-01T00:00:00Z"}} }] } )

code

请注意如何通过自定义元数据过滤器与系统生成的时间戳结合,在相似性搜索执行前沿两个维度(业务优先级和时间新鲜度)压缩候选集。AgentCore Memory提供多种操作符以覆盖常见查询模式。

AgentCore Memory还会使用x-amz-agentcore-memory-*前缀添加服务生成的元数据字段,您可以通过相同过滤操作符查询这些字段,从而支持无需自定义时间戳键的时域查询。

#### 为什么时间过滤能带来最大的准确率提升

在我们的实验中,带有时间约束的查询在使用元数据过滤后显示出最大的准确率提升。使用BEFORE和AFTER操作符的结构化DATETIME过滤可将其转换为确定性索引查找,避免歧义。

对于非搜索类检索,ListMemoryRecords提供不带语义搜索的元数据过滤功能。这在需要枚举符合特定元数据条件的记录而非查找语义相似内容时非常有用。例如,您可以列出某个客户的高优先级记录,或提取标记为特定部门的记录。

以下示例列出特定日期后创建的高优先级记录:

records = agentcore_client.list_memory_records( memoryId="mem-support-abc123", namespace="support/customer-123", metadataFilters=[ { "left": {"metadataKey": "priority"}, "operator": "EQUALS_TO", "right": {"metadataValue": {"stringValue": "high"}} }, { "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"}, "operator": "AFTER", "right": {"metadataValue": {"dateTimeValue": "2024-01-20T00:00:00Z"}} } ] )

code

## 企业应用场景

以下示例展示元数据过滤如何解决跨行业常见的企业检索挑战。

### 多租户SaaS应用

### 医疗健康与合规敏感领域

如果您的医疗AI代理需要跨多个部门管理患者互动,类似 patients/patient-123 的命名空间已为每位患者的记忆提供隔离。但在单个患者命名空间内,对“用药史”的广泛搜索会返回所有部门的结果:心脏病学、内分泌学和初级护理。通过索引 department、record_type、severity 和 symptoms 等元数据键,您的代理可以在患者命名空间内沿多个临床维度缩小检索范围。

results = agentcore_client.retrieve_memory_records( memoryId="mem-healthcare-001", namespace="patients/patient-123", searchCriteria={ "searchQuery": "medication history", "topK": 10, "metadataFilters": [ { "left": {"metadataKey": "department"}, "operator": "EQUALS_TO", "right": {"metadataValue": {"stringValue": "Cardiology"}} }, { "left": {"metadataKey": "symptoms"}, "operator": "CONTAINS", "right": {"metadataValue": {"stringValue": "chest pain"}} } ] } )

code

症状 STRINGLIST 上的 CONTAINS 操作符会检查列表是否包含指定值,从而将检索范围限定到特定临床指标。

在合规性方面,元数据过滤有助于满足监管要求:

- **HIPAA**:部门级过滤确保心内科医生的查询仅检索心内科相关记录,降低出现无关临床数据的风险。
- **GDPR**:对 x-amz-agentcore-memory-createdAt 的元数据过滤可识别超出保留期限的记录。您可通过 DeleteMemoryRecord 或命名空间级删除处理数据删除。
- **SOC 2**:系统生成的时间戳提供可验证的追溯记录,证明检索范围正确。您还可以对 data_classification 键(值如 PII、confidential 或 general)进行索引,实现敏感性感知检索。

### 基于优先级的客户支持路由

如果您的支持组织需要处理成千上万的工单,就需要能够根据紧急程度和升级状态对上下文进行优先级排序的代理。元数据通过结合自定义元数据过滤器与系统时间戳过滤器,支持“查找过去30天内的高优先级账单记录”等检索模式。在实时会话中,代理可以快速提取最相关的高优先级上下文,而无需浏览已解决的低优先级问题。当工单从低级升级为关键问题时,合并规则会将元数据与最新升级状态保持一致,而非初始分类。

### 金融服务与时间精度

金融数据本质上具有时间敏感性。“Q3投资组合讨论”的查询必须返回特定于Q3的记录,而非其他季度的记录。财富管理代理可以通过DATETIME过滤与自定义元数据结合,实现精确检索范围,帮助您避免其他资产类别和时间段的干扰:

results = agentcore_client.retrieve_memory_records( memoryId="mem-wealth-001", namespace="clients/client-789", searchCriteria={ "searchQuery": "portfolio rebalancing strategy", "topK": 10, "metadataFilters": [ { "left": {"metadataKey": "asset_class"}, "operator": "EQUALS_TO", "right": {"metadataValue": {"stringValue": "equities"}} }, { "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"}, "operator": "AFTER", "right": {"metadataValue": {"dateTimeValue": "2024-07-01T00:00:00Z"}} }, { "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"}, "operator": "BEFORE", "right": {"metadataValue": {"dateTimeValue": "2024-09-30T23:59:59Z"}} } ] } )

code

### 多代理系统与内存协调

随着代理系统逐渐成熟并变得更为普及,元数据在多个代理如何通过共享内存层进行协作和协调方面变得至关重要。

- **代理来源追踪**:在多代理工作流中,了解哪个代理创建了某条记忆对于建立信任、调试和路由至关重要。通过索引source_agent、agent_role和workflow_step等关键字段,监督代理可以筛选出特定代理存储的记忆。例如,您可以在客户命名空间内通过source_agent:"billing_agent"过滤,回答“上一次会话中账单代理得出了什么结论?”

- **代理限定的内存可见性**:在多代理流水线(分诊机器人→一级代理→专家代理)中,可通过元数据控制每个代理可检索的记忆范围。分诊机器人写入的记忆会标记workflow_step:"triage"。处理升级请求的专家代理可通过workflow_step:"triage"筛选来了解初始分类,或通过agent_role:"tier1"筛选来查看已尝试的解决方案,避免重复工作。agent_role的自定义llmExtractionInstruction会将记忆整合为体现最高专业水平处理的结果,而非仅显示最近一次操作。

- 在检索增强生成(RAG)管道中实现元数据门控检索:检索代理通过 source_type: "knowledge_base" 过滤以实现事实依据,个性化代理通过 interaction_type: "preference" 过滤以获取用户特定上下文,安全代理通过 content_flag: "reviewed" 过滤以获取经过审核的内容。三个代理查询相同命名空间但获得完全不同的结果集,而无需管理多个内存存储。

## 元数据模式演进

生产环境中的内存系统并非静态,元数据模式需要随着所服务的应用程序同步演进。AgentCore Memory 通过仅添加的更新模型支持模式演进。您可以根据需要向现有内存资源添加新的索引元数据键:

agentcore_client.update_memory( memoryId="mem-support-abc123", addIndexedKeys=[ {"metadataKey": "customer_segment", "metadataValueType": "STRING"} ] )

code

新键立即可用于新事件和内存记录。现有记录不会自动获得新字段,但随着旧记忆与新记忆合并时,它们会自然获取新元数据。您无法删除已索引的键,这有助于防止现有数据的过滤能力意外丢失。您可以自由添加、删除或修改策略级元数据模式中非索引键,以适应不断变化的提取需求。

## 最佳实践

从代理所需的过滤维度入手。避免一开始就索引所有可能的元数据字段。每个索引字段都会占用一个索引键配额,并在写入和读取路径上增加成本:写入时需要更多处理工作,读取时需要进行查询压缩。建议从3到5个直接影响检索质量的键开始,随着具体需求出现再逐步添加。

编写清晰具体的定义。定义字段和 llmExtractionInstruction 共同构成LLM接收的元数据提取主要指令。不要写成“工单的优先级”,而应写成“基于客户影响的优先级级别。服务中断影响生产环境时使用'critical',性能下降时使用'high',功能请求使用'medium',文档或界面问题使用'low'”。

选择与领域语义匹配的合并规则。LATEST_VALUE 是大多数字段的安全默认值,但并非总是正确。在支持升级流程的 agent_type 中,应保留最资深的代理类型而非最新类型。自定义合并指令可以表达这种领域逻辑。

通过验证规则约束LLM输出。在验证字段中定义 allowedValues 以强制使用受控词汇表。如果没有验证,LLM可能会为相同概念生成“High”、“high”、“HIGH”或“critical”等不一致值,导致下游过滤匹配失败。

为事件驱动路径设计元数据。对于在事件发生时已知且在会话内保持不变的键(如部门或租户等级),将元数据附加到事件,让 AgentCore Memory 通过提取自动处理冲突解决和合并。将直接批量API路径保留给需要批量导入和预处理内容的场景,此时您已经知道正确的元数据值。

在策略层面规划元数据模式。每个记忆策略可以拥有独立的元数据模式,使不同策略能够以不同方式提取和处理相同键。语义策略可能使用自定义提取指令从对话上下文中分类优先级,而摘要策略可能使用针对摘要特定元数据优化的定义。这种灵活性支持按策略优化元数据处理,同时不损害共享的索引键基础设施。

在批量创建记录时要谨慎使用memoryStrategyId。当在批量创建请求中包含memoryStrategyId时,服务会将输入元数据过滤为该策略模式中的键,其他键会被静默丢弃。这有助于强制保持与提取生成记录的一致性。如果省略该参数,负载中的元数据将原样存储。根据使用场景选择:对于应与提取记录保持一致的记录使用模式强制一致性,或对于需要外部管理元数据的批量导入使用完全控制。

使用非索引模式键进行上下文丰富。并非每个元数据键都需要可过滤。未声明为索引键的模式键仍会填充到提取记录中,并在get和list响应中可见,但无法用于过滤表达式。这对于需要丰富记录以供下游使用(如情感、摘要备注或来源URL)的元数据非常有用,同时不会消耗索引键配额。将索引键保留给需要主动过滤的维度。

对已知值使用确定性提取。如果某个键代表在事件创建时代理已知的固定组织属性(如部门、租户层级或合规范围),请将其配置为STRICTLY_CONSISTENT并在每个事件中提供。这可确保结果记录中的精确值,并消除LLM提取可能引入的归一化偏差(如“eng”与“Engineering”的差异)。将llmExtractionConfig保留给必须从对话内容中推断的维度(如情感或主题)。

避免以下反模式:

- 不要对描述或全名等高基数自由文本字段进行索引,这些字段会膨胀索引但不提供有用的过滤边界。

- 不要使用元数据存储每次交互都会变化的值;元数据最适合用于稳定或缓慢变化的属性。

- 不要仅通过元数据实现命名空间隔离。没有命名空间隔离的tenant_id元数据字段是一种依赖惯例的安全模型,任何遗漏的过滤都会导致该模型失效。

## 结论

AgentCore Memory中的元数据过滤解决了根本的检索挑战。命名空间已通过用户、租户或项目等主要实体隔离记忆。在命名空间作用域之上叠加结构化元数据过滤,可以在相似性匹配运行前将代理的检索范围缩小到精确的上下文边界,从而显著提高准确性,并为合规性、基于优先级的上下文管理和细粒度组织过滤提供实用基础。基于LLM的提取避免了手动标记的负担,而可配置的提取指令则能在大规模场景中处理元数据传播和冲突解决。

要开始使用,请确定三到五个对您的使用案例的检索质量影响最直接的过滤维度。首先使用虚拟内存资源进行概念验证(PoC),以测试相关策略,然后根据具体需求扩展模式。以下资源提供实际操作指南:

- Amazon Bedrock AgentCore 文档:  
- AgentCore Memory 代码示例:  
- 关于 Amazon Bedrock AgentCore Memory 的博客:构建上下文感知代理  

## 关于作者  
'"`