Agentic AI AcademyAgentic AI Academy
AgentCore Memory/Lesson 2 of 5

Memory Strategies

Semantic, summary, user-preference, episodic — built-in to self-managed

Intermediate 14 minBuilder
What you'll be able to do
  • Explain what a strategy is, when it can be attached, and the hard cap of 6 strategies per memory
  • Choose between the three tiers — built-in, built-in with overrides, and self-managed — by cost, control, and IAM requirements
  • Configure the four built-in strategy types and map each SDK config key to its CLI enum without the SUMMARY/SUMMARIZATION mix-up
  • Trace an event through the Extraction → Consolidation → Reflection pipeline and read the immutable INVALID audit trail
  • Avoid the per-strategy traps: summary's required {sessionId} namespace and episodic's cross-actor reflection privacy risk
  • Override built-in extraction with appendToPrompt and wire up the required memoryExecutionRoleArn
At a glance

A memory strategy tells AgentCore Memory *what* to extract from the raw events you write — facts, per-session summaries, user preferences, or structured episodes. This lesson walks the three implementation tiers (built-in, built-in with overrides, self-managed), the four built-in strategy types and their extraction pipeline, and the naming and per-strategy quirks that trip up almost everyone the first time (the SDK config key vs the CLI enum, summary's session-scoped namespace, and episodic's cross-actor privacy gotcha).

  1. 1A strategy = what to extract
  2. 2Three tiers: built-in, overrides, self-managed
  3. 3The four built-in strategy types
  4. 4The naming gotcha: SDK key vs CLI enum
  5. 5The extraction pipeline: Extraction → Consolidation → Reflection
  6. 6Per-strategy quirks and overrides

A strategy = what to extract

From the previous lesson, recall the split: short-term memory is the raw, immutable interaction events you write with CreateEvent; long-term memory is the derived memory records AgentCore extracts across sessionsbut only if you attached a strategy. No strategy means no extraction: you get raw events and nothing else.

A strategy is the instruction that tells AgentCore Memory what to pull out of those raw events and how to organize it. You attach strategies at CreateMemory time, or add them later to an existing memory resource.

python
import boto3
control = boto3.client('bedrock-agentcore-control')

resp = control.create_memory(
    name="ShoppingSupportAgentMemory",
    memoryStrategies=[
        {'summaryMemoryStrategy': {
            'name': 'SessionSummarizer',
            'namespaceTemplates': ['/summaries/{actorId}/{sessionId}/']}},
        {'userPreferenceMemoryStrategy': {
            'name': 'UserPreferenceExtractor',
            'namespaceTemplates': ['/users/{actorId}/preferences/']}}
    ])
# then poll until ACTIVE before writing events
# control.get_memory(memoryId=...)['memory']['status'] == 'ACTIVE'

Two limits to internalize now. There is a hard cap of 6 strategies per memory — and per the quotas page this one is not adjustable, so design within it. (The account-level ceiling of strategies is adjustable; the per-memory 6 is fixed [VOLATILE — verify the live quotas page].) Extraction is also asynchronous: a record written by CreateEvent does not appear in RetrieveMemoryRecords instantly. Build for eventual consistency — a retrieve immediately after a create will commonly return nothing.

Key insight

The mental model in one line

Short-term = the raw events you write. Long-term = the records the service derives if a strategy is attached. The strategy is the only thing standing between a transcript and a useful, queryable memory.

Three tiers: built-in, overrides, self-managed

AgentCore gives you three ways to implement a strategy, trading control for cost and operational burden.

TierWho owns extraction?Pick the model / prompt?IAMCost profile
Built-inAgentCore (managed, benchmarked prompts)NoNone extraHighest storage cost; extraction included
Built-in with overridesAgentCore pipeline + your instructionsOverride instructions + choose the Bedrock modelRequires memoryExecutionRoleArnBedrock LLM calls billed to your account
Self-managedYou (any model/prompt/schema)Entirely yoursYou own the extraction infraLowest storage cost

Built-in is the default starting point: managed extraction and consolidation with prompts AWS has benchmarked. You attach a strategy type and AgentCore does the rest. It carries a higher storage cost because the service stores and manages the derived records for you.

