Autonomous agents
Memory for AI agents
An agent that runs every day and starts from nothing every day is not learning, it is repeating. Give it a store it can query for what previous runs established.
Today
The agent runs on a schedule. Each run re-reads the same inbox, re-derives the same conclusions, and rediscovers the same three facts about the same customer, because the only thing carried between runs is whatever you thought to write into a file. When it does something wrong, you cannot tell whether it reasoned badly or simply did not know something an earlier run had found out.
With a memory
Each run writes what it established and queries what earlier runs established. The second run does not re-derive the first run's conclusions, it reads them, along with when they were established and from what. When two runs disagree, that disagreement is stored as a conflict rather than one silently overwriting the other, so the next run can see that the question is open.
What that looks like
The second run is cheaper than the first
Recall returns a handful of relevant memories rather than the whole history, so the prompt does not grow with the number of runs and neither does the bill.
A wrong conclusion can be traced
Every memory carries the source it came from. When an agent acts on something false, you can find out whether the fact was wrong or the reasoning was.
Two agents can share one memory
The research agent and the drafting agent read the same store. What one learns on Monday is available to the other on Tuesday without a handoff format between them.
Contradictions surface instead of thrashing
When today's finding contradicts last week's, both are kept with their sources and timestamps. The agent sees an open question rather than flipping its answer every run.
The shape of it
from persistmemory import PersistMemory
client = PersistMemory(api_key=os.environ["PERSISTMEMORY_API_KEY"])
# What earlier runs already worked out.
found = client.search.query(query="onboarding blockers for Northwind", limit=5)
context = "\n".join(f"- {r.memory.content}" for r in found.results)
result = agent.run(task, context=context)
# What this run established. This returns a job: extraction, entity
# resolution and conflict detection all happen afterwards, so it may
# produce one memory, several, or none.
client.memories.remember(text=result.finding)What this does not do
This does not make an agent reliable. An agent that reasons badly with no memory will reason badly with a good one, and a memory of its own wrong conclusions is worse than none. Memory is worth adding once the reasoning is sound and the thing holding it back is that it starts blank.