Skip to main content

Persistent memory for AI agents. Three methods. Zero infra.

Project description

kemi

Persistent memory for AI agents. Three methods. Zero infra.

PyPI version Python versions License: MIT Tests Coverage

from kemi import MemoryService

memory = MemoryService()  # SQLite + local embeddings, no API keys needed

memory.remember("user123", "User prefers dark mode")
memory.remember("user123", "User is vegetarian")

results = memory.recall("user123", "what are the user's preferences?")
# Returns ranked, deduplicated memories

memory.forget("user123")  # GDPR-compliant deletion

Note: from kemi import Memory still works as a backwards-compatible alias. New code should import MemoryService directly.


Why kemi?

Every other memory library either hosts your data on their servers, requires Docker and 4 services to run, or locks you into a specific framework.

kemi is different:

Zero infrastructure pip install kemi, no Docker, no cloud, no setup
Zero hard dependencies Only the core library + SQLite. Optional backends live behind extras ([chroma], [qdrant], [postgres], etc.)
Your data stays yours Stored in SQLite on your machine, never leaves
Bring your own embedding OpenAI, local models (fastembed), or any function
Framework agnostic Works with LangChain, CrewAI, AutoGen, or plain Python
MCP ready Use as a memory server for Claude Desktop, Cursor, and Continue
100% free MIT license, no paid tiers, no cloud lock-in

Install

pip install kemi                    # Core only — zero hard dependencies
pip install "kemi[local]"           # + local embeddings (no API key, ~130MB download)
pip install "kemi[openai]"          # + OpenAI embeddings (1536-dim)
pip install "kemi[postgres]"        # + PostgreSQL + pgvector (ANN, FTS, hybrid search)
pip install "kemi[mcp]"            # + MCP server (Claude Desktop, Cursor, Continue)
pip install "kemi[langchain]"      # + LangChain BaseChatMemory adapter
pip install "kemi[chroma]"         # + ChromaDB vector store
pip install "kemi[qdrant]"         # + Qdrant vector store
pip install "kemi[redis]"          # + Redis vector store
pip install "kemi[all]"            # Everything (heavy)

Quick Start

Zero-config (local embeddings)

from kemi import MemoryService

memory = MemoryService()
memory.remember("user123", "User is vegetarian", importance=0.9)
results = memory.recall("user123", "food preferences")

With OpenAI embeddings

from kemi import MemoryService
from kemi.adapters.embedding.openai import OpenAIEmbedAdapter

memory = MemoryService(embed=OpenAIEmbedAdapter())
memory.remember("user123", "User prefers concise responses")
results = memory.recall("user123", "communication style")

With PostgreSQL + pgvector

from kemi import MemoryService
from kemi.adapters.storage.postgres import PostgresStorageAdapter

store = PostgresStorageAdapter(dsn="postgresql://user:pass@localhost:5432/kemi", embedding_dim=384)
memory = MemoryService(store=store)
memory.remember("user123", "User prefers dark mode")
results = memory.recall("user123", "color theme preferences")

Inject into system prompts

context = memory.context_block("user123", query="user preferences", max_tokens=500)
# Returns formatted string ready to paste into an LLM system prompt

Async (FastAPI)

from fastapi import FastAPI
from kemi import MemoryService

app = FastAPI()
memory = MemoryService()

@app.post("/chat")
async def chat(user_id: str, message: str):
    await memory.aremember(user_id, message)
    context = await memory.acontext_block(user_id, message)
    return {"context": context}

GDPR-compliant deletion

memory.forget("user123")            # Delete all memories for a user
memory.forget("user123", memory_id) # Delete one specific memory

Features