Built-in with overrides keeps AgentCore's pipeline and fixed record schema but lets you replace the extraction instructions and choose which Bedrock model runs them. Because those are now your LLM calls, you must supply a memoryExecutionRoleArn the service assumes, and the Bedrock inference is billed to your account.

Self-managed (GA October 2025) hands extraction and consolidation entirely to you — any model, prompt, and schema — and you push the finished records into AgentCore purely for storage and retrieval. It has the lowest storage cost of the three because the service is doing the least work.

Tip

Start built-in, graduate deliberately

Reach for overrides only when the benchmarked prompts genuinely miss your domain, and for self-managed only when you already run your own extraction pipeline. Both move LLM cost and IAM responsibility onto you. Most teams ship on plain built-in.

The four built-in strategy types

Built-in (and built-in-with-overrides) ship in four flavors. Each runs a different subset of the pipeline and extracts a different shape of record.

StrategyWhat it extractsPipeline steps
SemanticStandalone factual info about the userExtraction, Consolidation
SummaryPer-session summaries (topics / tasks / decisions)Consolidation only
User PreferencePreferences, choices, stylesExtraction, Consolidation
EpisodicStructured episodes + cross-episode reflectionsExtraction, Consolidation, Reflection

Semantic captures durable facts ("the user is allergic to peanuts", "works in EST"). It outputs JSON facts and processes only USER and ASSISTANT message roles. Default namespace: /strategy/{memoryStrategyId}/actors/{actorId}/.

Summary produces a rolling per-session summary as XML <topic> chunks. It runs Consolidation only (no separate Extraction step) — and crucially its namespace must include {sessionId} because a summary is session-scoped (more on that below).

User Preference extracts JSON records of context / preference / categories ("prefers email over phone", "dark mode"), again from USER/ASSISTANT roles only.

Episodic (GA October 2025) auto-detects when an episode completes, outputs XML, and — uniquely — runs a Reflection step that analyzes patterns across episodes. Episodes are indexed by "intent" and reflections by "use case". For best results, include TOOL results in the events you write so the model sees what actually happened. Episodes and reflections take longer to appear than the other types.

Note

Episodic also has a custom cousin

The dossier notes a customMemoryStrategy variant alongside episodicMemoryStrategy for episodic configuration; on the SDK side there are matching add_episodic_strategy / add_custom_episodic_strategy helpers. Stick to the documented built-in shape unless you have a concrete reason to customize.

The naming gotcha: SDK key vs CLI enum

This is the single most common configuration error, and it is worth memorizing cold. The SDK / API config key and the CLI enum for the same strategy do not always share a name. The worst offender is Summary.

StrategySDK / API config keyCLI / TUI enum
SemanticsemanticMemoryStrategySEMANTIC
SummarysummaryMemoryStrategySUMMARIZATION (not SUMMARY)
User PreferenceuserPreferenceMemoryStrategyUSER_PREFERENCE
EpisodicepisodicMemoryStrategy (custom: customMemoryStrategy)configured via TUI / CLI

The trap: the SDK key is summaryMemoryStrategy, but the CLI enum is SUMMARIZATIONnot the intuitive SUMMARY. Pass SUMMARY to the CLI and it will reject it.

In the boto3 / SDK path you pass the config-key objects:

python
control.create_memory(
    name="ComprehensiveMem",
    memoryStrategies=[
        {'semanticMemoryStrategy':       {'name': 'Facts'}},
        {'summaryMemoryStrategy':        {'name': 'Summaries',
                                          'namespaceTemplates': ['/summaries/{actorId}/{sessionId}/']}},
        {'userPreferenceMemoryStrategy': {'name': 'Prefs'}}
    ])

In the starter-toolkit CLI you pass the enums on --strategies:

bash
# short-term only (no strategies)
agentcore add memory --name my_agent_memory

# attach built-in strategies by their CLI ENUMS
agentcore add memory --name ShoppingMem --strategies SUMMARIZATION,USER_PREFERENCE
agentcore add memory --name ComprehensiveMem --strategies SEMANTIC,SUMMARIZATION,USER_PREFERENCE

