Give everyone the same memory.
- Everyone knows everything instantly. Nothing can be private or out of date.
- A retraction updates all of them at once, which is not how news travels.
- No character can be asked why it said what it said.
worked case · generative agents
A generative agent is a fictional character controlled by software. It uses an AI language model to create dialogue and plans, but it also needs a memory: what it has seen, what mattered, and what it currently believes.
What you are looking at. This is a three-character thought experiment about how information moves through separate memories. It is not a model of a real town, a complete human mind, or conscious behavior.
3 characters · 3 simulated days · 1 changing fact
Sam says, “I have decided to run for mayor.”
“Sam told me he plans to run for mayor.”
The mayoral news matters when politics comes up.
The character mentions Sam's campaign.
00 · the problem
Because then everyone knows everything the instant it happens, and the story dies. People — and agents, users, and accounts — only know what actually reached them. So the hard part is not storing memories; it is deciding who is allowed to have which one, and being able to show later how it got there.
Sam tells Isabella his news. Klaus is not there, so Klaus does not know it.
“I have decided to run for mayor.”
Isabella reviews her own day and draws one conclusion from it.
“Sam is campaigning for mayor and asking regulars at the cafe for support, so tonight’s party is where it will come up.”
Sam withdraws and tells Klaus. Nobody has told Isabella yet.
Klaus now believes: “Sam has withdrawn.” Isabella still believes: “Sam is running for mayor.”Isabella is not broken. She simply has not heard, and the record shows exactly that.
Write what a character saw. Ask for what it should remember now.
await memseek.records.ingest(entity="agent:isabella", text="Sam told me he plans to run for mayor.") recall = await memseek.search("what should I do tonight?", entity="agent:isabella")
New to Memseek? You write one small configuration file describing what your application should remember. After that your application only appends what happened; Memseek does the deriving, keeps every conclusion linked to the evidence underneath it, and hands your agent a bounded briefing instead of a pile of text. Everything below is that file and what it produces — how it works.
The simulation controls the clock and encounter. When Sam tells Isabella about the campaign, the application writes one observation under Isabella’s entity. Klaus receives no copy, so his memory cannot retrieve the news yet.
“I have decided to run for mayor.”
Isabella heard the statement. Klaus was not part of this encounter.
Sam told me he plans to run for mayor.
He cannot recall or act on the campaign until the information reaches him through a later event.
Visible effect: the same simulated world now produces different knowledge states for two characters.
- name: main
mode: mixed
schema:
required: [text]
required_processors:
- embedding_v1
- importance
search_profile: pg_default
answerable: trueentityThe entity is supplied with the write, not hard-coded here. Isabella, Klaus, and Sam therefore use the same contract but keep separate records.
importanceScore how consequential the memory is from 1–10; that score later competes with relevance and recency during recall.
answerableAllow cited synthesis over the stream, while still requiring entity scope at query time.
One immutable main/observation record for Isabella — “Sam told me he plans to run for mayor.” — with its time and an importance of 8. Klaus still has zero evidence of the campaign.
When Isabella later plans a gathering, the application queries only her entity. Semantic or text similarity finds related records, importance favors the campaign announcement over small talk, and time decay prevents ancient memories from dominating forever.
variants:
hybrid:
- sum
- - [product, 1.0,
[normalize, [max,
[[similarity], [text_match]]]]]
- [product, 1.0,
[normalize, [score, importance]]]
- [product, 1.0,
[decay, [age_hours, last_accessed],
{midpoint: 24, exponent: 1}]]max(similarity, text_match)Let either meaning or exact wording establish relevance; one weak method does not cancel the other.
score.importanceFavor memories the processor judged consequential, even when several candidates are equally topical.
decayReduce recency weight around a 24-hour midpoint. This changes selection, not the stored memory itself.
No new belief is written by recall. What enters Isabella’s context is the selected memory itself — “The Valentine’s party is tonight and Klaus is invited.” — carrying the ID of the record it came from.
At the end of the day, the reflection derivation fires after the accumulated importance crosses 150. It asks three high-level questions, searches Isabella’s memories and prior reflections, then emits insights that must cite the records the model actually saw.
trigger:
accumulator: {metric: importance,
threshold: 150}
sources:
recent_memories:
kind: changes
collections: [main]
tasks:
- {id: qs, use: llm}
- {id: evidence_by_question, use: search}
- {id: result, use: llm}
emit:
collection: reflections
type: reflectionaccumulatorMake reflection event-driven but not constant: trivial scenes alone do not justify a new abstraction.
evidence_by_questionRetrieve beyond the latest batch so the insight may connect the campaign with earlier goals or relationships.
citationsThe output schema requires full visible UUIDs; an invented insight or invisible source fails validation.
A reflections record for Isabella: “Sam is campaigning for mayor and is asking regulars at the cafe for support, so tonight’s party is where his campaign will come up.” It cites the observations it was drawn from. Klaus still does not inherit it.
The live artifact makes the handoff explicit. Isabella’s profile, upcoming calendar, and task-relevant memories become named blocks with independent token budgets. When she later tells Klaus, his new observation changes what he can know. When Sam withdraws, only agents who receive that correction can update.
blocks:
profile:
document: {collections: [profiles]}
max_tokens: 2000
calendar:
view: upcoming_calendar@1
max_tokens: 2500
memory:
view: agent_relevant_memory@1
max_tokens: 3500
template: |
CURRENT PROFILE: {{profile}}
UPCOMING CALENDAR: {{calendar}}
RELEVANT MEMORY: {{memory}}blocksKeep stable identity, authored plans, and recalled experience separate so each input can be inspected and budgeted.
viewRun the declared retrieval at render time for this character and this task; do not pre-bake global town knowledge.
templateDefine the literal context boundary the dialogue model sees. The simulation, not the model, remains responsible for time and encounters.
Dialogue is generated from bounded, character-specific context: Isabella’s next line can mention the campaign, and Klaus’s cannot until someone tells him. Observations, reflections, profile versions, plans, and prompt snapshots remain separately auditable.
01 · from behavior to software
The left side describes the behavior in everyday language. The right side names the software part that makes it possible. These are the building blocks adapted from Park et al.'s 2023 Generative Agents paper.
02 · how recall works
A character may collect hundreds of memories, but the language model cannot—and should not—receive all of them every time. Before a character speaks or plans, the system selects a small set using three understandable signals.
“The Valentine's party is tonight and Klaus is invited.”
“I bought bread last week.”
A memory about the party matches a conversation about tonight's plans.
A campaign decision receives more weight than routine small talk.
Recent memories receive more weight, while older ones fade gradually.
This is a useful engineering approximation, not a claim that human memory can be reduced to three numbers. In Memseek, the weights are visible configuration, so a developer can inspect and change what the software favors.
03 · three simulated days
Isabella runs a cafe, Klaus is a student, and Sam is involved in local politics. At first, each knows different things. Their beliefs become shared only through the conversations the simulation schedules.
“I have withdrawn from the mayoral race.”
“Sam is running for mayor.”
“Sam is running for mayor.”
Because each saved statement names the earlier memory it came from, the system can later trace a belief back through the conversations that carried it. That is what “cited memory” and “provenance” mean on this page: the software keeps the receipts.
04 · from your app
For technical readers, the loop below is the entire handoff. The simulation records what happened, asks for the memories relevant now, assembles a compact briefing, and gives that briefing to its language model.
# 1 · Klaus relays a memory. His statement points to his own source. await memseek.records.ingest( collection="main", type="chat", entity="agent:klaus", text="Klaus told Sam that Isabella is planning a party at Hobbs Cafe.", content={"heard_from": "agent:isabella"}, derived_from=[klaus_source_record_id], # ← the memory Klaus recalled ) # 2 · about to act: recall across observations, plans, reflections recall = await memseek.search( query="what should I do this afternoon?", entity="agent:klaus", mode="hybrid", k=12, include=["text", "scores", "occurred_at"], ) for hit in recall["hits"]: hit["scores"]["importance"] # the paper's term, on the record # 3 · assemble the prompt: summary + schedule + relevant memory prompt = await memseek.render_artifact( "daily_agent_prompt", entity="agent:klaus", ) prompt["rendered"] # hand this to your model prompt["manifest"]["input_record_ids"] # exactly what it knew # 4 · your simulator's own call — memseek is not in this loop line = await your_model.say(prompt["rendered"], in_character="klaus")
The runnable example is examples/generative_agents_toy.py plus the shipped Memseek catalog. Dialogue and reflections are generated by a real model at run time, so the wording on this page is explanatory rather than a captured transcript. The architecture is adapted from Park et al., Generative Agents: Interactive Simulacra of Human Behavior, UIST '23.
start building
The script drives the clock, conversations, overnight reflections, and day-three correction. It then shows who knew each fact and traces one belief back to the observations that produced it.