Memory
You are the agent's long-term memory system with automatic forgetting and retrieval reinforcement. When you run this skill, decide what's worth remembering and append it to state/memory.jsonl.
Internal Logic (One Sentence)
Select a small set of high-signal events from this tick, append them to state/memory.jsonl, then rely on a maintenance script to combine Ebbinghaus-style retention decay with ACT-R base-level activation from repeated presentation or retrieval.
Architecture (conceptual)
Three layers:
1. Working context (implicit)
- What: Recent tool-loop messages plus any workspace files you choose to read in this step.
- Purpose: Immediate reasoning; there is no separate hidden memory buffer beyond workspace + thread.
- Usage: Read only files that exist; skip missing paths.
2. Long-term store (state/memory.jsonl)
- What: JSONL in the agent workspace with automatic forgetting.
- Purpose: Persist what should survive across ticks (events, decisions, plan outcomes).
- Forgetting: Old memories fade and are eventually removed (see Forgetting and Activation below).
- Reinforcement: Frequently accessed or repeated memories are reinforced and last longer.
3. Optional "step bundle" (convention)
- If you want one rich JSONL line per tick, you may bundle highlights into
summaryfrom whatever files you read in this step-purely optional.
Forgetting and Activation
Memories naturally decay over time, but repeated experience and retrieval should make a memory easier to recover. This skill therefore uses two complementary signals:
- Ebbinghaus-style retention for simple time decay.
- ACT-R base-level activation for repeated presentation/retrieval.
Research basis: references/research_basis.md.
Retention Formula
retention = e^(-t / (S x importance_multiplier))
Where:
t= ticks since memory creationS= memory strength coefficient (default: 100 ticks, configurable viaAGENT_MEMORY_STRENGTHenv var)importance_multiplier= high: 1.5, medium: 1.0, low: 0.5
ACT-R Base-Level Activation
The maintenance script also computes:
activation = ln(sum((current_tick - presentation_tick)^(-d))) + importance_bonus + access_bonus
retrieval_probability = logistic(activation - threshold)
retention = max(ebbinghaus_retention, retrieval_probability)
Where:
_presentationsstores the ticks when the memory was encoded or strongly re-encountered.ddefaults to0.5, a common ACT-R decay value._access_countprovides a small retrieval-practice bonus.- The max rule keeps the simple forgetting curve as a conservative floor while allowing repeated social facts, names, promises, and routes to persist.
Decay Rules
| Retention Level | Status | Behavior |
|---|---|---|
retention > 0.5 |
Active | Memory is fully accessible |
0.1 < retention < 0.5 |
Fading | Memory marked as _faded: true |
retention < 0.1 |
Forgotten | Memory is removed from the store |
Reinforcement
When a memory is accessed or re-encoded:
- Increase
_access_countby 1 when the runtime can identify retrieval. - Append current tick to
_presentationswhen the same fact/event is strongly re-encountered. - Keep
_presentationsshort if needed by retaining the newest and most important ticks.
This models retrieval practice and repeated exposure without pretending the simulation has exact human neural memory.
Memory Limits
To prevent unbounded growth:
- Default maximum: 1000 entries (configurable via
AGENT_MEMORY_MAX_ENTRIES) - When over limit, lowest-retention memories are removed first
Importance Guidelines
When writing memories, set importance appropriately:
| Importance | Use Case | Retention (approx) |
|---|---|---|
high |
Life-changing events, critical decisions, major discoveries | ~150 ticks |
medium |
Notable events, moderate decisions (default) | ~100 ticks |
low |
Minor observations, routine activities | ~50 ticks |
Tip: Set importance: high for memories that should persist across the entire simulation.
Entry type values (recommended)
Use type to help future grep / manual scanning:
| Type | When it applies | Example |
|---|---|---|
need |
After notable need change | "Satiety dropped; decided to find food" |
emotion |
After strong emotion / regulation | "Relieved after plan succeeded" |
cognition |
Thought / appraisal update | "Reframed delay as acceptable" |
intention |
Intention changed | "Switched intention to head home" |
plan |
Plan created or revised | "New plan: 3 steps to reach clinic" |
react |
Notable environment interaction | "codegen: move to cafe" |
plan_execution |
Step finished or failed | "Step 'walk to cafe' completed" |
event |
General occurrence | "Met Alice; she mentioned the job" |
observation |
Notable perception to recall later | Short summary of what you saw / heard |
social / decision / discovery / plan_outcome |
As in the table below |
Use type + tags so grep and tail-scans stay useful.
When to Write a Memory
Write a memory when:
- You had a meaningful interaction (conversation, transaction, conflict)
- You discovered something new (a new location, a new agent, useful information)
- An important state change occurred (need became critical, plan completed/failed)
- You made a significant decision (changed plans, formed an opinion)
- Something emotionally notable happened
Skip memory when:
- Nothing happened (idle tick, walking without events)
- The observation is essentially the same as last tick
- The information is already captured in a recent memory entry
Memory Entry Format
Each entry is a single JSON line in state/memory.jsonl:
{"tick": 42, "time": "2024-01-15T10:30:00", "type": "event", "summary": "Met Alice at the park. She mentioned a job opening at the library.", "tags": ["social", "alice", "job"], "importance": "medium"}
Fields
| Field | Type | Description |
|---|---|---|
tick |
int | Current tick number (from the step context) |
time |
string | ISO format timestamp |
type |
string | Category - see Memory Types below |
summary |
string | 1-2 sentence factual description of what happened |
tags |
list | 2-5 short keywords for retrieval (agent names, locations, topics) |
importance |
string | high (life-changing), medium (notable), low (minor) |
How to Write
- Optionally
workspace_readany relevant context files. - Decide if anything is worth remembering (see criteria above).
- If yes, construct the memory entry and append:
{
"tool_name": "workspace_write",
"arguments": {
"path": "state/memory.jsonl",
"content": "<existing content>\n<new JSON line>"
}
}
Important: Since workspace_write overwrites the file, first workspace_read("state/memory.jsonl") to get existing content, then append the new entry.
- If nothing notable happened, call
doneimmediately.
Memory Retrieval
Readers of state/memory.jsonl typically scan the last few lines for recent context.
Reading Recent Memories
Focus on the most recent entries (last 5-10) when you need continuity.
Searching older memories
Use grep on state/memory.jsonl to search for names or tags.
Maintenance Script
Run periodically to apply forgetting curve:
python skills/memory/scripts/memory_maintenance.py \
--memory-file state/memory.jsonl \
--current-tick 100
Configuration via environment variables:
AGENT_MEMORY_STRENGTH: Memory strength coefficient (default: 100)AGENT_MEMORY_ACTR_DECAY: ACT-R decay parameter (default: 0.5)AGENT_MEMORY_RETRIEVAL_THRESHOLD: logistic retrieval threshold (default: -2.5)AGENT_MEMORY_MAX_ENTRIES: Maximum memories to keep (default: 1000)
Guidelines
- Keep summaries concise (1-2 sentences max). This is a log, not a diary.
- Use specific names and locations, not vague references.
- Don't duplicate information already in the most recent memory entry.
- Timestamp all entries for temporal reasoning.
- Tag entries with relevant keywords for efficient retrieval.
- Set importance based on how long the memory should persist.