agentcore deploy && agentcore status

Watch out

SUMMARIZATION, not SUMMARY

The CLI enum for the per-session summary strategy is SUMMARIZATION. The SDK key is summaryMemoryStrategy. They look like they should match and they don't — this is the error you will hit and re-hit until it's muscle memory.

The extraction pipeline: Extraction → Consolidation → Reflection

Every built-in strategy runs the same async pipeline; the four types simply differ in which steps they use.

  1. Extraction — the model reads raw events and produces candidate insights (facts, preferences, episodes). Semantic, User Preference, and Episodic run this; Summary skips it.
  2. Consolidation — candidate insights are reconciled against existing records. The consolidation engine decides per record: ADD (new), UPDATE (supersede), or NO-OP (nothing new). Critically, when a record is superseded, the outdated one is marked INVALID rather than deleted — you keep an immutable audit trail of how the memory evolved. All four types run Consolidation.
  3. Reflectionepisodic only. After episodes accumulate, Reflection analyzes patterns across episodes to derive higher-order insights (the "use case" index).
text
 raw events
 [Extraction]      ← Semantic, User Preference, Episodic  (Summary skips)
     │  candidate insights
 [Consolidation]   ← ALL types: ADD / UPDATE / NO-OP
     │  outdated records → INVALID (kept, immutable audit)
 [Reflection]      ← EPISODIC ONLY: cross-episode patterns
 queryable memory records

Because the engine never destructively overwrites, you can audit why a memory record says what it says today — the superseded INVALID versions remain. Do not treat INVALID records as garbage to clean up; they are the history.

Watch out

Async means eventual consistency

The whole pipeline runs asynchronously after the event is written. A retrieve_memories call fired immediately after create_event may return nothing because Consolidation hasn't run yet. Tutorials add a deliberate time.sleep; production code should poll or tolerate the gap rather than assume the record exists.

Per-strategy quirks and overrides

Two built-in strategies have sharp edges that aren't obvious from the config key.

Summary is session-scoped — its namespace MUST contain {sessionId}. A summary describes one session, so AgentCore requires {sessionId} in the namespace template. Omit it and the strategy is misconfigured.

python
# CORRECT — summary namespace includes {sessionId}
{'summaryMemoryStrategy': {
    'name': 'SessionSummarizer',
    'namespaceTemplates': ['/summaries/{actorId}/{sessionId}/']}}

Episodic reflections can span multiple actors — a privacy gotcha. Reflection looks for patterns across episodes, and depending on how you've scoped namespaces, those episodes can belong to different actors. If actor A and actor B's episodes feed the same reflection, A's data can leak into an insight surfaced for B. Mitigate by reflecting at the actor level (scope the namespace so each actor's reflections stay within {actorId}) or by adding guardrails. Treat this as a default-unsafe behavior to design around, not an edge case.

Overrides: appendToPrompt REPLACES the default — despite the name. When you use built-in-with-overrides, the field is called appendToPrompt (max ~30 KB [VOLATILE — verify quotas]), but it does not append — it replaces the default extraction instructions. So you must rebuild on the documented base prompt, not just add a sentence to it. Two more rules: do not rename the consolidation operations (AddMemory / UpdateMemory) and do not change the record schema. Overrides also require memoryExecutionRoleArn, and the LLM calls are billed to your account.

python
# built-in-with-overrides sketch (custom strategy with overridden instructions)
{'customMemoryStrategy': {
    'name': 'DomainSemantic',
    'configuration': {
        # appendToPrompt REPLACES the default instructions — build on the base
        'appendToPrompt': '<your full extraction instructions, <= 30KB>',
        # plus your chosen Bedrock model id; requires memoryExecutionRoleArn on the memory
    }}}

Example

Scoping episodic safely

Pick a namespace like /episodes/{actorId}/ (and the reflection index per-actor) so reflections never reach across users. If your product genuinely needs cross-user patterns, do it deliberately with anonymization or a Bedrock Guardrail — never as an accidental side effect of a broad namespace template.

Watch out

appendToPrompt is a misnomer

It replaces, it does not append. If you treat it like an append and pass only a fragment, you lose the entire benchmarked base prompt and extraction quality collapses. Start from the documented base instructions and edit from there.

