

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 长期记忆的结构化元数据
<a name="long-term-memory-metadata"></a>

Amazon Bedrock M AgentCore emory 中的元数据筛选允许您向长期内存记录添加结构化属性。您可以使用这些属性来缩小检索期间返回的记录范围。命名空间已经按主要实体（用户、租户、患者、客户）隔离了内存。但是，在单个命名空间中，广泛的语义搜索会返回所有含义接近的内容。使用元数据筛选，您只能检索与特定属性值匹配的结果。例如，您只能检索高优先级记录，只能检索来自特定部门的记录，或者只能检索在给定时间范围内创建的记录。

通过元数据过滤，您可以：
+ 按命名空间内的业务维度（优先级、部门、渠道、时间范围）进行范围检索
+ 在创建时将结构化元数据附加到事件和内存记录
+ 让大型语言模型 (LLM) 在内存摄取期间自动从对话内容中提取元数据
+ 将 LLM-extracted 值限制为特定值以实现一致的过滤
+ 在`RetrieveMemoryRecords`或应用`AND`逻辑时`ListMemoryRecords`，每个查询最多可组合 5 个过滤器
+ 过滤系统生成的时间戳 (`x-amz-agentcore-memory-createdAt`,`x-amz-agentcore-memory-updatedAt`)，无需声明额外的索引密钥

