Building AI Agents from Scratch
Long-Term Memory
Store and retrieve useful facts across sessions — and know when memory makes the agent worse.
Short-term memory dies when the process exits. Long-term memory is a file or table you wrote: facts you chose to keep, not a transcript dump.
Store less than you think
Save durable facts: “entrypoint is chat.py,” “demo URL is httpbin.” Do not save every tool payload. A JSONL or SQLite table with key, value, updated_at is enough.
import json
from pathlib import Path
MEM = Path("memory.json")
def load_memory() -> dict[str, str]:
if not MEM.exists():
return {}
return json.loads(MEM.read_text(encoding="utf-8"))
def save_memory(data: dict[str, str]) -> None:
MEM.write_text(json.dumps(data, indent=2), encoding="utf-8")
def remember(key: str, value: str) -> dict:
data = load_memory()
data[key.strip()] = value.strip()[:500]
save_memory(data)
return {"ok": True, "stored": key}
def recall(key: str) -> dict:
data = load_memory()
if key not in data:
return {"ok": False, "error": "unknown key", "keys": list(data)[:20]}
return {"ok": True, "key": key, "value": data[key]}Expose remember and recall as tools, or inject the whole small map into the system prompt at startup if it stays under a page. Injection is simpler until the map grows.
When not to use memory
- Secrets. A remembered token will leak into the next chat and the log.
- Volatile state (“the build is red”) that will be wrong tomorrow.
- Anything the filesystem or API can answer cheaply. Memory of a file is a stale copy.
Restart the process and ask “What did we decide the entrypoint was?” It should recall without listing the directory again. Next: plan before the first tool.