Try it: Configure all four strategy types and watch consolidation work

Goal: stand up a memory with multiple strategies, prove the SDK-key vs CLI-enum mapping, and observe the async pipeline and INVALID audit trail.

1. Create via the SDK. With boto3 bedrock-agentcore-control, call create_memory with three strategies in memoryStrategies: a semanticMemoryStrategy, a summaryMemoryStrategy (give it namespaceTemplates: ['/summaries/{actorId}/{sessionId}/'] — confirm it rejects a template missing {sessionId}), and a userPreferenceMemoryStrategy. Poll get_memory(...)['memory']['status'] until ACTIVE.

2. Prove the enum mismatch. In a fresh project, run agentcore add memory --name LabMem --strategies SUMMARY and observe the error. Fix it to SUMMARIZATION,SEMANTIC,USER_PREFERENCE, then agentcore deploy && agentcore status.

3. Write events and watch eventual consistency. Using the data-plane client bedrock-agentcore, create_event a short conversation (USER + ASSISTANT messages) that states a durable fact and a preference. Immediately call retrieve_memory_records — note it likely returns nothing. Add a time.sleep(40) and retry; the records should now appear.

4. Trigger an UPDATE. Write a second event that contradicts the earlier fact (e.g. the user changed a preference). After the async window, list the records and find the superseded one marked INVALID alongside the new ACTIVE record — that's the immutable audit trail.

5. Reason about episodic privacy. On paper, design a namespace template for an episodicMemoryStrategy that guarantees reflections never mix two actors. Explain in three sentences why /episodes/{actorId}/ is safer than /episodes/ and when you'd reach for a Bedrock Guardrail instead.

6. (Stretch) Overrides. Sketch a built-in-with-overrides semantic strategy: note that you'd need a memoryExecutionRoleArn on the memory, that appendToPrompt REPLACES the base instructions (so you build on the documented base), and that the Bedrock LLM calls would bill to your account.

Key takeaways

  1. 1A strategy defines what AgentCore extracts from raw events; with no strategy you get only short-term events and nothing is extracted. Attach at CreateMemory or later, up to a hard, non-adjustable cap of 6 strategies per memory.
  2. 2Three tiers trade control for cost: built-in (managed prompts, highest storage cost), built-in-with-overrides (your instructions + chosen Bedrock model, needs memoryExecutionRoleArn, LLM billed to you), and self-managed (you own extraction, lowest storage cost).
  3. 3Four built-in types: Semantic (facts), Summary (per-session summaries), User Preference (preferences/styles), Episodic (structured episodes + cross-episode Reflection).
  4. 4Naming gotcha: the SDK config key and CLI enum differ — summaryMemoryStrategy maps to SUMMARIZATION (NOT SUMMARY); semanticMemoryStrategy/SEMANTIC; userPreferenceMemoryStrategy/USER_PREFERENCE.
  5. 5Pipeline: Extraction → Consolidation (ADD/UPDATE/NO-OP; superseded records marked INVALID and kept as an immutable audit trail) → Reflection (episodic only). It's async, so design for eventual consistency.
  6. 6Summary requires {sessionId} in its namespace (it's session-scoped). Episodic reflections can span multiple actors — a privacy gotcha; reflect at the actor level or add guardrails.
  7. 7In built-in-with-overrides, appendToPrompt REPLACES the default instructions despite its name; build on the documented base, keep the consolidation op names and schema, and supply a memoryExecutionRoleArn.

Quiz

Lock in what you learned

Check your understanding

0 / 4 answered

1.You configured a memory with one strategy, write events all day, and `RetrieveMemoryRecords` keeps returning records that look stale or wrong shortly after each new event. What is the most likely cause?

2.Which mapping between the SDK/API config key and the starter-toolkit CLI enum is correct?

3.Your team needs a memory whose episodic reflections must NOT mix data across different end users. What is the right design?

4.You switch a semantic strategy to built-in-with-overrides and supply an `appendToPrompt` containing just one extra instruction sentence. Extraction quality collapses. Why?

Go deeper

Hand-picked sources to keep learning