PatternMem RAG
Framework-agnostic Python middleware that wraps any existing RAG pipeline and makes it self-improving — via persistent failure-pattern memory across queries.
# Before
answer = my_rag_pipeline(query)
# After — one line
answer = await PatternMemMiddleware(pipeline=my_rag_pipeline).ainvoke(query)
Why PatternMem?
Self-RAG, CRAG, and DSPy all reflect within a single query. PatternMem is the missing layer: it makes failure signals persistent across the entire query history — so the second time a pipeline fails on a similar question, it already knows what went wrong and pre-empts the failure.
PatternMem does not reimplement evaluation, LLM calling, or graph storage. It sits between your pipeline and the eval/storage libraries you already have.
Quickstart
pip install patternmem-rag
import asyncio
from patternmem import PatternMemMiddleware
async def my_rag_pipeline(query, **kwargs):
# your existing pipeline here
return {"answer": "...", "chunks": [...]}
async def main():
async with PatternMemMiddleware(
pipeline=my_rag_pipeline,
backend="json", # local file, zero credentials
eval="auto", # tries RAGAS → DeepEval → no-op
) as mw:
answer = await mw.ainvoke("What is the capital of France?")
print(answer)
asyncio.run(main())
Zero-credential mode (no API keys needed)
answer = await PatternMemMiddleware(
pipeline=my_pipeline,
backend="json",
eval="none",
observability=None,
).ainvoke(query)
Run the included demo:
python examples/zero_credential_demo.py
How it works
Query ──► [Phase 1: ~50ms]
Embed query (MiniLM, local)
Lookup patterns (cosine similarity ≥ 0.82)
on HIT → Augmenter injects retrieval_hint / generation_constraint
Pipeline called → Answer returned to caller immediately
[Phase 2: async background]
EvalRouter: RAGAS / DeepEval / none → FailureSignal
[Phase 3: async background]
BackgroundReflector: LLM extracts FailurePattern → Backend write
Decay/eviction loop (patterns below weight 0.1 are pruned)
The caller never waits for Phases 2 or 3.
Optional extras
| Extra | What it adds |
|---|---|
pip install patternmem-rag[ragas] |
RAGAS evaluation adapter |
pip install patternmem-rag[deepeval] |
DeepEval evaluation adapter |
pip install patternmem-rag[neo4j] |
Neo4j / AuraDB backend |
pip install patternmem-rag[langfuse] |
Langfuse observability |
pip install patternmem-rag[networkx] |
NetworkX in-memory backend |
pip install patternmem-rag[chroma] |
ChromaDB vector backend |
pip install patternmem-rag[faiss] |
FAISS local vector index backend |
Configuration reference
PatternMemMiddleware(
pipeline, # any callable (sync or async)
llm=None, # explicit LLM; auto-resolved if omitted
backend="json", # "json" | "sqlite" | "networkx" | MemoryBackend
eval="auto", # "ragas" | "deepeval" | "auto" | "none"
observability=None, # "langfuse" | "otel" | None
similarity_threshold=0.82, # cosine similarity floor for pattern lookup
allow_param_override=False, # allow temperature/CoT overrides
rewrite_feedback=False, # inject hints into query rewriter
)
Backend choice guide
| Backend | Best for | Persistence | Dependencies |
|---|---|---|---|
"json" |
Zero-config, development | File | None |
"sqlite" |
Single-process production | File (WAL) | aiosqlite (core) |
"networkx" |
Notebooks, graph experiments | Optional file | networkx |
"chroma" |
Large stores, existing Chroma setup | File / HTTP server | chromadb |
"faiss" |
High-speed local search, no server | File (index + sidecar) | faiss-cpu |
"neo4j" |
Multi-process, AuraDB, scale | Native graph | neo4j driver |
Custom backend
Implement MemoryBackend and pass an instance directly:
from patternmem import MemoryBackend, PatternMemMiddleware
class MyRedisBackend(MemoryBackend):
async def write_pattern(self, pattern): ...
async def lookup_patterns(self, embedding, top_k=3): ...
async def get_stats(self): ...
async def update_pattern(self, id, decay_weight): ...
async def delete_pattern(self, id): ...
mw = PatternMemMiddleware(pipeline=my_pipeline, backend=MyRedisBackend())
FAQ
Q: Does PatternMem replace RAGAS or DeepEval? No. It wraps them. It uses their scores as signals, stores the resulting patterns, and pre-empts future failures.
Q: Does it change my prompts?
Never. All augmentation flows through augmented_input kwargs — PatternMem never touches your prompt template.
Q: What if evaluation isn't installed?
eval="none" is a first-class mode. The middleware still runs the full 3-phase loop; Phase 2 returns an UNKNOWN signal and Phase 3 stores it with no external calls.
Q: What's the LLM used for?
Only Phase 3 (root cause extraction and hint generation from a FailureSignal). It borrows your pipeline's LLM — it never creates one.
Q: What's out of scope? Celery integration (documented stub), Redis/Postgres backends (open ABC for community), any dashboard (use Langfuse's native UI).
Contributing
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
- All backends must pass the contract test suite in
tests/contract/test_backend_contract.py. - Keep public API surface stable — anything not in
patternmem.__init__.__all__is internal.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file patternmem_rag-0.1.1.tar.gz.
File metadata
- Download URL: patternmem_rag-0.1.1.tar.gz
- Upload date:
- Size: 43.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f8244bdd6675efe5f899b8f90a002a66eefa539eebd44d0ca8ecf8f39241f83
|
|
| MD5 |
6b9d225d7f38eff9d264ab6e4272d9a1
|
|
| BLAKE2b-256 |
4e01e7bf79dc496976a01a4a0029a899a5d72c3fb9ce7786030ca760ff38791f
|
File details
Details for the file patternmem_rag-0.1.1-py3-none-any.whl.
File metadata
- Download URL: patternmem_rag-0.1.1-py3-none-any.whl
- Upload date:
- Size: 42.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2555dc7ce6d6dffb3b64537417ad3f2b1670eafaca84e58e0572ff9c41699eba
|
|
| MD5 |
596ff3756b8ce78faae3b01b7650da84
|
|
| BLAKE2b-256 |
1177693003f8abd482c81202aa7851c3df0ea815534fea7604eb6a76dc2314ea
|