Self-Updating Instructions (Procedural Memory)

Table of content

Your CLAUDE.md file is static. You write it once, update it manually when something breaks, and hope you remember to capture lessons learned. Most don’t. The same mistakes recur across sessions because the agent can’t learn from its own failures.

Self-updating instructions flip this model. The agent observes what works, what fails, and what you correct. It modifies its own operating instructions automatically. This is procedural memory: the “know-how” that persists across sessions.

CoALA’s memory model

The Cognitive Architectures for Language Agents (CoALA) paper by Sumers et al. divides agent memory into four types:

Memory TypeContentsUpdate Frequency
WorkingCurrent contextEvery turn
EpisodicPast experiencesPer session
SemanticFacts and knowledgeWhen learned
ProceduralOperating instructionsWhen behavior changes

Procedural memory stores the agent’s operational knowledge. This includes prompt templates, code snippets for common tasks, and decision-making rules. Unlike episodic memory (what happened), procedural memory encodes how to act.

Most AI tools only implement working memory. Some add episodic (conversation history). Almost none update procedural memory automatically.

Generative agents: where this started

The 2023 Generative Agents paper from Stanford built a simulated town where 25 AI agents lived, formed relationships, and organized events without scripting. The agents decided what to do based on memories of past interactions.

Their memory architecture:

Observe → Store → Retrieve → Reflect → Plan → Act

Observations feed into a memory stream. Each observation gets scored on recency and importance. When accumulated importance exceeds a threshold (roughly 2-3 times per day), the agent generates reflections: higher-level, abstract thoughts synthesized from recent observations.

These reflections become retrievable alongside raw observations. When planning actions, the agent queries its memory for relevant observations and reflections, then decides what to do.

Reflections are not summaries. They’re generalizations. An agent that observes “Isabella always greets me warmly” and “Isabella invited me to her party” might reflect “Isabella considers me a friend.” That reflection changes how the agent behaves toward Isabella going forward.

Ablation studies showed all three components matter. Remove reflection and agents lose coherence over time.

Lance Martin’s Claude Diary

Lance Martin of LangChain built a working implementation of self-updating instructions for Claude Code. His claude-diary plugin transforms session logs into persistent rules that update CLAUDE.md automatically.

The approach:

  1. Session logs accumulate in ~/.claude/projects/
  2. At session end, an LLM reads the logs
  3. It extracts generalizable lessons (“when X happens, do Y”)
  4. These become new rules in CLAUDE.md

Episodic memory becomes procedural memory. The agent learns your preferences without you encoding them by hand.

Example transformation:

Session log: "User corrected agent's TypeScript. Agent used 'any' type,
user requested explicit types. Agent redid with interfaces."

Generated rule: "Always use explicit TypeScript types. Prefer interfaces
over 'any'. Ask for type definitions if unclear."

The rule persists across sessions. Future Claude instances start with this knowledge built in.

Alex Newman’s claude-mem

Alex Newman’s claude-mem takes a different approach to the same problem. Rather than extracting rules, it compresses observations and injects relevant context at session start.

The philosophy: “Memory isn’t storage. It’s compression.”

Observe → Compress → Store → Retrieve → Inject

Each tool call during a session generates an observation. These get compressed to roughly 500 tokens each, then stored with embeddings for retrieval. At the next session start, relevant memories load automatically.

This preserves context without manual CLAUDE.md updates. The agent remembers what it did, which tools worked, and what you corrected. It can’t modify its base instructions, but it can recall similar situations.

The difference:

ApproachWhat UpdatesGranularityExplicitness
Claude DiaryInstructions in CLAUDE.mdBroad rulesHuman-readable rules
claude-memContextual memoriesSpecific observationsImplicit patterns

Both beat static instructions. Claude Diary writes explicit rules. claude-mem retrieves relevant past observations.

Implementation patterns

Extract-and-write

The simplest form. Parse session logs, extract lessons, append to instructions.

def update_instructions(session_log, instructions_file):
    lessons = llm.extract(
        session_log,
        prompt="What reusable lessons should be added to the agent's instructions?"
    )

    if lessons:
        with open(instructions_file, "a") as f:
            f.write(f"\n## Learned from session {session_id}\n")
            f.write(lessons)

Simple, explicit, auditable. But instructions grow without bound and duplicates pile up.

Reflection triggers

Like Generative Agents, trigger reflection when importance accumulates past a threshold.

class AgentMemory:
    def __init__(self, reflection_threshold=100):
        self.observations = []
        self.importance_sum = 0
        self.threshold = reflection_threshold

    def observe(self, event):
        importance = self.score_importance(event)
        self.observations.append((event, importance))
        self.importance_sum += importance

        if self.importance_sum > self.threshold:
            self.reflect()
            self.importance_sum = 0

    def reflect(self):
        recent = self.observations[-20:]  # Last 20 observations
        reflection = llm.synthesize(
            recent,
            prompt="What patterns or lessons emerge from these observations?"
        )
        self.observations.append((reflection, high_importance))

Self-regulating. Can produce useful generalizations. But reflection quality varies and failures are hard to trace.

Correction detection

When users override agent output, that’s signal. Watch for corrections specifically.

def on_user_edit(original, corrected, context):
    if significant_difference(original, corrected):
        lesson = llm.extract(
            f"Original: {original}\nCorrected: {corrected}\nContext: {context}",
            prompt="What should the agent do differently next time?"
        )
        add_to_procedural_memory(lesson)

Corrections are failures. Capturing them builds memory around your actual preferences and edge cases.

What to update

Not all observations should become instructions. Filter for:

Update TypeExampleValue
Preferences“Use tabs not spaces”High
Corrections“Don’t commit .env files”High
Patterns“Always run tests before commit”High
One-off fixes“Fixed typo in config.json”Low
Context“Working on auth feature”Episodic only

Preferences and corrections become procedural memory. One-off fixes and contextual notes stay episodic.

What goes wrong

Self-updating instructions fail in predictable ways:

RiskExampleMitigation
OverfittingOne bad experience becomes absolute ruleRequire multiple observations before rule creation
ContradictionNew rule conflicts with existing ruleCheck for conflicts before adding
Unbounded growthInstructions file becomes unmanageableSet size limits, prune old rules
DriftAgent behavior diverges from intentHuman review of new rules
Lock-inEarly mistakes become permanentVersion control, periodic review

The CoALA paper warns that procedural updates “are risky both for the agent’s functionality and alignment.” Review generated rules before they take effect.

Practical setup

For Claude Code users, start with one of these approaches:

Manual reflection (no plugins required):

End each session with: “What lessons from this session should be added to CLAUDE.md?”

Review suggestions, add the good ones manually. This builds the habit without automation risk.

claude-diary (automated rules):

Install from Lance Martin’s repo. Configure which sessions should trigger reflection. Review generated rules in git diffs before committing.

claude-mem (automated context):

Install via /plugin marketplace add thedotmack/claude-mem. Memories inject automatically at session start. No instruction modification; context comes from retrieval.

Why bother

Static instructions rot. You write them once, update when something breaks badly enough to notice, and lose most lessons along the way.

Self-updating instructions make the agent learn from its own sessions. It observes what works, encodes that as procedural knowledge, and starts smarter next time.

The risk is drift. Automated updates can accumulate bad rules. But manual updates require discipline most people lack. I’d rather review auto-generated rules than pretend I’ll maintain a CLAUDE.md file by hand.


Next: AI Memory Compression

Topics: ai-agents memory claude-code