| name | memory |
| description | Persist important outcomes from this step to long-term storage with automatic forgetting curve. |
Memory
Purpose
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, ACT-R base-level activation, and optional spaced-review metadata from repeated presentation or retrieval.
Use When
Use this skill after meaningful observations, conversations, decisions, plan outcomes, emotional events, discoveries, or state changes that should affect future ticks.
Procedure
- Read relevant current state and recent
state/memory.jsonl entries if present.
- Decide whether the tick contains high-signal information worth preserving.
- Skip duplicates and routine noise.
- Append concise JSONL entries with type, summary, tags, tick/time, and importance.
- Run or schedule
scripts/memory_maintenance.py periodically to decay, reinforce, and prune old entries.
Write
Append state/memory.jsonl; the maintenance script rewrites the same file with retention metadata and pruning.
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
summary from 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 creation
S = memory strength coefficient (default: 100 ticks, configurable via AGENT_MEMORY_STRENGTH env 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:
_presentations stores the ticks when the memory was encoded or strongly re-encountered.
d defaults to 0.5, a common ACT-R decay value.
_access_count provides 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_count by 1 when the runtime can identify retrieval.
- Append current tick to
_presentations when the same fact/event is strongly re-encountered.
- Keep
_presentations short 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.
Spaced Review Metadata
For memories that should be deliberately revisited, optionally add:
| Field | Meaning |
|---|
_target_retention_interval | How many ticks the memory should remain useful |
_spacing_ratio | Conservative review gap as a fraction of the retention target, often 0.1-0.3 |
_next_review_tick | Tick when retrieval should be attempted again |
_last_retrieval_success | Whether the last review succeeded |
Guidelines:
- Use short review intervals for information needed soon.
- Use longer intervals for long-term identity, relationship, route, promise, or skill-relevant facts.
- Successful retrieval should increase strength and usually lengthen the next interval.
- Failed retrieval should shorten the next interval and keep the memory available for relearning.
- Avoid dense repetition immediately after successful recall; it has lower marginal benefit.
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_read any 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
done immediately.
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)
Notes
- 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.