Persistent Memory
By default, each agent job starts fresh with no memory of previous runs. This guide shows how to give agents persistent memory using a context file pattern.
The Problem
Section titled “The Problem”Without persistent memory, agents:
- Can’t track progress over time
- Repeat the same work each run
- Can’t learn from previous results
- Have no historical context
The Solution
Section titled “The Solution”Agents can maintain a context file (typically context.md) that persists between runs:
- At job start: Read the context file
- During execution: Use context to inform decisions
- At job end: Update the context file with results
Basic Implementation
Section titled “Basic Implementation”Agent Configuration
Section titled “Agent Configuration”name: my-agentdescription: An agent with persistent memory
system_prompt: | ## Context Management
You maintain a `context.md` file in the current directory.
At the START of each run: 1. Read context.md to understand your configuration and history 2. If context.md doesn't exist, create it with sensible defaults
At the END of each run: 1. Update context.md with the results of this run 2. Include timestamp and relevant data
allowed_tools: - Read - Write - Edit # Add other tools your agent needsContext File Structure
Section titled “Context File Structure”A well-structured context file might look like:
# Agent Context
## Configuration- **Target**: Office chairs under $200- **Retailers**: Staples, IKEA- **Check Frequency**: Every 4 hours
## Current Status- **Last Check**: 2024-01-15 09:00 UTC- **Status**: Monitoring- **Active Alerts**: None
## History| Date | Event | Notes ||------|-------|-------|| 2024-01-15 | Price check | Staples $159, IKEA $299 || 2024-01-14 | Price check | Staples $179, IKEA $299 || 2024-01-13 | Started | Initial configuration |Managing History Growth
Section titled “Managing History Growth”Without limits, history can grow indefinitely. Instruct your agent to maintain a bounded history:
system_prompt: | ## Context Management
When updating context.md: - Keep only the last 10 history entries - Delete older entries to prevent file growth - Always include the most recent resultExample bounded history section:
## Recent History (Last 10 Checks)| Date | Staples Price | IKEA Price | Notes ||------|---------------|------------|-------|| 2024-01-15 09:00 | $159.99 | $299.99 | Below target! || 2024-01-15 05:00 | $159.99 | $299.99 | || 2024-01-14 21:00 | $179.99 | $299.99 | |...Advanced Patterns
Section titled “Advanced Patterns”Structured JSON Context
Section titled “Structured JSON Context”For more complex state, use JSON:
system_prompt: | You maintain state in `context.json`. Example structure: ```json { "config": { "target": "office chair", "maxPrice": 200 }, "lastCheck": "2024-01-15T09:00:00Z", "history": [ {"date": "2024-01-15", "price": 159.99, "retailer": "Staples"} ] }Keep history array to last 10 entries.
### Separate Files for Different Purposes
For complex agents, use multiple files:
```yamlsystem_prompt: | You maintain several files: - `config.json` - User preferences (rarely changes) - `state.json` - Current monitoring state - `history.jsonl` - Append-only log of events
Read all at start. Update state.json and history.jsonl at end.Conditional Context Updates
Section titled “Conditional Context Updates”Only update context when meaningful changes occur:
system_prompt: | Update context.md only when: - Price changes from previous check - New alert condition is triggered - Configuration changes
If no changes, just update the "Last Check" timestamp.Example: Hurricane Watcher
Section titled “Example: Hurricane Watcher”The hurricane-watcher example demonstrates this pattern:
name: hurricane-watcherdescription: Monitors hurricane activity
system_prompt: | You maintain a `context.md` file to remember state between runs.
## Context File Structure
```markdown # Hurricane Watcher Context
## Configuration - **Monitoring Location**: [city, state/country] - **Check Frequency**: [how often you expect to run] - **Alert Threshold**: [threat level that triggers concern]
## Current Status - **Last Check**: [timestamp] - **Current Threat Level**: [NONE/LOW/MODERATE/HIGH/EXTREME] - **Active Storms**: [count and names if any]
## Recent History | Date | Threat Level | Notable Events | |------|--------------|----------------| | ... | ... | ... |Keep history to last 10 entries.
allowed_tools:
- WebSearch
- WebFetch
- Read
- Write
- Edit
## Excluding Context from Git
Add runtime context files to `.gitignore`:
```bash# .gitignorecontext.mdcontext.jsonstate.json*.jsonlmetadata.jsonThis keeps your repository clean while allowing local state persistence.
Combining with Metadata
Section titled “Combining with Metadata”Use context for long-term memory and metadata for hook triggers:
metadata_file: metadata.json
system_prompt: | ## Files You Maintain
1. **context.md** - Long-term memory and history 2. **metadata.json** - Current run results for notifications
At the end of each run: 1. Update context.md with results and history 2. Write metadata.json for conditional hooks: ```json { "shouldNotify": true, "summary": "Price dropped to $159" } ```
hooks: after_run: - type: discord when: "metadata.shouldNotify" channel_id: "..." bot_token_env: DISCORD_BOT_TOKENBest Practices
Section titled “Best Practices”- Use markdown for human-readable context - Easy to review and debug
- Bound history growth - Prevent unlimited file growth
- Include timestamps - Know when data was recorded
- Structure consistently - Make it easy for the agent to parse
- Exclude from git - Keep runtime state out of version control
- Store secrets in context - Use environment variables instead
- Allow unlimited growth - Agent will eventually hit context limits
- Rely on complex parsing - Keep format simple and predictable
- Mix config and state - Separate what changes from what doesn’t
Troubleshooting
Section titled “Troubleshooting”Context file keeps growing
Section titled “Context file keeps growing”Add explicit instructions to limit history:
system_prompt: | IMPORTANT: Keep the history section to exactly 10 entries. Delete the oldest entries when adding new ones.Agent doesn’t read context
Section titled “Agent doesn’t read context”Ensure Read tool is allowed:
allowed_tools: - Read # Required for reading context - Write - EditAgent creates inconsistent format
Section titled “Agent creates inconsistent format”Provide explicit examples in your system prompt:
system_prompt: | Your context.md MUST follow this exact format: ```markdown # Context
## Status - Last Check: [ISO timestamp] - Result: [one-line summary]
## History | Date | Result | |------|--------| | [date] | [result] |## Related Pages
- [Agent Configuration](/configuration/agent-config/) — Full configuration reference- [Hooks](/concepts/hooks/) — Combine with metadata for conditional actions- [Example Projects](/guides/examples/) — Working examples with persistent memory