**Topics**
+ [开始使用](#long-term-memory-metadata-getting-started)
+ [重要概念](#long-term-memory-metadata-concepts)
+ [先决条件](#long-term-memory-metadata-prerequisites)
+ [第 1 步：使用索引密钥和元数据架构创建内存](#long-term-memory-metadata-configure)
+ [步骤 2：验证配置](#long-term-memory-metadata-configure-step2)
+ [第 3 步：在摄取期间添加元数据](#long-term-memory-metadata-ingest)
+ [第 4 步：使用元数据过滤器进行查询](#long-term-memory-metadata-query)
+ [第 5 步：改进您的元数据架构](#long-term-memory-metadata-evolve)
+ [配额](#long-term-memory-metadata-quotas)
+ [最佳实践](#long-term-memory-metadata-best-practices)

## 开始使用
<a name="long-term-memory-metadata-getting-started"></a>

设置元数据筛选涉及五个步骤：

1.  **使用索引密钥和元数据架构**创建内存—
   +  **索引密钥 **-使用`CreateMemory`（或`UpdateMemory`）声明要筛选的元数据密钥（例如，、`priority``channel`、`tags`）。每个内存最多可以声明 10 个索引密钥。索引键定义过滤器表达式中可查询的属性。一旦添加了索引密钥，就无法将其删除。
   +  **元数据架构 ** — 定义策略以控制 LLM 如何从对话中提取价值。`metadataSchema`该架构指定要提取哪些密钥、如何解决事件间的冲突以及要应用的验证约束条件。元数据架构是可选的——没有元数据架构的策略不执行元数据提取。

1.  **验证配置 **-用于`GetMemory`确认您的索引密钥和策略元数据架构设置正确。

1.  **在摄取期间添加元数据 ** — 使用附加可选元数据发送事件`CreateEvent`，或直接使用`IngestData`附加可选元数据提交内容；或使用直接在记录上提供元数据。`BatchCreateMemoryRecords`对于基于提取的提取（`CreateEvent`和`IngestData`），LLM 会自动提取和填充生成的内存记录上的元数据。这种提取基于策略的元数据架构和提交的内容，即使没有附加元数据也是如此。

1.  **使用元数据过滤器进行查询 **-使用 `metadataFilters` on`RetrieveMemoryRecords`（带预筛选的语义搜索）或`ListMemoryRecords`（仅限元数据筛选）来限定结果范围。

1.  **随着时间的推移改进架构 ** — 随着筛选需求的增长，添加新的索引密钥或修改策略元数据架构。

后续部分将详细介绍每个步骤。

## 重要概念
<a name="long-term-memory-metadata-concepts"></a>

### 索引元数据密钥
<a name="long-term-memory-metadata-indexed-keys"></a>

 **索引密钥**在中的内存资源级别上声明`CreateMemory`（或稍后通过添加`UpdateMemory`）。索引密钥以针对快速查询筛选进行了优化的格式存储。在`metadataFilters`和中只能查询索引密钥。`ListMemoryRecords` `RetrieveMemoryRecords`

以下示例声明了两个索引密钥：

```
{
  "indexedKeys": [
    { "key": "priority", "type": "STRING" },
    { "key": "tags",     "type": "STRINGLIST" }
  ]
}
```

支持的`type`值：`STRING`、`STRINGLIST`、`NUMBER`。

密钥必须匹配`^[a-zA-Z0-9\s._:/=+@-]*$`（最多 128 个字符）。

添加索引密钥不会回填现有记录。只有在声明密钥之后创建或更新的记录才会为该密钥编制索引。有关架构随时间演变的更多详细信息，请参阅[第 5 步：改进您的元数据架构](#long-term-memory-metadata-evolve)。

### 元数据架构（每种策略）
<a name="long-term-memory-metadata-schema"></a>

内存策略可以选择在中**声明**元数据架构`memoryRecordSchema.metadataSchema`。元数据架构告诉LLM在生成内存记录时要从对话内容中提取哪些元数据。在事件驱动的提取过程中，只有策略元数据架构中定义的密钥才会填充到生成的内存记录中。

架构中的每个条目都定义：
+  **`key`**— 元数据密钥名称。如果此密钥也被声明为索引键，则提取的值是可筛选的。如果它不是索引键，则该值仍会填充在记录中并在`GetMemoryRecord`和`ListMemoryRecords`响应中可见，但不能在过滤器表达式中使用。
+  **`type`**— 值类型 (`STRING`,`STRINGLIST`,`NUMBER`)。
+  **`definition`**（必填）— 字段所代表内容的自然语言描述。具体一点——不是 * “优先级”，*写上 * “基于客户影响的问题优先级”。值范围从严重（最严重）到低（最不严重）。”* 
+  **`llmExtractionInstruction`**（可选）— 有关 LLM 应如何提取或解析价值观的更多指导。您可以使用内置的`LATEST_VALUE`（保留最新的值），也可以提供自定义的自然语言说明，例如 * “根据业务影响进行分类：`critical`用于影响生产的服务中断、`high`性能下降、功能请求、`medium``low`文档或表面问题”。*
+  **`validation`**（可选）— 将 LLM 的输出限制为一组受控值。未经验证，LLM 可能会产生`"High"`或`"HIGH"`针对相同概念的过滤器匹配中断。`"high"`

以下示例显示了带有验证的元数据架构条目：

```
{
  "metadataSchema": [
    {
      "key": "priority",
      "type": "STRING",
      "extractionConfig": {
        "llmExtractionConfig": {
          "definition": "Issue priority level based on customer impact. Values range from critical (most severe) to low (least severe).",
          "llmExtractionInstruction": "LATEST_VALUE",
          "validation": {
            "stringValidation": {
              "allowedValues": ["critical", "high", "medium", "low"]
            }
          }
        }
      }
    }
  ]
}
```

按类型划分的验证选项：


| Type | 验证 | 说明 | 
| --- | --- | --- | 
|  `STRING`  |  `stringValidation.allowedValues`  | 限制为固定集合（最多 10 个值，每个值最多 256 个字符，匹配`^[a-zA-Z0-9\s._:/=+@-]*$`） | 
|  `STRINGLIST`  |  `stringListValidation.allowedValues`  | 将列表成员限制为固定集合（最多 10 个值，每个值最多 256 个字符，匹配`^[a-zA-Z0-9\s._:/=+@-]*$`） | 
|  `STRINGLIST`  |  `stringListValidation.maxItems`  | 列表中的最大项目数 (1—5) | 
|  `NUMBER`  |  `numberValidation.minValue`  | 允许的最小值 | 
|  `NUMBER`  |  `numberValidation.maxValue`  | 允许的最大值 | 

### 确定性元数据（STRICTLY\_CONSIFENT 提取类型）
<a name="long-term-memory-metadata-deterministic"></a>

确定性元数据密钥包含应用程序在创建事件时已经知道的值。这些值未经修改即可精确复制到生成的内存记录中。诸如`department``compliance_level`、或之类的组织分类器`agent_id`不应由 LLM 推断。LLM 推理引入了可变性。例如，同一对话可以在一条记录`"eng"`上生成，另一条记录`"Engineering"`上可以生成。

对于这些密钥，请在元数据架构条目`STRICTLY_CONSISTENT`中设置为`extractionType`。通过提取和合并，事件上提供的值将保持不变。该密钥不向 LLM 咨询。

以下 JSON 显示了同时具有`STRICTLY_CONSISTENT`和`LLM_INFERRED`提取类型的元数据架构：

```
{
  "metadataSchema": [
    {
      "key": "department",
      "type": "STRING",
      "extractionType": "STRICTLY_CONSISTENT"
    },
    {
      "key": "compliance_level",
      "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"
        }
      }
    }
  ]
}
```

省略时`extractionType`，默认值为`LLM_INFERRED`。

#### 提取和巩固隔离
<a name="long-term-memory-metadata-deterministic-isolation"></a>

 `STRICTLY_CONSISTENT`按键的作用不仅仅是跳过 LLM 推断。它们在提取过程中按其确定性值对事件进行分组。具有不同值的事件将单独处理。合并遵循同样的规则。来自一个值组的记录永远不会与另一个值组的记录合并。

以下 Python 示例显示了具有两个确定性密钥（`department`和`priority`）的支持会话：

```
# Event 1: high-priority billing inquiry
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
        "content": {"text": "I'm seeing duplicate charges on my invoice and it's blocking our deployment."}}}],
    metadata={
        "department": {"stringValue": "billing"},
        "priority": {"stringValue": "high"}
    }
)

# Event 2: also high-priority billing (same deterministic values as Event 1)
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
        "content": {"text": "The charges appeared after we upgraded from standard to enterprise tier last week."}}}],
    metadata={
        "department": {"stringValue": "billing"},
        "priority": {"stringValue": "high"}
    }
)

# Event 3: high-priority engineering (same priority, different department)
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
        "content": {"text": "Your team found a provisioning bug that triggered the duplicate charge."}}}],
    metadata={
        "department": {"stringValue": "engineering"},
        "priority": {"stringValue": "high"}
    }
)

# Event 4: low-priority billing (same department as Events 1-2, different priority)
agentcore_client.create_event(
    memoryId="mem-support-abc123",
    actorId="customer-123",
    sessionId="session-escalation-001",
    payload=[{"conversational": {"role": "USER",
        "content": {"text": "Also, can you update the billing contact email on file when you get a chance?"}}}],
    metadata={
        "department": {"stringValue": "billing"},
        "priority": {"stringValue": "low"}
    }
)
```

系统按所有确定性键值的精确组合对事件进行分组：
+ 活动 1 和 2 共享`department=billing, priority=high`。它们一起提取。
+ 事件 3 的不同之处在于`department`。尽管共享，但它是单独提取`priority=high`的。
+ 事件 4 的不同之处在于`priority`。尽管共享，但它是单独提取`department=billing`的。

所有确定性键值都必须匹配才能对事件进行分组。带有 AND `department=billing` 的查询仅`priority=high`返回紧急重复的收费事实。其他事件位于不同的分区中。合并期间，来自不同值组合的记录永远不会合并。

#### 约束
<a name="long-term-memory-metadata-deterministic-constraints"></a>


| 约束 | Detail | 
| --- | --- | 
| 每个策略的最大确定性密钥 | 3 | 
| 密钥类型 | 必须是 `STRING`  | 
| 必须编入索引 | 密钥还必须在内存中声明 `indexedKeys`  | 
| 没有 `extractionConfig`  |  `STRICTLY_CONSISTENT`密钥不能有`extractionConfig`。该值来自事件，而不是 LLM。 | 
| 支持的策略 | 语义、用户偏好和情节策略（包括自定义覆盖）。摘要策略不支持。 | 
| 缺失值 | 如果事件到达时没有确定性键的值，则该键将从该事件的分组中省略并且在结果记录中不存在。 | 

**重要**  
更改配置为哪些密钥`STRICTLY_CONSISTENT`会更改用于提取和合并的分组。在先前配置下创建的记录将与在新配置下创建的记录隔离。在采集事件之前规划您的确定性密钥配置。

### 索引密钥和架构密钥如何交互
<a name="long-term-memory-metadata-key-relationships"></a>

索引密钥和架构密钥之间的关系决定了元数据的行为：
+  **架构中已索引 \+ ** — 密钥由 LLM 在提取的记录中填充，可在查询*表达*式中进行筛选。对于您既要提取又要筛选的密钥，这是最常见的配置。
+  **已索引 \+ 不在架构中 ** — 在事件驱动的提取过程中，密钥*未*填充到记录中。此密钥上的过滤器不返回提取记录的结果。要填充这些密钥，请使用批处理 API（`BatchCreateMemoryRecords`或`BatchUpdateMemoryRecords`）。
+  **在架构中 \+ 未编制索引 ** — LLM 提取并填充记录中的值，该值在和响应中`GetMemoryRecord`可见。`ListMemoryRecords`但是，它不能用于过滤器表达式。这对于丰富上下文很有用——像`sentiment`或`summary_notes`这样的元数据可以在不消耗索引密钥预算的情况下丰富下游消费记录。

### 元数据如何从事件流向内存记录
<a name="long-term-memory-metadata-event-vs-record"></a>

事件元数据仅接受`stringValue`条目。内存记录支持`stringValue``stringListValue`、和`numberValue`类型——在提取期间由 LLM 填充或直接通过批处理 API 提供。该`dateTimeValue`类型是为系统生成的字段（`x-amz-agentcore-memory-createdAt`和`x-amz-agentcore-memory-updatedAt`）保留的。只有策略中定义的密钥才`metadataSchema`会填充在提取的记录中，不在架构中的事件元数据密钥将被忽略。有关入场限制，请参阅[配额](#long-term-memory-metadata-quotas)。

### System-generated 元数据
<a name="long-term-memory-metadata-system-fields"></a>

每条内存记录都带有以下系统字段，可使用相同的过滤器运算符进行查询：


| 字段 | Type | 说明 | 
| --- | --- | --- | 
|  `x-amz-agentcore-memory-recordType`  |  `stringValue`  | 内存记录的类型 | 
|  `x-amz-agentcore-memory-createdAt`  |  `dateTimeValue`  | 记录创建时间戳 | 
|  `x-amz-agentcore-memory-updatedAt`  |  `dateTimeValue`  | 记录上次更新时间戳 | 

您无需将它们声明为索引密钥——它们始终可供过滤。这些系统生成的`dateTimeValue`字段支持`BEFORE`和`AFTER`运算符，无需您声明日期时间索引键即可实现时间范围查询。

## 先决条件
<a name="long-term-memory-metadata-prerequisites"></a>

在配置元数据筛选之前，请确认您已经：
+ 具有呼叫`CreateMemory`、、、、`UpdateMemory`、`CreateEvent``IngestData``ListMemoryRecords``RetrieveMemoryRecords``BatchCreateMemoryRecords`、和权限的 Amazon 账户 `BatchUpdateMemoryRecords` 
+ 亚马逊 Bedrock 访问权限 AgentCore 
+ 清晰地查看您的代理最需要的 3—5 个筛选维度（部门、优先级、区域、项目等）

## 第 1 步：使用索引密钥和元数据架构创建内存
<a name="long-term-memory-metadata-configure"></a>

以下内容创建了一个包含五个索引密钥和一个元数据架构的客户支持存储器。`priority``agent_type`、和`sentiment`在策略的元数据架构中定义——LLM 从对话内容中提取其价值。请注意，`sentiment`它在架构中但*未*声明为索引密钥：LLM 从对话中获取其值并将其填充到记录中，但不能用于过滤器表达式。`tags`(`STRINGLIST`)、`channel` (`STRING`) 和 `ticket_id` (`STRING`) 被声明为索引密钥，但不在架构中——它们在事件驱动的提取期间不会被填充，但可以通过批处理 API 提供。

```
aws bedrock-agentcore-control create-memory \
  --name "CustomerSupportMemory" \
  --event-expiry-duration 30 \
  --indexed-keys '[
    {"key": "priority",   "type": "STRING"},
    {"key": "agent_type", "type": "STRING"},
    {"key": "tags",       "type": "STRINGLIST"},
    {"key": "channel",    "type": "STRING"},
    {"key": "ticket_id",  "type": "STRING"}
  ]' \
  --memory-strategies '[
    {
      "semanticMemoryStrategy": {
        "name": "SupportSemanticStrategy",
        "description": "Captures support interaction details",
        "namespaceTemplates": ["support/{actorId}"],
        "memoryRecordSchema": {
          "metadataSchema": [
            {
              "key": "priority",
              "type": "STRING",
              "extractionConfig": {
                "llmExtractionConfig": {
                  "definition": "Issue priority level based on customer impact. Values range from critical (most severe) to low (least severe).",
                  "llmExtractionInstruction": "LATEST_VALUE",
                  "validation": {
                    "stringValidation": {
                      "allowedValues": ["critical", "high", "medium", "low"]
                    }
                  }
                }
              }
            },
            {
              "key": "agent_type",
              "type": "STRING",
              "extractionConfig": {
                "llmExtractionConfig": {
                  "definition": "Support agent classification.",
                  "llmExtractionInstruction": "Prefer the most specialized agent type. Hierarchy: specialist > tier3 > tier2 > tier1 > bot."
                }
              }
            },
            {
              "key": "sentiment",
              "type": "STRING",
              "extractionConfig": {
                "llmExtractionConfig": {
                  "definition": "Customer sentiment during the interaction.",
                  "llmExtractionInstruction": "LATEST_VALUE",
                  "validation": {
                    "stringValidation": {
                      "allowedValues": ["positive", "neutral", "negative", "frustrated"]
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]'
```

## 步骤 2：验证配置
<a name="long-term-memory-metadata-configure-step2"></a>

`GetMemory`用于确认索引密钥和元数据架构已被接受：

```
aws bedrock-agentcore-control get-memory --memory-id "<memory-id>"
```

## 第 3 步：在摄取期间添加元数据
<a name="long-term-memory-metadata-ingest"></a>

有两种方法可以将元数据传送到内存记录中。通过基于提取的提取（`CreateEvent`或`IngestData`），LLM 会在提取的记录上填充元数据。通过直接创建记录（`BatchCreateMemoryRecords`或`BatchUpdateMemoryRecords`），您可以明确提供元数据。

### Event-driven 摄取
<a name="long-term-memory-metadata-ingest-events"></a>

在创建时将`stringValue`元数据附加到事件。LLM 使用策略的元数据架构在生成的内存记录上提取和填充元数据。只有策略中定义的密钥才`metadataSchema`会填充在结果记录中，不在架构中的事件元数据密钥在提取过程中会被忽略。

**注意**  
 `IngestData`接受相同的内容`metadata`并提供相同的提取管道，因此元数据的行为与。`CreateEvent`区别在于`IngestData`不保留短期事件。

```
aws bedrock-agentcore create-event \
  --memory-id "<memory-id>" \
  --actor-id "customer-123" \
  --session-id "session-001" \
  --event-timestamp "$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")" \
  --metadata '{
    "priority":  {"stringValue": "high"},
    "channel":   {"stringValue": "email"},
    "ticket_id": {"stringValue": "TKT-5001"}
  }' \
  --payload '[
    {"conversational": {"role": "USER",      "content": {"text": "I have a billing issue that is blocking my production deployment"}}},
    {"conversational": {"role": "ASSISTANT", "content": {"text": "I understand this is urgent. Let me escalate to our billing specialist team."}}}
  ]'
```

在此示例中，`priority`位于策略中`metadataSchema`，因此其值会传播到内存记录。`channel``ticket_id`并且不在架构中，因此在提取过程中会被忽略。LLM 还推断`agent_type`（可能`"specialist"`基于升级）和`sentiment`（可能`"frustrated"`）从对话内容中推断出——这些架构密钥是填充的，尽管它们不是作为事件元数据提供的。

### 从对话内容中隐式提取元数据
<a name="long-term-memory-metadata-implicit-extraction"></a>

架构密钥不需要事件元数据即可生成值。当架构密钥在原始事件上没有匹配的元数据时，LLM 的值完全来自对话内容。它使用密钥的`definition`和`llmExtractionInstruction`来确定值。这对于仅存在于对话本身中的维度很有用，无需呼叫者在事件创建时提供维度。

使用与步骤 1 相同的客户支持内存，以下事件根本没有元数据：

```
aws bedrock-agentcore create-event \
  --memory-id "<memory-id>" \
  --actor-id "customer-789" \
  --session-id "session-002" \
  --event-timestamp "$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")" \
  --payload '[
    {"conversational": {"role": "USER",      "content": {"text": "My production deployment is down because of a billing hold on our account"}}},
    {"conversational": {"role": "ASSISTANT", "content": {"text": "I understand the urgency. Let me connect you with our billing specialist team right away."}}}
  ]'
```

LLM 会分析对话内容并填充提取的内存记录（、和`sentiment`）上的所有三个架构密钥 `priority``agent_type`，尽管这些密钥都不是作为事件元数据提供的：

```
{
  "content": {"text": "Customer reported a production outage caused by a billing hold. Escalated to billing specialist."},
  "metadata": {
    "priority":   {"stringValue": "critical"},
    "agent_type": {"stringValue": "specialist"},
    "sentiment":  {"stringValue": "frustrated"}
  }
}
```

验证规则仍然适用——无论该值来自事件元数据还是内容推断，LLM 的输出都受限于您指定的允许值。

### LLM 如何解决跨事件的冲突
<a name="long-term-memory-metadata-conflict-resolution"></a>

当会话中的多个事件为同一个元数据密钥携带不同的值时，LLM 使用。`llmExtractionInstruction`这决定了在生成的内存记录上保留哪个值。

例如，假设一个支持会话，其中第一个事件已经`priority: "low"`发生，后一个事件升级为`priority: "critical"`。LLM 根据以下指令解决了这个问题：
+  **`LATEST_VALUE`**（内置）— LLM 保留最新的值。在这种情况下，内存记录会生成`priority: "critical"`。
+  **自定义指令 ** — 您可以表达特定领域的逻辑。例如，也会生成 * “在*会话期间报告的最高严重性”`"critical"`，但原因不同——这是最高的严重性，而不仅仅是最新的严重性。

另一个例子：例如`agent_type`，指令 * “首选最专业的代理类型。层次结构：专家 > 第 3 层 > 第 2 层 > 第 1 层 > 机器人”*，如果会话从机器人开始并升级到第 2 层代理，则内存记录会生成。`agent_type: "tier2"`

### 确定性元数据摄取
<a name="long-term-memory-metadata-ingest-deterministic"></a>

配置为的密钥`STRICTLY_CONSISTENT`遵循不同的摄取路径。您在事件中提供的值是生成的记录中的值。没有 LLM 推断，也没有冲突解决方案。

AgentCore 在提取之前，内存按事件的确定性键值对事件进行分组。例如，标记的事件与标记的事件`department: "engineering"`是分开处理的`department: "finance"`。

整合是在这些集团内部进行的。带有 “`compliance_level: "hipaa"`永不合并” 的记录与带有标签`compliance_level: "standard"`的记录合并。这使得确定性密钥非常适合：
+  **合规隔离 **-具有不同合规级别的记录永远不会混在一起。
+  **组织路由 **- Department-scoped 检索时没有交叉污染。
+  **Multi-tenant 子过滤 **- Tenant-specific 属性完全按照提供的方式保存。

如果事件没有确定性密钥的值，则结果记录中不存在该密钥。

直接写入路径（`BatchCreateMemoryRecords`和`BatchUpdateMemoryRecords`）绕过提取。`STRICTLY_CONSISTENT`提取类型对它们没有影响。直接提供元数据，就像你已经为这些 API 所做的那样。

### 使用批处理 API 直接创建记录
<a name="long-term-memory-metadata-ingest-batch"></a>

对于知识库导入、自我管理策略或预处理内容，使用`BatchCreateMemoryRecords`（或`BatchUpdateMemoryRecords`）明确提供元数据。这完全绕过了 LLM 提取——调用者控制元数据值。

如何处理批量创建的记录上的元数据取决于您是否提供：`memoryStrategyId`
+  **W `memoryStrategyId` ** ith — 该服务根据该策略筛选输入元数据`memoryRecordSchema`。只有架构中定义的密钥才存储在记录中。所有其他密钥（包括不在架构中的索引密钥）将被静默删除。这为您提供了架构强制的一致性，确保批量创建的记录具有与事件驱动提取生成的记录相同的元数据形状。
+  **不`memoryStrategyId`**使用 — 该服务将所有元数据密钥按原样存储在有效负载中。这包括已编入索引的密钥、策略架构中的密钥以及两者都没有索引的密钥。但是，只有索引密钥是可筛选的——尝试对非索引密钥进行筛选会返回 a。`ValidationException` Non-indexed 密钥在`ListMemoryRecords`响应中`GetMemoryRecord`仍然可见。

以下示例创建了一条不`memoryStrategyId`包含所有提供的元数据的记录：

```
aws bedrock-agentcore batch-create-memory-records \
  --memory-id "<memory-id>" \
  --records '[{
    "requestIdentifier": "import-001",
    "namespaces": ["support/customer-456"],
    "content": {"text": "Customer prefers phone support for urgent billing issues"},
    "timestamp": "2026-01-15T10:00:00Z",
    "metadata": {
      "priority":   {"stringValue": "high"},
      "agent_type": {"stringValue": "billing_agent"},
      "channel":    {"stringValue": "phone"},
      "ticket_id":  {"stringValue": "TKT-7890"}
    }
  }]'
```

要强制架构一致性，请包括`memoryStrategyId`。在这种情况下，只保留该策略中`memoryRecordSchema`存在的密钥：

```
aws bedrock-agentcore batch-create-memory-records \
  --memory-id "<memory-id>" \
  --records '[{
    "requestIdentifier": "import-002",
    "namespaces": ["support/customer-456"],
    "memoryStrategyId": "<strategy-id>",
    "content": {"text": "Billing dispute resolved after account credit applied"},
    "timestamp": "2026-01-16T14:00:00Z",
    "metadata": {
      "priority":   {"stringValue": "medium"},
      "agent_type": {"stringValue": "billing_agent"},
      "channel":    {"stringValue": "phone"}
    }
  }]'
```

在第二个示例中，如果策略的架构仅定义`priority``agent_type``sentiment`、和，则`channel`会以静默方式从存储的记录中删除。

### 使用更新记录 BatchUpdateMemoryRecords
<a name="long-term-memory-metadata-batch-update"></a>

 `BatchUpdateMemoryRecords`遵循与相同的`memoryStrategyId`元数据过滤行为`BatchCreateMemoryRecords`。以下示例更新现有记录的内容和元数据：

```
aws bedrock-agentcore batch-update-memory-records \
  --memory-id "<memory-id>" \
  --records '[{
    "memoryRecordId": "<record-id>",
    "namespaces": ["support/customer-456"],
    "content": {"text": "Customer prefers phone support for urgent billing issues. Account credit applied."},
    "metadata": {
      "priority":   {"stringValue": "critical"},
      "agent_type": {"stringValue": "billing_agent"},
      "channel":    {"stringValue": "phone"}
    }
  }]'
```

## 第 4 步：使用元数据过滤器进行查询
<a name="long-term-memory-metadata-query"></a>

元数据过滤器在向量相似度搜索运行*之前*应用（预过滤）。这会首先减少候选集合。因此， K-nearest 邻居 (KNN) 搜索在更小、更相关的子集上运行。

### Filter 结构
<a name="long-term-memory-metadata-query-structure"></a>

每个过滤器都是一个`{ left, operator, right }`表达式：

```
{
  "left":     { "metadataKey": "priority" },
  "operator": "EQUALS_TO",
  "right":    { "metadataValue": { "stringValue": "high" } }
}
```

每个查询最多**可以组合 ** 5 个过滤器。使用`AND`逻辑应用多个过滤器。

### 支持的运算符
<a name="long-term-memory-metadata-operators"></a>


| 运算符 | 需要正确的值 | 结合使用 | Description | 
| --- | --- | --- | --- | 
|  `EQUALS_TO`  | 是 | 字符串，数字 | 完全匹配。 | 
|  `CONTAINS`  | 是 | 字符串清单 | 返回 STRINGLIST 中任何元素包含完全匹配的给定字符串的记录。 | 
|  `EXISTS`  | 否 | 所有类型 | 密钥存在于记录中 | 
|  `NOT_EXISTS`  | 否 | 所有类型 | 记录中缺少密钥 | 
|  `GREATER_THAN`  | 是 (`numberValue`) | NUMBER | 数字大于比较 | 
|  `GREATER_THAN_OR_EQUALS`  | 是 (`numberValue`) | NUMBER | 数值大于或等于比较 | 
|  `LESS_THAN`  | 是 (`numberValue`) | NUMBER | 小于数值的比较 | 
|  `LESS_THAN_OR_EQUALS`  | 是 (`numberValue`) | NUMBER | 数值小于或等于比较 | 
|  `BEFORE`  | 是 (`dateTimeValue`) | 日期 TimeValue | 时间戳在给定值之前 | 
|  `AFTER`  | 是 (`dateTimeValue`) | 日期 TimeValue | 时间戳位于给定值之后 | 

注意：事件元数据过滤器仅`ListEvents`支持`EXISTS``NOT_EXISTS``EQUALS_TO`、和且仅支持`stringValue`。

### 使用元数据过滤器进行检索（语义搜索 \+ 预过滤）
<a name="long-term-memory-metadata-retrieve"></a>

开启`RetrieveMemoryRecords`，嵌套`metadataFilters`在里面`searchCriteria`。以下示例将结果范围限定为当年语义搜索与 “账单问题” 匹配之前的高优先级记录：

```
aws bedrock-agentcore retrieve-memory-records \
  --memory-id "<memory-id>" \
  --namespace "support/customer-123" \
  --search-criteria '{
    "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"}}
      }
    ]
  }'
```

在运行相似度搜索之前，将自定义元数据过滤器与系统生成的时间戳相结合，可以从两个维度（业务优先级和新近度）压缩候选集合。

### 带有元数据过滤器的列表（无语义搜索）
<a name="long-term-memory-metadata-list"></a>

 `ListMemoryRecords`无需语义搜索即可提供元数据过滤。当您需要枚举符合特定元数据条件的记录时，这非常有用，例如，列出客户的所有高优先级记录，或提取在特定日期之后创建的所有记录。

开启`ListMemoryRecords`，`metadataFilters`是顶级参数：

```
aws bedrock-agentcore list-memory-records \
  --memory-id "<memory-id>" \
  --namespace "support/customer-123" \
  --metadata-filters '[
    {
      "left":     {"metadataKey": "priority"},
      "operator": "EQUALS_TO",
      "right":    {"metadataValue": {"stringValue": "high"}}
    },
    {
      "left":     {"metadataKey": "x-amz-agentcore-memory-createdAt"},
      "operator": "AFTER",
      "right":    {"metadataValue": {"dateTimeValue": "2026-01-20T00:00:00Z"}}
    }
  ]'
```

### 组合多个过滤器
<a name="long-term-memory-metadata-combining"></a>

此查询将检索范围定为特定客户命名空间内的 2026 年第三季度股票讨论：

```
{
  "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": "2026-07-01T00:00:00Z"}}
    },
    {
      "left":     {"metadataKey": "x-amz-agentcore-memory-createdAt"},
      "operator": "BEFORE",
      "right":    {"metadataValue": {"dateTimeValue": "2026-09-30T23:59:59Z"}}
    }
  ]
}
```

时间戳的筛选值必须采用 UTC（ISO 8601 格式）。该服务在比较之前将所有存储的时间戳标准化为 UTC，因此请务必以 UTC 表示过滤器值。

## 第 5 步：改进您的元数据架构
<a name="long-term-memory-metadata-evolve"></a>

AgentCore 内存支持架构演变，因此您可以根据需求的变化调整元数据配置。

### 添加索引密钥
<a name="long-term-memory-metadata-evolve-add-keys"></a>

您可以随时向内存中添加新的索引密钥：

```
aws bedrock-agentcore-control update-memory \
  --memory-id "<memory-id>" \
  --add-indexed-keys '[
    {"key": "customer_segment", "type": "STRING"}
  ]'
```

新密钥立即可用于传入的事件和内存记录。现有记录不会被回填——只有新的或更新的记录带有新密钥。您无法删除先前建立索引的密钥，这可以防止意外丢失对现有数据的筛选功能。

### 修改策略的元数据架构
<a name="long-term-memory-metadata-evolve-modify-schema"></a>

您可以自由地在策略的元数据架构中添加、删除或更新条目。这控制了 LLM 从今后的对话中提取哪些元数据。

例如，要向现有策略添加新字`resolution_type`段，请执行以下操作：

```
aws bedrock-agentcore-control update-memory \
  --memory-id "<memory-id>" \
  --memory-strategies '{
    "modifyMemoryStrategies": [
      {
        "memoryStrategyId": "<strategy-id>",
        "memoryRecordSchema": {
          "metadataSchema": [
            {
              "key": "resolution_type",
              "type": "STRING",
              "extractionConfig": {
                "llmExtractionConfig": {
                  "definition": "How the customer support issue was resolved",
                  "validation": {
                    "stringValidation": {
                      "allowedValues": ["refund", "replacement", "escalation", "self-resolved"]
                    }
                  }
                }
              }
            }
          ]
        }
      }
    ]
  }'
```

如果您不再希望 LLM 提取该字段，也可以从策略的元数据架构中移除该密钥。移除架构条目会停止提取新记录，但不会影响现有记录中已有的元数据。

现有内存记录不会追溯接收新 LLM-extracted 字段。但是，当在正常内存生命周期内将较旧的内存与较新的内存合并时，将使用当前架构重新提取合并的记录，并将包括新的元数据字段。

## 配额
<a name="long-term-memory-metadata-quotas"></a>


| 资源 | 限制 | 
| --- | --- | 
| 每个内存的索引密钥 | 10 | 
| 每个策略的密钥严格\_一致 | 3 | 
| 每个策略的元数据架构条目 | 20 | 
| 内存记录元数据条目（用户提供） | 20 | 
| 每个查询的筛选条件 | 5 | 
|  `allowedValues`每条验证规则 | 10 | 
|  `maxItems`用于`STRINGLIST`验证 | 5 | 
|  `definition`/`llmExtractionInstruction`长度 | 每个 1000 个字符 | 
| 元数据密钥长度 | 128 个字符 | 
|  `stringValue`长度 | 256 个字符 | 
| `STRINGLIST`成员的长度 | 64 个字符 | 

## 最佳实践
<a name="long-term-memory-metadata-best-practices"></a>
+  **从直接影响检索质量的 3—5 个过滤器尺寸开始。**每个索引字段都会消耗存储基础架构容量，10 个密钥的限制反映了这一点。从三到五个直接影响检索质量的密钥开始，然后在出现具体需求时添加更多密钥。
+  **写出清晰的特定`definition`字符串。**`definition`描述了该字段所代表的内容。而不是 * “票证的优先级”，而应*写上 * “根据客户影响问题优先级”。值范围从严重（最严重）到低（最不严重）。”* `llmExtractionInstruction`用于详细的提取逻辑。
+  **使用限制 LLM 输出。`validation.allowedValues`**未经验证，LLM 可能会产生`"High"`或`"HIGH"`针对相同概念的过滤器匹配中断。`"high"`
+  **选择与域名语义相匹配的冲突解决规则。**`LATEST_VALUE`是安全的默认值，但对于诸如`agent_type`升级工作流程之类的字段，保留最高级值的自定义指令更为正确。
+  **首选以事件为导向的对话内容路径。**让 LLM 处理提取和冲突解决。在您已经知道正确的元数据值的情况下，为批量导入保留批量 API。
+  **在策略层面规划架构。**每种策略都有自己的策略`metadataSchema`，允许不同的策略以不同的方式提取和处理相同的密钥。语义策略可能使用自定义提取指令对对话上下文中的优先级进行分类，而摘要策略可能会使用针对特定摘要元数据进行调整的不同定义。
+  **故意使用`memoryStrategyId`批量创建的记录。**当你加入时`memoryStrategyId`，服务会将输入元数据过滤为仅限该策略架构中的密钥——所有其他密钥都将被静默删除。当你省略它时，有效负载中的所有元数据都将按原样存储。根据您的用例进行选择：对应与提取生成的记录相匹配的记录采用架构强制一致性，或者完全控制批量导入（在外部管理元数据）。
+  **使用非索引架构密钥来丰富上下文。**并非每个元数据密钥都需要可筛选。未声明为索引键的架构密钥仍填充在提取的记录中，并在 get/list 响应中可见，只是不能在过滤器表达式中使用。这对于在不消耗索引密钥预算的情况下丰富下游消费记录的元数据非常有用。`sentiment` `summary_notes`
+  **对已经知道的值使用确定性提取。**有些密钥代表固定的组织属性`department`，例如`tenant_tier`、或`compliance_scope`。如果应用程序在事件创建时具有这些值，请将它们配置为`STRICTLY_CONSISTENT`。为每个事件提供价值。这样可以保证记录上的精确值，并消除了 LLM 提取可能引入的不一致表示形式（例如`"eng"`对比`"Engineering"`）。保留`LLM_INFERRED`必须从对话内容中推断出来的维度，例如情绪或话题。
+  **尽早规划确定性关键时段。**每个`STRICTLY_CONSISTENT`密钥使用 10 个索引密钥插槽中的一个。索引密钥一旦添加就无法删除。如果您计划使用确定性元数据，请预留空位。

### Anti-patterns 避免
<a name="long-term-memory-metadata-anti-patterns"></a>
+  **不要索引描述或全名**等高基数自由文本字段，它们会在不提供有用的过滤器边界的情况下膨胀索引。
+  **不要将元数据用于每次交互**时都会发生变化的值，元数据对于稳定或变化缓慢的属性最有效。
+  **不要仅依靠元数据来隔离租户。**没有命名空间隔离的`tenant_id`元数据字段是一种通过约定实现安全的模型，它会打破任何漏掉的过滤器。使用命名空间作为`who`、和使用元数据。`what` `when` `how urgent`
+  **不要对必须精确的值使用 LLM 提取。**如果密钥必须带有特定的已知值（例如`department`或`ticket_id`），请使用`STRICTLY_CONSISTENT`提取或通过批处理 API 提供该值。LLM 提取可能会产生相同概念的变体。