Corrective memory for AI agents
to make informed decisions.
A correction, step by step
A chat agent approves a refund exception, a voice agent reads it, and a lead revokes it. Every question below has one answer, set by the rule for that fact.
Sep 12 remember customer-4812 refund_exception = approved # chat agent Sep 20 recall customer-4812 refund_exception # voice agent sees approved Oct 2 remember customer-4812 refund_exception = revoked # replaces approved recall now -> revoked, replaced approved from Sep 12 recall as of Sep 20 -> approved, with the chat message it came from history -> approved on Sep 12, revoked on Oct 2
Try it in a minute
One pip install brings the client and the database. No model or embedding API key needed. The quick start walks through history, as-of reads, and connecting your agent.
# pip install polign-recall from polign_recall import Client with Client(local_dir="./recall-data") as memory: memory.remember("user", "prefers_editor", "vim") memory.remember("user", "prefers_editor", "neovim") memory.recall("user", "prefers_editor")[0].value # neovim memory.history("user", "prefers_editor") # vim, then neovim
Runs on the store you already have
Recall is the memory. The vector store underneath is yours to choose, and the records are the same on every one. polign_db is the backend we built for it and the only one with every capability today; a Qdrant you already run works for the memory tools. The table says exactly what each one gives you.
| Capability | polign_db | Qdrant |
|---|---|---|
| Remember, recall, forget, history, as-of reads, corrections by rule, evidence links, audit bundles | Yes | Yes |
One server for many agents (recall serve), keys bound to a namespace, Kubernetes workload identity | Yes | Yes |
| Agent resume after a crash (needs leases) | Yes | No |
| Keyword search beside vector search | Yes | No, vector search only |
| Cached reads of busy facts | Yes | No, every read refolds the history |
| Where the data lives | Your S3, GCS or Azure bucket; any node can be replaced | Qdrant's own storage |
| Cost of holding memory | Measured: about $3.20 per million searches straight from S3 and about $0.01 per million writes, no index in RAM, nothing running when idle. Method | From Qdrant's own capacity planning guidance: vectors and index are held in RAM or on local disk, sized per collection. Not measured by us |
Postgres with pgvector is next, with leases, so resume will work there too. Start on whichever store you have; the records do not change shape when you move.
Typed memory, no schema to write
A memory is a subject, a predicate, and a typed value. Recall starts with predicates for coding work and personal facts, and a predicate nothing has defined yet is defined by its first use. A new name that only reorders an existing one is filed under it. Or keep a fixed list, and agents write only the kinds you declared.
Corrections by rule
A predicate declares whether it holds one value or many. A new value replaces the old one when only one is allowed, and is added alongside when several are. A statement can also end a belief filed under another predicate: "dislikes mangoes" replaces "likes mangoes", and both answers say so. Every read shows the same value held under another predicate, so a conflict is never hidden. Nothing is deleted, and if a rule was wrong, one correction fixes every past and present answer.
History you can query
Forgetting records a withdrawal instead of deleting. Ask what is believed now, what was believed at any earlier moment, or the full history of a fact. Nothing is edited in place.
Shared across agents
Agents in different processes and on different machines use the same memory. A
correction one agent writes is returned by later reads from the others. One
recall serve answers many agents at once, each inside the namespace its key
names, and a pod on Kubernetes needs no key at all: it proves who it is with its own
service account token. See it inside a sandbox.
Replayable audit
Export a versioned bundle of the events and rules behind a memory query result. A standalone verifier reproduces that result offline, without a database or an embedding model. It covers what memory returned, not the agent's reasoning.
Your storage, your choice
Runs on polign_db against your own S3, GCS, or Azure bucket, the backend with every capability, or on a Qdrant you already run. The table above says what each gives you. Keys bound to a namespace are the isolation boundary between teams and agents. No embedding service is needed to start; bring your own model for semantic search.
Resume after a crash
An agent can record its working state and turns to Recall as it works. When its pod dies or its image is upgraded, the next process picks up from those records instead of a snapshot. Read how it works, or use it with LangGraph.
How it is built
Every memory is an event in an append-only log, and every answer is a fold
over that log at the instant you ask about. The registry holds the correction rules, the
backend holds the records, and recall serve puts keys and namespaces in front of
both. Read the architecture, with diagrams.
Become a design partner
Give us your agent and we will wire Polign Recall into it.
- You bring an agent that is in or near production, and a real memory problem
- We do the integration work, architecture help, a Recall deployment in your cloud on polign_db or the store you already run, and migration from your current memory store
- The commitment is one engineer on your side who owns it, and one 30-minute engineering call a week for the first 4 to 6 weeks
- Done means success criteria we write down together before day one, for one production-like agent writing memory into Polign
- Your infrastructure stays in your account and on your bill
- No charge for 60 days, with written success criteria agreed up front. Meet them and it converts to $12k for the next 12 months. See pricing
What ships today
- Go library with no dependencies outside the standard library
- Python client on PyPI as polign-recall
- MCP server through the
recallcommand, read-only or read-write recall serve: one server for many agents over HTTP and MCP, with keys bound to a namespace, and Kubernetes workload identity so a pod needs no key at all- Claude Code plugin for memory across sessions
- LangGraph package for agents that resume after a crash
- Pydantic AI package for agents that remember their users across runs
- LiveKit Agents package for voice agents that remember the caller
- Vapi adapter for caller memory through authenticated webhooks
- Qdrant backend for teams that already run Qdrant, without agent leases or keyword search
- Starter predicates for coding and personal assistants; new ones are defined by first use, or keep a fixed list
- As-of reads that answer what was believed at an earlier time
- Audit bundles with an offline verifier
- Word-overlap search built in; model embeddings optional
- Plain text in, sentences out, optional: with a model configured, Recall works out the facts and decides how each is filed. Without one, your agent proposes facts and Recall validates them
recall explainshows why each answer is held: the text it came from, the rule that decides it, and its history- Evidence links: a fact proposed from text keeps the exact words it came from
- Corrections across predicates: the registry pairs predicates that contradict each other (likes and dislikes, owns and gave away), so a later statement under one ends the same value under the other. An agent can name anything else a statement ends. Conflicts that no rule settles are shown, never guessed
- Forget is a withdrawal that keeps the history readable; delete the records in the store to erase them
- Runs where you run it: your laptop, your cluster, your bucket
Give your agents one memory.
Open source, on the store you already run.