DEV Community

Cover image for Your Agent Doesn't Have a Reasoning Problem, It Has a Memory Problem
Anannya Roy Chowdhury
Anannya Roy Chowdhury

Posted on

Your Agent Doesn't Have a Reasoning Problem, It Has a Memory Problem

*Part 2 of "Multi-Agent Systems in Production: What They Don't Tell You", a four-part series following the saga of Horcrux Hunt, a multi-agent Harry Potter game that taught me everything about production AI the expensive way.


Harry Had Perfect Reasoning and a 77% Failure Rate

After fixing the cost problem (Part 1), I still had a mystery: Harry kept losing.

Not because he couldn't reason but when given correct, relevant context, Harry made optimal decisions over 95% of the time. I tested this by hand-crafting perfect context and feeding it to the model. Brilliant moves every time.

But his in-game win rate was only 23%. Something between "perfect reasoning ability" and "actual gameplay" was destroying his performance.

I ran 100 games and tracked every failure. Every single one traced back to the same root cause: Harry was remembering the wrong things.

Not a reasoning problem. A memory architecture problem.


The Adversarial Memory Stress Test

Horcrux Hunt isn't just a game, it's a memory stress test designed by accident and refined by design. It exposes every weakness in how agents manage context because it has a thinking adversary actively corrupting memory.

Harry's challenge:

  • Track probabilities across 15 locations over 50 turns
  • Each observation provides a signal (positive, negative, or "destroyed, but it was a decoy!")
  • Distinguish real Horcruxes from decoys planted to waste his moves
  • Reduce uncertainty with each turn while Voldemort fights back

Voldemort's anti-memory strategy:

  • Relocate Horcruxes mid-game → Harry's old signals become lies
  • Plant decoys at high-probability locations → inject false confidence
  • Time relocations after Harry commits → maximize wasted actions
  • Increase uncertainty every turn Harry gets closer

The game is fundamentally an entropy race Harry reducing uncertainty, Voldemort increasing it.

This is the same problem your customer service agent faces (user changes intent), your code agent faces (repo state changes), or your research agent faces (new evidence contradicts old conclusions). Horcrux Hunt just makes the adversary explicit.


The Four Memory Failure Modes

Every failure I observed fell into one of four categories.

1. Stale Memory (The Relocation Trap)

What happened: Harry attacked Hogwarts with high confidence based on a positive signal from turn 12. But Voldemort relocated the Horcrux on turn 24. Harry attacked on turn 25, found nothing, wasted a precious action.

Root cause: The positive signal from turn 12 was 13 turns stale. Voldemort's relocation invalidated it. Harry's reasoning was perfect ("attack highest probability location"). His memory was lying to him.

2. Retrieval Failure (Buried Signal)

What happened: Harry re-searched a location he'd already confirmed empty. A negative signal from turn 8 existed in his context, but buried under 4,800 tokens of subsequent history.

Root cause: Relevant information existed but was functionally invisible. In 6,000 tokens of context, the model's attention couldn't find a critical 20-token signal from 40 turns ago. The signal was there. Harry couldn't find it in the noise.

3. Memory Overload (The Timeout)

What happened: By turn 40, Harry's context was 6,000 tokens. Generation took 25 seconds. Lambda timed out at 30 seconds. The game crashed. Harry lost by default.

Root cause: Too much memory. The context window became a liability, not because the information was wrong, but because carrying all of it was physically too slow.

4. Decay Problem (Lost in the Noise)

