Releases: PlateerLab/synaptic-memory
v0.16.0 — engine default flip, CDC batching, 30× eval coverage
Synaptic Memory v0.16.0 — release notes
Release date: 2026-04-17 · License: MIT · Install:
pip install "synaptic-memory[sqlite,korean,vector,mcp]"
TL;DR
v0.16.0 is the cleanup release that makes Synaptic's benchmark
numbers match what the SDK actually does. Five changes:
graph.search()now defaults toengine="evidence"— the
hybrid BM25 + HNSW + PPR + MMR pipeline that the MCP tool path
already used. Legacy HybridSearch is deprecated and will be
removed in v0.17.0.- CDC sync drops 3N round-trips per table to one batch SELECT —
HashTableSyncerandTimestampTableSyncernow issue a single
get_pk_index_batch(...)query instead of three per-row awaits. - Concurrent
_ensure_graph()is race-safe — MCP first-turn
tool dispatches no longer risk constructing two SynapticGraph
instances. - Korean query-time morphological stripping (from v0.15.1)
stays in. - Evaluation coverage grows 30× — 715 queries across 5
Korean-heavy corpora → 22,400 queries across 8 corpora that
now include the standard English multi-hop benchmarks
(HotPotQA-dev, MuSiQue-Ans-dev, 2WikiMultihopQA-dev).
The net effect on the embedder-free baseline is large:
| Korean benchmark | v0.15.0 | v0.16.0 | Δ |
|---|---|---|---|
| Allganize RAG-ko | 0.621 | 0.947 | +0.326 |
| Allganize RAG-Eval | 0.615 | 0.911 | +0.296 |
| AutoRAG KO | 0.592 | 0.906 | +0.314 |
| PublicHealthQA KO | 0.318 | 0.546 | +0.228 |
English HotPotQA-24 rose 0.727 → 0.875 on the same pipeline.
What shipped
1. Engine default: "evidence"
Public API: SynapticGraph.search(query, ...) — the engine kwarg
defaults to "evidence".
Why now. v0.14.x–v0.15.x carried engine="legacy" as the
default for call-site stability. Meanwhile every benchmark in the
README and the draft arXiv preprint was measured through
EvidenceSearch via the MCP tool path. Keeping SDK callers on the
legacy cascade meant our own documented numbers didn't reflect what
a first-time user of graph.search() saw. This release closes that
gap.
Migration. Callers that depended on legacy-specific behaviour
— query_decomposer hook, LLMReranker / NoOpReranker injection,
reinforcement-boosted ranking, or the specific stages_used
shape — must pass engine="legacy" explicitly. A
DeprecationWarning fires; the path is scheduled for removal in
v0.17.0. See tests/test_search_engine_param.py,
tests/test_reranker.py, tests/test_query_decomposer.py,
tests/qa/test_edge_cases.py::TestReinforcementRanking,
tests/qa/test_search_quality.py::test_resonance_ordering for the
six places in-tree that opt-in.
2. CDC sync: N+1 → 1 batch SELECT
src/synaptic/extensions/cdc/state.py
grows a SyncStateStore.get_pk_index_batch(source_url, table, pks)
method that returns {pk: (node_id, row_hash, fk_edges_json)} for
every changed PK in one SQLite query (chunked to 500 host variables
per statement). sync.py's
HashTableSyncer.sync_table() and TimestampTableSyncer.sync_table()
now call this once per table instead of 3 × N times per row.
Impact. 100 rows: ~300 ms → ~1 ms of state lookups. 10 k rows:
30 s → under 100 ms.
3. Concurrent _ensure_graph() race
src/synaptic/mcp/server.py's
lazy initialisation path now holds an asyncio.Lock with a
double-checked fast path. Previously, two tool invocations firing
on the same first turn could both see _graph is None and
construct two SynapticGraph instances, leaking a backend
connection. Fast path (graph already set) still takes no lock.
4. Korean query-time morphological stripping
(Carried from v0.15.1, rebased onto v0.16.0.)
_normalize_korean(text, query_mode=True) drops Kiwi-surviving
interrogative / copular noise forms (무엇, 어떻, 대해,
설명, …) at search time only. Index-time normalisation is
unchanged, so existing graph files are not invalidated. Kiwi only
fires when the query is ≥50 % Hangul, which is why English and
code queries are mathematically unchanged.
Net effect on Allganize RAG-ko alone:
0.621 → 0.743 (Kiwi in v0.15.1) → 0.947 (engine flip in v0.16.0).
5. Evaluation coverage: 715 → 22,400 queries
New scripts:
examples/ablation/download_benchmarks.py— pulls HotPotQA-dev
(distractor), MuSiQue-Ans-dev, and 2WikiMultihopQA-dev from
HuggingFace and converts them to the BEIR-style JSON that
run_ablation.pyalready consumes.examples/ablation/run_tier1_benchmarks.py— standard IR
metrics (MRR, R@5, R@10, Hit@10) for the three English
multi-hop corpora.
Initial 500-query subset numbers (embedder-free, 2026-04-17):
| Dataset | Docs | MRR@10 | R@5 | Hit@10 |
|---|---|---|---|---|
| HotPotQA dev (distractor) | 66,635 | 0.784 | 0.585 | 91.8 % |
| 2WikiMultihopQA dev | 56,687 | 0.795 | 0.501 | 91.2 % |
| MuSiQue-Ans dev | 21,100 | 0.590 | 0.379 | 76.2 % |
MuSiQue is the honest outlier — R@5 0.379 vs HippoRAG2's 0.747.
2-4 hop chains that share no lexical overlap are exactly where an
embedder-free PPR pipeline underperforms an LLM-extracted entity
graph. Embedder path is tracked as v0.16.1.
6. Streaming invariance sharpens
Re-running examples/ablation/streaming_experiment.py on the
new default:
| Metric | v0.15.x (legacy engine) | v0.16.0 (evidence engine) |
|---|---|---|
| Bit-wise identical top-10 | 51.5 % | 96.0 % |
| Top-1 identical | 54.5 % | 100 % |
| |Δ MRR| (batch vs streaming) | 0.0100 | 0.0000 |
The Top-K Set Invariance theorem in
docs/paper/theorem.md holds more tightly.
Deprecations
graph.search(engine="legacy")—DeprecationWarning, removal
scheduled for v0.17.0.SynapticGraph(reranker=LLMReranker(...) | NoOpReranker(...))—
honoured only on the legacy engine; removal with legacy.SynapticGraph(query_decomposer=...)— same.
Upgrade notes
You called graph.search(query) with no kwargs
Before: ran the HybridSearch cascade.
After: runs the EvidenceSearch pipeline.
Retrieval numbers should improve on Korean and English alike.
If you specifically depend on the legacy shape
(stages_used == "synonym" branches, resonance-descending
strict order), pin it explicitly: graph.search(query, engine="legacy").
You called sync_from_database(dsn) on a large CDC graph
No API change. Under the hood the sync is several orders of
magnitude faster on tables with many updated rows (10 k row
test: 30 s → <100 ms). tests/test_cdc_search_regression.py
continues to guard that mode="cdc" produces the same top-k as
mode="full".
You depend on the Mem0-style Reranker/QueryDecomposer hooks
These remain available under engine="legacy" but are not wired
into EvidenceSearch. A migration story for query decomposition
through EvidenceSearch is planned (the compare_search compound
tool covers the main use cases today).
Release checklist
- Version bump in
pyproject.toml,src/synaptic/__init__.py,
src/synaptic/mcp/__init__.py. - CHANGELOG entry under
## [0.16.0] - 2026-04-17. - README.md, README.ko.md, docs/comparison/synaptic_results.md
updated with v0.16.0 numbers. - docs/paper/draft.md + theorem.md updated with v0.16.0
streaming invariance and English benchmark numbers. - Figures regenerated
(ablation_bar.py,streaming_invariance.py,
tier1_benchmark.py). - 819 unit tests pass on Python 3.14 + macOS (local);
tests/test_cdc_search_regression.pygreen. -
uv build && uv publish— requires PyPI token. - GitHub release (
gh release create v0.16.0 --generate-notes). - Announce on r/LocalLLaMA, GeekNews, X.
Next up — roadmap
- v0.16.1 (2026 Q2) — PPR first-hit O(corpus) optimisation so
HotPotQA-dev full (7,405 q) runs in under 15 min, plus an
embedder rerun that closes the MuSiQue / 2Wiki gaps. - v0.17.0 — legacy HybridSearch removal;
extensions/→
core/rename with backward-compat re-exports. - v0.18.0 — observability (
search(explain=True),
structured logs, Prometheus / OpenTelemetry metrics).
See the full list at docs/ROADMAP.md.
v0.13.0 — Graph-aware agent search + structured data tools
Highlights
Major improvements to multi-turn agent search quality on structured data.
🔥 Agent benchmark results
| Dataset | Before | After |
|---|---|---|
| X2BEE Hard agent | 1/19 (5%) | 17/19 (89%) |
| assort Hard agent | 1/15 (7%) | 12/15 (80%) |
| KRRA Hard MRR | 0.808 | 1.000 (15/15) |
🌐 Public benchmarks (EvidenceSearch + embed + reranker)
| Dataset | Before | After |
|---|---|---|
| HotPotQA-24 | 0.727 | 0.964 |
| Allganize RAG-ko | 0.621 | 0.905 |
| PublicHealthQA | 0.318 | 0.600 |
What's new
Added
SynapticGraph.from_database()— one-line DB → ontology migration. SQLite / PostgreSQL / MySQL / Oracle / SQL Server. Auto-discovers schema, foreign keys, and M:N join tables.- Structured data tools —
filter_nodes,aggregate_nodes,join_relatedwith accurate{total, showing, truncated}count reporting. aggregate_nodesWHERE pre-filter — conditional aggregation (where_property/where_op/where_value).- Graph-aware expansion —
GraphExpandernow followsRELATEDedges for ENTITY nodes, surfacing FK-linked rows automatically. join_relatededge-first strategy — O(degree) instead of O(N) property scan.- Graph composition hint —
build_graph_context()tells the agent which tools fit the data (documents vs structured), plus table schemas and FK relationships. - Value-centric row content —
TableIngesterorders row values by semantic priority (name > description > category > rest). - LLM-as-Judge evaluation —
eval/run_all.py --judgeadds semantic answer validation alongside ID matching. - X2BEE benchmark dataset — 40 queries over real AWS RDS PostgreSQL (19,843 rows).
Changed
build_graph_context()now includes structured schemas + FK + composition hints.- Agent system prompt: explicit tool-selection guidance, fallback strategies, structured data patterns.
- Public dataset runner uses
EvidenceSearchpipeline with optional embeddings/reranker.
Fixed
filter_nodesno longer early-breaks at limit; total counts are accurate.aggregate_nodesgroups includenode_titlefield for FK group values.from_database()async row_reader for PostgreSQL (asyncpg coroutines).
Install
```bash
pip install synaptic-memory==0.13.0
```
Full changelog: https://github.com/PlateerLab/synaptic-memory/blob/main/CHANGELOG.md
v0.9.0 — BM25 Hybrid, Supersede, Auto-Chunking, LongMemEval
Synaptic Memory v0.9.0
Core Improvements
- BM25 hybrid scoring — corpus-size adaptive (large: BM25 80%, small: substring 70%)
- Supersede detection — same-title nodes prefer newest (by updated_at)
- Auto-chunking API —
add_document(chunk_size=1000)with sentence-boundary splitting + PART_OF edges - PPR edge type weights — CAUSED 1.0 > RELATED 0.4 (reduces noise from S2 ablation -14~-32%)
- Kind soft boost — hard filter → 1.5x score boost (MRR +9%)
- Phrase node filter —
_phrasenodes excluded from search results - Evidence threshold — 0.2→0.3 + first-sentence position bias
Benchmarks
- 14 external datasets (6 new: NFCorpus, SciFact, FiQA, MIRACLRetrieval, MultiLongDoc, XPQARetrieval)
- LongMemEval (ICLR 2025) — 500-question long-term memory evaluation
- PPR / Evidence / PhraseExtractor unit tests (67 new)
- Ablation S8 LLM Full stage
Results (FTS only, MemoryBackend)
| Dataset | MRR | Change |
|---|---|---|
| KLUE-MRC | 0.731 | +20% |
| SciFact | 0.536 | +29% |
| Ko-StrategyQA | 0.393 | +24% |
| FiQA (57K) | 0.209 | +58% |
| MultiLongDoc | 0.154 | +120% |
Install: pip install synaptic-memory==0.9.0
v0.8.0 — Graph API 확장 (list/update/maintain/add_turn + 커스텀 NodeKind)
Summary
Graph API expansion release addressing 5 user feedback items: full node listing, partial updates, unified maintenance, conversation session management, and custom NodeKind support.
New Features
graph.list() — List all nodes
nodes = await graph.list() # all
lessons = await graph.list(kind=NodeKind.LESSON) # filter by kind
recent = await graph.list(limit=10) # with limitgraph.update() — Partial node update
await graph.update(node_id, title="New Title", tags=["updated"])- No need to call
backend.update_node()directly - Cache auto-invalidation
graph.maintain() — Unified consolidate + decay + prune
result = await graph.maintain()
print(result.total_affected) # consolidated + decayed + pruned combinedMaintenanceResultdataclass for consistent return type- Existing
consolidate(),decay(),prune()still available individually
graph.add_turn() — Conversation session/turn helper
session, user_node, asst_node = await graph.add_turn(
"Hello",
"Hi! How can I help you?",
session_id="my_session",
)- Auto-creates/reuses SESSION nodes
- user → assistant FOLLOWED_BY linking
- Auto-chaining between turns
Custom NodeKind
await graph.add("Korean Culture", "Greeting etiquette", kind="culture")
await graph.add("Dark Mode", "Preferred", kind="preference")
await graph.list(kind="culture") # filter by custom kindNode.kindtype widened tostr(fully backward-compatible withNodeKindenum)- Safe DB serialization/deserialization across all backends (
_safe_node_kind())
Breaking Changes
None. All existing APIs remain backward-compatible.
Install
pip install synaptic-memory==0.8.0Full Changelog: v0.7.0...v0.8.0
v0.7.0 — PPR + Evidence Chain + HotPotQA 0.856
Synaptic Memory v0.7.0 — PPR, Evidence Chain, Auto-Ontology 최적화, HotPotQA 0.856
Added
- Evidence Chain Assembly — small LLM augmentation for multi-hop reasoning, HotPotQA Correctness 0.856 (+9.2%)
- Personalized PageRank (PPR) engine — replaced spreading activation, multi-hop retrieval +28%
- End-to-end QA benchmark — HotPotQA 24-question suite for Cognee comparison (Correctness 0.784)
- Auto-ontology optimization — HybridClassifier, batch LLM processing, EmbeddingRelation, PhraseExtractor
Fixed
- PhraseExtractor search noise — phrase filtering and optimization
Changed
- Removed
__pycache__from repo and updated.gitignore
Benchmark Results
| Dataset | MRR | nDCG@10 | R@10 |
|---|---|---|---|
| Allganize RAG-Eval | 0.796 | 0.811 | 0.863 |
| HotPotQA-200 | 0.742 | 0.599 | 0.652 |
| AutoRAGRetrieval | 0.646 | 0.681 | 0.798 |
| KLUE-MRC | 0.607 | 0.643 | 0.760 |
Install: pip install synaptic-memory[all]
v0.6.0 — Auto-Ontology + Hybrid Search
Synaptic Memory v0.6.0 — 자동 온톨로지 + 하이브리드 검색 + 벤치마크
Added
- Auto-ontology construction — LLM-based ontology building with search-optimized metadata generation
- LLM classifier prompt optimization — few-shot examples improved accuracy from 50% to 86%
- FTS + embedding hybrid scoring — S7 Auto+Embed achieved MRR 0.83
- Kind/tag/search_keywords utilization in search — FTS and ranking boost
- Ontology auto-construction + benchmark framework + search engine improvements
Changed
- Updated README with auto-ontology, benchmark results, and differentiation points
v0.5.0 — Ontology + Agent Activity + Neo4j
Synaptic Memory v0.5.0 — 온톨로지 + 에이전트 활동 추적 + Intent 검색 + Neo4j
Added
- Ontology Engine — dynamic type hierarchy, property inheritance, relation constraint validation (
OntologyRegistry) - Agent Activity Tracking — session/tool call/decision/outcome capture (
ActivityTracker) - Intent-based Agent Search — 6 search strategies: similar_decisions, past_failures, related_rules, reasoning_chain, context_explore, general (
AgentSearch) - Neo4j Backend — native Cypher graph traversal, dual label, typed relationships, fulltext index
- Auto-embedding — automatic vector generation on
add()/search() - Qdrant + MinIO + CompositeBackend — storage separation by purpose
- 5-axis Resonance Scoring — added context axis (session tag Jaccard similarity)
- GraphTraversal Protocol —
shortest_path(),pattern_match(),find_by_type_hierarchy() - Node.properties — ontology extension attributes, supported across all backends
- MCP 9 new tools (total 16): agent session/action/decision/outcome tracking, ontology tools
- 6 new
NodeKindvalues: tool_call, observation, reasoning, outcome, session, type_def - 5 new
EdgeKindvalues: is_a, invoked, resulted_in, part_of, followed_by docker-compose.ymlfor Neo4j dev environmentdocs/COMPARISON.md— comparison with existing agent memory systems- 185+ unit tests, 22 Neo4j integration tests
Fixed
- MemoryBackend fuzzy search ineffectiveness bug + 12 edge case QA tests
- Library distribution quality:
__version__,py.typed, lazy imports, embedding extra
v0.4.0 — MCP Server
Synaptic Memory v0.4.0 — MCP 서버 (7개 tool) + synaptic-mcp CLI
Added
- MCP Server — 7 tools (knowledge search/add/link/reinforce/stats/export/consolidate)
- SQLite Backend — FTS5, recursive CTE, WAL mode
- QA Test Suite — 169 Wikipedia + 368 GitHub real-data verification cases
synaptic-mcpCLI entry point
v0.3.0 — Protocol Implementations
Synaptic Memory v0.3.0 — 프로토콜 구현체 + LRU 캐시 + JSON export + 노드 병합
Added
- Protocol implementations — LLM QueryRewriter, RegexTagExtractor, EmbeddingProvider
- LRU Cache — NodeCache with hit rate tracking
- JSON Exporter — structured JSON export
- Node Merge — duplicate node merging with edge reconnection
- Find Duplicates — title similarity-based duplicate detection
v0.2.0 — PostgreSQL Backend
Synaptic Memory v0.2.0 — PostgreSQL 백엔드 + PyPI 준비
Added
- PostgreSQL backend — asyncpg + pgvector HNSW + pg_trgm + recursive CTE
- Vector search with cosine distance (pgvector)
- Trigram fuzzy matching with graceful ILIKE fallback
- Hybrid search: FTS + fuzzy + vector merged results
- Connection pooling (asyncpg Pool, min=2, max=10)
- Configurable
embedding_dimparameter ResonanceWeightsadded to public exports- Configurable consolidation thresholds (TTL, promotion access counts)
- README.md, ARCHITECTURE.md, ROADMAP.md documentation
- GitHub Actions CI (Python 3.12/3.13)
- Integration test suite for PostgreSQL (13 tests)
Changed
- Consolidation constants now accept
__init__parameters instead of module globals