Skip to main content

セマンティック検索(埋め込み)

ベクトル埋め込みを使用した概念メモリ検索 — キーワードだけでなく意味で検索。


セマンティック検索(埋め込み)

Synapse はベクトル埋め込みを使用したセマンティック検索をサポートしています。FTS5(キーワードマッチング)とは異なり、セマンティック検索はキーワードが一致しなくても意味でメモリを検索します。

仕組み

1. Memory stored → embedding generated → vector stored
2. Search query → embedding generated → vector compared
3. Cosine similarity → top N results returned

埋め込みとは?

埋め込みはテキストの数値ベクトル表現です。類似する意味のテキストは類似するベクトルを持ちます。Synapse は各メモリのコンテンツに対しベクトル(例:1536 次元)を生成します。

コサイン類似度

意味的に類似するメモリを見つけるため、Synapse はクエリベクトルと各メモリベクトルのコサイン類似度を計算します。類似度が高い = より関連性が高い。

セマンティック検索を使うべき場面

セマンティック検索が適している場合:

  • X が保存されている表現と異なる形で記述されている「X に関するメモリ」を探したい
  • FTS5 が結果を返さない(キーワードが一致しない)
  • 概念的グループ化が欲しい(例:一部が「release」と言っている場合でも、すべての「deployment」メモリ)
  • クエリが質問の場合:「認証はどう処理していますか?」

FTS5 が適している場合:

  • 正確なキーワードが分かっている
  • ブールロジック(AND、OR、NOT)が必要
  • サブミリ秒の応答が必要
  • フレーズマッチングが欲しい

エンドポイント

GET /memory/semantic-search

curl -H "Authorization: Bearer YOUR_MIND_KEY" \
     "https://synapse.schaefer.zone/memory/semantic-search?q=container+orchestration"

レスポンス:

{
  "results": [
    {
      "id": "mem_001",
      "category": "project",
      "key": "project_synapse_deployment",
      "content": "Synapse deployed using Docker Swarm on vps1...",
      "tags": ["docker", "swarm", "deployment"],
      "similarity": 0.89
    },
    {
      "id": "mem_042",
      "category": "fact",
      "key": "kubernetes_cluster",
      "content": "We use Kubernetes for production orchestration...",
      "tags": ["kubernetes", "orchestration"],
      "similarity": 0.84
    }
  ]
}

デプロイメントメモリの検索

# FTS5 might miss some — semantic catches all
curl .../memory/semantic-search?q=deployment+process

「deployment」「release」「publishing」「rolling out」などに関するメモリを返します。

認証パターンの検索

curl .../memory/semantic-search?q=how+do+users+log+in

login、auth、JWT、セッション管理、OAuth などに関するメモリを返します。

類似メモリの検索

# Find memories similar to a specific one
curl .../memory/related/mem_001

セマンティック類似度(共通タグと埋め込みベクトルの両方)を使用します。

埋め込みの生成

埋め込みはいつ生成されるか?

  • メモリ保存時 — 埋め込みサービスが構成されていれば、同期的に生成
  • バッチ生成POST /memory/embed-batch が埋め込みを持たないメモリに対して生成
  • 非同期更新 — コンテンツ更新時に埋め込みを再生成

埋め込みプロバイダー

Synapse は構成可能な埋め込みプロバイダーをサポートします。

  • OpenAItext-embedding-3-smalltext-embedding-3-large
  • ローカルモデル(Ollama 経由など)
  • カスタム(embeddings インターフェースを実装)

環境変数で構成:

EMBEDDINGS_PROVIDER=openai
EMBEDDINGS_API_KEY=sk-...
EMBEDDINGS_MODEL=text-embedding-3-small

バッチ生成

埋め込みが欠落しているメモリが多数ある mind の場合:

# Generate embeddings for up to 100 memories
curl -X POST https://synapse.schaefer.zone/memory/embed-batch \
  -H "Authorization: Bearer YOUR_MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"limit": 100}'

# Check progress
curl -H "Authorization: Bearer YOUR_MIND_KEY" \
     https://synapse.schaefer.zone/memory/embed-batch-status

パフォーマンス

操作 レイテンシ
埋め込み生成(OpenAI) 100〜200ms
セマンティック検索(1k メモリ) 50〜100ms
セマンティック検索(10k メモリ) 200〜500ms
バッチ生成(100 メモリ) 10〜20s
セマンティック検索はベクトル計算のため FTS5 より遅くなります。既知のキーワードには FTS5 を、概念的クエリにはセマンティックを使用してください。

制限事項

埋め込みのコスト

OpenAI を使用する場合、埋め込み生成にはコストがかかります(text-embedding-3-small で 100 万トークンあたり約 $0.02)。平均 100 トークンのメモリ 10,000 件で約 $0.02 — 無視できる程度です。

コールドスタート

埋め込みが構成される前に保存されたメモリには埋め込みがありません。POST /memory/embed-batch を実行してバックフィルしてください。

プロバイダー依存

埋め込みプロバイダーがダウンした場合、セマンティック検索は graceful に失敗します(空の結果またはエラーを返す)。FTS5 は引き続き動作します。

埋め込みが利用できない場合

埋め込みサービスが構成されていない場合:

  • GET /memory/semantic-search は 503 Service Unavailable を返す
  • POST /memory は引き続き動作(埋め込みは生成されないだけ)
  • FTS5 検索は引き続き動作

ベストプラクティス

次のステップ