Never lose context. Never forget decisions. Never repeat mistakes.
The memory problem is the single biggest reason agents feel dumb over time. Not the models. Not the prompts. Memory management.
MemoryRouter fixes it with one tool, zero dependencies, zero setup.
Agent memory files grow unbounded. After a week, you've got thousands of lines across dozens of files. Every session loads everything — even when the user asks "what's the weather?"
That's tokens burned on irrelevant memories, every interaction, forever.
Then compaction kicks in and details vanish.
The bottleneck isn't the model. It's what the model gets to see.
| Failure Mode | Cause | Fix |
|---|---|---|
| ------------- | ------- | ----- |
| Forgets everything | Loads irrelevant files, context window fills up | Smart manifest — load only what matters |
| Repeats mistakes | Lessons not captured or loaded | Entity index + audit for conflicts |
| Repeats work | No session state persistence | WAL protocol — write state before responding |
| Slow responses | Loads 50+ files when only 3 matter | Token budgeting — cap context window |
| Duplicates everywhere | No automated cleanup | --audit finds high-similarity pairs |
┌──────────────────────────────────────────────────────┐
│ MEMORYROUTER ⚡ │
├──────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ AUTO-TIER │ │ MANIFEST │ │
│ │ MEMORY.md │ → │ GENERATOR │ │
│ │ │ │ │ │
│ │ Core (always │ │ Required: │ │
│ │ loaded) │ │ MEMORY.md │ │
│ │ + Archive │ │ Recent logs │ │
│ │ (on demand) │ │ Boosted: │ │
│ └──────────────┘ │ entity files │ │
│ └──────┬───────┘ │
│ │ │
│ ┌──────────────▼──────────────┐ │
│ │ ENTITY RESOLUTION │ │
│ │ "alice" → preferences.md, │ │
│ │ notes.md, decisions.md│ │
│ └──────────────┬──────────────┘ │
│ │ │
│ ┌──────────────▼──────────────┐ │
│ │ TOKEN BUDGET FILTER │ │
│ │ 20K budget → 7 files │ │
│ │ 100K budget → 16 files │ │
│ └──────────────┬──────────────┘ │
│ │ │
│ ┌──────────────▼──────────────┐ │
│ │ AGENT LOADS ONLY WHAT │ │
│ │ MATTERS → 70-85% REDUCTION │ │
│ └─────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
node skills/memory-router/memory-router.js --tier --confirm
Output:
[memory-router] MEMORY.md: 7809 lines, 309254 chars
[memory-router] ✅ Pre-tier backup: memory/backups/MEMORY-backup-2026-05-23-1234567890.md (7809 lines saved)
[memory-router] Tiered: 202 core sections, 1002 archived
[memory-router] MEMORY.md reduced from 7809 lines to 2222 lines
node skills/memory-router/memory-router.js --tier --dry-run
Output:
[memory-router] MEMORY.md: 7809 lines, 309254 chars
[memory-router] ── DRY RUN ──
[memory-router] Would archive: memory/active/MEMORY-archive-2026-05-23.md
[memory-router] Would reduce MEMORY.md from 7809 lines to ~2222 lines
[memory-router] Core sections: 202, Archive sections: 1002
[memory-router] ✅ No files were modified.
node skills/memory-router/memory-router.js --restore --force
⚠️ Destructive — overwrites MEMORY.md. Requires --force flag. Extracts only the original content from the backup (metadata headers are stripped). Always creates a backup of the current MEMORY.md before overwriting.
node skills/memory-router/memory-router.js --compact
Creates memory/memory-manifest.json — the agent's shopping list of what to load.
node skills/memory-router/memory-router.js --compact --query "alice"
Files linked to "alice" get priority. No AI, no embeddings — just fast entity resolution.
node skills/memory-router/memory-router.js --compact --budget 20000
Only loads files that fit within 20K tokens. Tight budgets load core only. Generous budgets load archive on demand.
node skills/memory-router/memory-router.js --audit # Find duplicates & conflicts
node skills/memory-router/memory-router.js --status # Health overview
node skills/memory-router/memory-router.js --entity add alice person preferences.md
Memory management is the bottleneck, not model capability. Every agent system hits the same wall — context window fills up, everything loads, irrelevant memories dilute the signal.
MemoryRouter takes a routing approach rather than a compression approach:
User query → --compact --query "alice"
↓
Manifest generated
↓
Load required files (MEMORY.md, recent daily logs)
↓
Boost entity-matched files (preferences.md, notes.md)
↓
Agent loads only what matters → 70-85% context reduction
--tier)When MEMORY.md exceeds configurable thresholds (default: 500 lines or 25KB), splits into:
memory/active/Safety features (v2):
--tier creates a full backup in memory/backups/ before modifying MEMORY.md--dry-run — Preview what tiering would do without making changes--confirm — Required for destructive writes (no auto-tier without explicit confirmation)minCoreLines/minCoreChars thresholds--restore --force — Restore MEMORY.md from the latest backup (requires --force flag)Sections are classified by header keywords (identity, preferences, etc.) or by content heuristics.
--compact)Creates memory/memory-manifest.json with a file list:
{
"generated": "2026-05-21",
"files": [
{ "path": "MEMORY.md", "tier": "core", "required": true, "size": 50346 },
{ "path": "memory/2026-05-21.md", "tier": "recent", "required": true, "size": 2034 },
{ "path": "self-improving/memory.md", "tier": "domain", "required": false, "size": 670 }
]
}
Options:
| Flag | Description |
|---|---|
| ------ | ------------- |
--query "text" | Entity-aware boosting — files linked to matching entities get priority |
--budget N | Token budget — only loads files that fit within N tokens |
--audit)Scans all memory files for:
Output: memory/memory-audit-report.md
--status)Quick snapshot of MEMORY.md line/char counts, file counts per directory, archive count, manifest status, entity index size, and WAL state.
--entity)| Command | Description |
|---|---|
| --------- | ------------- |
--entity add | Add entity (e.g., alice person preferences.md) |
--entity list | List all entities |
--entity search | Search entities (direct and fuzzy match) |
--wal)| Command | Description |
|---|---|
| --------- | ------------- |
--wal init | Initialize SESSION-STATE.md with template |
--wal get | Show current session state |
--wal update | Update a section |
Edit config.json to customize behavior:
{
"thresholds": {
"memoryMdMaxLines": 500,
"memoryMdMaxChars": 25000,
"tierArchiveMinAgeDays": 3,
"auditMaxFiles": 50
},
"tiering": {
"archiveDir": "memory/active",
"retentionDays": 90,
"keepInMemory": [
"identity", "preferences", "relationships",
"projects", "patterns", "boundaries", "key_facts"
]
},
"manifest": {
"generateOnTier": true,
"manifestPath": "memory/memory-manifest.json"
},
"audit": {
"reportPath": "memory/memory-audit-report.md",
"duplicateThreshold": 0.7,
"conflictKeywords": [
"revised", "updated", "changed", "no longer",
"actually", "correction", "mistake"
]
}
}
| Setting | Default | Description |
|---|---|---|
| --------- | --------- | ------------- |
memoryMdMaxLines | 500 | Auto-tier trigger (lines) |
memoryMdMaxChars | 25000 | Auto-tier trigger (characters) |
tierArchiveMinAgeDays | 3 | Minimum age before archiving |
retentionDays | 90 | ⚠️ Archive retention period. Files older than this are candidates for deletion (irreversible). Set to 365+ until confident. |
keepInMemory | see above | Headers/keywords that stay in core |
generateOnTier | true | Auto-generate manifest after tiering |
duplicateThreshold | 0.7 | Similarity score to flag as duplicate |
conflictKeywords | see above | Words that signal fact revision |
backupDir | memory/backups | Directory for pre-tier backups |
minCoreLines | 20 | Abort if core sections below this |
minCoreChars | 1000 | Abort if core chars below this |
When the agent wakes up, use the manifest instead of loading all memory files:
memory/memory-manifest.jsonrequired: true filesrequired: false files, use memory_search to check relevanceResult: 70–85% context reduction — load what matters, skip the rest.
Add to your HEARTBEAT.md:
### ⚡ MemoryRouter (SAFE commands only)
- Run `node skills/memory-router/memory-router.js --compact` to update manifest ✅ safe
- Run `node skills/memory-router/memory-router.js --audit` to check for issues ✅ safe
- Run `node skills/memory-router/memory-router.js --status` for health overview ✅ safe
- ⚠️ Do NOT auto-run `--tier` or `--restore` during heartbeats
- `--tier --dry-run` is side-effect free (no files created)
- For tiering: run `--tier --dry-run` manually, review output, then `--tier --confirm`
| Metric | Result |
|---|---|
| -------- | -------- |
| Tiering speed (8K lines) | 25ms |
| Tiering speed (15K lines) | 30ms |
| Token reduction | 96% (7,809 → 222 lines) |
| File count reduction | 53 → 15 files |
| Memory footprint | ~2MB (Node.js runtime) |
| Approach | Tokens Saved | Setup Effort | Maintenance | Privacy |
|---|---|---|---|---|
| ---------- | ------------- | ------------- | ------------- | --------- |
| Raw file injection | 0% | None | Manual | ✅ |
| MemoryRouter | 70–85% | None | Automated | ✅ |
| Obsidian vault | 40–60% | High | Medium | ⚠️ Cloud |
| Vector DB (ChromaDB) | 70–85% | Very High | High | ✅ |
| mem0 | 70–85% | High | Medium | ⚠️ Cloud |
MemoryRouter gives you the best token savings of the vector DB approach with zero setup effort.
Pick one canonical name per entity and reuse it consistently:
--entity search periodically to verify your indexExamples:
# ✅ Good — consistent, descriptive
node memory-router.js --entity add alice person preferences.md
node memory-router.js --entity add openclaw system AGENTS.md
# ❌ Bad — inconsistent, ambiguous
node memory-router.js --entity add alice person preferences.md
node memory-router.js --entity add Alice person notes.md
node memory-router.js --entity add JS person docs.md
The manifest JSON tells the agent which files to load:
{
"generated": "2026-05-21",
"version": 2,
"query": "memory management",
"budget": 20000,
"files": [
{
"path": "MEMORY.md",
"tier": "core",
"required": true,
"size": 50346
},
{
"path": "memory/2026-05-21.md",
"tier": "recent",
"ageDays": 0,
"required": true,
"size": 2034
},
{
"path": "self-improving/memory.md",
"tier": "domain",
"required": false,
"size": 670
}
]
}
| Field | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
tier | string | core, recent, domain, or archive |
required | bool | Always load this file |
size | int | File size in bytes |
boosted | bool | Entity match — higher priority |
entityMatch | string | Entity name that matched |
load | bool | Included under budget mode |
budgetUsed | int | Total tokens loaded (budget mode) |
budgetEfficiency | string | Percentage remaining (budget mode) |
| Problem | Fix |
|---|---|
| --------- | ----- |
| "No MEMORY.md found" | Create one: echo "# MEMORY.md" > MEMORY.md |
| "Memory directory not found" | Create it: mkdir -p memory |
| Tiering not working | Check thresholds — if under 500 lines and 25KB, nothing happens (by design) |
| Manifest shows wrong files | Run --compact again — it regenerates fresh each time |
| Entity search returns nothing | Add entities first: --entity add |
| Budget too small | Core files always load. Budget only controls optional files. |
--tier and --restore permanently modify user memory files.
--tier rewrites MEMORY.md, moving sections to archive files--restore overwrites MEMORY.md with backup content--confirm / --force) — they will refuse to run without it--tier --dry-run first to preview what will changeThe retentionDays config (default: 90) marks archived files as candidates for deletion after that period. This is irreversible — once deleted, archived memory sections cannot be recovered.
Before enabling retention:
memory/ directoryretentionDays to a large value (365+) until you're confident| Command | Safe in automation? | Modifies files? |
|---|---|---|
| --------- | ------------------- | ------------------ |
--compact | ✅ Yes | Writes memory-manifest.json (generated output) |
--audit | ✅ Yes | Writes memory-audit-report.md (generated report) |
--status | ✅ Yes | No file writes |
--entity add | ⚠️ Yes — but writes entity index | Yes (persists entity → file mapping) |
--entity list/search | ✅ Yes | No file writes |
--wal init | ⚠️ Yes — but creates SESSION-STATE.md | Yes (creates new file) |
--wal get | ✅ Yes | No file writes |
--wal update | ⚠️ Yes — but modifies SESSION-STATE.md | Yes (updates session state) |
--tier --dry-run | ✅ Yes | No file writes (side-effect free) |
--tier --confirm | ❌ No — rewrites MEMORY.md + creates backup | Yes |
--restore --force | ❌ No — overwrites MEMORY.md | Yes |
--compact, --audit, --status, --entity list/search, --wal get, and --tier --dry-run are safe for unattended/heartbeat use.
--entity add, --wal init, and --wal update write persistent files — review before automating.
--tier --confirm and --restore --force are destructive — never automate.
Built with defense-in-depth:
--confirm, --force)共 5 个版本