Feature What it does
Semantic deduplication "I'm vegetarian" and "I don't eat meat" are detected as the same memory
Importance-weighted scoring Recent, important memories rank higher in search results
Temporal decay Memories fade if never recalled -- transitions from ACTIVE to DECAYING
Conflict detection Flags contradictory memories ("I love coffee" vs "I hate coffee")
Hybrid search Combines semantic (vector) search with keyword (BM25) search
MMR reranking Ensures diverse results -- not 5 nearly-identical memories
Lifecycle management Automatic state transitions: ACTIVE -> DECAYING -> ARCHIVED -> DELETED
Query decomposition Breaks complex queries into sub-queries with Reciprocal Rank Fusion
Entity extraction Zero-dependency regex or spaCy-based entity linking
Version history Track changes to memories with rollback support
Webhooks Dispatch lifecycle events (remembered, updated, deleted, conflict) to HTTP endpoints
Audit trail Compliance-grade operation log with retention and export
Plugin system Four extension points: WebhookSink, AuditSink, QueryCacheProvider, HookSink

MCP Server

Any MCP-compatible agent (Claude Desktop, Cursor, Continue) can use kemi as its memory layer:

pip install "kemi[mcp]"
python -m kemi

Claude can then remember facts about you across sessions -- no API keys, no cloud, everything local.

Exposed tools

remember, recall, recall_stream, recall_explain, forget, context_block, prune, stats, consolidate, topics, graph, list_users


Adapters

Type Default Alternatives
Embedding fastembed (local, 384-dim) OpenAI (1536-dim), custom function
Storage SQLite (WAL mode) SQLite-vec (ANN), PostgreSQL + pgvector, Redis, Qdrant, Chroma, JSON file, custom

Integrations

LangChain

from kemi import MemoryService
from kemi.integrations.langchain import KemiMemory

memory = MemoryService()
chat_memory = KemiMemory(user_id="alice", memory=memory)

LangGraph / CrewAI / AutoGen

kemi works with any framework. Just use the core remember / recall / forget methods wherever you need persistent memory.

Export / Import

memory.export("backup.json")       # backup all memories
memory.import_from("backup.json")  # restore from backup

CLI

kemi remember user123 "User prefers dark mode"
kemi recall user123 "preferences"
kemi forget user123
kemi stats user123
kemi export backup.json
kemi import backup.json

Use --json for machine-readable output or --quiet to suppress info messages.


Documentation

Guide What you'll learn
Architecture Module map, data flow diagrams, plugin extension points
Quickstart Get running in 5 minutes
Recipes Complete working examples
Configuration Tuning kemi for your use case
Adapters Embeddings, storage, custom implementations
API Stability Stability tiers and deprecation policy
Contributing How to contribute, changelog conventions

Data Privacy

kemi is designed so your data never leaves your machine:

  • All memories stored in local SQLite at ~/.kemi/memories.db
  • Embeddings computed locally (fastembed) or via your own API key (OpenAI)
  • No telemetry, no analytics, no phone-home
  • Full GDPR-compliant deletion with memory.forget()
  • Optional field-level Fernet encryption for content, metadata, and user IDs

Requirements

  • Python 3.10+

License

MIT -- free forever, no exceptions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kemi-0.4.0.tar.gz (2.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kemi-0.4.0-py3-none-any.whl (230.3 kB view details)

Uploaded Python 3

File details

Details for the file kemi-0.4.0.tar.gz.

File metadata

  • Download URL: kemi-0.4.0.tar.gz
  • Upload date:
  • Size: 2.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for kemi-0.4.0.tar.gz
Algorithm Hash digest
SHA256 2092c8fe2e2fe9db53da3b860187de6db93e723da2dd4a72143a14ebc84ab7fd
MD5 041d06625256ef0e3eb89f259a44f1a5
BLAKE2b-256 82d31481acbde61237c3955eda6d1c9555cab138a0dd796b68674a933ad2214c

See more details on using hashes here.

File details

Details for the file kemi-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: kemi-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 230.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for kemi-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 60c609b1a0fe4c93b3e676d6a95cbcb2450153565de33a3915fb983e01187959
MD5 51f5627da5d689865a5401956f3de37c
BLAKE2b-256 546fe9caa81de294a83bac27738a9b1c64a08e2aa0f4df64468d51461e3d082a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page