agent-memory-skill/docs/architecture.md

193 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Memory Architecture
## The Problem
AI agents forget everything between sessions. Common solutions (dump everything into context, vector-search everything) create bloat and noise. Human memory works differently: it has layers, it decays, and it surprises you with random connections.
## Design Principles
### Single Source of Truth (DRY)
Each fact lives in ONE place. If a contact exists in a CRM card, don't also list them in a "key contacts" section of your state file. Instead, reference them: `see vault/crm/alice.md`.
**Violation test:** Search for any person/project name. If it appears in 3+ files with substantive detail, you have a DRY violation.
### Context is a Shared Resource (KISS)
Every byte loaded per turn costs tokens. An agent loading 40KB of context files is burning ~10,000 tokens before the conversation starts. Measure your context budget:
- State file (volatile): target <4KB
- Config files: target <15KB total
- Per-turn overhead = sum of all always-loaded files
### Build Only What You Use (YAGNI)
Don't create "knowledge graphs," "daily digests," or "weekly reviews" unless you actively query them. If a cron job generates a report nobody reads, it's waste.
## Three-Layer Architecture
```
Layer 1: HOT CONTEXT (always loaded, <4KB)
└── State file — volatile: active focus, blockers, reminders
NOT: contacts, history, reference, tools
Layer 2: SEARCHABLE VAULT (on-demand, unlimited)
└── Cards with YAML frontmatter — one file per entity
Searched via: semantic search, grep, graph traversal
Organized by: domain directories + index files (MOC)
Layer 3: ARCHIVE (deep search only)
└── Old daily logs, completed projects, cold contacts
Still searchable but excluded from default queries
```
### Layer 1: Hot Context
This is what's loaded every turn. Must be ruthlessly slim.
**Include:** Current week's focus, active blockers, 3-5 pending items, security rules, navigation hints.
**Exclude:** Contact lists (use vault), tool docs (separate file), event history (daily files), anything searchable.
**Audit:** If your state file exceeds 80 lines, something belongs in Layer 2.
### Layer 2: Searchable Vault
One markdown file per entity (person, project, company, idea). YAML frontmatter enables filtering and automation.
**Directory structure:**
```
vault/
├── crm/ # contacts and companies
│ ├── clients/
│ ├── leads/
│ └── personal/
├── projects/ # active and past projects
├── MOC/ # Maps of Content (index files)
└── .graph/ # computed graph data
```
**Why one file per entity:** Enables granular decay, individual relevance scoring, and precise search results. A single "contacts.md" with 200 entries can't decay the whole file is either loaded or not.
### Layer 2b: Daily Files (Episodic Memory)
Daily logs (`YYYY-MM-DD.md`) sit between vault and archive. They capture the raw narrative of each day conversations, decisions, reasoning, context that doesn't fit neatly into entity cards.
**Never delete daily files.** The decay system handles visibility:
- Active (0-7 days): loaded at session start
- Warm (8-21 days): searchable, not auto-loaded
- Cold (22-60 days): deep search only
- Archive (60+): creative mode, explicit queries
**Why keep everything:**
- Disk: 365 daily files 4MB. Irrelevant cost.
- Context: knowledge graphs capture entities but lose reasoning and tone.
- Search: semantic search finds old dailies just as well as new ones.
- Source rebuild: re-reading 100+ messages is far more expensive than keeping a 10KB summary.
**Compression:** If a daily file exceeds 20KB, extract key facts into vault cards and trim the daily to a 20-line summary. Keep the YAML frontmatter intact.
### Layer 3: Archive
One-off analysis reports. Completed project retrospectives. Generated artifacts that served a temporary purpose. These are still searchable but excluded from default queries. Daily files are NOT archive they stay in their directory with tier-based visibility.
## Forgetting Curve
Inspired by Ebbinghaus (1885): memory strength decays over time without reinforcement.
### Relevance Score
Each card has `relevance: 0.0-1.0` in its frontmatter. Decays linearly:
```
relevance = max(floor, 1.0 - days_since_access × rate)
Default: rate=0.015, floor=0.1
→ After 7 days: 0.90
→ After 21 days: 0.69
→ After 33 days: 0.50
→ After 60 days: 0.10 (floor)
```
### Tier Assignment
Based on days since `last_accessed`:
| Tier | Days | Description |
|------|------|-------------|
| core | manual | Never auto-assigned. Identity, security, pricing. |
| active | 0-7 | Hot context. Searched in all modes. |
| warm | 8-21 | Default search radius. Gradually fading. |
| cold | 22-60 | Deep search only. Mostly forgotten. |
| archive | 60+ | Creative mode or explicit recall only. |
### Touch Protocol
When an agent reads or references a card, it should promote the card:
```bash
python3 memory-engine.py touch <filepath>
```
Each touch promotes one tier up (graduated recall), not straight to top.
Multiple reads = stronger memory natural spaced repetition.
**When to touch:**
- Agent reads card content to answer a question
- Agent updates card with new information
- User explicitly mentions the entity
**When NOT to touch:**
- Card appears in search results but isn't opened
- Automated scan (decay script itself)
- Bulk operations
## Search Protocols
Different tasks need different search depths:
### Heartbeat Mode (fast checks)
Search: core + active only.
Use for: quick status checks, routine monitoring, simple questions.
Cost: minimal only hot cards in scope.
### Normal Mode (default)
Search: core + active + warm.
Use for: most questions, task execution, lookups.
Cost: moderate includes fading but recent cards.
### Deep Mode (complex tasks)
Search: all tiers.
Use for: strategy, complex analysis, "find everything about X."
Cost: high full vault scan.
### Creative Mode (divergent thinking)
Method: random sample from cold + archive tiers.
Use for: brainstorming, finding unexpected connections, "what if" scenarios.
Not semantic search deliberately random to surface forgotten associations.
```bash
python3 memory-engine.py creative 5 vault/
```
## Multi-Agent Shared Memory
When multiple agents share a vault:
1. **Shared YAML schema** all agents use same frontmatter fields
2. **Each agent touches on read** keeps decay accurate across agents
3. **One vault, one truth** don't fork the vault per agent
4. **Conflict resolution** last write wins for metadata; append-only for history sections
## Context Budget Calculator
Measure your actual per-turn cost:
```
Always-loaded files:
STATE.md _____ bytes
CONFIG.md _____ bytes
IDENTITY.md _____ bytes
RULES.md _____ bytes
─────────────────────────
Total context: _____ bytes ÷ 4 ≈ _____ tokens
Target: <25KB (6,000 tokens) for always-loaded context
```
Every 1KB saved = ~250 tokens freed per turn for actual conversation.