用于长期记忆的结构化元数据
Amazon Bedrock AgentCore Memory 中的元数据筛选允许您向长期内存记录添加结构化属性。您可以使用这些属性来缩小检索期间返回的记录范围。命名空间已经按主要实体(用户、租户、患者、客户)隔离记忆。但是,在单个命名空间中,广泛的语义搜索会返回所有含义相近的内容。使用元数据筛选,您只能检索与特定属性值匹配的结果。例如,您可以仅检索高优先级记录,仅检索特定部门的记录,或者仅检索在给定时间范围内创建的记录。
通过元数据筛选,您可以:
-
按命名空间内的业务维度(优先级、部门、渠道、时间范围)进行范围检索
-
在创建时将结构化元数据附加到事件和内存记录
-
让大型语言模型 (LLM) 在内存摄取期间自动从对话内容中提取元数据
-
将值限制为特定 LLM-extracted 值以实现一致筛选
-
RetrieveMemoryRecords或的每个查询最多可组合 5 个过滤器ListMemoryRecords,应用AND逻辑 -
筛选系统生成的时间戳 (
x-amz-agentcore-memory-createdAt,x-amz-agentcore-memory-updatedAt),无需声明其他索引键
开始使用
设置元数据筛选包括五个步骤:
-
使用@@ 索引密钥和元数据架构创建您的内存 —
-
索引键-使用
CreateMemory(或UpdateMemory)声明要筛选的元数据键(例如、prioritychannel、tags)。每个内存最多可以声明 10 个索引密钥。索引键定义了过滤器表达式中哪些属性是可查询的。一旦添加了索引密钥,就无法将其删除。 -
元数据架构 — 定义策略以控制 LLM 如何从对话中提取值。
metadataSchema该架构指定要提取的密钥、如何解决事件间的冲突以及要应用的验证约束。元数据架构是可选的,没有元数据架构的策略不会执行元数据提取。
-
-
验证配置-
GetMemory用于确认您的索引密钥和策略元数据架构设置正确。 -
使用@@ 元数据摄取数据-使用
CreateEvent可选元数据发送事件,或使用BatchCreateMemoryRecords直接在记录上提供元数据。对于事件驱动的摄取,LLM 会自动提取并填充生成的内存记录中的元数据。这种提取基于策略的元数据架构和对话内容,即使事件中没有附加元数据也是如此。 -
使用@@ 元数据筛选器进行查询-使用
metadataFiltersonRetrieveMemoryRecords(带预筛选的语义搜索)或ListMemoryRecords(仅限元数据筛选)来限定结果范围。 -
随着时间的推移发展您的架构 — 随着筛选需求的增长,添加新的索引键或修改策略元数据架构。
接下来的章节将详细介绍每个步骤。
重要概念
已编制索引的元数据密钥
索引密钥是在内存资源级别声明的CreateMemory(或稍后通过添加UpdateMemory)。索引密钥以经过优化的格式存储,可进行快速查询筛选。在 on and 中只能查询已编入索引的metadataFilters密钥。ListMemoryRecords RetrieveMemoryRecords
以下示例声明了两个索引密钥:
{ "indexedKeys": [ { "key": "priority", "type": "STRING" }, { "key": "tags", "type": "STRINGLIST" } ] }
支持的type值:STRING、STRINGLIST、NUMBER。
密钥必须匹配^[a-zA-Z0-9\s._:/=+@-]*$(最多 128 个字符)。
添加索引密钥不会回填现有记录。只有在声明密钥后创建或更新的记录才会为该密钥编制索引。有关架构随着时间的推移而演变的更多详细信息,请参阅第 5 步:改进您的元数据架构。
元数据架构(按策略)
内存策略可以选择在中声明元数据架构memoryRecordSchema.metadataSchema。元数据架构告诉 LLM 在生成记忆记录时要从对话内容中提取哪些元数据。在事件驱动的提取过程中,只有在策略的元数据架构中定义的密钥才会填充到生成的内存记录中。
架构中的每个条目都定义:
-
key— 元数据密钥名称。如果此键也被声明为索引键,则提取的值是可筛选的。如果它不是索引键,则该值仍会填充在记录中并在GetMemoryRecord和ListMemoryRecords响应中可见,但不能在过滤器表达式中使用。 -
type— 值类型 (STRING、STRINGLIST、NUMBER)。 -
definition(必填)-以自然语言描述该字段所代表的内容。具体一点,不是 “优先级”,而是写上 “基于客户影响的问题优先级别”。值范围从临界(最严重)到低(最不严重)不等。” -
llmExtractionInstruction(可选)— 有关法学硕士应如何提取或解析值的更多指南。您可以使用内置的LATEST_VALUE(保留最新值),也可以提供自定义的自然语言说明,例如 “根据业务影响进行分类:critical用于影响生产的服务中断、high性能降低、功能请求、mediumlow文档或外观问题”。 -
validation(可选)— 将 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 | 验证 | 说明 |
|---|---|---|
|
|
|
限制为固定集(最多 10 个值,每个值最多 256 个字符,匹配 |
|
|
|
将列表成员限制为固定集合(最多 10 个值,每个值最多 256 个字符,匹配 |
|
|
|
列表中的最大项目数 (1—5) |
|
|
|
允许的最小值 |
|
|
|
允许的最大值 |
确定性元数据(严格一致的提取类型)
确定性元数据键包含您的应用程序在创建事件时已经知道的值。这些值未经修改即可精确复制到生成的内存记录中。法学硕士agent_id不应推断出诸如departmentcompliance_level、或之类的组织分类器。LLM 推理引入了可变性。例如,同一对话可以在一条记录和另一条记录"Engineering"上产生"eng"。
对于这些密钥,请在元数据架构条目STRICTLY_CONSISTENT中设置为extractionType。事件中提供的值在提取和合并中传播时保持不变。没有向法学硕士咨询该密钥。
以下 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。
提取和整合隔离
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返回紧急重复的费用事实。其他事件位于不同的分区中。合并期间,来自不同值组合的记录永远不会合并。
约束
| 约束 | Detail |
|---|---|
|
每种策略的最大确定性密钥 |
3 |
|
密钥类型 |
必须是 |
|
必须编制索引 |
密钥也必须在内存中声明 |
|
没有 |
|
|
支持的策略 |
语义、用户偏好和情节策略(包括自定义覆盖)。摘要策略不支持。 |
|
缺失值 |
如果事件到达时没有确定性键的值,则该键将从该事件的分组中省略,并且在生成的记录中不存在。 |
重要
更改配置为哪些密钥STRICTLY_CONSISTENT会更改用于提取和合并的分组。在先前配置下创建的记录将与在新配置下创建的记录隔离开来。在摄取事件之前,请规划您的确定性密钥配置。
索引键和架构键的交互方式
索引键和架构键之间的关系决定了元数据的行为方式:
-
架构中的索引 +-密钥由 LLM 填充到提取的记录上,并且可以在查询表达式中进行筛选。对于要同时提取和筛选的密钥,这是最常见的配置。
-
已编入索引 + 不在架构中 — 在事件驱动的提取过程中,不会在记录中填充密钥。对于提取的记录,此键上的筛选器不会返回任何结果。要填充这些密钥,请使用 Batch API(
BatchCreateMemoryRecords或BatchUpdateMemoryRecords)。 -
在 schema 中 + 未编制索引 — LLM 提取并填充记录中的值,该值在和响应中
GetMemoryRecord可见。ListMemoryRecords但是,它不能用于过滤器表达式。这对于情境丰富非常有用,比如sentiment或这样的元数据summary_notes,可以丰富下游消费记录,而不会消耗已编制索引的密钥预算。
元数据如何从事件流向内存记录
事件元数据仅接受stringValue条目。内存记录支持stringValuestringListValue、和numberValue类型 — 在提取期间由 LLM 填充或通过 Batch API 直接提供。该dateTimeValue类型是为系统生成的字段(x-amz-agentcore-memory-createdAt和x-amz-agentcore-memory-updatedAt)保留的。只有策略中定义的密钥才metadataSchema会填充到提取的记录中,架构中没有的事件元数据键会被忽略。有关入场限制,请参阅配额。
System-generated 元数据
每条内存记录都带有以下系统字段,可使用相同的过滤器运算符进行查询:
| 字段 | Type | 说明 |
|---|---|---|
|
|
|
存储记录的类型 |
|
|
|
记录创建时间戳 |
|
|
|
记录上次更新时间戳 |
您无需将它们声明为索引密钥,它们始终可用于筛选。这些系统生成的dateTimeValue字段支持BEFORE和AFTER运算符,无需您声明日期时间索引键即可实现时间范围查询。
先决条件
在配置元数据筛选之前,请确认您已经:
-
有权调用
CreateMemory、、、UpdateMemory、CreateEventListMemoryRecordsRetrieveMemoryRecordsBatchCreateMemoryRecords、和的 AWS 账户BatchUpdateMemoryRecords -
亚马逊 Bedrock 访问权限 AgentCore
-
清晰查看您的代理最需要的 3-5 个筛选维度(部门、优先级、区域、项目等)
步骤 1:使用索引键和元数据架构创建内存
以下内容创建了一个包含五个索引键和一个元数据架构的客户支持内存。 priorityagent_type、和sentiment在策略的元数据架构中定义 — LLM 从对话内容中提取其值。请注意,它sentiment位于架构中,但未声明为索引键:LLM 从对话中获取其值并将其填充到记录中,但不能在过滤器表达式中使用。 tags(STRINGLIST)、channel (STRING) 和 ticket_id (STRING) 被声明为索引键,但不在架构中 — 它们不会在事件驱动的提取期间填充,但可以通过 Batch 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:验证配置
GetMemory用于确认索引键和元数据架构已被接受:
aws bedrock-agentcore-control get-memory --memory-id "<memory-id>"
第 3 步:使用元数据摄取数据
将元数据导入内存记录有两种途径。
Event-driven 摄入
在创建事件时将stringValue元数据附加到事件。LLM 使用策略的元数据架构在生成的内存记录上提取和填充元数据。只有策略中定义的密钥才metadataSchema会填充到结果记录中,提取过程中会忽略架构中不存在的事件元数据键。
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,因此其值会传播到内存记录。 channelticket_id且不在架构中,因此在提取过程中会忽略它们。LLM 还会从对话内容中推断agent_type(可能"specialist"基于升级)和sentiment(很可能"frustrated")——即使这些架构密钥没有作为事件元数据提供,它们也会被填充。
从对话内容中提取隐式元数据
架构键不需要事件元数据即可生成值。当架构键在原始事件上没有匹配的元数据时,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 会分析对话内容并在提取的内存记录中填充所有三个架构键 — priority agent_type、和 sentiment — 尽管没有提供任何架构键作为事件元数据:
{ "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 会使用. llmExtractionInstruction 这决定了在生成的内存记录中保留哪个值。
例如,假设一个支持会话,其中第一个事件有priority: "low",后一个事件升级到priority: "critical"。法学硕士根据以下指令解决了这个问题:
-
LATEST_VALUE(内置)— LLM 保留最新的值。在这种情况下,内存记录将获得priority: "critical"。 -
自定义指令-您可以表达特定于域的逻辑。例如,“在会话期间报告最高严重性” 也会产生
"critical",但出于不同的原因——它是最高严重性,而不仅仅是最新的严重性。
另一个例子:agent_type使用 “首选最专业的代理类型” 指令。层次结构:专家 > Tier3 > tier2 > tier1 > bot”,如果会话从机器人开始并升级到 Tier2 代理,则内存记录将获得。agent_type: "tier2"
确定性元数据摄取
配置为的密钥STRICTLY_CONSISTENT遵循不同的摄取路径。您在事件上提供的值是落在结果记录上的值。没有法学硕士的推论,也没有冲突解决方案。
AgentCore 内存在提取之前按事件的确定性键值对事件进行分组。例如,标记的事件与标记的事件department: "engineering"是分开处理的department: "finance"。
整合是在这些群体中进行的。带有 “compliance_level: "hipaa"永不合并” 的记录会与标有标签compliance_level: "standard"的记录合并。这使得确定性密钥非常适合:
-
合规性隔离-不同合规级别的记录永远不会混在一起。
-
组织路由-在没有交叉污染的情况下进行 Department-scoped 检索。
-
Multi-tenant 子筛选- Tenant-specific 属性完全按照提供的方式保留。
如果事件没有确定性键的值,则生成的记录中将不存在该键。
直接写入路径(BatchCreateMemoryRecords和BatchUpdateMemoryRecords)旁路提取。STRICTLY_CONSISTENT提取类型对它们没有影响。直接提供元数据,就像为这些 API 所做的那样。
使用 Batch API 直接创建记录
对于知识库导入、自我管理策略或预处理内容,请使用BatchCreateMemoryRecords(或BatchUpdateMemoryRecords)明确提供元数据。这完全绕过了 LLM 提取——调用者控制元数据值。
如何处理批量创建的记录的元数据取决于您是否提供了:memoryStrategyId
-
使用
memoryStrategyId— 该服务根据该策略筛选输入元数据memoryRecordSchema。只有架构中定义的密钥才存储在记录中。所有其他密钥(包括不在架构中的索引键)都将被静默删除。这为您提供了架构强制执行的一致性,确保批量创建的记录与事件驱动的提取生成的记录具有相同的元数据形状。 -
不带
memoryStrategyId— 该服务按记录的原样将所有元数据密钥存储在有效载荷中。这包括已建立索引的密钥、策略架构中的密钥以及两者都没有编制索引的密钥。但是,只有已编入索引的键是可筛选的——尝试筛选非索引键会返回。ValidationExceptionNon-indexed 密钥在GetMemoryRecord和ListMemoryRecords响应中仍然可见。
以下示例创建了一条不带的记录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"} } }]'
在第二个示例中,如果策略的架构仅定义priorityagent_typesentiment、和,则channel会静默地从存储的记录中删除。
使用更新记录 BatchUpdateMemoryRecords
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:使用元数据过滤器进行查询
元数据过滤器在向量相似度搜索运行之前应用(预过滤)。这会首先减少候选集。因此, K-nearest 邻居 (KNN) 搜索对更小、更相关的子集进行操作。
Filter 结构
每个过滤器都是一个{ left, operator, right }表达式:
{ "left": { "metadataKey": "priority" }, "operator": "EQUALS_TO", "right": { "metadataValue": { "stringValue": "high" } } }
每个查询最多可以组合 5 个过滤器。使用AND逻辑应用多个过滤器。
支持的运算符
| 运算符 | 需要正确的值 | 结合使用 | Description |
|---|---|---|---|
|
|
是 |
字符串、数字 |
完全匹配。 |
|
|
是 |
字符串列表 |
返回 STRINGLIST 中任何元素都包含精确匹配给定字符串的记录。 |
|
|
否 |
所有类型 |
钥匙存在于记录中 |
|
|
否 |
所有类型 |
记录中缺少密钥 |
|
|
是 ( |
NUMBER |
数值大于比较 |
|
|
是 ( |
NUMBER |
大于或等于的数值比较 |
|
|
是 ( |
NUMBER |
数值小于比较 |
|
|
是 ( |
NUMBER |
数值小于或等于比较 |
|
|
是 ( |
日期 TimeValue |
时间戳在给定值之前 |
|
|
是 ( |
日期 TimeValue |
时间戳在给定值之后 |
注意:事件元数据筛选仅ListEvents支持EXISTSNOT_EXISTS、和EQUALS_TO、和stringValue。
使用元数据过滤器进行检索(语义搜索+预过滤)
开启 RetrieveMemoryRecordsmetadataFilters,嵌套在里面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"}} } ] }'
在相似度搜索运行之前,将自定义元数据筛选器与系统生成的时间戳相结合,可以沿两个维度(业务优先级和最近程度)压缩候选集。
带有元数据过滤器的列表(无语义搜索)
ListMemoryRecords无需语义搜索即可进行元数据筛选。当您需要枚举符合特定元数据标准的记录时,这很有用,例如,列出客户的所有高优先级记录,或者提取在特定日期之后创建的所有记录。
O ListMemoryRecords n,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"}} } ]'
组合多个过滤器
此查询的检索范围仅限于特定客户命名空间内的 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 步:改进您的元数据架构
AgentCore 内存支持架构演变,因此您可以根据需求的变化调整元数据配置。
添加索引密钥
您可以随时向内存中添加新的索引密钥:
aws bedrock-agentcore-control update-memory \ --memory-id "<memory-id>" \ --add-indexed-keys '[ {"key": "customer_segment", "type": "STRING"} ]'
新密钥可立即用于传入事件和内存记录。现有记录不会回填——只有新的或更新的记录才会使用新的密钥。您无法删除先前已编入索引的密钥,这样可以防止意外丢失对现有数据的筛选功能。
修改策略的元数据架构
您可以在策略的元数据架构中自由添加、删除或更新条目。这控制 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 字段。但是,在正常的内存生命周期中,如果将较旧的内存与较新的内存合并,则使用当前架构重新提取合并记录,并将包括新的元数据字段。
配额
| 资源 | 限制 |
|---|---|
|
每个内存的索引密钥 |
10 |
|
每个策略严格一致的密钥 |
3 |
|
每个策略的元数据架构条目 |
20 |
|
内存记录元数据条目(用户提供) |
20 |
|
每个查询的筛选条件 |
5 |
|
|
10 |
|
|
5 |
|
|
每个 1000 个字符 |
|
元数据密钥长度 |
128 个字符 |
|
|
256 个字符 |
|
|
64 个字符 |
最佳实践
-
从直接影响检索质量的 3—5 个筛选维度开始。每个已编入索引的字段都会消耗存储基础架构容量,而 10 个密钥的限制反映了这一点。从直接影响检索质量的三到五个密钥开始,然后在出现具体需求时添加更多密钥。
-
写出清晰、具体的
definition字符串。definition描述了该字段所代表的内容。不是 “工单的优先级”,而是写上 “基于客户影响的问题优先级”。值范围从临界(最严重)到低(最不严重)不等。”llmExtractionInstruction用于详细的提取逻辑。 -
使用限制 LLM 输出。
validation.allowedValues如果不进行验证,法学硕士可能会产生中断的过滤器匹配"High""high",或者"HIGH"对于相同的概念,会破坏过滤器匹配。 -
选择与域语义相匹配的冲突解决规则。
LATEST_VALUE是一个安全的默认值,但是对于像上报工作流程这样的agent_type字段,保留最高级值的自定义指令更正确。 -
更喜欢以事件为导向的对话内容。让 LLM 来处理提取和冲突解决。保留 Batch API 以用于已知正确元数据值的批量导入。
-
在策略层面规划架构。每种策略都可以有自己的策略
metadataSchema,允许不同的策略以不同的方式提取和处理相同的密钥。语义策略可能使用自定义提取指令对对话上下文中的优先级进行分类,而摘要策略可能使用针对特定于摘要的元数据进行调整的不同定义。 -
请谨慎
memoryStrategyId对待批量创建的记录。当你包含时memoryStrategyId,该服务会将输入元数据筛选到该策略架构中的密钥——所有其他密钥都会被静默删除。省略它时,有效载荷中的所有元数据均按原样存储。根据您的用例进行选择:对应与提取生成的记录相匹配的记录采用架构强制一致性,或者完全控制批量导入(在外部管理元数据)。 -
使用未编入索引的架构键来丰富上下文。并非每个元数据密钥都需要可筛选。未声明为索引键的架构键仍会填充在提取的记录中,并在 get/list 响应中可见——它们只是不能在过滤器表达式中使用。这对于像这样的
sentiment元数据很有用,这些元数据summary_notes可以丰富下游消费记录,而不会消耗已编入索引的密钥预算。 -
对你已经知道的值使用确定性提取。有些密钥代表固定的组织属性
department,例如tenant_tier、或compliance_scope。如果应用程序在创建事件时具有这些值,请将其配置为STRICTLY_CONSISTENT。提供每个事件的值。这可以保证记录上的精确值,并删除 LLM 提取可能引入的不一致表示形式(例如"eng"vs."Engineering")。保留LLM_INFERRED必须从对话内容中推断出的维度,例如情绪或话题。 -
尽早规划确定性密钥槽。每个
STRICTLY_CONSISTENT按键使用 10 个索引键槽中的一个。已编入索引的密钥一旦添加就无法删除。如果您打算使用确定性元数据,请保留插槽。
Anti-patterns 以避免
-
不要为描述或全名等高基数自由文本字段编制索引,因为它们会在不提供有用的过滤器边界的情况下使索引膨胀。
-
不要将元数据用于每次交互时都会发生变化的值,因为元数据对于稳定或变化缓慢的属性最为有效。
-
不要仅依靠元数据进行租户隔离。没有命名空间隔离的
tenant_id元数据字段是一种通过约定进行安全的模型,它会破坏任何错过的过滤器。对使用命名空间who,将元数据用于whatwhen、和。how urgent -
对于必须精确的值,请勿使用 LLM 提取。如果密钥必须带有特定的已知值(如
department或ticket_id),请使用STRICTLY_CONSISTENT提取或通过 Batch API 提供该值。LLM 提取可能会产生相同概念的变体。