{"title":"セマンティック検索（埋め込み）","slug":"semantic-search","category":"concepts","summary":"ベクトル埋め込みを使用した概念メモリ検索 — キーワードだけでなく意味で検索。","audience":["human","llm"],"tags":["concept","semantic","embeddings","vector-search"],"difficulty":"advanced","updated":"2026-06-27","word_count":211,"read_minutes":1,"lang":"ja","translated":true,"requested_lang":"ja","content_markdown":"\n# セマンティック検索（埋め込み）\n\nSynapse はベクトル埋め込みを使用したセマンティック検索をサポートしています。FTS5（キーワードマッチング）とは異なり、セマンティック検索はキーワードが一致しなくても**意味**でメモリを検索します。\n\n## 仕組み\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### 埋め込みとは？\n\n埋め込みはテキストの数値ベクトル表現です。類似する意味のテキストは類似するベクトルを持ちます。Synapse は各メモリのコンテンツに対しベクトル（例：1536 次元）を生成します。\n\n### コサイン類似度\n\n意味的に類似するメモリを見つけるため、Synapse はクエリベクトルと各メモリベクトルのコサイン類似度を計算します。類似度が高い = より関連性が高い。\n\n## セマンティック検索を使うべき場面\n\n### セマンティック検索が適している場合：\n\n- X が保存されている表現と異なる形で記述されている「X に関するメモリ」を探したい\n- FTS5 が結果を返さない（キーワードが一致しない）\n- 概念的グループ化が欲しい（例：一部が「release」と言っている場合でも、すべての「deployment」メモリ）\n- クエリが質問の場合：「認証はどう処理していますか？」\n\n### FTS5 が適している場合：\n\n- 正確なキーワードが分かっている\n- ブールロジック（AND、OR、NOT）が必要\n- サブミリ秒の応答が必要\n- フレーズマッチングが欲しい\n\n## エンドポイント\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\nレスポンス：\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## 例\n\n### デプロイメントメモリの検索\n\n```bash\n# FTS5 might miss some — semantic catches all\ncurl .../memory/semantic-search?q=deployment+process\n```\n\n「deployment」「release」「publishing」「rolling out」などに関するメモリを返します。\n\n### 認証パターンの検索\n\n```bash\ncurl .../memory/semantic-search?q=how+do+users+log+in\n```\n\nlogin、auth、JWT、セッション管理、OAuth などに関するメモリを返します。\n\n### 類似メモリの検索\n\n```bash\n# Find memories similar to a specific one\ncurl .../memory/related/mem_001\n```\n\nセマンティック類似度（共通タグと埋め込みベクトルの両方）を使用します。\n\n## 埋め込みの生成\n\n### 埋め込みはいつ生成されるか？\n\n- **メモリ保存時** — 埋め込みサービスが構成されていれば、同期的に生成\n- **バッチ生成** — `POST /memory/embed-batch` が埋め込みを持たないメモリに対して生成\n- **非同期更新** — コンテンツ更新時に埋め込みを再生成\n\n### 埋め込みプロバイダー\n\nSynapse は構成可能な埋め込みプロバイダーをサポートします。\n\n- **OpenAI**（`text-embedding-3-small`、`text-embedding-3-large`）\n- **ローカルモデル**（Ollama 経由など）\n- **カスタム**（embeddings インターフェースを実装）\n\n環境変数で構成：\n\n```bash\nEMBEDDINGS_PROVIDER=openai\nEMBEDDINGS_API_KEY=sk-...\nEMBEDDINGS_MODEL=text-embedding-3-small\n```\n\n### バッチ生成\n\n埋め込みが欠落しているメモリが多数ある mind の場合：\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## パフォーマンス\n\n| 操作 | レイテンシ |\n|-----------|---------|\n| 埋め込み生成（OpenAI） | 100〜200ms |\n| セマンティック検索（1k メモリ） | 50〜100ms |\n| セマンティック検索（10k メモリ） | 200〜500ms |\n| バッチ生成（100 メモリ） | 10〜20s |\n\n> [!NOTE]\n> セマンティック検索はベクトル計算のため FTS5 より遅くなります。既知のキーワードには FTS5 を、概念的クエリにはセマンティックを使用してください。\n\n## 制限事項\n\n### 埋め込みのコスト\n\nOpenAI を使用する場合、埋め込み生成にはコストがかかります（text-embedding-3-small で 100 万トークンあたり約 $0.02）。平均 100 トークンのメモリ 10,000 件で約 $0.02 — 無視できる程度です。\n\n### コールドスタート\n\n埋め込みが構成される前に保存されたメモリには埋め込みがありません。`POST /memory/embed-batch` を実行してバックフィルしてください。\n\n### プロバイダー依存\n\n埋め込みプロバイダーがダウンした場合、セマンティック検索は graceful に失敗します（空の結果またはエラーを返す）。FTS5 は引き続き動作します。\n\n## 埋め込みが利用できない場合\n\n埋め込みサービスが構成されていない場合：\n\n- `GET /memory/semantic-search` は 503 Service Unavailable を返す\n- `POST /memory` は引き続き動作（埋め込みは生成されないだけ）\n- FTS5 検索は引き続き動作\n\n## ベストプラクティス\n\n> [!TIP]\n> - **概念的クエリにはセマンティックを使用** — 「X をどう処理するか？」\n> - **特定の用語には FTS5 を使用** — 「docker swarm」\n> - **定期的に埋め込みをバックフィル** — `POST /memory/embed-batch`\n> - **プロバイダーの健全性を監視** — セマンティック検索はそれに依存\n> - **タグと組み合わせ** — セマンティック + タグフィルタで結果を絞り込み\n\n## 次のステップ\n\n- [FTS5 Search](/docs/concepts/fts5-search)\n- [Memory API](/docs/api/memory)\n- [Architecture](/docs/concepts/architecture)\n","content_html":"<h1>セマンティック検索（埋め込み）</h1>\n<p>Synapse はベクトル埋め込みを使用したセマンティック検索をサポートしています。FTS5（キーワードマッチング）とは異なり、セマンティック検索はキーワードが一致しなくても<strong>意味</strong>でメモリを検索します。</p>\n<h2>仕組み</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>埋め込みとは？</h3>\n<p>埋め込みはテキストの数値ベクトル表現です。類似する意味のテキストは類似するベクトルを持ちます。Synapse は各メモリのコンテンツに対しベクトル（例：1536 次元）を生成します。</p>\n<h3>コサイン類似度</h3>\n<p>意味的に類似するメモリを見つけるため、Synapse はクエリベクトルと各メモリベクトルのコサイン類似度を計算します。類似度が高い = より関連性が高い。</p>\n<h2>セマンティック検索を使うべき場面</h2>\n<h3>セマンティック検索が適している場合：</h3>\n<ul>\n<li>X が保存されている表現と異なる形で記述されている「X に関するメモリ」を探したい</li>\n<li>FTS5 が結果を返さない（キーワードが一致しない）</li>\n<li>概念的グループ化が欲しい（例：一部が「release」と言っている場合でも、すべての「deployment」メモリ）</li>\n<li>クエリが質問の場合：「認証はどう処理していますか？」</li>\n</ul>\n<h3>FTS5 が適している場合：</h3>\n<ul>\n<li>正確なキーワードが分かっている</li>\n<li>ブールロジック（AND、OR、NOT）が必要</li>\n<li>サブミリ秒の応答が必要</li>\n<li>フレーズマッチングが欲しい</li>\n</ul>\n<h2>エンドポイント</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>レスポンス：</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>例</h2>\n<h3>デプロイメントメモリの検索</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>「deployment」「release」「publishing」「rolling out」などに関するメモリを返します。</p>\n<h3>認証パターンの検索</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>login、auth、JWT、セッション管理、OAuth などに関するメモリを返します。</p>\n<h3>類似メモリの検索</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>セマンティック類似度（共通タグと埋め込みベクトルの両方）を使用します。</p>\n<h2>埋め込みの生成</h2>\n<h3>埋め込みはいつ生成されるか？</h3>\n<ul>\n<li><strong>メモリ保存時</strong> — 埋め込みサービスが構成されていれば、同期的に生成</li>\n<li><strong>バッチ生成</strong> — <code>POST /memory/embed-batch</code> が埋め込みを持たないメモリに対して生成</li>\n<li><strong>非同期更新</strong> — コンテンツ更新時に埋め込みを再生成</li>\n</ul>\n<h3>埋め込みプロバイダー</h3>\n<p>Synapse は構成可能な埋め込みプロバイダーをサポートします。</p>\n<ul>\n<li><strong>OpenAI</strong>（<code>text-embedding-3-small</code>、<code>text-embedding-3-large</code>）</li>\n<li><strong>ローカルモデル</strong>（Ollama 経由など）</li>\n<li><strong>カスタム</strong>（embeddings インターフェースを実装）</li>\n</ul>\n<p>環境変数で構成：</p>\n<pre><code class=\"hljs language-bash\">EMBEDDINGS_PROVIDER=openai\nEMBEDDINGS_API_KEY=sk-...\nEMBEDDINGS_MODEL=text-embedding-3-small</code></pre><h3>バッチ生成</h3>\n<p>埋め込みが欠落しているメモリが多数ある mind の場合：</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>パフォーマンス</h2>\n<table>\n<thead>\n<tr>\n<th>操作</th>\n<th>レイテンシ</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>埋め込み生成（OpenAI）</td>\n<td>100〜200ms</td>\n</tr>\n<tr>\n<td>セマンティック検索（1k メモリ）</td>\n<td>50〜100ms</td>\n</tr>\n<tr>\n<td>セマンティック検索（10k メモリ）</td>\n<td>200〜500ms</td>\n</tr>\n<tr>\n<td>バッチ生成（100 メモリ）</td>\n<td>10〜20s</td>\n</tr>\n</tbody></table>\n<div class=\"callout callout-note\">セマンティック検索はベクトル計算のため FTS5 より遅くなります。既知のキーワードには FTS5 を、概念的クエリにはセマンティックを使用してください。</div><h2>制限事項</h2>\n<h3>埋め込みのコスト</h3>\n<p>OpenAI を使用する場合、埋め込み生成にはコストがかかります（text-embedding-3-small で 100 万トークンあたり約 $0.02）。平均 100 トークンのメモリ 10,000 件で約 $0.02 — 無視できる程度です。</p>\n<h3>コールドスタート</h3>\n<p>埋め込みが構成される前に保存されたメモリには埋め込みがありません。<code>POST /memory/embed-batch</code> を実行してバックフィルしてください。</p>\n<h3>プロバイダー依存</h3>\n<p>埋め込みプロバイダーがダウンした場合、セマンティック検索は graceful に失敗します（空の結果またはエラーを返す）。FTS5 は引き続き動作します。</p>\n<h2>埋め込みが利用できない場合</h2>\n<p>埋め込みサービスが構成されていない場合：</p>\n<ul>\n<li><code>GET /memory/semantic-search</code> は 503 Service Unavailable を返す</li>\n<li><code>POST /memory</code> は引き続き動作（埋め込みは生成されないだけ）</li>\n<li>FTS5 検索は引き続き動作</li>\n</ul>\n<h2>ベストプラクティス</h2>\n<div class=\"callout callout-ok\"></div><h2>次のステップ</h2>\n<ul>\n<li><a href=\"/docs/concepts/fts5-search\">FTS5 Search</a></li>\n<li><a href=\"/docs/api/memory\">Memory API</a></li>\n<li><a href=\"/docs/concepts/architecture\">Architecture</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"]}