In Chapter 5: Sandboxed Environment, we built a secure laboratory where our Agent can run code without destroying your computer. Our Agent is now smart, capable, and safe.
But there is still one major flaw: Amnesia.
If you tell a standard chatbot, "My name is Alice and I am a Python developer," it remembers you for that session. But if you refresh the page or come back tomorrow, it asks: "Who are you?"
In this chapter, we build the Long-Term Memory Updater. This is the component that gives our Agent a permanent memory, allowing it to remember your preferences, facts, and project details forever.
Standard Large Language Models (LLMs) are "stateless." They don't have a hard drive in their brain. Every time you send a message, you have to resend the entire conversation history so they know what's going on.
Eventually, that history gets too long and is deleted.
deer-flow solves this by acting like a Secretary in a meeting:
Next time you start a chat, the Agent reads this "Filing Cabinet" before saying hello.
User: "I strictly use TypeScript for all my projects."
Without Memory Updater:
With Memory Updater:
memory.json)We don't need a complex database for this. A simple JSON file works perfectly. It acts as the "Dossier" on the user.
It is structured into categories:
This is a background process. It does not run during your sentence (which would slow down the chat). It runs after a conversation turn.
It takes the recent chat messages, sends them to a cheaper, faster AI model, and asks: "Did we learn anything new about the user?"
Just like in Chapter 2, we use Middleware to trigger this process automatically. The Lead Agent doesn't need to consciously "decide" to remember; the system does it for them.
Let's visualize the flow of information when you tell the agent a fact.
Let's look at backend/src/agents/memory/updater.py to see how we implement this.
First, we define what our "Filing Cabinet" looks like. We create an empty structure if the file doesn't exist.
Simplified Code (updater.py):
def _create_empty_memory() -> dict:
return {
"version": "1.0",
"lastUpdated": "2024-01-01T12:00:00Z",
"user": {
# General info about the user
"workContext": {"summary": "", "updatedAt": ""},
"personalContext": {"summary": "", "updatedAt": ""},
},
"facts": [], # Specific items like "Project ID is 123"
}
Explanation: This JSON structure is what is injected into the Lead Agent's prompt every time a new chat starts.
The core magic happens in the MemoryUpdater class. It uses an LLM to read the chat and output JSON updates.
Simplified Code (updater.py):
class MemoryUpdater:
def update_memory(self, messages: list) -> bool:
# 1. Load the existing dossier
current_memory = get_memory_data()
# 2. Format a prompt: "Here is the old memory, here is the new chat."
prompt = MEMORY_UPDATE_PROMPT.format(
current_memory=json.dumps(current_memory),
conversation=format_conversation(messages),
)
# 3. Ask the AI to generate updates
response = self.model.invoke(prompt)
# 4. Apply the AI's suggestions to our JSON file
updated_memory = self._apply_updates(current_memory, json.loads(response))
return _save_memory_to_file(updated_memory)
Explanation: We don't write if "Python" in message statements. We rely on the AI's intelligence to understand the context. The AI returns a JSON object describing what to add or change, and we save it.
Writing to a file seems simple, but if the computer crashes while writing, we could corrupt the memory. We use an "Atomic Write" pattern (write to a temp file, then rename).
Simplified Code (updater.py):
def _save_memory_to_file(memory_data: dict) -> bool:
file_path = _get_memory_file_path()
# 1. Write to a temporary file first (Safety!)
temp_path = file_path.with_suffix(".tmp")
with open(temp_path, "w") as f:
json.dump(memory_data, f, indent=2)
# 2. Swap the files
temp_path.replace(file_path)
return True
Explanation: This ensures that memory.json is always valid. It's never half-written.
Finally, we need to ensure this runs automatically. We add MemoryMiddleware to our Lead Agent's pipeline in agent.py.
Simplified Code (agent.py):
def _build_middlewares(config):
middlewares = [
ThreadDataMiddleware(),
# ... other middlewares ...
# This middleware ensures the agent READS memory on startup
# AND triggers the updater after conversations.
MemoryMiddleware()
]
return middlewares
Explanation: By adding this one line, every conversation the Lead Agent has is automatically analyzed and filed away.
In this chapter, we solved the "Amnesia" problem.
We now have a complete, intelligent, safe, and persistent AI system running on our backend!
The final step is to open this system up to the outside world. What if you want to trigger this agent from a Slack message or a generic HTTP request?
Generated by Code IQ