How Memory Types Interact
The four memory types do not operate independently — they are orchestrated together by MemoryOrchestrator before every LLM call, and the results all flow into working memory. Understanding the interaction order and write-back pattern is essential to debugging unexpected agent behaviour.
The Read Phase: Pre-LLM Retrieval
Before every LLM call, three of the four memory types are queried in parallel. Working memory is always built; it receives the results from the others:
Task.WhenAll.
The Write Phase: Post-Response Storage
After the LLM response is received, two write-back operations may occur:
| Trigger | Memory Written | What Is Stored |
|---|---|---|
| Every turn | Working memory (next turn) | The user message + assistant response are appended to the in-memory conversation history for the next turn's context |
| Session end | Episodic memory (SQL) | Conversation summary + key facts + embedding written as an episode row |
| Multi-step task completion (optional) | Procedural memory (SQL, pending) | If ProcedureCaptureService detects a completed multi-step task, it stores a new procedure in pending-approval state |
| Document ingestion (manual) | Semantic memory (vector DB) | Indexed chunks added to the agent's vector collection |
Context Assembly Order
All four memory types contribute to working memory, assembled in this fixed order (highest-to-lowest model attention):
┌─────────────────────────────────────────────────┐
│ 1. System Prompt │ ← AgentComposite.SystemPrompt
├─────────────────────────────────────────────────┤
│ 2. Matched Procedure │ ← ProceduralMemory result
│ Step 1: Ask for vendor name... │
│ Step 2: Call vendor_lookup... │
├─────────────────────────────────────────────────┤
│ 3. Retrieved Knowledge │ ← SemanticMemory result
│ Source: HR Policy 2025.pdf │
│ Content: "Annual leave entitlement is..." │
├─────────────────────────────────────────────────┤
│ 4. Past Conversation Snippets │ ← EpisodicMemory result
│ 2025-03-14: User asked about leave balance │
├─────────────────────────────────────────────────┤
│ 5. Message History (pruned to budget) │ ← WorkingMemory (turns 1..n-1)
│ User: Hi, how many days do I have? │
│ Aria: You have 12 remaining. │
├─────────────────────────────────────────────────┤
│ 6. Current User Message │ ← Highest model attention
│ User: Can I take 5 days in June? │
└─────────────────────────────────────────────────┘
Priority Conflicts: When Memory Types Contradict
Because all memory types contribute to the same context window, conflicts can arise. The LLM resolves conflicts according to attention position — later content overrides earlier content for instruction-following. Design guidelines to avoid conflicts:
| Conflict Scenario | Result | Recommended Fix |
|---|---|---|
| Procedure says "Step 1: ask for name" but semantic knowledge says "skip if internal user" | LLM may be confused | Add conditional logic in the procedure step definition |
| Episodic snippet says user has 12 days remaining; database now shows 8 | LLM may quote stale data | Ensure live data queries (tools) override injected context — instruct in system prompt |
| Too many memory sources injected; message history pruned severely | Agent loses short-term context | Reduce SemanticTopK and EpisodicTopK to preserve more message history budget |
Use the Context Inspector (available to the OctopusDebug role) to inspect exactly what each memory type contributed to a specific turn. This is the fastest way to diagnose unexpected agent responses caused by conflicting memory content.