What happened: A critical positive signal from turn 3 was still valid at turn 40 (Voldemort hadn't relocated that particular Horcrux). But Harry couldn't find it among 37 turns of subsequent noise. He searched elsewhere and missed an easy win.

Root cause: Important early observations drowned out by recent but less important ones. No temporal weighting. No relevance scoring. Just raw chronological context.

The pattern: Every failure was memory architecture disguised as reasoning failure. The LLM's reasoning was fine. The information it received was wrong, stale, incomplete, or overwhelming.


The Memory Tax: Voldemort's Best Weapon

Context windows aren't a flat fee. They're a compounding tax and Voldemort exploits this ruthlessly:

Turn Harry's Context Cost Multiplier Voldemort's Advantage
1 ~800 tokens None (equal information)
10 ~1,800 tokens 2.25× Harry carries stale signals
25 ~3,500 tokens 4.4× Multiple relocations buried in context
50 ~6,000 tokens 7.5× Harry can't find relevant signals in noise

Every turn Voldemort corrupts (relocate, decoy) adds tokens to Harry's context that are actively misleading. Harry pays to carry lies. The longer the game goes, the more Harry pays to process increasingly corrupted memory.

This is the "Fail Fast, Fail Free" lens on memory: every token Harry doesn't need is a micro-failure, wasted money processing information that doesn't help or actively hurts his decisions.


Memory as Entropy Management

The insight that changed everything: memory architecture IS entropy management.

Shannon entropy measures uncertainty. With 15 equally-likely Horcrux locations:

H = log₂(15) = 3.9 bits (maximum uncertainty)
Enter fullscreen mode Exit fullscreen mode

Harry's job: each observation should reduce entropy (concentrate probability on fewer locations). Voldemort's job: each action should inject entropy (spread probability back out).

Turn 1:  H = 3.9 bits  (uniform, knows nothing)
Turn 10: H ≈ 2.8 bits  (narrowing, eliminated some locations)
Turn 30: H ≈ 1.4 bits  (confident, 2-3 likely locations)
Turn 50: H ≈ 0.6 bits  (near-certain, ready to attack)
Enter fullscreen mode Exit fullscreen mode

But Voldemort fights back:

Turn 25: Harry at H = 1.8 bits (getting close!)
Turn 26: Voldemort relocates → Harry at H = 2.5 bits (setback!)
Turn 27: Voldemort plants decoy → Harry at H = 2.9 bits (further back!)
Enter fullscreen mode Exit fullscreen mode

The memory question becomes: what should Harry carry in context to minimize entropy as fast as possible? The answer: not 50 turns of narrative. Just the current probability distribution.


The Three-Layer Memory Framework

Three layers, each with a specific job and dramatically different cost.

Layer 1: Working Memory (Context Window)-

What Harry sees RIGHT NOW. Most expensive real estate where every token costs money every single turn.

# What Harry's LLM actually receives (55 tokens):
AgentContext(
    turn=25,
    budget_remaining=3,
    available_allies=["ron"],
    cooldowns={"dumbledore": 2},
    belief_map={"Hogwarts": 0.34, "Azkaban": 0.22, "Ministry": 0.18},
    entropy=1.4,
    last_signal="negative @ Godrics Hollow"
)
Enter fullscreen mode Exit fullscreen mode

Rule: Only what's needed for THIS decision. Nothing historical. Nothing derivable. Nothing redundant.

Layer 2: Retrieval Memory (Computation Layer)-

Where probabilities are computed, entropy is tracked, and signals are processed. This layer does heavy work OUTSIDE the LLM.

class HorcruxBeliefMap:
    def update(self, location, signal, turn):
        if signal == "positive":
            self.beliefs[location] *= 3.0
        elif signal == "negative":
            self.beliefs[location] *= 0.1
        elif signal == "destroyed":
            self.beliefs[location] = 0.0

        # Decay old beliefs (Voldemort may have relocated)
        for loc in self.beliefs:
            if self.last_updated[loc] < turn - 10:
                self.beliefs[loc] *= 0.7  # uncertainty grows with time

        self.normalize()
Enter fullscreen mode Exit fullscreen mode

Cost: 0 tokens. A few microseconds of Python. Infinitely cheaper than asking Claude to reason over 50 turns of narrative.

Layer 3: Persistent Memory (Event Store)-

Complete game record. Every signal, every action, every state change. Lives in DynamoDB. Never enters the context window directly.

# DynamoDB item- cheap, complete, permanent
{
    "game_id": "horcrux_42",
    "turn_log": [...every event...],    # 5-10 KB
    "current_state": {...},              # latest snapshot
    "belief_history": [...],             # probability over time
    "ttl": epoch + 30_days              # auto-cleanup
}
Enter fullscreen mode Exit fullscreen mode

This is the "source of truth", if Layer 2 needs to recompute, it pulls from Layer 3. But Layer 3 never, ever enters the LLM's context.

Architecture:

Layer 3 stores EVERYTHING (¢)
    ▼ computed into
Layer 2 produces COMPRESSED STATE ($)
    ▼ injected as
Layer 1 receives ONLY WHAT'S NEEDED ($$$)
Enter fullscreen mode Exit fullscreen mode

The Key Fix: Dynamic Context Compression

Before (naive, dump everything into context):

Turn 1: Harry searched Hogwarts → negative
Turn 2: Harry searched Diagon Alley → positive  
Turn 3: Harry attacked Diagon → decoy!
Turn 4: Voldemort relocated...
Turn 5: Harry used Ron at Azkaban → positive
... (50 turns = 2,000+ tokens of narrative)
Enter fullscreen mode Exit fullscreen mode

Harry's LLM reads all of this. Costs $0.015. Takes 8 seconds. And half the signals are stale (Voldemort relocated since then).

After (compressed, only current beliefs):

# 55 tokens. $0.0002. <1 second.
"Horcrux likely at: Hogwarts (34%), Azkaban (22%), Ministry (18%).
Entropy: 1.4 bits (medium confidence). Budget: 3 actions remaining.
Ron available in 2 turns. Last signal: negative @ Godric's Hollow."
Enter fullscreen mode Exit fullscreen mode

97% compression: 2,000+ tokens → 55 tokens.

Why lossy works: The belief map is a sufficient statistic. If Hogwarts has p=0.34, it doesn't matter WHETHER that came from a positive signal on turn 3 or the absence of negative signals over 20 turns. The probability encodes all the decision-relevant information.

Harry makes better decisions with 55 focused tokens than with 6,000 noisy ones. Less context = less noise = less distraction = better signal-to-noise ratio.


Entropy-Gated Retrieval: Fail Fast, Fail Free for Memory

Not every Harry decision deserves the same memory investment. Entropy tells you which decisions are hard:

def harry_decide(game_state, belief_map):
    entropy = calculate_entropy(belief_map)

    if entropy < 1.0:  # LOW uncertainty, Harry is confident
        # No LLM needed. Heuristic: attack top target.
        return HeuristicDecision(belief_map.top_target())  # 0 tokens, $0

    elif entropy < 2.5:  # MEDIUM uncertainty, some ambiguity
        # Compressed belief map is enough context
        context = compress_to_55_tokens(belief_map)  # 55 tokens
        return llm_decide(context)

    else:  # HIGH uncertainty, genuinely hard
        # Worth the investment: richer retrieval
        context = build_full_context(belief_map, recent_signals)  # 200-500 tokens
        return llm_decide(context)
Enter fullscreen mode Exit fullscreen mode

This is "Fail Fast, Fail Free" for memory retrieval. When entropy is low, Harry already knows what to do and spending 200 tokens to confirm an obvious decision is waste. The entropy check catches that waste before it costs anything:

Entropy Strategy Tokens Cost % of Decisions
H < 1.0 Heuristic (attack top target) 0 $0 ~35%
1.0 ≤ H < 2.5 Compressed belief map 55 $0.0002 ~45%
H ≥ 2.5 Full retrieval 200-500 $0.002 ~20%

35% of Harry's decisions cost zero tokens. The entropy gate catches "I don't need to think about this" before the meter starts running.

ε-greedy exploration: Even when entropy is low, 10% of the time Harry explores a non-top location. This prevents tunnel vision whichis critical against Voldemort, who can exploit predictable behavior.


The Results

Same Harry. Same Voldemort. Same Claude 3 Sonnet. Same 50-turn game. Radically different memory architecture:

Metric Naive (all-in-context) Memory-Optimized Change
Tokens per decision 5,000 55 -97%
Context at Turn 50 6,000 tokens ~200 tokens -97%
Cost per game $1.95 $0.35 -82%
Latency per turn 12s 3s -75%
Harry win rate 23% 52% +29pp
Stale memory failures ~20% of turns <5% -75%
Hallucination rate ~15% ~3% -80%
Annual savings at scale $576,000

The hallucination reduction is the most satisfying: with 5,000 tokens, Harry had more material to confabulate from ("I think I remember a positive signal at..."). With 55 tokens of clean probabilities, there's nothing to hallucinate about.

And Harry wins more because Voldemort's memory corruption strategy stops working. Relocating a Horcrux only hurts Harry if Harry is carrying stale signals. With a Bayesian map that decays old beliefs automatically, relocations get priced in mathematically. Voldemort can't corrupt math.


Five Memory Design Principles (Learned from Horcrux Hunt)

  1. The LLM should consume memory, not produce it. Bayesian maps compute beliefs. The LLM receives results. Voldemort can't corrupt math the way he corrupts narrative.

  2. Match memory depth to decision difficulty. Entropy-gate your retrieval. Easy decisions don't deserve expensive context. Fail fast, fail free.

  3. Compress at boundaries, not inside the LLM. The compression from 2,000 tokens to 55 happens in deterministic Python and not via LLM summarization (which costs tokens and can hallucinate).

  4. Persist abundantly, retrieve selectively, present minimally. DynamoDB stores everything. Layer 2 computes what matters. Layer 1 shows only what's needed.

  5. Less context = better decisions. Harry performs BETTER with 55 focused tokens than 6,000 noisy ones. Signal-to-noise ratio > signal quantity. Always.


The Principle

Harry doesn't lose because he can't reason. He loses because he remembers wrong.

Fix the memory. The reasoning follows.

Every token of unnecessary context is a failure to apply "Fail Fast, Fail Free" at the memory layer. Check whether you need to think before you start thinking. Gate before you retrieve. The cheapest context is the context you never load.


💬 Quick memory test for your agent:

Run your agent through the same multi-turn task 5–10 times.

Then deliberately introduce something it was told several turns earlier.

🧠 Remembers it correctly? → Your memory architecture might be doing its job.
🔄 Remembers sometimes? → You probably have a retrieval or context-selection problem.
❌ Forgets, contradicts, or repeats itself? → Your agent may not have a reasoning problem at all. It may have a memory problem.
🤷 Never tested it? → Now you know what to test.

Drop your agent’s weirdest “I definitely told you that already” or "Never said that" moment in the comments. 👇
I’ll tell you which memory failure mode you're probably dealing with.


And if you want to follow the Horcrux Hunt production saga,

→ Read this blog to know more about the "Fail Fast, Fail Free" process: Part 0: Fail Fast, Fail Free

→ Next up: Part 3: When Harry's Tools Betray Him. We saw Memory is fixed. Cost is fixed. But when I added tools (search spells, ally abilities, divination artifacts), Harry started calling the wrong ones. 60% of tool interactions failed and not because Harry couldn't reason about WHICH tool to use, but because the tools themselves were having ambiguous descriptions.*


I am a Gen AI Developer Advocate & Architect. I built a multi-agent AI game to entertain a conference audience and accidentally created the most expensive stress test for multi-agent systems I'd ever seen. The game taught me that the hardest problem in AI isn't reasoning. So, I adapted the classic "Fail Safe" and came up with "Fail Fast, Fail Free" because it's all about remembering the right things at the right time.

Top comments (7)

Collapse
 
ai_unboxed profile image
AI Unboxed

The really interesting research direction you have pointed out is the selective forgetting. An agent that remembers everything indefinitely isn’t necessarily better than one that remembers selectively. When this happens, so the challenge is designing policies for what to retain, summarize, decay, retrieve, or discard while preserving the information required for long-horizon tasks. That feels like a fundamental problem for reliable agentic systems. Thanks for covering in detail.

Collapse
 
royanannya profile image
Anannya Roy Chowdhury

Thanks for mentioning. Yes, the agents need to pass right context to the LLMs, not all context.

Collapse
 
thetarunab profile image
Taruna Biswal

The RAG overload point is something I’ve encountered repeatedly. Retrieval quality isn’t simply about maximizing recall. Once you start injecting too many semantically related chunks into the context, you increase interference and make it harder for the model to identify the information that actually matters for the current decision. Context selection and compression are becoming just as important as retrieval itself. Nice one!

Collapse
 
royanannya profile image
Anannya Roy Chowdhury

Yes, the classic problem. Setting threshold alone doesn't help. Dynamic compression, shared context are techniques that will help along with this

Collapse
 
maxbuilds profile image
Max Velloc

The three-layer model makes the failure modes much easier to reason about: working context, retrieval, and durable event history each need different policies. I especially like the fail-fast angle—when retrieval confidence is low, surfacing uncertainty is safer than silently filling the context with loosely related memories. Measuring retrieval quality separately from answer quality would make this design easier to tune.

Collapse
 
rizzdev profile image
Andrew R

When two high-p locations got there different ways and one is a decoy. Your 55-token map can't tell them apart

Some comments may only be visible to logged-in visitors. Sign in to view all comments.