@@ -51,7 +51,7 @@ Synaptic Memory의 검색도 동일하게 작동한다:
5151 → 다음에 "테스트 스킵"을 검색하면 실패 경험이 먼저 뜬다
5252```
5353
54- 에이전트가 명시적으로 "이건 나쁜 패턴이야"라고 태깅할 필요 없다. ** 사용하고 결과를 기록하면 그래프가 스스로 학습** 한다.
54+ 에이전트가 명시적으로 "이건 나쁜 패턴이야"라고 태깅할 필요 없다. ** 사용하고 결과를 기록하면 그래프가 스스로 학습** 한다. Adaptive learning rate로 초기에는 빠르게, 성숙하면 안정적으로 학습한다.
5555
5656### 3. Memory Consolidation — 중요한 기억만 남기기
5757
@@ -65,6 +65,8 @@ L1 (Sprint, 90d) ← 반복 참조된 지식. 90일간 유지.
6565L2 (Monthly, 365d) ← 검증된 지식. 1년간 유지.
6666 ↓ 성공률 80%+
6767L3 (Permanent) ← 조직의 핵심 지식. 영구 보존.
68+ ↓ 성공률 60% 미만
69+ L2 (강등) ← 더 이상 유효하지 않은 지식은 강등.
6870```
6971
7072이걸 안 하면? 에이전트가 만들어내는 데이터가 무한히 쌓여서 검색 품질이 떨어진다. ** 쓰이는 지식만 살아남는 자연선택** .
@@ -114,6 +116,7 @@ Decision --[resulted_in]--> Outcome --[learned_from]<-- Lesson
114116 → 72시간 동안 안 쓴 L0 노드 삭제
115117 → 자주 참조된 노드 L1→L2 승격
116118 → 성공률 80%+ 노드 L3 (영구) 승격
119+ → 성공률 60% 미만 L3 노드 → L2 강등
117120 → edge weight < 0.1인 약한 연결 정리
118121```
119122
@@ -131,24 +134,26 @@ SynapticGraph (Facade)
131134 ├── AgentSearch ──────── 6가지 intent 기반 검색 전략
132135 ├── HybridSearch ─────── FTS + fuzzy + vector → synonym → LLM rewrite
133136 ├── ResonanceScorer ──── 5축 (relevance × importance × recency × vitality × context)
134- ├── HebbianEngine ────── co-activation 강화/약화
135- ├── ConsolidationCascade L0→L3 생명주기
137+ ├── HebbianEngine ────── co-activation 강화/약화 (adaptive rate)
138+ ├── ConsolidationCascade L0→L3 생명주기 + L3 강등
139+ ├── EmbeddingProvider ── 자동 벡터 생성 (vLLM/llama.cpp/Ollama)
136140 ├── NodeCache (LRU)
137141 └── Exporters (Markdown, JSON)
138142 │
139143 StorageBackend (Protocol — 20개 메서드)
140144 │
141145 ┌────┼──────────┬───────────────┬──────────────┐
142146 │ │ │ │ │
143- Memory SQLite PostgreSQL Neo4j CompositeBackend
144- (dev) (FTS5) (pgvector) (Cypher) (future )
147+ Memory SQLite PostgreSQL Neo4j CompositeBackend
148+ (dev) (FTS5) (pgvector) (Cypher) (Neo4j+Qdrant+MinIO )
145149```
146150
147151** 핵심 설계 결정:**
148152
149153- ** Protocol-based** — 코어가 백엔드를 모른다. SQLite든 Neo4j든 같은 API. 백엔드 교체 시 코드 변경 0.
150154- ** Zero core deps** — 코어는 순수 Python. ` pip install synaptic-memory ` 에 외부 의존성 없음.
151- - ** Additive evolution** — v0.1의 Node/Edge 모델이 v0.5까지 변경 없이 확장됨. properties dict 하나로 온톨로지 속성을 지원.
155+ - ** CompositeBackend** — Neo4j(그래프+FTS) + Qdrant(벡터 ANN) + MinIO(blob)를 하나의 StorageBackend로 통합. 용도별 라우팅.
156+ - ** Auto-embedding** — EmbeddingProvider를 주입하면 ` add() ` /` search() ` 시 자동으로 벡터 생성. vLLM, llama.cpp, Ollama, TEI 등 OpenAI-compatible 엔드포인트 호환.
152157
153158---
154159
@@ -164,40 +169,20 @@ Score = 0.35 × relevance 검색 매칭 점수 [0,1]
164169 + 0.20 × context 현재 세션 태그와의 Jaccard 유사도 [0,1]
165170```
166171
167- Intent별로 가중치가 다르다. ` past_failures ` 는 importance(성공률)에 0.35를 주고, ` context_explore ` 는 context(태그 친화도)에 0.40을 준다. 에이전트가 "왜 이걸 찾고 있는지"에 따라 ** 같은 쿼리라도 다른 결과** 가 나온다.
168-
169- ---
170-
171- ## Intent-based Search — 왜 필요한가
172-
173- 일반 검색은 "배포"를 치면 "배포"가 들어간 모든 문서를 반환한다. 하지만 에이전트가 원하는 건 상황에 따라 다르다:
174-
175- | 상황 | Intent | 검색 전략 |
176- | ------| --------| ----------|
177- | "비슷한 결정을 한 적 있나?" | ` similar_decisions ` | DECISION 노드 → RESULTED_IN → Outcome 확장 |
178- | "이게 실패한 적 있나?" | ` past_failures ` | failure_count > 0 필터 → 원인 Decision 역추적 → Lesson |
179- | "이것에 관한 규칙이 있나?" | ` related_rules ` | RULE/LESSON 필터 + 그래프 이웃 확장 |
180- | "이 결정의 결과는?" | ` reasoning_chain ` | Decision → Outcome → Lesson multi-hop |
181- | "관련된 것들을 보여줘" | ` context_explore ` | BFS N-hop 확장 |
182-
183- ``` python
184- # 같은 쿼리, 다른 intent → 다른 결과
185- await graph.agent_search(" 배포" , intent = " past_failures" ) # 실패 사례 중심
186- await graph.agent_search(" 배포" , intent = " related_rules" ) # 규칙/정책 중심
187- await graph.agent_search(" 배포" , intent = " reasoning_chain" ) # 결정→결과 체인
188- ```
172+ Intent별로 가중치가 다르다. ` past_failures ` 는 importance(성공률)에 0.35를, ` context_explore ` 는 context(태그 친화도)에 0.40을 준다. 에이전트가 "왜 이걸 찾고 있는지"에 따라 ** 같은 쿼리라도 다른 결과** 가 나온다.
189173
190174---
191175
192176## Install
193177
194178``` bash
195- pip install synaptic-memory # Core (MemoryBackend)
196- pip install synaptic-memory[sqlite] # + SQLite
197- pip install synaptic-memory[postgresql] # + PostgreSQL (pgvector)
198- pip install synaptic-memory[neo4j] # + Neo4j
199- pip install synaptic-memory[mcp] # + MCP server
200- pip install synaptic-memory[all] # Everything
179+ pip install synaptic-memory # 코어 (zero deps)
180+ pip install synaptic-memory[sqlite] # + SQLite
181+ pip install synaptic-memory[neo4j] # + Neo4j
182+ pip install synaptic-memory[neo4j,embedding] # + Neo4j + auto-embedding
183+ pip install synaptic-memory[scale] # Neo4j + Qdrant + MinIO + embedding
184+ pip install synaptic-memory[mcp] # + MCP server
185+ pip install synaptic-memory[all] # 전부
201186```
202187
203188## Quick Start
@@ -216,8 +201,9 @@ async def main():
216201 # 세션 시작
217202 session = await tracker.start_session(agent_id = " my-agent" )
218203
219- # 과거 경험 검색
220- result = await graph.agent_search(" DB 선택" , intent = " similar_decisions" )
204+ # 과거 경험 검색 (intent 자동 추론)
205+ result = await graph.agent_search(" DB 마이그레이션 실패" )
206+ # → intent="past_failures" 자동 선택
221207
222208 # 결정 기록
223209 decision = await tracker.record_decision(
@@ -238,6 +224,54 @@ async def main():
238224 await backend.close()
239225```
240226
227+ ## Auto-Embedding (vLLM / llama.cpp / Ollama)
228+
229+ EmbeddingProvider를 주입하면 모든 노드가 자동 임베딩 + 벡터 검색 활성화:
230+
231+ ``` python
232+ from synaptic import SynapticGraph, OpenAIEmbeddingProvider
233+
234+ # vLLM, llama.cpp, Ollama, TEI — 어디든 동일한 인터페이스
235+ embedder = OpenAIEmbeddingProvider(
236+ " http://gpu-server:8080/v1" , # OpenAI-compatible 엔드포인트
237+ model = " BAAI/bge-m3" ,
238+ )
239+
240+ graph = SynapticGraph(backend, embedder = embedder)
241+
242+ # 자동: title+content → 벡터 생성 → Qdrant 저장
243+ await graph.add(" 배포 전략" , " Blue-green 배포로 zero downtime 달성" )
244+
245+ # 자동: 쿼리 → 벡터 생성 → FTS + fuzzy + vector 동시 검색
246+ result = await graph.search(" 배포 방식" )
247+ ```
248+
249+ ## Scale: CompositeBackend
250+
251+ Neo4j(그래프) + Qdrant(벡터) + MinIO(blob)를 하나의 StorageBackend로:
252+
253+ ``` python
254+ from synaptic.backends.composite import CompositeBackend
255+ from synaptic.backends.neo4j import Neo4jBackend
256+ from synaptic.backends.qdrant import QdrantBackend
257+ from synaptic.backends.minio_store import MinIOBackend
258+
259+ composite = CompositeBackend(
260+ graph = Neo4jBackend(" bolt://localhost:7687" ),
261+ vector = QdrantBackend(" http://localhost:6333" ),
262+ blob = MinIOBackend(" localhost:9000" , access_key = " minio" , secret_key = " secret" ),
263+ )
264+ await composite.connect()
265+ graph = SynapticGraph(composite, embedder = embedder)
266+
267+ # 내부 라우팅:
268+ # - embedding → Qdrant에 자동 저장
269+ # - content > 100KB → MinIO에 자동 offload
270+ # - 나머지 → Neo4j (그래프 + FTS)
271+ # - search_vector → Qdrant ANN → Neo4j batch get
272+ # - graph traversal → Neo4j Cypher native
273+ ```
274+
241275## Ontology
242276
243277``` python
@@ -261,6 +295,9 @@ ontology.is_a("incident", "agent_activity") # True
261295ontology.infer_properties(" incident" ) # parent 속성 포함
262296ontology.validate_node(" incident" , {}) # ["Missing 'severity'"]
263297ontology.validate_edge(" resulted_in" , " concept" , " outcome" ) # ["source not in domains"]
298+
299+ graph = SynapticGraph(backend, ontology = ontology)
300+ # → graph.add(), graph.link() 시 자동 검증
264301```
265302
266303### 기본 온톨로지
@@ -279,25 +316,21 @@ knowledge agent_activity
279316
280317| Backend | 그래프 순회 | 벡터 검색 | 스케일 | 용도 |
281318| ---------| -----------| ----------| -------| ------|
282- | ` MemoryBackend ` | Python BFS | cosine | ~ 10K 노드 | 테스트, 프로토타이핑 |
283- | ` SQLiteBackend ` | CTE 재귀 | ✗ | ~ 100K 노드 | 임베디드, 단일 프로세스 |
284- | ` PostgreSQLBackend ` | CTE 재귀 | pgvector HNSW | ~ 1M 노드 | 프로덕션, 벡터 검색 |
285- | ` Neo4jBackend ` | Cypher native | ✗ (Qdrant 위임) | ~ 10B 노드 | 대규모 그래프, multi-hop |
286-
287- Neo4j는 ` GraphTraversal ` 확장 프로토콜을 추가 구현:
288-
289- ``` python
290- await backend.shortest_path(node_a, node_b, max_depth = 5 )
291- await backend.pattern_match(" (:Decision)-[:RESULTED_IN]->(:Outcome)" )
292- await backend.find_by_type_hierarchy(" agent_activity" )
293- ```
319+ | ` MemoryBackend ` | Python BFS | cosine | ~ 10K | 테스트, 프로토타이핑 |
320+ | ` SQLiteBackend ` | CTE 재귀 | ✗ | ~ 100K | 임베디드, 단일 프로세스 |
321+ | ` PostgreSQLBackend ` | CTE 재귀 | pgvector HNSW | ~ 1M | 프로덕션, 벡터 검색 |
322+ | ` Neo4jBackend ` | Cypher native | ✗ (Qdrant 위임) | ~ 10B | 대규모 그래프 |
323+ | ` QdrantBackend ` | ✗ | HNSW + 양자화 | ~ 10B | 벡터 전용 (ANN) |
324+ | ` MinIOBackend ` | ✗ | ✗ | ~ 10TB | blob 저장 (S3 호환) |
325+ | ` CompositeBackend ` | Neo4j | Qdrant | ∞ | ** 통합 라우터** |
294326
295327## MCP Server — 16 Tools
296328
297329``` bash
298- synaptic-mcp # stdio (Claude Code)
299- synaptic-mcp --db ./knowledge.db # SQLite
300- synaptic-mcp --dsn postgresql://... # PostgreSQL
330+ synaptic-mcp # stdio (Claude Code)
331+ synaptic-mcp --db ./knowledge.db # SQLite
332+ synaptic-mcp --embed-url http://localhost:8080/v1 # + auto-embedding
333+ synaptic-mcp --embed-url http://localhost:8080/v1 --embed-model BAAI/bge-m3
301334```
302335
303336** Knowledge** (7) — ` knowledge_search ` , ` knowledge_add ` , ` knowledge_link ` , ` knowledge_reinforce ` , ` knowledge_stats ` , ` knowledge_export ` , ` knowledge_consolidate `
@@ -326,23 +359,32 @@ synaptic-mcp --dsn postgresql://... # PostgreSQL
326359
327360### Consolidation Levels
328361
329- | Level | TTL | Promotion |
330- | -------| -----| -----------|
331- | L0 Raw | 72h | 3+ accesses → L1 |
332- | L1 Sprint | 90d | 10+ accesses → L2 |
333- | L2 Monthly | 365d | 10+ successes + 80%+ rate → L3 |
334- | L3 Permanent | ∞ | 영구 보존 |
362+ | Level | TTL | Promotion | Demotion |
363+ | -------| -----| -----------| ---------- |
364+ | L0 Raw | 72h | 3+ accesses → L1 | |
365+ | L1 Sprint | 90d | 10+ accesses → L2 | |
366+ | L2 Monthly | 365d | 10+ successes + 80%+ rate → L3 | |
367+ | L3 Permanent | ∞ | 영구 보존 | 성공률 60% 미만 → L2 |
335368
336369## Dev
337370
338371``` bash
339- uv sync --extra dev --extra sqlite --extra neo4j
340- uv run pytest -v # 171 + unit tests
372+ uv sync --extra dev --extra sqlite --extra neo4j --extra qdrant --extra minio
373+ uv run pytest -v # 185 + unit tests
341374uv run pytest -m neo4j # Neo4j integration (docker compose up neo4j)
375+ uv run pytest -m qdrant # Qdrant integration (docker start qdrant)
376+ uv run pytest -m composite # Full stack (Neo4j + Qdrant + MinIO)
342377uv run ruff check --fix && uv run ruff format
343378uv run pyright # strict mode
344379```
345380
381+ ``` bash
382+ # 개발 인프라
383+ docker compose up neo4j # Neo4j (bolt://localhost:7687)
384+ docker start qdrant # Qdrant (http://localhost:6333)
385+ # MinIO는 서버에서 직접 실행 (localhost:9000)
386+ ```
387+
346388## License
347389
348390MIT
0 commit comments