Stop Building Agent Memory. Your Agent Doesn’t Need It.

Stop Building Agent Memory. Your Agent Doesn't Need It.

Last week I looked at my Redis dashboard and realized something: 4 out of 5 agent memory databases had zero queries in 7 days. I spent three weeks building them. They sit there, collecting dust, like unused gym memberships.

The agent uses exactly one memory type. The other four? Never queried. Never read from. Never written to.

This is not a post about how to build agent memory. This is a post about why I built the wrong thing, and what I learned when I stripped it all away. Earlier, I wrote about how my AI agent kept breaking — this memory experiment was part of that same journey.

The Five Memory Types I Built

Here is what I implemented, based on every agent memory paper and blog post I could find:

1. Short-term conversation history. The last N turns of the conversation, stored in context. This is the memory the agent uses to follow a conversation without asking “what did I just say?” every three turns.

2. Long-term episodic memory. A vector database of past conversations, indexed by semantic similarity. When the user mentions “that thing we talked about last week,” the agent retrieves it.

3. Procedural memory. Learned workflows and tool-use patterns. If the user always asks for deployment logs after a failed build, the agent learns to fetch them proactively.

4. Semantic knowledge base. Facts about the user’s projects, team, and preferences. “The staging server is called staging-01.” “The team prefers Slack over email.” “The API key is stored in ~/.config/app/credentials.”

5. Emotional memory. User feedback and sentiment tracking. If the user expresses frustration with a response, the agent remembers and adjusts future responses.

I implemented all five. I wrote retrieval functions for each. I set up cron jobs to consolidate memories. I added metrics to track retrieval accuracy.

Then I watched my agent work for a week.

What Actually Got Used

The agent used short-term conversation history. Exclusively.

When I asked it to deploy a service, it remembered the service name from three turns ago. When I asked it to check the logs, it knew which deployment I was talking about. When I asked it to rollback, it remembered the previous version.

But it never queried the episodic memory. Not once. I had 847 conversations indexed in the vector database. Zero retrievals.

It never used procedural memory. I had built a system that was supposed to learn my workflows. It did not learn anything. Every deployment was a fresh conversation.

It never read from the semantic knowledge base. I had stored server names, API endpoints, team preferences. The agent asked me for them every single time.

And emotional memory? The agent did not even check if I was frustrated. It would apologize, then make the same mistake again.

Why the Other Four Failed

I spent a week debugging this. Why would the agent ignore four out of five memory systems I built for it?

The answer is uncomfortable: I built memory for problems my agent does not have.

Episodic memory failed because my conversations are short. I do not have hour-long dialogues with my agent. I have 5-turn conversations. “Deploy service X.” “Done.” “Check logs.” “Here they are.” “Rollback.” “Done.” There is nothing to retrieve from last week because last week’s conversation is irrelevant to this week’s task.

Procedural memory failed because my workflows are explicit. I do not want the agent to guess what I want next. I want to tell it. When I am ready for logs, I will ask for logs. The agent fetching them proactively is not helpful — it is presumptuous. And if the agent guesses wrong, I have to correct it, which takes more time than just asking.

Semantic memory failed because my environment changes. The staging server was staging-01 last month. Now it is staging-02. The API endpoint moved from v1 to v2. The credentials rotated. The knowledge base was stale faster than I could update it. The agent learned wrong facts and repeated them confidently.

Emotional memory failed because I do not want my agent to model my emotions. I want it to execute tasks. If I am frustrated, it is because the task failed. The solution is not to apologize — it is to fix the task. Tracking my sentiment does not help the agent do its job.

What I Kept

I deleted four of the five memory systems. Here is what I kept:

Short-term conversation history, with a twist. The agent keeps the last 10 turns in context. But I added one rule: if the conversation exceeds 10 turns, the agent must summarize the first 5 turns and drop them. This keeps the context window manageable while preserving the essential information.

