Agent memory
An AI agent forgets everything between model calls unless something remembers for it. Agent memory keeps two kinds of memory for your agents, in one of your…
An AI agent forgets everything between model calls unless something remembers for it. Agent memory keeps two kinds of memory for your agents, in one of your KiviDB databases:
- Working memory, per conversation (a session): the recent messages and a running summary of the older ones, so a long conversation fits in a prompt.
- Long-term memory, per user (an actor): lasting facts, preferences and events, pulled out of conversations in the background and found again by meaning when they are relevant.
Everything a store remembers is kept in the database it lives in, under keys
starting kividb:mem:. Nothing is stored anywhere else.
How it works
- After each turn, your agent adds the new messages to the session.
- Before the next model call, it asks for recall: the session's summary, its recent messages and the long-term memories most relevant to the user's latest message, as ready-to-use text.
- In the background, once a session has been quiet for the extraction delay (five minutes by default), the store's language model reads the messages it has not read yet and keeps what is worth remembering. A memory the same actor already has (by similarity) is not kept twice.
- Once a session holds more messages than summarize after, the oldest are folded into its summary and only the most recent are kept as they are.
Memories have a type. Every store has semantic (a fact or preference: "The
user deploys to eu-west-1") and episodic (something that happened: "The user
migrated their cache on 12 October"). You can add up to three types of your own,
each with a sentence describing what to extract, such as order_issue: "a
problem the user had with an order, with the order number".
Models and keys
A store uses two models, each with your own API key, stored encrypted and never shown again:
| Used for | Providers | |
|---|---|---|
| Language model | extracting memories and writing summaries | OpenAI, Anthropic, or any HTTPS endpoint with OpenAI's /chat/completions shape |
| Embeddings | finding memories by meaning | OpenAI, or any HTTPS endpoint with OpenAI's /embeddings shape; or none, and you send vectors |
You pay your provider for what these calls use; KiviDB adds no charge for agent memory beyond the database it lives in. With no language model, a store still keeps sessions and the memories you add yourself, but extracts and summarizes nothing. A custom endpoint must be HTTPS on a public address.
Personal data. By default, emails, phone numbers, payment card numbers, US
social security numbers and IP addresses are replaced with markers such as
[email] before a memory is kept. This is pattern matching: names and street
addresses are not caught. Working memory keeps messages as you sent them.
In the console
The Agent memory section lists every store in your organization with the database it lives in; each database also has an Agent memory tab with its own stores. A store shows its sessions with their summaries and messages, its memories (browse, search, forget), when extraction last ran and why it failed if it did, and a place to try it. Agent memory is not available on sharded databases yet.
API
Authenticate with an API key, as for the rest of the API. {id} is the
database, {store} the store's name, and {session} your own conversation id
(letters, digits, ., _, :, @ and -).
| Request | |
|---|---|
GET /agent-memory | every store in the organization, with its database |
GET /instances/{id}/agent-memory | this database's stores |
PUT /instances/{id}/agent-memory/{store} | create or change a store |
GET /instances/{id}/agent-memory/{store} | settings, and counts of sessions, memories and sessions waiting for extraction |
DELETE /instances/{id}/agent-memory/{store} | delete the store and everything it keeps |
POST /instances/{id}/agent-memory/{store}/sessions/{session}/events | add messages: {"actor_id": "user-7", "events": [{"role": "user", "content": "..."}]} |
GET /instances/{id}/agent-memory/{store}/sessions | a page of sessions, most recent first (?offset=) |
GET /instances/{id}/agent-memory/{store}/sessions/{session} | the summary and recent messages (?recent=50) |
DELETE /instances/{id}/agent-memory/{store}/sessions/{session} | forget a session's working memory |
POST /instances/{id}/agent-memory/{store}/sessions/{session}/extract | extract now instead of after the delay |
POST /instances/{id}/agent-memory/{store}/recall | {"session_id", "query"?, "actor_id"?, "limit"?}: summary, recent messages, relevant memories and a context string |
POST /instances/{id}/agent-memory/{store}/memories | add a memory yourself: {"text", "type"?, "actor_id"?, "topics"?} |
GET /instances/{id}/agent-memory/{store}/memories | a page of memories, newest first |
POST /instances/{id}/agent-memory/{store}/memories/search | {"query", "mode": "semantic" | "keyword" | "hybrid", "actor_id"?, "types"?, "limit"?} |
DELETE /instances/{id}/agent-memory/{store}/memories/{memory} | forget one memory |
Creating a store:
curl -X PUT https://api.kividb.io/instances/$DB/agent-memory/support-agent \
-H "Authorization: Bearer $KIVIDB_API_KEY" -H "Content-Type: application/json" \
-d '{
"llm_provider": "openai", "llm_model": "gpt-4o-mini", "llm_api_key": "'"$OPENAI_API_KEY"'",
"embed_provider": "openai", "embed_model": "text-embedding-3-small", "embed_api_key": "'"$OPENAI_API_KEY"'",
"dimensions": 1536
}'
A turn of a conversation, in Python:
import requests
API = f"https://api.kividb.io/instances/{DB}/agent-memory/support-agent"
H = {"Authorization": f"Bearer {KIVIDB_API_KEY}"}
def answer(session_id, user_id, user_message):
memory = requests.post(f"{API}/recall", headers=H, json={
"session_id": session_id, "actor_id": user_id, "query": user_message,
}).json()
reply = call_your_model(system=memory["context"], user=user_message)
requests.post(f"{API}/sessions/{session_id}/events", headers=H, json={
"actor_id": user_id,
"events": [{"role": "user", "content": user_message}, {"role": "assistant", "content": reply}],
})
return reply
Settings
| Setting | Default | |
|---|---|---|
extraction_delay_seconds | 300 | how long after a session's newest unread message extraction runs (30 to 3600) |
summarize_after | 40 | summarize once a session holds more messages than this |
keep_recent | 12 | messages kept as they are when summarizing |
session_ttl_seconds | 3600 | a session is forgotten this long after its last message |
memory_ttl_seconds | 31536000 | a long-term memory is kept this long (one year) |
dedupe_threshold | 0.92 | a new memory at least this similar to one the actor has is a duplicate |
custom_types | none | up to three {"name", "description"} |
redact_pii | true | replace common personal identifiers before keeping a memory |
From an AI assistant
The KiviDB MCP server has list_memory_stores, memory_add_messages,
memory_recall, memory_search, memory_add and memory_forget, so an
assistant can use a store you have made in the console.