{"title":"Kiến trúc Synapse","slug":"architecture","category":"concepts","summary":"Cách Synapse được xây dựng — Fastify, PostgreSQL, FTS5, embeddings, MCP server.","audience":["human","llm"],"tags":["architecture","design","components"],"difficulty":"intermediate","updated":"2026-06-27","word_count":572,"read_minutes":3,"lang":"vi","translated":true,"requested_lang":"vi","content_markdown":"\n# Kiến trúc Synapse\n\nSynapse là API bộ nhớ multi-tenant được xây dựng trên Fastify, PostgreSQL với\nFTS5, và một dịch vụ embeddings tùy chọn cho tìm kiếm ngữ nghĩa.\n\n## Kiến trúc tổng quan\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## Thành phần cốt lõi\n\n### 1. Synapse API (Fastify)\n\nHTTP server chính. Xử lý:\n\n- Endpoint REST (`/memory`, `/chat`, `/mind/tasks`, v.v.)\n- Xác thực (Mind Key cho agent, JWT cho con người)\n- Giới hạn tốc độ (chỉ xác thực `?key=`)\n- Phục vụ tệp tĩnh (giao diện web tại `/human`, `/docs`, v.v.)\n- Phân phối webhook\n\nĐược xây dựng với **Fastify 5** cho hiệu suất. Chạy trên cổng 12800 trong môi trường production.\n\n### 2. PostgreSQL với FTS5\n\nKho dữ liệu chính. Sử dụng PostgreSQL với phần mở rộng FTS5 cho tìm kiếm toàn\nvăn.\n\n**Bảng chính:**\n\n| Bảng | Mục đích |\n|-------|---------|\n| `users` | Tài khoản người dùng |\n| `minds` | Phạm vi mind (mỗi cái có một Mind Key) |\n| `memories` | Bản ghi bộ nhớ với bảng ảo FTS5 |\n| `tasks` | Quản lý tác vụ |\n| `chat_messages` | Lịch sử chat |\n| `scripts` | Script cố định |\n| `webhooks` | Đăng ký webhook |\n| `cron_jobs` | Tác vụ đã lên lịch |\n| `variables` | Cửa hàng key-value |\n| `audit_log` | Nhật ký kiểm toán |\n\n**FTS5** cho phép tìm kiếm toàn văn dưới mili giây trên toàn bộ nội dung bộ\nnhớ. Xem [Tìm kiếm FTS5](/docs/concepts/fts5-search) để biết chi tiết.\n\n### 3. Dịch vụ Embeddings (Tùy chọn)\n\nĐối với tìm kiếm ngữ nghĩa, Synapse tạo vector embeddings của nội dung bộ nhớ.\nChúng được lưu cùng với bộ nhớ và dùng cho tìm kiếm tương tự.\n\n- Provider: có thể cấu hình (OpenAI, mô hình cục bộ, v.v.)\n- Lưu dưới dạng cột `vector` trong bảng `memories`\n- Được sử dụng bởi endpoint `/memory/semantic-search`\n- Xem [Tìm kiếm ngữ nghĩa](/docs/concepts/semantic-search)\n\n### 4. MCP Server (Dịch vụ riêng)\n\nSynapse MCP server chạy như một tiến trình riêng (cổng 13100). Nó:\n\n- Cung cấp 79 công cụ qua Model Context Protocol\n- Hỗ trợ transport stdio, HTTP/SSE và WebSocket\n- Dịch các lệnh gọi công cụ MCP thành lệnh gọi Synapse API\n- Multi-tenant: một Mind Key mỗi phiên\n\n### 5. Browser Proxy (Dịch vụ riêng)\n\nĐối với tự động hóa trình duyệt, một dịch vụ riêng dựa trên Playwright chạy\ntrên cổng 13000. MCP server có thể gọi dịch vụ này cho các công cụ `browser_*`.\n\n### 6. SSH Proxy (Dịch vụ riêng)\n\nĐối với lệnh từ xa dựa trên SSH, một dịch vụ riêng chạy trên cổng 12900.\n\n## Mô hình Multi-Tenancy\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\nMỗi mind hoàn toàn tách biệt. Mind Key cấp quyền truy cập chính xác một mind.\nJWT cấp quyền truy cập tài khoản người dùng (để quản lý mind).\n\nXem [Multi-Tenancy](/docs/concepts/multi-tenancy) để biết chi tiết.\n\n## Luồng yêu cầu\n\n### Yêu cầu lưu bộ nhớ\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### Yêu cầu tìm kiếm bộ nhớ\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## Triển khai\n\nSynapse được triển khai dưới dạng Docker container. Xem `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## Đặc tính hiệu suất\n\n| Thao tác | Độ trễ | Thông lượng |\n|-----------|---------|------------|\n| Lưu bộ nhớ | ~5ms | 1000+ req/s |\n| Thu hồi bộ nhớ | ~20ms | 500 req/s |\n| Tìm kiếm FTS5 | ~10ms | 800 req/s |\n| Tìm kiếm ngữ nghĩa | ~50ms | 200 req/s |\n| Poll chat | ~5ms | 2000 req/s |\n\n## Bước tiếp theo\n\n- [Mô hình bộ nhớ](/docs/concepts/memory-model)\n- [Multi-Tenancy](/docs/concepts/multi-tenancy)\n- [Tìm kiếm FTS5](/docs/concepts/fts5-search)\n","content_html":"<h1>Kiến trúc Synapse</h1>\n<p>Synapse là API bộ nhớ multi-tenant được xây dựng trên Fastify, PostgreSQL với\nFTS5, và một dịch vụ embeddings tùy chọn cho tìm kiếm ngữ nghĩa.</p>\n<h2>Kiến trúc tổng quan</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>Thành phần cốt lõi</h2>\n<h3>1. Synapse API (Fastify)</h3>\n<p>HTTP server chính. Xử lý:</p>\n<ul>\n<li>Endpoint REST (<code>/memory</code>, <code>/chat</code>, <code>/mind/tasks</code>, v.v.)</li>\n<li>Xác thực (Mind Key cho agent, JWT cho con người)</li>\n<li>Giới hạn tốc độ (chỉ xác thực <code>?key=</code>)</li>\n<li>Phục vụ tệp tĩnh (giao diện web tại <code>/human</code>, <code>/docs</code>, v.v.)</li>\n<li>Phân phối webhook</li>\n</ul>\n<p>Được xây dựng với <strong>Fastify 5</strong> cho hiệu suất. Chạy trên cổng 12800 trong môi trường production.</p>\n<h3>2. PostgreSQL với FTS5</h3>\n<p>Kho dữ liệu chính. Sử dụng PostgreSQL với phần mở rộng FTS5 cho tìm kiếm toàn\nvăn.</p>\n<p><strong>Bảng chính:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Bảng</th>\n<th>Mục đích</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>users</code></td>\n<td>Tài khoản người dùng</td>\n</tr>\n<tr>\n<td><code>minds</code></td>\n<td>Phạm vi mind (mỗi cái có một Mind Key)</td>\n</tr>\n<tr>\n<td><code>memories</code></td>\n<td>Bản ghi bộ nhớ với bảng ảo FTS5</td>\n</tr>\n<tr>\n<td><code>tasks</code></td>\n<td>Quản lý tác vụ</td>\n</tr>\n<tr>\n<td><code>chat_messages</code></td>\n<td>Lịch sử chat</td>\n</tr>\n<tr>\n<td><code>scripts</code></td>\n<td>Script cố định</td>\n</tr>\n<tr>\n<td><code>webhooks</code></td>\n<td>Đăng ký webhook</td>\n</tr>\n<tr>\n<td><code>cron_jobs</code></td>\n<td>Tác vụ đã lên lịch</td>\n</tr>\n<tr>\n<td><code>variables</code></td>\n<td>Cửa hàng key-value</td>\n</tr>\n<tr>\n<td><code>audit_log</code></td>\n<td>Nhật ký kiểm toán</td>\n</tr>\n</tbody></table>\n<p><strong>FTS5</strong> cho phép tìm kiếm toàn văn dưới mili giây trên toàn bộ nội dung bộ\nnhớ. Xem <a href=\"/docs/concepts/fts5-search\">Tìm kiếm FTS5</a> để biết chi tiết.</p>\n<h3>3. Dịch vụ Embeddings (Tùy chọn)</h3>\n<p>Đối với tìm kiếm ngữ nghĩa, Synapse tạo vector embeddings của nội dung bộ nhớ.\nChúng được lưu cùng với bộ nhớ và dùng cho tìm kiếm tương tự.</p>\n<ul>\n<li>Provider: có thể cấu hình (OpenAI, mô hình cục bộ, v.v.)</li>\n<li>Lưu dưới dạng cột <code>vector</code> trong bảng <code>memories</code></li>\n<li>Được sử dụng bởi endpoint <code>/memory/semantic-search</code></li>\n<li>Xem <a href=\"/docs/concepts/semantic-search\">Tìm kiếm ngữ nghĩa</a></li>\n</ul>\n<h3>4. MCP Server (Dịch vụ riêng)</h3>\n<p>Synapse MCP server chạy như một tiến trình riêng (cổng 13100). Nó:</p>\n<ul>\n<li>Cung cấp 79 công cụ qua Model Context Protocol</li>\n<li>Hỗ trợ transport stdio, HTTP/SSE và WebSocket</li>\n<li>Dịch các lệnh gọi công cụ MCP thành lệnh gọi Synapse API</li>\n<li>Multi-tenant: một Mind Key mỗi phiên</li>\n</ul>\n<h3>5. Browser Proxy (Dịch vụ riêng)</h3>\n<p>Đối với tự động hóa trình duyệt, một dịch vụ riêng dựa trên Playwright chạy\ntrên cổng 13000. MCP server có thể gọi dịch vụ này cho các công cụ <code>browser_*</code>.</p>\n<h3>6. SSH Proxy (Dịch vụ riêng)</h3>\n<p>Đối với lệnh từ xa dựa trên SSH, một dịch vụ riêng chạy trên cổng 12900.</p>\n<h2>Mô hình Multi-Tenancy</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>Mỗi mind hoàn toàn tách biệt. Mind Key cấp quyền truy cập chính xác một mind.\nJWT cấp quyền truy cập tài khoản người dùng (để quản lý mind).</p>\n<p>Xem <a href=\"/docs/concepts/multi-tenancy\">Multi-Tenancy</a> để biết chi tiết.</p>\n<h2>Luồng yêu cầu</h2>\n<h3>Yêu cầu lưu bộ nhớ</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>Yêu cầu tìm kiếm bộ nhớ</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>Triển khai</h2>\n<p>Synapse được triển khai dưới dạng Docker container. Xem <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>Đặc tính hiệu suất</h2>\n<table>\n<thead>\n<tr>\n<th>Thao tác</th>\n<th>Độ trễ</th>\n<th>Thông lượng</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Lưu bộ nhớ</td>\n<td>~5ms</td>\n<td>1000+ req/s</td>\n</tr>\n<tr>\n<td>Thu hồi bộ nhớ</td>\n<td>~20ms</td>\n<td>500 req/s</td>\n</tr>\n<tr>\n<td>Tìm kiếm FTS5</td>\n<td>~10ms</td>\n<td>800 req/s</td>\n</tr>\n<tr>\n<td>Tìm kiếm ngữ nghĩa</td>\n<td>~50ms</td>\n<td>200 req/s</td>\n</tr>\n<tr>\n<td>Poll chat</td>\n<td>~5ms</td>\n<td>2000 req/s</td>\n</tr>\n</tbody></table>\n<h2>Bước tiếp theo</h2>\n<ul>\n<li><a href=\"/docs/concepts/memory-model\">Mô hình bộ nhớ</a></li>\n<li><a href=\"/docs/concepts/multi-tenancy\">Multi-Tenancy</a></li>\n<li><a href=\"/docs/concepts/fts5-search\">Tìm kiếm 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"]}