기본 경로는 인덱싱 API 호출 0회. 인프라 0. 락인 0. LLM 에이전트용 지식 그래프 + MCP 도구 서버. 하이브리드 검색, CDC 기반 실시간 DB 동기화, 한국어 FTS 내장.
pip install "synaptic-memory[sqlite,korean,vector]"
synaptic-quickstart --db quickstart.db위 두 줄로 작은 SQLite 기반 그래프를 만들고 3개 쿼리를 실행합니다. 전 과정
LLM 호출 0회입니다. --db를 빼면 의존성 없는 인메모리 smoke test로
실행됩니다. 확장 예제: examples/quickstart.py.
일반 RAG는 독립적인 chunk에서 답을 찾는 경우가 많습니다. Synaptic은 먼저 그래프를 만들기 때문에 에이전트가 검색하고, 관계를 따라가고, 정형 row를 조회하고, 어떤 evidence가 도움이 됐는지 기억할 수 있습니다.
| 일반 RAG | Synaptic Memory |
|---|---|
| chunk + vector search | 문서, chunk, row, edge |
| 데이터 변경 시 재빌드가 흔함 | live DB용 CDC sync |
| 기본은 single-shot retrieval | 멀티턴 탐색용 MCP 도구 |
| feedback은 인덱스 밖에 있음 | 선택적 memory event, feedback, health signal |
vector DB 대체재가 아닙니다. 기존 문서, SQL 데이터, embedding endpoint, agent runtime 주변에 붙는 graph/tool layer입니다.
import asyncio
from synaptic import SynapticGraph
async def main():
# 아무 데이터 → 지식 그래프 (CSV, JSONL, 디렉터리)
graph = await SynapticGraph.from_data("./내_데이터/", preset="rag")
try:
result = await graph.search("내 질문")
print(result.nodes[0].node.title if result.nodes else "결과 없음")
finally:
await graph.close()
asyncio.run(main())파일 형식 또는 DB 스키마 자동 감지, 온톨로지 프로파일 자동 생성, 인제스트, 인덱싱, FK 엣지 구축까지 전부 자동.
자주 쓰는 옵션은 preset으로 줄일 수 있습니다.
# local: 기본값, 외부 서비스 없음
graph = await SynapticGraph.from_chunks(chunks, preset="local")
# rag: SYNAPTIC_EMBED_URL / SYNAPTIC_RERANK_URL 환경변수를 읽음
graph = await SynapticGraph.from_data("./docs/", preset="rag")
# agent: rag + 멀티턴 탐색용 deterministic component bridging
graph = await SynapticGraph.from_data("./docs/", preset="agent")라이브 DB 동기화 (CDC) —
mode="cdc"로 증분 업데이트:updated_at류 컬럼이 있으면 워터마크 필터로 읽고, 없으면 row 내용 해시로 폴백. 삭제는 TEMP TABLE + LEFT JOIN으로 감지, FK 변경 시 RELATED 엣지 재연결. CDC 모드와 전체 재빌드가 동일 top-k를 반환함을 regression test로 잠금. SQLite, PostgreSQL, MySQL/MariaDB 지원.
오피스 파일(PDF/DOCX/PPTX/XLSX/HWP) 은 선택 패키지
xgen-doc2chunk를 통해 지원합니다.pip install synaptic-memory[docs]로 설치하거나, 자체 파서로 청킹한 결과를from_chunks()로 넘기세요.
내 데이터 (CSV, JSONL, PDF/DOCX/PPTX/XLSX/HWP, SQL 데이터베이스)
↓ 형식 자동 감지 / DB 스키마+FK 자동 발견
↓ DocumentIngester (텍스트) / TableIngester / DbIngester
↓
지식 그래프
├─ 문서: Category → Document → Chunk
└─ 정형: 테이블 row → ENTITY 노드 + RELATED 엣지 (FK)
↓
MCP 도구 → LLM 에이전트가 그래프 기반 멀티턴으로 탐색
라이브러리가 하는 건 딱 두 가지:
- 그래프를 잘 구축한다 — 기본은 비용 없는 deterministic extraction
- LLM에게 좋은 도구를 쥐어준다 — 판단은 LLM이, 코드는 데이터만
# 일반 로컬 그래프 + MCP 조합
pip install "synaptic-memory[sqlite,korean,vector,mcp]"
# 팀/프로덕션 그래프: PostgreSQL + pgvector
pip install "synaptic-memory[postgresql,embedding,reranker]"
# 스케일아웃 보조 구성: Kuzu 그래프 + Qdrant 벡터 + MinIO blob
pip install "synaptic-memory[scale]"
# LangChain retriever 예제를 실행할 때 추가
pip install "synaptic-memory[langchain]"
# 또는 Postgres / Kuzu / Qdrant / MinIO 까지 전부
pip install "synaptic-memory[all]"옵션별 설치
pip install synaptic-memory # 코어 (의존성 0, 인메모리만)
pip install synaptic-memory[sqlite] # + SQLite FTS5 백엔드
pip install synaptic-memory[korean] # + Kiwi 한국어 형태소 분석
pip install synaptic-memory[vector] # + usearch HNSW 벡터 인덱스
pip install synaptic-memory[mcp] # + Claude MCP 서버
pip install synaptic-memory[embedding] # + 임베딩 API (aiohttp)
pip install synaptic-memory[reranker] # + flashrank cross-encoder
pip install synaptic-memory[langchain] # + LangChain retriever 어댑터
pip install synaptic-memory[postgresql] # + asyncpg + pgvector
pip install synaptic-memory[mysql] # + aiomysql DB 인제스트
pip install synaptic-memory[oracle] # + oracledb DB 인제스트
pip install synaptic-memory[mssql] # + aioodbc DB 인제스트
pip install synaptic-memory[kuzu] # + 임베디드 property graph 백엔드
pip install synaptic-memory[qdrant] # + Qdrant 벡터 helper
pip install synaptic-memory[minio] # + MinIO/S3 호환 blob helper
pip install synaptic-memory[scale] # + Kuzu + Qdrant + MinIO + aiohttp
pip install synaptic-memory[docs] # + PDF/DOCX/PPTX/XLSX/HWP 로더기본 one-liner는 로컬 SQLite 그래프를 만듭니다. 이미 쓰는 운영 인프라에
붙일 때는 backend를 직접 만들고 연결한 뒤 from_data(), from_chunks(),
from_database()에 넘기면 됩니다.
from synaptic import SynapticGraph
from synaptic.backends.postgresql import PostgreSQLBackend
backend = PostgreSQLBackend("postgresql://user:pass@host:5432/synaptic")
await backend.connect()
graph = await SynapticGraph.from_data("./docs/", backend=backend, preset="rag")현재 backend 역할:
| 경로 | 설치 | 데이터 담당 | 적합한 상황 |
|---|---|---|---|
| 로컬 앱/노트북 | sqlite,korean,vector |
SQLite FTS5 + 로컬 usearch HNSW | 빠른 도입, 데모, 작은 서비스 |
| 팀 서비스 | postgresql,embedding,reranker |
PostgreSQL + pgvector + pg_trgm | 공유 그래프, 백업, SQL 운영 |
| 그래프 중심 임베디드 | kuzu,korean,embedding |
Kuzu property graph | 로컬 graph traversal / Cypher workflow |
| 스케일아웃 조합 | scale |
Kuzu 등 graph store + Qdrant + MinIO | graph/vector/blob 책임 분리 |
Qdrant와 MinIO는 단독 그래프 저장소가 아니라 helper service입니다.
CompositeBackend를 통해 사용합니다. graph storage는 node/edge를 갖고,
Qdrant는 ANN vector search를 담당하며, MinIO/S3 호환 저장소는 큰
Node.content를 외부 blob으로 분리합니다.
from synaptic.backends.composite import CompositeBackend
from synaptic.backends.kuzu import KuzuBackend
from synaptic.backends.minio_store import MinIOBackend
from synaptic.backends.qdrant import QdrantBackend
backend = CompositeBackend(
KuzuBackend("synaptic.kuzu"),
vector=QdrantBackend("http://localhost:6333", collection="synaptic"),
blob=MinIOBackend("localhost:9000", bucket="synaptic"),
)
await backend.connect()
graph = await SynapticGraph.from_data("./docs/", backend=backend, preset="scale")라이브러리는 backend contract와 retrieval layer를 제공합니다. 다만 수 TB급 운영 코퍼스에서는 별도 운영 레이어도 같이 설계해야 합니다. 예를 들면 durable ingestion queue, parser/OCR worker, 외부 lexical index, tenant/ACL filter, index lag 모니터링, 각 저장소별 backup/restore가 필요합니다.
import asyncio
from synaptic import SynapticGraph
async def main():
# CSV 파일
graph = await SynapticGraph.from_data("products.csv")
try:
result = await graph.search("내 질문")
for activated in result.nodes[:5]:
print(activated.node.title, activated.activation)
finally:
await graph.close()
asyncio.run(main())preset="rag"를 넘기면 SYNAPTIC_EMBED_URL, SYNAPTIC_RERANK_URL을 읽습니다.
여러 from_data(), from_chunks(), from_database() 호출에 같은 설정을 쓰고
싶다면 GraphBuildOptions를 사용할 수 있습니다.
synaptic-mcp --db my_graph.db
synaptic-mcp --db my_graph.db --embed-url http://localhost:11434/v1Claude가 MCP 도구로 그래프를 직접 탐색합니다. 검색, 인제스트, CDC 동기화까지 CLI로 내려가지 않고 대화 안에서.
복붙 가능한 claude_desktop_config.json 샘플:
examples/mcp_claude_desktop.json.
pip install "synaptic-memory[sqlite,korean,vector,langchain]"import asyncio
from synaptic import SynapticGraph
from synaptic.integrations.langchain import SynapticRetriever
async def main():
graph = await SynapticGraph.from_data("./docs/")
try:
retriever = SynapticRetriever(graph=graph, k=5)
docs = await retriever.ainvoke("내 질문")
for doc in docs:
print(doc.page_content[:80], " ", doc.metadata["score"])
finally:
await graph.close()
asyncio.run(main())실행 예제: examples/langchain_retriever.py.
각 hit이 LangChain Document로 변환되고 metadata에 node_id, title, score, 정형
속성이 모두 담깁니다 — RetrievalQA 체인·에이전트·RAG 그래프 어디서든 그대로 사용.
import asyncio
from synaptic.backends.sqlite_graph import SqliteGraphBackend
from synaptic.extensions.domain_profile import DomainProfile
from synaptic.extensions.document_ingester import DocumentIngester, JsonlDocumentSource
async def main():
profile = DomainProfile.load("my_profile.toml")
backend = SqliteGraphBackend("graph.db")
await backend.connect()
source = JsonlDocumentSource("docs.jsonl", "chunks.jsonl")
ingester = DocumentIngester(profile=profile, backend=backend)
await ingester.ingest(source)
asyncio.run(main())| 방식 | 인덱싱 시 LLM | 트레이드오프 |
|---|---|---|
| GraphRAG 계열 (MS GraphRAG, Cognee, Graphiti) | LLM으로 엔티티 + 관계 + 커뮤니티 요약 추출 | 서사형 코퍼스에서 recall 최상. 대신 문서 추가마다 LLM 토큰 비용 |
| LightRAG 계열 | LLM 호출을 쿼리 시점으로 지연 | 인덱스 비용 낮음. 대신 쿼리마다 비용 |
| Synaptic 기본 경로 | 없음. 구조·통계 시그널만 (FK, NEXT_CHUNK, phrase DF 허브, MENTIONS) | 비용 0 + 결정론적. 명시적 cross-reference를 LLM 없이 엣지화 |
기본 인덱싱은 LLM-free입니다. 그래프는 지식 저장소가 아니라 검색 인덱스입니다.
문서에 명시된 cross-reference는 LLM 없이 REFERENCES 엣지로 만들 수 있습니다.
OpenIE를 opt-in하면 bounded/revertible 방식으로 LLM 기반 semantic relation을
추가할 수 있지만, 기본 deterministic 경로에는 포함되지 않습니다.
현재 API:
graph.search()는 하나의 경로만 사용합니다. BM25 + HNSW + PPR + cross-encoder + MMR 기반 EvidenceSearch 파이프라인입니다. 예전engine=스위치는 제거되었으므로 예제는graph.search("질문")처럼 바로 호출하면 됩니다.
| 도구 | 용도 |
|---|---|
deep_search |
추천. 검색 → 확장 → 문서 읽기를 한 번에 |
compare_search |
복합 질문 자동 분해 + 병렬 검색 |
knowledge_search |
EvidenceSearch 기반 핵심 의미 검색 |
agent_search |
FTS + 벡터 하이브리드 + intent routing |
expand |
1-hop 그래프 이웃 탐색 |
get_document |
쿼리 관련 청크만 선별한 문서 전문 |
search_exact |
ID/코드 정밀 매칭 (BM25 우회) |
follow |
특정 엣지 타입 순회 |
| 도구 | 용도 |
|---|---|
filter_nodes |
속성 필터 (>=, <=, contains) — {total, showing} 반환으로 카운팅 정확 |
aggregate_nodes |
GROUP BY + COUNT/SUM/AVG/MAX/MIN + WHERE 사전 필터 |
join_related |
FK 기반 관련 레코드 조회 — RELATED 엣지 순회 (O(degree)) |
top_nodes |
“가장 X한”, “top N”, “최대/최소”, “최근” 질의를 단일 호출로 처리 |
대화 중에 Claude가 새 자료를 배울 수 있도록 하는 도구.
| 도구 | 용도 |
|---|---|
knowledge_add_document |
긴 텍스트를 자동 청킹해 그래프에 추가 |
knowledge_add_table |
컬럼+행 리스트를 ENTITY + FK 엣지로 인제스트 |
knowledge_add_chunks |
BYO-chunker 경로 |
knowledge_ingest_path |
로컬 CSV/JSONL/TXT 파일 단건 인제스트 |
knowledge_remove |
단건 노드 삭제 (엣지 cascade) |
knowledge_sync_from_database |
CDC 증분 동기화 |
knowledge_backfill |
누락된 임베딩·phrase 허브 복구 |
| 도구 | 용도 |
|---|---|
list_categories |
카테고리 목록 + 문서 수 |
count |
종류/카테고리/연도별 카운트 |
session_info |
멀티턴 세션 상태 조회 |
모든 도구는 { data, hints, session } 형태로 반환. SearchSession이 턴 간 상태를 추적하므로 같은 청크를 두 번 읽지 않습니다.
쿼리
↓ Kiwi 형태소 분석 (한국어) 또는 정규식 (기타)
↓ BM25 FTS + title 3배 가중치 + substring fallback
↓ 벡터 검색 (usearch HNSW, 선택)
↓ Vector PRF (유사 관련 피드백, 2-pass)
↓ PPR 그래프 탐색 (PersonalizedPageRank)
↓ GraphExpander (1-hop: 카테고리 형제, 다음 청크, 엔티티 멘션)
↓ HybridReranker (어휘 + 의미 + 그래프 + 구조 + 메모리 + 권위 + 시간)
↓ MaxP 문서 집계 (커버리지 보너스)
↓ Cross-encoder reranker (bge-reranker-v2-m3, 선택)
↓ EvidenceAggregator (MMR 다양성 + 문서당 캡 + 카테고리 커버리지)
결과
사용·시간 메모리 축 (opt-in, 기본 off). reranker에 다섯 번째 가중 신호
memory — 각 노드를 어떻게 사용됐는지로 점수화한다: 중요도(강화된 성공 vs 실패),
최신성(updated_at), 활력(vitality). memory=0.0(기본)이면 랭킹은 그대로다. 켜면
검색이 진화한다 — 쿼리에 답이 된 결과를 reinforce하면 다음 검색에서 올라가고, decay된
노드는 가라앉는다. 정적 인덱스는 구조적으로 못 하는 일이다.
from synaptic.extensions.hybrid_reranker import RerankerWeights
# 메모리 축 활성화 (나머지 가중치는 합이 ~1 이 되도록 재조정)
graph.reranker_weights = RerankerWeights(
lexical=0.35, semantic=0.20, graph=0.10, structural=0.10, memory=0.25,
)
await graph.reinforce([node_id], success=True) # 이 결과가 도움 됨 → 다음엔 상위로검색을 항상 stateful하게 만들지 않고도 관찰할 수 있습니다.
from synaptic import FeedbackSignal, MemoryScope
scope = MemoryScope(workspace_id="docs", user_id="alice")
result = await graph.search("환불 예외", record=True, scope=scope)
await graph.record_feedback(
event_id=result.event_id,
signal=FeedbackSignal.EXPLICIT_POSITIVE,
success=True,
scope=scope,
)
health = await graph.memory_health(scope=scope)
signals = await graph.scan_memory_signals(scope=scope)event, feedback, provenance, health signal은 그래프 metadata로 저장됩니다.
Node.content에 섞지 않고, LLM prompt에 원본 metadata 전체를 자동으로 밀어 넣지도 않습니다.
루트 README는 현재 설치 경로와 공개 API를 기준으로 유지합니다. 상세 수치는 오래된 측정값이 현재 API 계약처럼 보이지 않도록 버전이 붙은 보고서에 둡니다.
빠른 로컬 smoke:
synaptic-quickstart --json가벼운 한국어 FTS 벤치마크:
pip install "synaptic-memory[korean]"
python examples/benchmark_allganize.py선택 패키지/API key가 준비된 경우 competitor harness:
python examples/benchmark_vs_competitors/run_comparison.py --only synaptic참고 보고서:
| 보고서 | 내용 |
|---|---|
| docs/comparison/synaptic_results.md | 재현 가능한 Synaptic 벤치마크 결과와 provenance |
| docs/REPORT-rag-vs-synaptic.md | 금융 법령 multi-hop 검색에서 RAG와 synaptic-memory 비교 |
| docs/REPORT-memory-operating-layer-eval.md | memory operating layer 평가와 health/reporting gate |
| examples/benchmark_vs_competitors/README.md | competitor adapter 공정성 주의사항 |
SynapticGraph.from_data("./data/") ← Easy API
↓
자동 감지 → DomainProfile → 인제스트 → 인덱싱
↓
StorageBackend (Protocol)
├── MemoryBackend (테스트용)
├── SqliteGraphBackend (권장, FTS5 + HNSW)
├── KuzuBackend (임베디드 Cypher)
├── PostgreSQLBackend (pgvector)
└── CompositeBackend (백엔드 조합)
↓
검색 파이프라인 (BM25 + 벡터 + PRF + PPR + reranker + MMR)
↓
에이전트 도구 → MCP 서버 → LLM 에이전트
| 백엔드 | 설치 옵션 | 역할 | 용도 |
|---|---|---|---|
MemoryBackend |
core | 인프로세스 그래프 | 테스트와 예제 |
SqliteGraphBackend |
sqlite, vector |
로컬 그래프 + FTS5 + usearch HNSW | 기본 로컬/임베디드 배포 |
KuzuBackend |
kuzu |
임베디드 property graph + Cypher | 그래프 중심 로컬 workflow |
PostgreSQLBackend |
postgresql |
durable graph + pgvector + pg_trgm | 공유 프로덕션 서비스 |
QdrantBackend |
qdrant |
vector-only helper | CompositeBackend 뒤 ANN search |
MinIOBackend |
minio |
blob-only helper | CompositeBackend 뒤 큰 content offload |
CompositeBackend |
scale |
graph + vector + blob store 라우터 | 스케일아웃 조합 |
| 옵션 | 추가 기능 |
|---|---|
sqlite |
aiosqlite 백엔드 (실사용 기본) |
korean |
Kiwi 한국어 형태소 분석기 |
vector |
usearch HNSW 인덱스 |
embedding |
임베딩 API 호출용 aiohttp |
reranker |
flashrank cross-encoder |
mcp |
Claude Desktop/Code MCP 서버 |
langchain |
LangChain retriever 어댑터 |
postgresql |
asyncpg + pgvector |
mysql |
aiomysql DB 인제스트 |
oracle |
oracledb DB 인제스트 |
mssql |
aioodbc DB 인제스트 |
kuzu |
임베디드 Kuzu graph 백엔드 |
qdrant |
Qdrant vector helper |
minio |
MinIO/S3 호환 blob helper |
scale |
Kuzu + Qdrant + MinIO + aiohttp |
rag |
spaCy + aiohttp endpoint helper |
all |
주요 DB, vector, MCP, 한국어, reranker 옵션 묶음 |
docs |
PDF/DOCX/PPTX/XLSX/HWP 문서 로더 (xgen-doc2chunk) |
| 문서 | 내용 |
|---|---|
| docs/GUIDE.md | 친절한 전체 안내서 (처음 접하는 사람용) |
| docs/TUTORIAL.md | 30분 단계별 실습 |
| docs/CONCEPTS.md | 파이프라인 심화 설명 |
| docs/ADOPTION.md | 설치 옵션, preset, 첫 적용 경로 |
| docs/ARCHITECTURE.md | 신경망 영감 초기 설계 |
| docs/COMPARISON.md | GraphRAG / LightRAG 등과 비교 |
| docs/ROADMAP.md | 역사적 로드맵 |
uv sync --extra dev --extra sqlite --extra mcp
uv run pytest tests/ -q
uv run ruff check --fixApache-2.0 — LICENSE 참조. 출처(copyright/attribution notice)만 보존하면 상용·수정·재배포 모두 자유.