{"title":"Tìm kiếm ngữ nghĩa (Embeddings)","slug":"semantic-search","category":"concepts","summary":"Tìm kiếm bộ nhớ khái niệm sử dụng vector embeddings — tìm theo ý nghĩa, không chỉ từ khóa.","audience":["human","llm"],"tags":["concept","semantic","embeddings","vector-search"],"difficulty":"advanced","updated":"2026-06-27","word_count":698,"read_minutes":3,"lang":"vi","translated":true,"requested_lang":"vi","content_markdown":"\n# Tìm kiếm ngữ nghĩa (Embeddings)\n\nSynapse hỗ trợ tìm kiếm ngữ nghĩa sử dụng vector embeddings. Khác với FTS5 (khớp\ntừ khóa), tìm kiếm ngữ nghĩa tìm bộ nhớ theo **ý nghĩa** — ngay cả khi không có\ntừ khóa nào khớp.\n\n## Cách hoạt động\n\n```\n1. Memory stored → embedding generated → vector stored\n2. Search query → embedding generated → vector compared\n3. Cosine similarity → top N results returned\n```\n\n### Embeddings là gì?\n\nEmbeddings là biểu diễn vector số của văn bản. Văn bản có ý nghĩa tương tự có\nvector tương tự. Synapse tạo một vector (ví dụ 1536 chiều) cho nội dung mỗi bộ\nnhớ.\n\n### Tương đồng cosine\n\nĐể tìm bộ nhớ tương tự về mặt ngữ nghĩa, Synapse tính tương đồng cosine giữa\nvector truy vấn và mỗi vector bộ nhớ. Tương đồng cao hơn = liên quan hơn.\n\n## Khi nào sử dụng tìm kiếm ngữ nghĩa\n\n### Sử dụng tìm kiếm ngữ nghĩa khi:\n\n- Bạn muốn \"bộ nhớ về X\" khi X được mô tả khác với lưu trữ\n- FTS5 trả về không kết quả (không khớp từ khóa)\n- Bạn muốn nhóm khái niệm (ví dụ tất cả bộ nhớ \"deployment\", ngay cả khi một số nói \"release\")\n- Truy vấn là một câu hỏi: \"làm thế nào chúng ta xử lý xác thực?\"\n\n### Sử dụng FTS5 khi:\n\n- Bạn biết từ khóa chính xác\n- Bạn cần logic boolean (AND, OR, NOT)\n- Bạn cần phản hồi dưới mili giây\n- Bạn muốn khớp cụm từ\n\n## Endpoint\n\n### GET /memory/semantic-search\n\n```bash\ncurl -H \"Authorization: Bearer YOUR_MIND_KEY\" \\\n     \"https://synapse.schaefer.zone/memory/semantic-search?q=container+orchestration\"\n```\n\nPhản hồi:\n\n```json\n{\n  \"results\": [\n    {\n      \"id\": \"mem_001\",\n      \"category\": \"project\",\n      \"key\": \"project_synapse_deployment\",\n      \"content\": \"Synapse deployed using Docker Swarm on vps1...\",\n      \"tags\": [\"docker\", \"swarm\", \"deployment\"],\n      \"similarity\": 0.89\n    },\n    {\n      \"id\": \"mem_042\",\n      \"category\": \"fact\",\n      \"key\": \"kubernetes_cluster\",\n      \"content\": \"We use Kubernetes for production orchestration...\",\n      \"tags\": [\"kubernetes\", \"orchestration\"],\n      \"similarity\": 0.84\n    }\n  ]\n}\n```\n\n## Ví dụ\n\n### Tìm bộ nhớ triển khai\n\n```bash\n# FTS5 might miss some — semantic catches all\ncurl .../memory/semantic-search?q=deployment+process\n```\n\nTrả về bộ nhớ về \"deployment\", \"release\", \"publishing\", \"rolling out\", v.v.\n\n### Tìm mẫu xác thực\n\n```bash\ncurl .../memory/semantic-search?q=how+do+users+log+in\n```\n\nTrả về bộ nhớ về đăng nhập, xác thực, JWT, quản lý phiên, OAuth, v.v.\n\n### Tìm bộ nhớ tương tự\n\n```bash\n# Find memories similar to a specific one\ncurl .../memory/related/mem_001\n```\n\nSử dụng tương đồng ngữ nghĩa (qua tag chung VÀ vector embedding).\n\n## Tạo embedding\n\n### Khi nào embeddings được tạo?\n\n- **Khi lưu bộ nhớ** — nếu dịch vụ embeddings được cấu hình, embedding được tạo đồng bộ\n- **Tạo hàng loạt** — `POST /memory/embed-batch` tạo embeddings cho bộ nhớ thiếu\n- **Cập nhật bất đồng bộ** — khi nội dung được cập nhật, embedding được tạo lại\n\n### Provider embedding\n\nSynapse hỗ trợ provider embedding có thể cấu hình:\n\n- **OpenAI** (`text-embedding-3-small`, `text-embedding-3-large`)\n- **Mô hình cục bộ** (qua Ollama hoặc tương tự)\n- **Tùy chỉnh** (triển khai giao diện embeddings)\n\nCấu hình qua biến môi trường:\n\n```bash\nEMBEDDINGS_PROVIDER=openai\nEMBEDDINGS_API_KEY=sk-...\nEMBEDDINGS_MODEL=text-embedding-3-small\n```\n\n### Tạo hàng loạt\n\nCho mind với nhiều bộ nhớ thiếu embeddings:\n\n```bash\n# Generate embeddings for up to 100 memories\ncurl -X POST https://synapse.schaefer.zone/memory/embed-batch \\\n  -H \"Authorization: Bearer YOUR_MIND_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"limit\": 100}'\n\n# Check progress\ncurl -H \"Authorization: Bearer YOUR_MIND_KEY\" \\\n     https://synapse.schaefer.zone/memory/embed-batch-status\n```\n\n## Hiệu suất\n\n| Thao tác | Độ trễ |\n|-----------|---------|\n| Tạo embedding (OpenAI) | 100-200ms |\n| Tìm kiếm ngữ nghĩa (1k bộ nhớ) | 50-100ms |\n| Tìm kiếm ngữ nghĩa (10k bộ nhớ) | 200-500ms |\n| Tạo hàng loạt (100 bộ nhớ) | 10-20s |\n\n> [!NOTE]\n> Tìm kiếm ngữ nghĩa chậm hơn FTS5 do tính toán vector. Sử dụng FTS5 cho từ\n> khóa đã biết, ngữ nghĩa cho truy vấn khái niệm.\n\n## Giới hạn\n\n### Chi phí embeddings\n\nNếu sử dụng OpenAI, tạo embeddings tốn tiền (~$0.02 mỗi 1M token cho\ntext-embedding-3-small). Cho 10.000 bộ nhớ trung bình 100 token mỗi cái, đó là\n~$0.02 — không đáng kể.\n\n### Khởi động lạnh\n\nBộ nhớ lưu trước khi embeddings được cấu hình sẽ không có embeddings. Chạy\n`POST /memory/embed-batch` để backfill.\n\n### Phụ thuộc provider\n\nNếu provider embeddings ngừng hoạt động, tìm kiếm ngữ nghĩa thất bại một cách\nmềm mại (trả về kết quả rỗng hoặc lỗi). FTS5 vẫn hoạt động.\n\n## Khi Embeddings không khả dụng\n\nNếu dịch vụ embeddings không được cấu hình:\n\n- `GET /memory/semantic-search` trả về 503 Service Unavailable\n- `POST /memory` vẫn hoạt động (chỉ không có embedding được tạo)\n- Tìm kiếm FTS5 vẫn hoạt động\n\n## Thực hành tốt nhất\n\n> [!TIP]\n> - **Sử dụng ngữ nghĩa cho truy vấn khái niệm** — \"làm thế nào chúng ta xử lý X?\"\n> - **Sử dụng FTS5 cho thuật ngữ cụ thể** — \"docker swarm\"\n> - **Backfill embeddings thường xuyên** — `POST /memory/embed-batch`\n> - **Giám sát sức khỏe provider** — tìm kiếm ngữ nghĩa phụ thuộc vào nó\n> - **Kết hợp với tag** — ngữ nghĩa + bộ lọc tag thu hẹp kết quả\n\n## Bước tiếp theo\n\n- [Tìm kiếm FTS5](/docs/concepts/fts5-search)\n- [Memory API](/docs/api/memory)\n- [Kiến trúc](/docs/concepts/architecture)\n","content_html":"<h1>Tìm kiếm ngữ nghĩa (Embeddings)</h1>\n<p>Synapse hỗ trợ tìm kiếm ngữ nghĩa sử dụng vector embeddings. Khác với FTS5 (khớp\ntừ khóa), tìm kiếm ngữ nghĩa tìm bộ nhớ theo <strong>ý nghĩa</strong> — ngay cả khi không có\ntừ khóa nào khớp.</p>\n<h2>Cách hoạt động</h2>\n<pre><code class=\"hljs language-plaintext\">1. Memory stored → embedding generated → vector stored\n2. Search query → embedding generated → vector compared\n3. Cosine similarity → top N results returned</code></pre><h3>Embeddings là gì?</h3>\n<p>Embeddings là biểu diễn vector số của văn bản. Văn bản có ý nghĩa tương tự có\nvector tương tự. Synapse tạo một vector (ví dụ 1536 chiều) cho nội dung mỗi bộ\nnhớ.</p>\n<h3>Tương đồng cosine</h3>\n<p>Để tìm bộ nhớ tương tự về mặt ngữ nghĩa, Synapse tính tương đồng cosine giữa\nvector truy vấn và mỗi vector bộ nhớ. Tương đồng cao hơn = liên quan hơn.</p>\n<h2>Khi nào sử dụng tìm kiếm ngữ nghĩa</h2>\n<h3>Sử dụng tìm kiếm ngữ nghĩa khi:</h3>\n<ul>\n<li>Bạn muốn &quot;bộ nhớ về X&quot; khi X được mô tả khác với lưu trữ</li>\n<li>FTS5 trả về không kết quả (không khớp từ khóa)</li>\n<li>Bạn muốn nhóm khái niệm (ví dụ tất cả bộ nhớ &quot;deployment&quot;, ngay cả khi một số nói &quot;release&quot;)</li>\n<li>Truy vấn là một câu hỏi: &quot;làm thế nào chúng ta xử lý xác thực?&quot;</li>\n</ul>\n<h3>Sử dụng FTS5 khi:</h3>\n<ul>\n<li>Bạn biết từ khóa chính xác</li>\n<li>Bạn cần logic boolean (AND, OR, NOT)</li>\n<li>Bạn cần phản hồi dưới mili giây</li>\n<li>Bạn muốn khớp cụm từ</li>\n</ul>\n<h2>Endpoint</h2>\n<h3>GET /memory/semantic-search</h3>\n<pre><code class=\"hljs language-bash\">curl -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span> \\\n     <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone/memory/semantic-search?q=container+orchestration&quot;</span></code></pre><p>Phản hồi:</p>\n<pre><code class=\"hljs language-json\"><span class=\"hljs-punctuation\">{</span>\n  <span class=\"hljs-attr\">&quot;results&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-punctuation\">[</span>\n    <span class=\"hljs-punctuation\">{</span>\n      <span class=\"hljs-attr\">&quot;id&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;mem_001&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;category&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;project&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;key&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;project_synapse_deployment&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;content&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;Synapse deployed using Docker Swarm on vps1...&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;tags&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-punctuation\">[</span><span class=\"hljs-string\">&quot;docker&quot;</span><span class=\"hljs-punctuation\">,</span> <span class=\"hljs-string\">&quot;swarm&quot;</span><span class=\"hljs-punctuation\">,</span> <span class=\"hljs-string\">&quot;deployment&quot;</span><span class=\"hljs-punctuation\">]</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;similarity&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">0.89</span>\n    <span class=\"hljs-punctuation\">}</span><span class=\"hljs-punctuation\">,</span>\n    <span class=\"hljs-punctuation\">{</span>\n      <span class=\"hljs-attr\">&quot;id&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;mem_042&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;category&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;fact&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;key&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;kubernetes_cluster&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;content&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-string\">&quot;We use Kubernetes for production orchestration...&quot;</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;tags&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-punctuation\">[</span><span class=\"hljs-string\">&quot;kubernetes&quot;</span><span class=\"hljs-punctuation\">,</span> <span class=\"hljs-string\">&quot;orchestration&quot;</span><span class=\"hljs-punctuation\">]</span><span class=\"hljs-punctuation\">,</span>\n      <span class=\"hljs-attr\">&quot;similarity&quot;</span><span class=\"hljs-punctuation\">:</span> <span class=\"hljs-number\">0.84</span>\n    <span class=\"hljs-punctuation\">}</span>\n  <span class=\"hljs-punctuation\">]</span>\n<span class=\"hljs-punctuation\">}</span></code></pre><h2>Ví dụ</h2>\n<h3>Tìm bộ nhớ triển khai</h3>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># FTS5 might miss some — semantic catches all</span>\ncurl .../memory/semantic-search?q=deployment+process</code></pre><p>Trả về bộ nhớ về &quot;deployment&quot;, &quot;release&quot;, &quot;publishing&quot;, &quot;rolling out&quot;, v.v.</p>\n<h3>Tìm mẫu xác thực</h3>\n<pre><code class=\"hljs language-bash\">curl .../memory/semantic-search?q=how+<span class=\"hljs-keyword\">do</span>+<span class=\"hljs-built_in\">users</span>+<span class=\"hljs-built_in\">log</span>+<span class=\"hljs-keyword\">in</span></code></pre><p>Trả về bộ nhớ về đăng nhập, xác thực, JWT, quản lý phiên, OAuth, v.v.</p>\n<h3>Tìm bộ nhớ tương tự</h3>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Find memories similar to a specific one</span>\ncurl .../memory/related/mem_001</code></pre><p>Sử dụng tương đồng ngữ nghĩa (qua tag chung VÀ vector embedding).</p>\n<h2>Tạo embedding</h2>\n<h3>Khi nào embeddings được tạo?</h3>\n<ul>\n<li><strong>Khi lưu bộ nhớ</strong> — nếu dịch vụ embeddings được cấu hình, embedding được tạo đồng bộ</li>\n<li><strong>Tạo hàng loạt</strong> — <code>POST /memory/embed-batch</code> tạo embeddings cho bộ nhớ thiếu</li>\n<li><strong>Cập nhật bất đồng bộ</strong> — khi nội dung được cập nhật, embedding được tạo lại</li>\n</ul>\n<h3>Provider embedding</h3>\n<p>Synapse hỗ trợ provider embedding có thể cấu hình:</p>\n<ul>\n<li><strong>OpenAI</strong> (<code>text-embedding-3-small</code>, <code>text-embedding-3-large</code>)</li>\n<li><strong>Mô hình cục bộ</strong> (qua Ollama hoặc tương tự)</li>\n<li><strong>Tùy chỉnh</strong> (triển khai giao diện embeddings)</li>\n</ul>\n<p>Cấu hình qua biến môi trường:</p>\n<pre><code class=\"hljs language-bash\">EMBEDDINGS_PROVIDER=openai\nEMBEDDINGS_API_KEY=sk-...\nEMBEDDINGS_MODEL=text-embedding-3-small</code></pre><h3>Tạo hàng loạt</h3>\n<p>Cho mind với nhiều bộ nhớ thiếu embeddings:</p>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Generate embeddings for up to 100 memories</span>\ncurl -X POST https://synapse.schaefer.zone/memory/embed-batch \\\n  -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span> \\\n  -H <span class=\"hljs-string\">&quot;Content-Type: application/json&quot;</span> \\\n  -d <span class=\"hljs-string\">&#x27;{&quot;limit&quot;: 100}&#x27;</span>\n\n<span class=\"hljs-comment\"># Check progress</span>\ncurl -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span> \\\n     https://synapse.schaefer.zone/memory/embed-batch-status</code></pre><h2>Hiệu suất</h2>\n<table>\n<thead>\n<tr>\n<th>Thao tác</th>\n<th>Độ trễ</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Tạo embedding (OpenAI)</td>\n<td>100-200ms</td>\n</tr>\n<tr>\n<td>Tìm kiếm ngữ nghĩa (1k bộ nhớ)</td>\n<td>50-100ms</td>\n</tr>\n<tr>\n<td>Tìm kiếm ngữ nghĩa (10k bộ nhớ)</td>\n<td>200-500ms</td>\n</tr>\n<tr>\n<td>Tạo hàng loạt (100 bộ nhớ)</td>\n<td>10-20s</td>\n</tr>\n</tbody></table>\n<div class=\"callout callout-note\">Tìm kiếm ngữ nghĩa chậm hơn FTS5 do tính toán vector. Sử dụng FTS5 cho từ\nkhóa đã biết, ngữ nghĩa cho truy vấn khái niệm.</div><h2>Giới hạn</h2>\n<h3>Chi phí embeddings</h3>\n<p>Nếu sử dụng OpenAI, tạo embeddings tốn tiền (~$0.02 mỗi 1M token cho\ntext-embedding-3-small). Cho 10.000 bộ nhớ trung bình 100 token mỗi cái, đó là\n~$0.02 — không đáng kể.</p>\n<h3>Khởi động lạnh</h3>\n<p>Bộ nhớ lưu trước khi embeddings được cấu hình sẽ không có embeddings. Chạy\n<code>POST /memory/embed-batch</code> để backfill.</p>\n<h3>Phụ thuộc provider</h3>\n<p>Nếu provider embeddings ngừng hoạt động, tìm kiếm ngữ nghĩa thất bại một cách\nmềm mại (trả về kết quả rỗng hoặc lỗi). FTS5 vẫn hoạt động.</p>\n<h2>Khi Embeddings không khả dụng</h2>\n<p>Nếu dịch vụ embeddings không được cấu hình:</p>\n<ul>\n<li><code>GET /memory/semantic-search</code> trả về 503 Service Unavailable</li>\n<li><code>POST /memory</code> vẫn hoạt động (chỉ không có embedding được tạo)</li>\n<li>Tìm kiếm FTS5 vẫn hoạt động</li>\n</ul>\n<h2>Thực hành tốt nhất</h2>\n<div class=\"callout callout-ok\"></div><h2>Bước tiếp theo</h2>\n<ul>\n<li><a href=\"/docs/concepts/fts5-search\">Tìm kiếm FTS5</a></li>\n<li><a href=\"/docs/api/memory\">Memory API</a></li>\n<li><a href=\"/docs/concepts/architecture\">Kiến trúc</a></li>\n</ul>\n","urls":{"html":"/docs/concepts/semantic-search","text":"/docs/concepts/semantic-search?format=text","json":"/docs/concepts/semantic-search?format=json","llm":"/docs/concepts/semantic-search?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}