The summary is not stored in a database. It is not indexed. It is not retrievable later. It exists only for the duration of the conversation. When the conversation ends, the memory is gone.

And that is fine.

The Lesson

The lesson I learned is this: agent memory is not about storing everything. It is about storing what matters for the task at hand. This echoes what I found when I cut my homelab AI agent costs by 60% — the best optimization is often removing what you don’t need.

I built a memory system designed for a general-purpose assistant that has long conversations with users, learns their preferences over time, and builds a relationship. That is not what my agent does. My agent is a tool. It executes tasks. It does not need to remember my birthday.

The papers I read about agent memory are written by people building chatbots and companions. They need episodic memory because their value proposition is continuity. My agent’s value proposition is execution. Continuity is a bug, not a feature.

If I were building a coding agent that works on the same codebase every day, I would implement semantic memory for the codebase structure. If I were building a customer support agent, I would implement episodic memory for customer history. If I were building a personal assistant, I would implement procedural memory for user habits.

But I am building a deployment agent. It deploys services. It checks logs. It rollbacks failures. It does not need to remember what we talked about last Tuesday.

What I Would Do Differently

If I could go back, I would not start with five memory types. I would start with zero. I would watch my agent work for a week. I would note every time the agent asked for information it should have remembered. I would note every time the agent made a mistake because it forgot something.

Then I would build exactly one memory system to fix exactly that problem.

Maybe that memory system is conversation summarization. Maybe it is a cache of recent deployments. Maybe it is nothing at all.

The point is: I would build memory in response to a specific failure, not in anticipation of a hypothetical need.

The Counterintuitive Part

Here is the part that surprised me: after I deleted four of the five memory systems, my agent got faster.

Not because the memory queries were slow. They were not — I optimized them to under 50ms. The agent got faster because it stopped waiting for memory retrievals that never returned useful information.

The agent would send a query to the episodic memory database. The database would return three semantically similar conversations from last month. The agent would read them. None of them were relevant. The agent would discard them and proceed.

That is 50ms wasted. Multiplied by every turn, multiplied by every conversation.

When I removed the memory queries, the agent just… worked. It did what I told it to do. It did not pause to retrieve irrelevant context. It did not second-guess itself based on stale knowledge. It executed.

What I Use Now

My agent memory architecture now fits in 20 lines of code:

class AgentMemory:
    def __init__(self, max_turns=10):
        self.conversation = []
        self.max_turns = max_turns
    
    def add_turn(self, role, content):
        self.conversation.append({"role": role, "content": content})
        if len(self.conversation) > self.max_turns:
            # Summarize and drop first 5 turns
            summary = self._summarize(self.conversation[:5])
            self.conversation = [{"role": "system", "content": summary}] + self.conversation[5:]
    
    def get_context(self):
        return self.conversation

That is it. No vector database. No Redis. No cron jobs. No retrieval strategies.

The agent remembers what it needs to remember for the current conversation. When the conversation ends, the memory is gone. And that is exactly what I want.

The Real Question

The real question is not “what memory types should my agent have?” The real question is “what task is my agent trying to accomplish, and what does it need to remember to accomplish it?”

For a deployment agent: the current service name, the current version, the last error message. That is it.

For a code review agent: the current PR, the coding standards, the previous comments. That is it.

For a customer support agent: the customer’s ticket history, the product documentation, the escalation rules. That is it.

The memory architecture follows from the task. Not the other way around.

What I Learned

I learned that sophisticated does not mean better. I learned that academic papers describe ideal systems, not practical ones. I learned that the best memory system is the one your agent actually uses.

And I learned that sometimes the answer is not “add more memory.” The answer is “delete most of it.”

My agent has one memory type now. It uses it every time. It works.

Your agent probably doesn’t need the other four either.


Discover more from Susiloharjo

Subscribe to get the latest posts sent to your email.

Leave a Comment

Discover more from Susiloharjo

Subscribe now to keep reading and get access to the full archive.

Continue reading