Episodic memory
Episodic memory
Episodic memory is the embedding-backed memory layer for source-backed entries from previous threads. It helps an agent recognize similar situations without mixing episodic evidence into the user profile or session memory.
Memory.episodicMemory(...) and memory.episodicMemory.
agents_memory_entries, scoped by agentId + resourceId.
openai/text-embedding-3-small.
For implementation details and verbatim prompts, see the episodic memory implementation notes.
Runtime flow
Episodic memory has a read path before the model call and a write path after successful turns.
Configure
Enable memory.episodicMemory with an OpenAI credential.
Retrieve
Embed the current user message and search entries in the same agentId + resourceId scope.
Inject
Surface top entries in the model prompt as <memory>.
Answer
The model can use injected entries or call recall_memory for a deliberate lookup.
Extract
After the turn, extract, validate, dedupe, embed, and store new source-backed entries.
Entry shape
Stored entries are compact notes about concrete situations. They should preserve the useful mechanism, not just an isolated statement.
- Symptoms, environment details, and troubleshooting context.
- Causal mappings and directionality, such as which record held state and which record was checked.
- Mismatched identifiers or values, such as producer value versus matcher expectation.
- Assistant diagnostic findings, confirmed resolutions, outcomes, and open case state.
- Stable user preferences and profile-shaped context.
- Agent behavior rules or rewritten agent instructions.
- Current-thread objectives that only belong in session memory.
- Generic advice, recalled-memory restatements, or unsupported speculation.
{
"entries": [
{
"content": "A workspace stayed inactive after renewal because record A held the active subscription while record B was used for entitlement checks. Merging the records and refreshing derived entitlements resolved the lockout.",
"source": "verified_assistant_finding",
"evidence": "The active subscription is on record A, but entitlement checks are reading record B."
}
]
}
Extractor decisions
The extractor reads the role-labeled transcript JSON after the agent has answered. It writes entries only when the transcript contains durable episodic context that could help a future turn recognize a similar situation, continue an investigation, avoid repeated work, or apply a previous mechanism or fix. Known <user-profile> and <memory> context can be passed in for dedupe and exclusions, but those blocks are not sources for new entries.
- The transcript contains a concrete situation with a useful mechanism, current diagnostic state, attempted step, ruled-out path, outcome, or open question.
- The entry preserves causal direction, such as which record held state, which service checked it, or which emitted value did not match a rule.
- Unresolved cases are allowed when the observation is stable enough to resume later. Uncertainty stays explicit instead of being upgraded into fact.
- Useful details that only make sense together stay in one entry rather than being split into disconnected facts.
- Stable user preferences, user-profile details, and agent behavior rules are not episodic entries.
- Generic advice, assistant summaries, recalled-memory restatements, and unsupported recommendations are ignored.
- Earlier diagnostic branches are skipped when the same transcript later corrects or supersedes them.
- Current-thread details that have no likely value outside the thread are left to session memory.
user_assertion: the user directly stated the mechanism, fix, outcome, attempted step, or open state.user_accepted_assistant_proposal: the assistant proposed a mechanism or fix and the user explicitly accepted, applied, or verified it.verified_assistant_finding: the assistant stated a concrete diagnostic conclusion, ruled-out path, attempted-step result, or open case state.
- Every default-extracted entry must include exact evidence from the transcript.
- User-sourced entries require exact user-message evidence.
verified_assistant_findingcan use exact assistant evidence, or exact user evidence that confirms or grounds the finding.- After validation, entries are normalized, capped by
maxEntryLength, limited bymaxEntriesPerTurn, deduped by exact hash, checked for similarity duplicates, embedded, and stored.
Retrieval and injection
The runtime retrieves broadly enough for the current turn, then injects entries most-recent-first so stale case context is less likely to dominate fresh context.
autoInjectdefaults totrue.autoInjectTopKdefaults to12.- The current user message is the retrieval query.
recall_memory(query)remains available for more specific lookups.
- Ranking uses lexical and vector signals plus recency weighting.
- Exact normalized hashes prevent duplicate inserts.
- Similarity dedupe defaults to
dedupeSimilarityThreshold = 0.86. - Embedding vectors are never exposed to the frontend.
<memory> <description>Source-backed case entries retrieved from previous threads for this turn.</description> <value> - A priority item routed incorrectly because the source emitted tier=enterprise_plus while the matcher expected tier=enterprise-plus. Updating the matcher to accept both variants resolved the case. (2 days ago) </value> </memory>
Config and storage
{
"memory": {
"enabled": true,
"storage": "n8n",
"episodicMemory": {
"enabled": true,
"credential": "openai-credential-id"
}
}
}
const memory = new Memory()
.storage(myMemoryBackend)
.episodicMemory({
embedder,
embeddingModel: "openai/text-embedding-3-small",
});
agents_memory_entriesstores content, content hash, provenance fields, embedding model name, embedding values, metadata, and timestamps.- n8n JSON config stores only the episodic memory credential. The integration maps that credential to
openai/text-embedding-3-small. - SDK consumers pass a Vercel AI SDK
embedder.embeddingModelis the stored label for that embedder, not a frontend setting. - n8n resolves embedding credentials through n8n credentials. Episodic memory does not read embedding credentials from environment variables.
semanticRecallis a separate older recall path and is not part of Episodic memory.
Boundaries
Episodic memory only powers source-backed entries injected through <memory> and queried through recall_memory. <user-profile> is separate and stores what this agent remembers about the user. <session-memory> is separate and stores current-thread state.
- Read and write scope is fixed to
agentId + resourceId. - Episodic memory stores source-backed entries that may be useful in later threads.
- User-profile memory stores what this agent remembers about the user.
- Session memory stores the current thread objective, decisions, state, and follow-ups.