To fix this, I implemented a usage-reinforced decay engine based on the Ebbinghaus forgetting curve. Instead of treating all memories as equal, the system assigns a "strength" score to every piece of stored information.
The Logic Behind the Decay Engine #
The goal is to simulate human memory: information that isn't accessed fades away, but information that is frequently retrieved becomes "hardened" and resists deletion.
-
Initial Weight: Every new memory is stored with a base strength value.
-
Temporal Decay: I apply a decay function that reduces the strength score over time.
-
Reinforcement: Whenever the agent retrieves a specific memory via RAG (Retrieval-Augmented Generation), that memory's strength is boosted.
-
Pruning: Once a memory's strength drops below a specific threshold, it's purged from the active context or moved to cold storage.
Implementation Detail #
The core of the system relies on a modified decay formula. Instead of a linear drop, I used an exponential decay where the rate is slowed down by the number of times the memory has been accessed.
import math
import time
def calculate_memory_strength(initial_strength, last_accessed, access_count, decay_rate=0.1):
elapsed_time = time.time() - last_accessed
effective_decay = decay_rate / (1 + access_count)
current_strength = initial_strength * math.exp(-effective_decay * elapsed_time)
return current_strength
This approach transforms the memory from a simple sliding window into a dynamic priority queue. In real-world testing, the agent stopped asking the same clarifying questions every 20 turns because the "core" identity and constraint memories were reinforced enough to survive the pruning cycles.
This is a much more robust AI workflow for anyone building long-term LLM agents who can't just rely on massive context windows to solve the "forgetting" problem.
Next S3 to SNS: Real-time upload notifications →