Sieve
Autonomous Memory Compaction & Self-Cleaning Store for AI Agents
Sieve acts as an automated garbage collector and cache eviction daemon for AI agent memory.
Instead of dumping endless logs into a vector store or burning money on an LLM call every turn to resolve contradictions, Sieve continuously scores, supersedes, and prunes memories in the background using non-autoregressive calibrated decisions (100% local, $0 API cost).
Package Notice: Published on PyPI as
sieve-memory(pip install sieve-memory). Distinct from unrelated projects such as cloud videosieveorllm-sieve.
Why Sieve? • Quickstart • Interactive Web UI • Integration Guide • Benchmarks • Architecture • REST API & CLI
What Sieve Does (In 30 Seconds)
- Ingest & Score (~0.2ms Mock / ~33ms Laya): Categorizes incoming conversation turns into
decision,reference,task, orsmalltalkand scores them on calibrated scales forimportance(0.0 to 1.0) andactionable(0.0 to 1.0). - Background Pairwise Sweeps (FTS5 BM25): Evaluates whether a new fact contradicts or supersedes an older fact (e.g. "We switched from PostgreSQL to MongoDB" supersedes "Our database is PostgreSQL"). The outdated item is marked
status='archived'withsuperseded_by='<new_id>'. - Pinned Memory Retention: High-priority facts (or manual pins) remain immune to staleness pruning and stay active indefinitely.
- Clean System Prompt Context:
memory.get_context(namespace="user_1")orGET /contextyields clean, deduplicated, non-contradictory context ready for injection into your LLM prompt.
The Problem Sieve Solves
Every modern AI agent stores conversational memory, but current approaches break at scale:
| Approach | Latency | Per-Turn Cost | Resolves Supersession & Staleness? |
|---|---|---|---|
| Vector DBs (Chroma, Pinecone) | ~15ms | $0 | ❌ No. Embeddings compute topical similarity, not ground truth. If an agent records "User prefers PostgreSQL" on Monday and "Switched to MongoDB" on Wednesday, vector search returns both with high cosine similarity. The LLM hallucinates outdated facts. |
| Generative LLMs (Mem0, Letta) | ~800–2500ms | $$$ | ✅ Yes, but slow & expensive. Asking GPT-4o on every single conversational turn to extract facts and check for contradictions adds 1–2 seconds of user latency and thousands of unnecessary tokens. |
| Sieve (Built on Laya) | ~33ms | $0 | ✅ Yes. Calibrated non-autoregressive scoring runs locally. Background sweeps automatically supersede outdated facts and keep system prompts clean and up-to-date. |
Sieve is not a vector store, not a search index, and not a chat UI.
It is the lightweight metadata and curation layer that sits beside your agent storage and tells you what to keep, pin, or retire.
Quickstart (5 Minutes)
1. Installation
# Zero-dependency core (runs anywhere, instant setup, built-in heuristic MockScorer)
pip install sieve-memory
# Optional extras for specific deployment targets:
pip install "sieve-memory[laya]" # Real neural decision model (ConvAI Laya checkpoint)
pip install "sieve-memory[serve]" # FastAPI REST microservice & visual UI dashboard
pip install "sieve-memory[integrations]" # LangChain & ChromaDB connectors
pip install "sieve-memory[all]" # Complete suite with all backends
2. Run the Interactive Demos
# Agent workflow demo (remember -> update -> sweep -> context window)
python examples/agent_quickstart.py
# End-to-end batch curation demo
python examples/run_v0.py
Interactive Web Dashboard
Sieve ships with a built-in dark mode dashboard for visualizing memory curation in real-time.
# Start the visual dashboard (or pass --db path)
sieve ui --port 8000
Open http://localhost:8000/ui in your browser:
- Active Memories: Real-time cards showing importance levels, categories, and pinning controls.
- Superseded & Stale: View facts pruned by background sweeps with pointers to the superseding item.
- Action Items Inbox: Real-time ranking of open tasks and pending follow-ups.
- System Prompt Live Preview: Inspect exactly what prompt context Sieve generates for your LLM.
How to Use Sieve in Your Projects
Pattern 1: Drop-in Memory for Any AI Agent (OpenAI, Anthropic, LangChain)
Use SieveMemory directly inside your agent loop. It automatically partitions by namespace (user_id or session_id), supports continuous background workers, and prepares clean context strings for your system prompt:
from sieve import SieveMemory
# 1. Initialize memory store (persisted in SQLite + FTS5)
memory = SieveMemory(db_path="agent_memory.db")
# Optional: Start background curation daemon (runs sweeps every 60s)
memory.start_daemon(interval_seconds=60)
# 2. Record conversation facts as your agent talks to a user
session = "user_42"
memory.remember("User's primary database is PostgreSQL.", namespace=session)
memory.remember("TODO: Send invoice to Alice by Friday.", namespace=session)
memory.remember("Deployment target is AWS us-east-1.", namespace=session)
# 3. Later, the user changes a decision:
memory.remember("Update: We switched the database from PostgreSQL to MongoDB.", namespace=session)
# 4. Trigger a sweep manually (or let the background daemon handle it)
sweep_stats = memory.sweep(namespace=session)
print(f"Archived {sweep_stats['items_archived']} superseded items.")
# 5. Inject only active, non-superseded facts into your LLM system prompt
system_context = memory.get_context(namespace=session)
print(system_context)
What the LLM sees in its prompt:
- [DECISION] Update: We switched the database from PostgreSQL to MongoDB.
- [TASK] TODO: Send invoice to Alice by Friday.
- [REFERENCE] Deployment target is AWS us-east-1.
(Notice: The old PostgreSQL fact was automatically identified as superseded, archived, and excluded from the active context window.)
Pattern 2: Modern LangChain Agent Integration (LCEL)
Use SieveChatMessageHistory as a drop-in replacement for standard message history in LangChain:
from sieve.integrations.langchain import SieveChatMessageHistory
# Automatically prunes superseded messages every 4 turns
history = SieveChatMessageHistory(session_id="user_alice", db_path="memory.db")
history.add_user_message("We chose PostgreSQL as our database.")
history.add_ai_message("Got it, PostgreSQL configured.")
history.add_user_message("Actually, we migrated to MongoDB instead.")
# In your LangChain agent prompt:
# Only active, non-superseded messages remain in history.messages!
print(history.messages)
Pattern 3: Sidecar alongside ChromaDB / Vector DBs
You don't need to replace your vector database. Sieve acts as an active filter:
import chromadb
from sieve.integrations.chroma import SieveChromaSync
client = chromadb.Client()
collection = client.create_collection("agent_docs")
sync = SieveChromaSync(collection, db_path="sieve.db")
# Add memories into both Sieve and Chroma
sync.add(
documents=["Primary DB is PostgreSQL.", "Actually, switched to MongoDB."],
ids=["doc_1", "doc_2"],
namespace="user_alice",
)
# Run sweep: marks doc_1 as archived in both Sieve and Chroma metadata
sync.sweep(namespace="user_alice")
# Query Chroma: automatically filters out stale/superseded records!
results = sync.query(
query_texts=["What database are we using?"],
namespace="user_alice",
only_active=True,
)
Pattern 4: Standalone Microservice (FastAPI REST Server)
Run Sieve as an internal microservice for distributed agents across any tech stack (Python, TypeScript, Go, Rust):
pip install "sieve-memory[serve]"
sieve serve --port 8000 --db sieve.db --api-key my_secret_key
GET /context?namespace=default: Formatted markdown bullet points ready for LLM prompt injectionPOST /items: Ingest single memory with immediate scoring (supportscreated_atbackdating)POST /items/batch: Bulk ingest with per-item status trackingGET /active?limit=50&offset=0: Fetch active memory items (including pinned) ranked by importanceGET /inbox?threshold=0.6: Fetch open action items ranked by actionabilityPOST /item/{id}/pin&/unpin: Pin or unpin memoriesPOST /item/{id}/restore: Reactivate an archived memory and mark sticky restorationGET /namespaces: List all active namespacesDELETE /namespace/{namespace}: Permanently delete all memories in a namespaceGET /metrics: System operational metrics (DB size, item counts, scorer backend, sweep durations)POST /sweep/staleness: Trigger background staleness sweepPOST /sweep/redundancy: Trigger background redundancy detectionPOST /sweep/retention: Enforce retention bounds (max_active_itemsandarchive_ttl_seconds)GET /ui: Interactive web dashboard (supports API key token prompt and toast notifications)
Production Deployment & Security
# Production server with API key auth, custom checkpoint, and SQLite WAL storage
SIEVE_DB_PATH=/var/data/sieve.db \
SIEVE_API_KEY=your-secure-secret-token \
SIEVE_SCORER=laya \
SIEVE_LAYA_CHECKPOINT=convaiinnovations/laya \
SIEVE_LAYA_DEVICE=cuda \
uvicorn sieve.api:app --host 0.0.0.0 --port 8000
| Setting | Default | Purpose |
|---|---|---|
SIEVE_DB_PATH |
sieve.db |
Filepath to persistent SQLite database. Runs in WAL mode with auto-migrations. |
SIEVE_API_KEY |
(None) | Bearer token / X-API-Key auth. When set, all read/write endpoints require authentication. |
SIEVE_SCORER |
mock |
Decision backend: mock (offline heuristic) or laya (calibrated neural model). |
SIEVE_LAYA_CHECKPOINT |
convaiinnovations/laya |
Hugging Face model checkpoint for LayaScorer. Cached in memory. |
SIEVE_LAYA_DEVICE |
None (auto) |
Target device for neural inference: cuda, mps, or cpu. |
SIEVE_CORS_ORIGINS |
(None) | Comma-separated list of allowed origins (or *) for external browser clients. |
Dashboard Authentication: When
SIEVE_API_KEYis configured on the server, the/uidashboard provides an inline 🔑 API Key manager modal, storing your token in this browser'slocalStorageand attaching it to all asynchronous requests. Security Note: Never expose Sieve directly to the public internet withoutSIEVE_API_KEYconfigured or without an authenticated reverse-proxy (Nginx/Caddy) providing TLS and access control. Note that on ephemeral hosting (such as Vercel serverless), the database defaults to/tmp/sieve.db.
Retention Policy & Operational Backups
Sieve supports automatic capacity bounds and live online backups:
# Atomic online hot backup (WAL-safe without locking concurrent writes)
sieve backup /var/backups/sieve_$(date +%Y%m%d).db --db /var/data/sieve.db
# Enforce active context limits and TTL purging via CLI
sieve retention --namespace user_1 --max-active 20 --ttl 2592000
In Python:
from sieve import SieveMemory, PolicyConfig
# Configure retention limits: max 20 active facts, purge archived facts older than 30 days
policy = PolicyConfig(
max_active_items=20,
archive_ttl_seconds=30 * 86400,
pinned_immune=True, # Pinned items are never auto-pruned
restored_immune=True, # User-restored items are protected from sweep archiving
)
memory = SieveMemory(policy_config=policy)
Reproducible Benchmarks
Run the local pipeline benchmark on your machine:
# Evaluate with lightweight Mock heuristics
python benchmarks/benchmark.py --scorer mock
# Evaluate with real calibrated Laya neural inference
python benchmarks/benchmark.py --scorer laya
Evaluation Transparency: Rather than testing only positive replacements against matching regexes, Sieve measures Precision, Recall, and F1 against adversarial hard negatives (clarification questions, orthogonal updates sharing keywords, and complementary elaborations in
benchmarks/eval_dataset.py).
Benchmark Summary (Local M-Series / Linux):
======================================================================
SUMMARY COMPARISON TABLE
======================================================================
Metric | Sieve (Laya ModernBERT) | LLM per Turn (4o-mini)
------------------------------------------------------------------------------
Latency per Item | ~90–380 ms | ~850 ms
API Cost (10,000 items) | $0.00 | ~$1.35
Staleness Precision | 100.0% (0 false alarms) | ~95%
Staleness F1 Score | 75.0% – 88.9% | ~92–95%
Context Window Growth | Bounded (Pruned) | Bounded
Context Bloat Reduction | 21–34% saved | 30–35% saved
======================================================================
Switching from Mock to Real Neural Inference (Laya)
By default, Sieve runs MockScorer—a zero-dependency heuristic engine designed for rapid development and CI tests.
To use the real Laya calibrated neural checkpoint:
pip install laya
from sieve import SieveMemory
# Loads the calibrated Laya checkpoint from Hugging Face (~33ms per inference)
memory = SieveMemory(use_real_laya=True)
Every other layer of your stack (SQLite store, FTS5 sweeps, policy rules, REST API) remains completely unchanged.
How It Works
Raw Text Memory
│
▼
1. INGESTION ───► SQLite Store (Partitioned by Namespace)
│
▼
2. CALIBRATED ───► Evaluates:
SCORING • Importance: Will this matter beyond the moment? (0.0 - 1.0)
• Actionable: Is there an open task or follow-up? (P(true))
• Category: decision | reference | task | smalltalk
│
▼
3. POLICY ───► • Pin if importance >= 0.85 (immune to auto-archiving)
ENGINE • Route to Action Inbox if actionable >= 0.60
• Queue for batched review if confidence is low
│
▼
4. PAIRWISE ───► • Uses SQLite FTS5 BM25 to find topically related candidates
SWEEPS • Scores staleness: Does the newer item invalidate the older one?
• Archives outdated facts with pointer to `superseded_by`
What Sieve Scores
| Metric | Type | Question Evaluated |
|---|---|---|
importance |
score |
Will this matter beyond the moment it was written? |
actionable |
noul |
Is there an open task, pending decision, or required follow-up? |
category |
choice |
decision · reference · task · smalltalk |
staleness |
noul (pairwise) |
Does the newer item make the older item outdated or invalid? |
redundancy |
noul (pairwise) |
Do two items convey substantially identical information? |
CLI Reference
# Launch Sieve REST API server & web dashboard
sieve serve --port 8000 --db sieve.db --api-key my_secret
# Launch visual dashboard in browser
sieve ui --port 8000
# Remember a fact directly from terminal
sieve remember "Decided to adopt PostgreSQL" --namespace project_x
# Print active memory context formatted for direct LLM system prompt injection
sieve context --namespace project_x
# Pin critical items so they are permanently protected from pruning
sieve pin cli_179166_4ff0
sieve unpin cli_179166_4ff0
# Archive or delete memories
sieve archive cli_179166_4ff0
sieve delete cli_179166_4ff0
# Run curation sweeps (supersede outdated facts)
sieve sweep --namespace project_x
# Check open task inbox
sieve inbox --namespace project_x
# View store statistics
sieve stats --namespace project_x
Testing
Sieve has 100% passing tests covering CRUD, thread-safety, namespaces, FTS5 BM25 candidate ranking, policy staleness, LangChain & ChromaDB integrations, background daemons, and the REST API:
python -m pytest tests/ -v
License
MIT © Ashutosh Bansal
Metadata
Release files for sieve-memory 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sieve_memory-0.1.3.tar.gz | 1.1 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sieve_memory-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.2 MB
Release files / sieve_memory-0.1.3.tar.gz
| Download URL | sieve_memory-0.1.3.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e9ff18dc6180752be5c585dceeafe0ff4aa779bd962f6be289fda0583674d5b0
|
|
BLAKE2b-256 checksum How to use checksums |
33d7249a82a3fcb404f17a049fc712a72720c26c01ec5a394b97a69fc603d785
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / sieve_memory-0.1.3-py3-none-any.whl
| Download URL | sieve_memory-0.1.3-py3-none-any.whl |
|---|---|
| Size | 1.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8d213abc58ccad91a0ea95eee38a56177879bd14f5d488adb08c9f667f45062f
|
|
BLAKE2b-256 checksum How to use checksums |
0d8fe0445aa7d9f00221ab08d8a0100718bde307c753dcd052d2a91b3087df87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logSecurity for sieve-memory 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for sieve_memory-0.1.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.