{"title":"Synapse 아키텍처","slug":"architecture","category":"concepts","summary":"Synapse의 구축 방식 — Fastify, PostgreSQL, FTS5, 임베딩, MCP 서버.","audience":["human","llm"],"tags":["architecture","design","components"],"difficulty":"intermediate","updated":"2026-06-27","word_count":411,"read_minutes":2,"lang":"ko","translated":true,"requested_lang":"ko","content_markdown":"\n# Synapse 아키텍처\n\nSynapse는 Fastify, FTS5가 포함된 PostgreSQL, 그리고 의미론적 검색을 위한\n선택적 임베딩 서비스를 기반으로 구축된 다중 테넌트 메모리 API입니다.\n\n## 고수준 아키텍처\n\n```\n┌──────────────────────────────────────────────────────────┐\n│                       Clients                            │\n├──────────────┬──────────────┬──────────────┬─────────────┤\n│  LLM Agents  │  Web Browsers│  MCP Clients │  Webhooks   │\n│  (curl/SDK)  │  (humans)    │ (Claude/etc) │  (external) │\n└──────┬───────┴──────┬───────┴──────┬───────┴──────┬──────┘\n       │              │              │              │\n       └──────────────┴──────────────┴──────────────┘\n                              │\n                              ▼\n              ┌───────────────────────────────┐\n              │    Synapse API (Fastify)      │\n              │    port 12800                 │\n              │    - REST endpoints           │\n              │    - Auth (Mind Key / JWT)    │\n              │    - Rate limiting            │\n              │    - Static file serving      │\n              └───────────────┬───────────────┘\n                              │\n              ┌───────────────┼───────────────┐\n              ▼               ▼               ▼\n       ┌─────────────┐ ┌─────────────┐ ┌─────────────┐\n       │ PostgreSQL  │ │ Embeddings  │ │ MCP Server  │\n       │ + FTS5      │ │ Service     │ │ (separate)  │\n       │             │ │ (optional)  │ │ port 13100  │\n       │ - memories  │ │             │ │             │\n       │ - tasks     │ │ - generate  │ │ - 79 tools  │\n       │ - chat      │ │   embeddings│ │ - stdio/SSE │\n       │ - scripts   │ │             │ │ - WebSocket │\n       └─────────────┘ └─────────────┘ └─────────────┘\n```\n\n## 핵심 구성 요소\n\n### 1. Synapse API (Fastify)\n\n메인 HTTP 서버입니다. 처리하는 작업:\n\n- REST 엔드포인트 (`/memory`, `/chat`, `/mind/tasks` 등)\n- 인증 (에이전트용 Mind Key, 사람용 JWT)\n- 속도 제한 (`?key=` 인증만)\n- 정적 파일 제공 (`/human`, `/docs` 등의 웹 UI)\n- 웹훅 디스패치\n\n성능을 위해 **Fastify 5**로 구축되었습니다. 프로덕션에서는 포트 12800에서\n실행됩니다.\n\n### 2. FTS5가 포함된 PostgreSQL\n\n기본 데이터 저장소입니다. 전문 검색을 위해 FTS5 확장이 포함된\nPostgreSQL을 사용합니다.\n\n**주요 테이블:**\n\n| 테이블 | 용도 |\n|-------|---------|\n| `users` | 사용자 계정 |\n| `minds` | 마인드 범위 (각각 Mind Key 보유) |\n| `memories` | FTS5 가상 테이블이 있는 메모리 레코드 |\n| `tasks` | 작업 관리 |\n| `chat_messages` | 채팅 기록 |\n| `scripts` | 영구 스크립트 |\n| `webhooks` | 웹훅 등록 |\n| `cron_jobs` | 예약된 작업 |\n| `variables` | 키-값 저장소 |\n| `audit_log` | 감사 추적 |\n\n**FTS5**는 모든 메모리 콘텐츠에 대해 서브밀리초 전문 검색을 가능하게\n합니다. 자세한 내용은 [FTS5 검색](/docs/concepts/fts5-search)을 참조하십시오.\n\n### 3. 임베딩 서비스 (선택 사항)\n\n의미론적 검색을 위해 Synapse는 메모리 콘텐츠의 벡터 임베딩을 생성합니다.\n이는 메모리와 함께 저장되며 유사도 검색에 사용됩니다.\n\n- 제공자: 구성 가능 (OpenAI, 로컬 모델 등)\n- `memories` 테이블의 `vector` 컬럼으로 저장\n- `/memory/semantic-search` 엔드포인트에서 사용\n- [의미론적 검색](/docs/concepts/semantic-search) 참조\n\n### 4. MCP 서버 (별도 서비스)\n\nSynapse MCP 서버는 별도의 프로세스 (포트 13100)로 실행됩니다. 다음을\n수행합니다:\n\n- Model Context Protocol을 통해 79개 도구 노출\n- stdio, HTTP/SSE, WebSocket 전송 지원\n- MCP 도구 호출을 Synapse API 호출로 변환\n- 다중 테넌트: 세션당 하나의 Mind Key\n\n### 5. Browser Proxy (별도 서비스)\n\n브라우저 자동화를 위해 Playwright 기반의 별도 서비스가 포트 13000에서\n실행됩니다. MCP 서버는 `browser_*` 도구를 위해 이를 호출할 수 있습니다.\n\n### 6. SSH Proxy (별도 서비스)\n\nSSH 기반 원격 명령을 위해 별도의 서비스가 포트 12900에서 실행됩니다.\n\n## 다중 테넌시 모델\n\n```\nUser Account (email + password)\n  │\n  ├── Mind 1 (Mind Key 1)\n  │   ├── Memories\n  │   ├── Tasks\n  │   ├── Chat\n  │   └── Scripts\n  │\n  ├── Mind 2 (Mind Key 2)\n  │   └── ... (isolated from Mind 1)\n  │\n  └── Mind 3 (Mind Key 3)\n      └── ...\n```\n\n각 마인드는 완전히 격리되어 있습니다. Mind Key는 정확히 하나의 마인드에만\n접근 권한을 부여합니다. JWT는 사용자 계정 (마인드 관리용)에 접근 권한을\n부여합니다.\n\n자세한 내용은 [다중 테넌시](/docs/concepts/multi-tenancy)를 참조하십시오.\n\n## 요청 흐름\n\n### 메모리 저장 요청\n\n```\n1. Client sends POST /memory with Authorization: Bearer mk_xxx\n2. Fastify receives request\n3. Auth middleware validates Mind Key, attaches mind_id to request\n4. Memory route handler:\n   a. Validate JSON body (zod schema)\n   b. Insert into memories table\n   c. Update FTS5 index\n   d. (Async) Generate embedding if embeddings enabled\n   e. Trigger webhooks for memory.store event\n5. Return { id, status: \"stored\" }\n```\n\n### 메모리 검색 요청\n\n```\n1. Client sends GET /memory/search?q=docker\n2. Auth middleware validates Mind Key\n3. Memory route handler:\n   a. Parse query (FTS5 syntax)\n   b. Execute FTS5 MATCH against memories table\n   c. Filter by mind_id (tenant isolation)\n   d. Rank by relevance\n   e. Return results\n```\n\n## 배포\n\nSynapse는 Docker 컨테이너로 배포됩니다. `docker-compose.yml`을 참조하십시오:\n\n```yaml\nservices:\n  synapse:\n    image: registry.gitlab.com/schaefer-services/synapse:latest\n    ports:\n      - \"12800:12800\"\n    environment:\n      - DATABASE_URL=postgres://...\n      - JWT_SECRET=...\n      - SYNAPSE_HOST=0.0.0.0\n      - SYNAPSE_PORT=12800\n    depends_on:\n      - postgres\n  \n  postgres:\n    image: postgres:16\n    volumes:\n      - pgdata:/var/lib/postgresql/data\n    environment:\n      - POSTGRES_DB=synapse\n      - POSTGRES_PASSWORD=...\n```\n\n## 성능 특성\n\n| 작업 | 지연 시간 | 처리량 |\n|-----------|---------|------------|\n| 메모리 저장 | ~5ms | 1000+ req/s |\n| 메모리 회상 | ~20ms | 500 req/s |\n| FTS5 검색 | ~10ms | 800 req/s |\n| 의미론적 검색 | ~50ms | 200 req/s |\n| 채팅 폴링 | ~5ms | 2000 req/s |\n\n## 다음 단계\n\n- [메모리 모델](/docs/concepts/memory-model)\n- [다중 테넌시](/docs/concepts/multi-tenancy)\n- [FTS5 검색](/docs/concepts/fts5-search)\n","content_html":"<h1>Synapse 아키텍처</h1>\n<p>Synapse는 Fastify, FTS5가 포함된 PostgreSQL, 그리고 의미론적 검색을 위한\n선택적 임베딩 서비스를 기반으로 구축된 다중 테넌트 메모리 API입니다.</p>\n<h2>고수준 아키텍처</h2>\n<pre><code class=\"hljs language-plaintext\">┌──────────────────────────────────────────────────────────┐\n│                       Clients                            │\n├──────────────┬──────────────┬──────────────┬─────────────┤\n│  LLM Agents  │  Web Browsers│  MCP Clients │  Webhooks   │\n│  (curl/SDK)  │  (humans)    │ (Claude/etc) │  (external) │\n└──────┬───────┴──────┬───────┴──────┬───────┴──────┬──────┘\n       │              │              │              │\n       └──────────────┴──────────────┴──────────────┘\n                              │\n                              ▼\n              ┌───────────────────────────────┐\n              │    Synapse API (Fastify)      │\n              │    port 12800                 │\n              │    - REST endpoints           │\n              │    - Auth (Mind Key / JWT)    │\n              │    - Rate limiting            │\n              │    - Static file serving      │\n              └───────────────┬───────────────┘\n                              │\n              ┌───────────────┼───────────────┐\n              ▼               ▼               ▼\n       ┌─────────────┐ ┌─────────────┐ ┌─────────────┐\n       │ PostgreSQL  │ │ Embeddings  │ │ MCP Server  │\n       │ + FTS5      │ │ Service     │ │ (separate)  │\n       │             │ │ (optional)  │ │ port 13100  │\n       │ - memories  │ │             │ │             │\n       │ - tasks     │ │ - generate  │ │ - 79 tools  │\n       │ - chat      │ │   embeddings│ │ - stdio/SSE │\n       │ - scripts   │ │             │ │ - WebSocket │\n       └─────────────┘ └─────────────┘ └─────────────┘</code></pre><h2>핵심 구성 요소</h2>\n<h3>1. Synapse API (Fastify)</h3>\n<p>메인 HTTP 서버입니다. 처리하는 작업:</p>\n<ul>\n<li>REST 엔드포인트 (<code>/memory</code>, <code>/chat</code>, <code>/mind/tasks</code> 등)</li>\n<li>인증 (에이전트용 Mind Key, 사람용 JWT)</li>\n<li>속도 제한 (<code>?key=</code> 인증만)</li>\n<li>정적 파일 제공 (<code>/human</code>, <code>/docs</code> 등의 웹 UI)</li>\n<li>웹훅 디스패치</li>\n</ul>\n<p>성능을 위해 <strong>Fastify 5</strong>로 구축되었습니다. 프로덕션에서는 포트 12800에서\n실행됩니다.</p>\n<h3>2. FTS5가 포함된 PostgreSQL</h3>\n<p>기본 데이터 저장소입니다. 전문 검색을 위해 FTS5 확장이 포함된\nPostgreSQL을 사용합니다.</p>\n<p><strong>주요 테이블:</strong></p>\n<table>\n<thead>\n<tr>\n<th>테이블</th>\n<th>용도</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>users</code></td>\n<td>사용자 계정</td>\n</tr>\n<tr>\n<td><code>minds</code></td>\n<td>마인드 범위 (각각 Mind Key 보유)</td>\n</tr>\n<tr>\n<td><code>memories</code></td>\n<td>FTS5 가상 테이블이 있는 메모리 레코드</td>\n</tr>\n<tr>\n<td><code>tasks</code></td>\n<td>작업 관리</td>\n</tr>\n<tr>\n<td><code>chat_messages</code></td>\n<td>채팅 기록</td>\n</tr>\n<tr>\n<td><code>scripts</code></td>\n<td>영구 스크립트</td>\n</tr>\n<tr>\n<td><code>webhooks</code></td>\n<td>웹훅 등록</td>\n</tr>\n<tr>\n<td><code>cron_jobs</code></td>\n<td>예약된 작업</td>\n</tr>\n<tr>\n<td><code>variables</code></td>\n<td>키-값 저장소</td>\n</tr>\n<tr>\n<td><code>audit_log</code></td>\n<td>감사 추적</td>\n</tr>\n</tbody></table>\n<p><strong>FTS5</strong>는 모든 메모리 콘텐츠에 대해 서브밀리초 전문 검색을 가능하게\n합니다. 자세한 내용은 <a href=\"/docs/concepts/fts5-search\">FTS5 검색</a>을 참조하십시오.</p>\n<h3>3. 임베딩 서비스 (선택 사항)</h3>\n<p>의미론적 검색을 위해 Synapse는 메모리 콘텐츠의 벡터 임베딩을 생성합니다.\n이는 메모리와 함께 저장되며 유사도 검색에 사용됩니다.</p>\n<ul>\n<li>제공자: 구성 가능 (OpenAI, 로컬 모델 등)</li>\n<li><code>memories</code> 테이블의 <code>vector</code> 컬럼으로 저장</li>\n<li><code>/memory/semantic-search</code> 엔드포인트에서 사용</li>\n<li><a href=\"/docs/concepts/semantic-search\">의미론적 검색</a> 참조</li>\n</ul>\n<h3>4. MCP 서버 (별도 서비스)</h3>\n<p>Synapse MCP 서버는 별도의 프로세스 (포트 13100)로 실행됩니다. 다음을\n수행합니다:</p>\n<ul>\n<li>Model Context Protocol을 통해 79개 도구 노출</li>\n<li>stdio, HTTP/SSE, WebSocket 전송 지원</li>\n<li>MCP 도구 호출을 Synapse API 호출로 변환</li>\n<li>다중 테넌트: 세션당 하나의 Mind Key</li>\n</ul>\n<h3>5. Browser Proxy (별도 서비스)</h3>\n<p>브라우저 자동화를 위해 Playwright 기반의 별도 서비스가 포트 13000에서\n실행됩니다. MCP 서버는 <code>browser_*</code> 도구를 위해 이를 호출할 수 있습니다.</p>\n<h3>6. SSH Proxy (별도 서비스)</h3>\n<p>SSH 기반 원격 명령을 위해 별도의 서비스가 포트 12900에서 실행됩니다.</p>\n<h2>다중 테넌시 모델</h2>\n<pre><code class=\"hljs language-plaintext\">User Account (email + password)\n  │\n  ├── Mind 1 (Mind Key 1)\n  │   ├── Memories\n  │   ├── Tasks\n  │   ├── Chat\n  │   └── Scripts\n  │\n  ├── Mind 2 (Mind Key 2)\n  │   └── ... (isolated from Mind 1)\n  │\n  └── Mind 3 (Mind Key 3)\n      └── ...</code></pre><p>각 마인드는 완전히 격리되어 있습니다. Mind Key는 정확히 하나의 마인드에만\n접근 권한을 부여합니다. JWT는 사용자 계정 (마인드 관리용)에 접근 권한을\n부여합니다.</p>\n<p>자세한 내용은 <a href=\"/docs/concepts/multi-tenancy\">다중 테넌시</a>를 참조하십시오.</p>\n<h2>요청 흐름</h2>\n<h3>메모리 저장 요청</h3>\n<pre><code class=\"hljs language-plaintext\">1. Client sends POST /memory with Authorization: Bearer mk_xxx\n2. Fastify receives request\n3. Auth middleware validates Mind Key, attaches mind_id to request\n4. Memory route handler:\n   a. Validate JSON body (zod schema)\n   b. Insert into memories table\n   c. Update FTS5 index\n   d. (Async) Generate embedding if embeddings enabled\n   e. Trigger webhooks for memory.store event\n5. Return { id, status: &quot;stored&quot; }</code></pre><h3>메모리 검색 요청</h3>\n<pre><code class=\"hljs language-plaintext\">1. Client sends GET /memory/search?q=docker\n2. Auth middleware validates Mind Key\n3. Memory route handler:\n   a. Parse query (FTS5 syntax)\n   b. Execute FTS5 MATCH against memories table\n   c. Filter by mind_id (tenant isolation)\n   d. Rank by relevance\n   e. Return results</code></pre><h2>배포</h2>\n<p>Synapse는 Docker 컨테이너로 배포됩니다. <code>docker-compose.yml</code>을 참조하십시오:</p>\n<pre><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">services:</span>\n  <span class=\"hljs-attr\">synapse:</span>\n    <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">registry.gitlab.com/schaefer-services/synapse:latest</span>\n    <span class=\"hljs-attr\">ports:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">&quot;12800:12800&quot;</span>\n    <span class=\"hljs-attr\">environment:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">DATABASE_URL=postgres://...</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">JWT_SECRET=...</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">SYNAPSE_HOST=0.0.0.0</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">SYNAPSE_PORT=12800</span>\n    <span class=\"hljs-attr\">depends_on:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">postgres</span>\n  \n  <span class=\"hljs-attr\">postgres:</span>\n    <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">postgres:16</span>\n    <span class=\"hljs-attr\">volumes:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">pgdata:/var/lib/postgresql/data</span>\n    <span class=\"hljs-attr\">environment:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">POSTGRES_DB=synapse</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">POSTGRES_PASSWORD=...</span></code></pre><h2>성능 특성</h2>\n<table>\n<thead>\n<tr>\n<th>작업</th>\n<th>지연 시간</th>\n<th>처리량</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>메모리 저장</td>\n<td>~5ms</td>\n<td>1000+ req/s</td>\n</tr>\n<tr>\n<td>메모리 회상</td>\n<td>~20ms</td>\n<td>500 req/s</td>\n</tr>\n<tr>\n<td>FTS5 검색</td>\n<td>~10ms</td>\n<td>800 req/s</td>\n</tr>\n<tr>\n<td>의미론적 검색</td>\n<td>~50ms</td>\n<td>200 req/s</td>\n</tr>\n<tr>\n<td>채팅 폴링</td>\n<td>~5ms</td>\n<td>2000 req/s</td>\n</tr>\n</tbody></table>\n<h2>다음 단계</h2>\n<ul>\n<li><a href=\"/docs/concepts/memory-model\">메모리 모델</a></li>\n<li><a href=\"/docs/concepts/multi-tenancy\">다중 테넌시</a></li>\n<li><a href=\"/docs/concepts/fts5-search\">FTS5 검색</a></li>\n</ul>\n","urls":{"html":"/docs/concepts/architecture","text":"/docs/concepts/architecture?format=text","json":"/docs/concepts/architecture?format=json","llm":"/docs/concepts/architecture?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}