[ SDK REFERENCE ]
MemBlock Documentation
Everything you need to store, query, and reason over structured memory in Python.
pip install memblock
Installation Extras
The base install gives you everything for local memory with SQLite. Add optional extras for additional capabilities.
pip install "memblock[postgres]"
PostgreSQL storage backend for production multi-tenant deployments
pip install "memblock[embeddings]"
Local vector embeddings via FastEmbed — CPU-only, no API key needed
pip install "memblock[llm]"
LLM-powered memory extraction with OpenAI, Anthropic, and Google Gemini
pip install "memblock[reranker-cohere]"
Cohere-based reranker for improved search relevance
pip install "memblock[reranker-cross-encoder]"
HuggingFace cross-encoder reranker — runs locally
pip install "memblock[pool]"
Connection pooling via psycopg_pool for production PostgreSQL deployments
pip install "memblock[pgvector]"
Server-side HNSW vector search via pgvector — replaces brute-force cosine
pip install "memblock[all-cloud]"
All cloud backends, cloud embeddings (OpenAI, Gemini), LLM extraction, Cohere reranker, pooling, and pgvector — works on Python 3.13+
pip install "memblock[all]"
Everything including local FastEmbed & cross-encoder reranker — requires Python ≤ 3.12 (onnxruntime dependency)
Core API
The essential methods for storing, querying, and building context from memory.
MemBlock()
MemBlock(storage="sqlite:///:memory:", encryption_key=None, embeddings=False)
Initialize a MemBlock instance. Supports SQLite (local file or in-memory) and PostgreSQL. Pass an encryption_key to enable AES-256 per-block encryption.
Returns: MemBlock instance
.store()
mem.store(content, type=BlockType.FACT, confidence=1.0, tags=None, encryption_level=EncryptionLevel.NONE, happened_at=None, temporal_precision="exact")
Store a new memory block. Supports 5 types: FACT, PREFERENCE, EVENT, ENTITY, RELATION. Optionally set happened_at for temporal anchoring and encrypt at STANDARD or SENSITIVE level.
Returns: Block
.query()
mem.query(type=None, tags=None, text_search=None, min_confidence=0.0, sort_by="relevance", limit=10)
Query blocks with structured filters. Combines full-text search, tag filtering, type filtering, and optional semantic (vector) hybrid search.
Returns: list[Block]
.build_context()
mem.build_context(query=None, token_budget=4000, strategy="relevance")
Build an LLM-ready context string from relevant memory. Strategies: relevance, graph_walk, type_grouped, adaptive. The new adaptive strategy combines relevance + graph expansion + deduplication.
Returns: str
.build_context_with_confidence()
mem.build_context_with_confidence(query=None, token_budget=4000, strategy="relevance", evidence_threshold=0.3)
Build context with confidence metadata for adversarial robustness. Returns a tuple of (context_string, ContextConfidence). When evidence is below threshold, signals that the question may be unanswerable.
Returns: (str, ContextConfidence)
.multi_hop_query()
mem.multi_hop_query(text_search, limit=10)
Multi-hop iterative retrieval for complex reasoning. Performs 3 passes: hybrid search, entity extraction + focused queries, and graph walk with proximity boosting. Best for questions connecting multiple facts.
Returns: list[Block]
.update()
mem.update(block_id, content=None, confidence=None, tags=None)
Update an existing block by ID. Only provided fields are modified. Triggers on_update hooks.
Returns: Block | None
.delete()
mem.delete(block_id, cascade=False)
Delete a block by ID. With cascade=True, also removes linked child blocks and graph edges.
Returns: bool
Knowledge Graph
Connect memories into a traversable graph. No external graph database required.
.link()
mem.link(source_id, target_id, relation=EdgeRelation.RELATED_TO)
Create a directed edge between two blocks. Supported relations: RELATED_TO, DERIVED_FROM, CONTRADICTS, SUPPORTS, PRECEDES, PART_OF.
Returns: None
.neighbors()
mem.neighbors(block_id, relation=None)
Get all blocks directly connected to a block. Optionally filter by relation type.
Returns: list[Block]
.traverse()
mem.traverse(block_id, max_depth=3)
Walk the knowledge graph from a starting block up to max_depth hops. Returns all reachable blocks.
Returns: list[Block]
Org-Level Analytics
Track what questions users are asking across your organization. Deduplicated, frequency-counted, with noise filtering and time-series breakdowns. Opt in with enable_analytics=True.
.log_question()
mem.log_question(question, user_id=None, org_id=None)
Log a user question for analytics. Automatically normalizes text, deduplicates, and tracks frequency and unique users. Noise (greetings, short strings) is filtered out and returns None.
Returns: QuestionRecord | None
.get_top_questions()
mem.get_top_questions(org_id=None, limit=20, since=None, until=None)
Get the most frequently asked questions for an organization, ordered by frequency. Optionally filter by time range.
Returns: list[QuestionRecord]
.get_trending_questions()
mem.get_trending_questions(org_id=None, window_days=7, limit=10)
Get questions trending upward — compares recent frequency against historical average to surface emerging topics.
Returns: list[QuestionTrend]
.get_question_breakdown()
mem.get_question_breakdown(question, org_id=None, granularity="daily")
Get a time-series breakdown of how often a specific question was asked. Granularity: "daily", "weekly", or "monthly".
Returns: dict[str, int]
.question_stats()
mem.question_stats(org_id=None)
Get aggregate analytics stats: total unique questions, total asks, and the top question with its frequency.
Returns: dict
Advanced
Tamper detection, async support, and data export.
.verify()
mem.verify()
Run tamper detection across the entire operation log. SHA-256 hash-chain verification catches any unauthorized modification.
Returns: TamperReport
.export_markdown()
mem.export_markdown()
Export all memory blocks as a formatted Markdown string. Useful for debugging, sharing, or archiving.
Returns: str
AsyncMemBlock
async with AsyncMemBlock(storage=...) as mem:
Async wrapper around MemBlock. All methods (store, query, build_context, etc.) are awaitable. Use as an async context manager.
Returns: AsyncMemBlock instance
Production
Connection pooling, per-user instance caching, and server-side vector search for multi-tenant deployments.
MemBlockPool()
MemBlockPool(storage, max_instances=100, **shared_kwargs)
LRU-cached instance factory for multi-tenant deployments. Creates and caches per-user MemBlock instances. Evicts least-recently-used when exceeding max_instances. Use as a context manager.
Returns: MemBlockPool instance
pool.get()
pool.get(user_id, **overrides)
Get or create a MemBlock instance for a user. Returns cached instance if available, creates new one otherwise. LRU eviction keeps memory bounded.
Returns: MemBlock
AsyncMemBlockPool()
AsyncMemBlockPool(storage, max_instances=100, **shared_kwargs)
Async wrapper around MemBlockPool. Returns AsyncMemBlock instances via await pool.get(). Use as an async context manager with FastAPI or aiohttp.
Returns: AsyncMemBlockPool instance
Connection Pooling
MemBlock(storage="postgresql://...", user_id="u_123", pool=connection_pool)
Pass a psycopg_pool.ConnectionPool to share connections across requests. Connections are borrowed on use and returned on close() — no per-request connection overhead.
Returns: MemBlock instance (pooled)
pgvector Search
pip install "memblock[pgvector]"
When the pgvector PostgreSQL extension is installed, MemBlock auto-detects it and uses server-side HNSW vector search instead of brute-force Python cosine. Dual-write to BYTEA + vector column ensures backward compatibility. No code changes needed.
Returns: Automatic — transparent upgrade
Block Types
Every memory block has a type. Use the right type to enable structured queries and context building.
Quick Example
from memblock import MemBlock, BlockType
mem = MemBlock(storage="sqlite:///memory.db")
# Store a preference
mem.store("User prefers dark mode", type=BlockType.PREFERENCE)
# Query by text
results = mem.query(text_search="dark mode")
# Build LLM context
context = mem.build_context(
query="user preferences",
token_budget=2000
)Analytics Example
from memblock import MemBlock
mem = MemBlock(
storage="sqlite:///memory.db",
enable_analytics=True,
org_id="my_org"
)
# Log questions from your chatbot users
mem.log_question("How do I reset my password?", user_id="user_42")
mem.log_question("How do I reset my password?", user_id="user_88")
mem.log_question("What is the refund policy?", user_id="user_42")
# See what users are asking most
top = mem.get_top_questions(limit=10)
# → [QuestionRecord("how do i reset my password", freq=2, users=2), ...]
# Get trending questions (rising in the last 7 days)
trending = mem.get_trending_questions(window_days=7)
# Daily breakdown for a specific question
breakdown = mem.get_question_breakdown(
"How do I reset my password?",
granularity="daily"
)
# → {"2026-03-16": 2}
# Aggregate stats
stats = mem.question_stats()
# → {"total_unique_questions": 2, "total_asks": 3, ...}Temporal + Multi-Hop Example
from memblock import MemBlock, BlockType
from datetime import datetime, timezone
mem = MemBlock(storage="sqlite:///memory.db")
# Store events with temporal anchoring
mem.store(
"User deployed v2.0 to production",
type=BlockType.EVENT,
happened_at=datetime(2024, 3, 10, tzinfo=timezone.utc),
temporal_precision="day",
tags=["deploy", "v2"]
)
# Temporal queries are parsed automatically
results = mem.query(text_search="What happened last March?")
# Multi-hop retrieval for complex questions
results = mem.multi_hop_query("Who recommended the restaurant?")
# Adaptive context with confidence gating
context, confidence = mem.build_context_with_confidence(
query="user preferences",
strategy="adaptive",
evidence_threshold=0.3
)
if not confidence.sufficient_evidence:
print("Not enough information to answer")Production Example
from psycopg_pool import ConnectionPool
from memblock import MemBlockPool, AsyncMemBlockPool, BlockType
# Connection pooling + instance factory
pg_pool = ConnectionPool(
"postgresql://user:pass@localhost/mydb",
min_size=4, max_size=20
)
# Sync — each user gets a cached MemBlock instance
with MemBlockPool(
"postgresql://user:pass@localhost/mydb",
max_instances=100,
pool=pg_pool,
) as pool:
mem = pool.get("user_123")
mem.store("Prefers dark mode", type=BlockType.PREFERENCE)
# Async — works with FastAPI / aiohttp
async with AsyncMemBlockPool(
"postgresql://user:pass@localhost/mydb",
max_instances=100,
pool=pg_pool,
) as pool:
mem = await pool.get("user_456")
await mem.store("Works at Acme", type=BlockType.FACT)
# pgvector is automatic — just install the extra
# pip install "memblock[pgvector]"
# If pgvector extension exists in your DB, vector
# search uses server-side HNSW instead of Python cosine