Memory for AI agents
How an agent stores what it learns and gets it back: memories and contexts, grades, documents and the facts extracted from them, closing and superseding instead of deleting, asking what was believed on a past date, and the kit that gives a coding agent all of it in one command.
The shape of a memory
A memory is a piece of text with a context, labels, a grade and provenance. It is embedded and stored once; everything after that is a stamp or a ledger row, never an edit. The create call:
POST /api/memory/memories
{
"content": "...", // required
"context": "handbook", // required: a shelf name of your choosing
"tags": ["billing"], // optional
"metadata": {"source": "wiki/42"}, // optional, yours
"user_id": "user:maeve", // who contributed it: provenance, not a filter
"compartment": "matter:acme", // optional; default "public" (tenant-shared)
"acl_classification": 0, // 0..3
"acl_owners": ["user:maeve"], // optional: only these principals may see it
"grade": 0.8, "grade_band": "decision", // optional: how much weight it carries
"occurred_at": "2026-10-01T09:00:00Z", // optional: when the thing happened
"reconcile": true // default: let the judge compare it with neighbours
}
→ 201 {"memory_id": "…"}
Two of those fields are easy to conflate. user_id records who said it and filters nothing.
acl_owners decides who may see it and is enforced inside the query. Isolation between tenants is
the key itself.
Recall
POST /api/memory/search
{
"query": "what currency do we invoice in",
"context": "handbook", // optional: one shelf
"limit": 20, // 1..100
"identity": "user:maeve", // who is asking; drives the gate
"focus_matter": "matter:acme", // optional: ONLY this compartment
"min_grade": 0.3, // optional floor
"grade_bands": ["decision", "fact"], // optional shelf inside the gate
"grade_weight": 0.2, // 0..0.5: grade as a ranking signal
"date_from": "2026-01-01", "date_to": "2026-06-30" // facts dated in the window
}
→ {"query", "results": [{memory_id, content, score, created_at, occurred_at,
grade, grade_band, acl_matter, acl_classification, acl_owners,
outcome_helpful, outcome_harmful, metadata, …}], "total"}
Ranking is the vector score weighted by a bounded temporal factor: recent memory is favoured, but age is measured by activity, not by the calendar, so a thread that slept for a month does not come back stale. The gate, the lifecycle filter and the grade floor are all compiled into the same query; there is no post-filtering of results.
Grades
A grade (0 to 1) and a band (a label of your choosing: fact, decision,
note, raw) say how much weight a memory carries. Grades are a value axis, not an
access label: a search can floor on them, shelve on bands, or lean on them in ranking, and a memory can be
regraded in place (POST /api/memory/memories/{id}/grade) with a ledger row holding the old and
new grade. A consumer can ask chat to mark every source with its grade so the answer carries the weight of
what it drew on (context.grade_view).
Documents
POST /api/documents/upload (multipart)
file=@handbook.pdf user_id=user:maeve chunking_strategy=semantic_sections
title="Staff handbook" matter=matter:acme classification=1 owners=user:maeve
extract_facts=true grade=0.7 grade_band=fact
→ 201 {document_id, filename, chunks_created, pages_processed, ocr_used, fact_extraction, …}
The platform extracts text (OCR when a PDF has none), chunks it, embeds the chunks and stores them with the
document's labels and page numbers. With extract_facts on, each chunk also yields one-claim
facts with a date where the passage supports one (fact_date, basis stated or
inferred; a year that appears only inside a citation is never used). Chat answers cite the
document, page and chunk. Retiring a document (DELETE /api/documents/{id}) closes its chunks and
facts; reopening (POST /api/documents/{id}/reopen) brings the original points back, nothing
re-embedded.
Close and supersede, never delete
The store's delete is a no-op by design. A finished memory is closed; a wrong one is superseded by a successor that inherits its labels unless told otherwise. Both leave the memory readable by id and out of retrieval, with a lifecycle event in an append-only ledger.
POST /api/memory/memories/{id}/close {"reason": "done" | "obsolete" | "error" | "junk"}
POST /api/memory/memories/{id}/supersede {"content": "corrected text", "reason": "..."}
GET /api/memory/memories/{id}/lineage the chain both ways, every hop gated
Physical erasure exists, but as a separate governed path with a plan, a permission and a receipt per memory; see erasure and the record.
What was believed on a date
GET /api/memory/as-of?t=2026-06-30T00:00:00Z&q=invoice+terms
GET /api/memory/as-of?t=2026-06-30T00:00:00Z&context=handbook (everything the shelf held then)
The as-of read answers with what existed at T and had not been retired by then, each hit marked with its
later_status. It is the one read that consults the lifecycle ledger instead of the live filter,
and it is gated and audited like any other.
Session distillation
POST /api/memory/consolidate-session turns a conversation into a summary, an entity graph and
one-claim facts, reconciled against what is already held. The platform also summarises idle sessions on its
own, so a long-running agent's threads do not grow without bound. Reconciliation runs in propose
mode: a new belief that refines or contradicts an existing one lands in a review queue, and the store does not
change until someone ratifies (outcomes and learning).
The kit: a coding agent that remembers
Yohanun Guilds is the same API packaged for Claude Code, Codex and any MCP host. Each project gets a named agent with private memory; a guild carries shared knowledge to every agent you run. Install, connect, onboard a project:
pip install yohanun
yohanun init --api-key sile_... --owner "Your Name"
cd ~/dev/myapp
yohanun agent add myapp --matter project:myapp --project-dir . --wire
--wire adds two hooks: one at session start (where you left off, what is still open) and one on
every prompt (up to three relevant memories as context, searched with your actual question). Daily use is
four verbs, by you or by the agent:
yohanun store "picked pnpm over npm — workspace protocol" --type decision
yohanun search "why did we pick pnpm"
yohanun due # open tasks
yohanun close <memory_id> # done: retired, never deleted
yohanun supersede <memory_id> "corrected fact"
yohanun consolidate # session end
For other hosts, yohanun mcp serve exposes the same memory as MCP tools. The kit's README on
PyPI is the full reference, including
backfilling a project's past sessions into memory. The longer story is on the Guilds
page.
Why this matters. Memory that keeps its history is what separates an estate from a cache: Memory for AI agents that keeps its history, and the measured comparison with mem0 in A mem0 alternative, with the numbers.
Get a key
Yohanun is in invited beta. Tell us what you are building and we send a key with a developer account; a memory-profile key for your own model, or a chat-profile key if you want the platform to run the model and meter it. There is no card and no self-serve sign-up.
Request an invite