Embedding APIの選択

作成日:
embedding machine-learning AI vector-search semantic-search

概要

Embedding(埋め込み)は、テキストを数値ベクトルに変換する技術です。セマンティック検索やレコメンデーション、類似度計算などで使用されます。

Embedding APIには大きく分けて2つの選択肢があります:

選択肢概要
マネージドサービスOpenAI、Cohere、Google等のAPIを利用
セルフホストオープンソースモデルを自分のサーバーで実行

マネージドサービス

OpenAI Embeddings

最も広く使われているEmbedding API。高品質で多言語対応。

const response = await fetch('https://api.openai.com/v1/embeddings', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'text-embedding-3-small',
    input: 'Dockerはコンテナ仮想化のプラットフォームです',
  }),
})

const data = await response.json()
const embedding = data.data[0].embedding  // 1536次元のベクトル

利用可能なモデル:

モデル次元数価格(1Mトークン)特徴
text-embedding-3-small1536$0.02コスパ最良、十分な品質
text-embedding-3-large3072$0.13最高品質
text-embedding-ada-0021536$0.10旧モデル(互換性維持用)

推奨: 多くのユースケースでは text-embedding-3-small で十分。

Cohere Embed

多言語対応に優れたEmbedding API。

const response = await fetch('https://api.cohere.ai/v1/embed', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${COHERE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'embed-multilingual-v3.0',
    texts: ['Dockerはコンテナ仮想化のプラットフォームです'],
    input_type: 'search_document',  // または 'search_query'
  }),
})

利用可能なモデル:

モデル次元数価格(1Mトークン)特徴
embed-multilingual-v3.01024$0.10100+言語対応
embed-english-v3.01024$0.10英語特化

Voyage AI

検索用途に特化したEmbedding API。

モデル次元数特徴
voyage-large-21536高品質、検索向け
voyage-code-21536コード検索向け
voyage-multilingual-21024多言語対応

Google Vertex AI

Google CloudのEmbedding API。

モデル次元数特徴
text-embedding-005768多言語対応
text-multilingual-embedding-002768多言語特化

マネージドサービスの比較

観点OpenAICohereVoyage AIGoogle
品質
日本語
価格
導入の容易さ
ドキュメント

推奨: 日本語コンテンツには OpenAI text-embedding-3-small がコストパフォーマンス良好。

セルフホスト

自分のサーバーでEmbeddingモデルを実行する選択肢。

セルフホストの利点と欠点

利点:

  • APIコストが不要(大量処理時に有利)
  • データが外部に送信されない(プライバシー)
  • オフライン環境でも動作
  • レイテンシの制御が可能

欠点:

  • サーバーの運用コスト
  • GPUが必要な場合がある
  • モデル更新の管理が必要
  • 品質がマネージドに劣る場合がある

Sentence Transformers(Python)

最も広く使われているオープンソースのEmbeddingライブラリ。

from sentence_transformers import SentenceTransformer

# 多言語対応モデル(推奨)
model = SentenceTransformer('intfloat/multilingual-e5-large')

# 埋め込みを生成
texts = [
  'Dockerはコンテナ仮想化のプラットフォームです',
  'Kubernetesはコンテナオーケストレーションツールです',
]
embeddings = model.encode(texts)

print(embeddings.shape)  # (2, 1024)

推奨モデル:

モデル次元数サイズ特徴
intfloat/multilingual-e5-large10242.2GB多言語、高品質
intfloat/multilingual-e5-base7681.1GB多言語、バランス
intfloat/multilingual-e5-small384470MB多言語、軽量
sentence-transformers/all-MiniLM-L6-v238490MB英語、超軽量

Ollama

ローカルLLM実行環境。Embeddingにも対応。

# モデルをダウンロード
ollama pull nomic-embed-text

# REST APIで埋め込みを生成
curl http://localhost:11434/api/embeddings -d '{
  "model": "nomic-embed-text",
  "prompt": "Dockerはコンテナ仮想化のプラットフォームです"
}'

利用可能なEmbeddingモデル:

モデル次元数特徴
nomic-embed-text768軽量、汎用
mxbai-embed-large1024高品質
all-minilm384超軽量

Hugging Face TEI(Text Embeddings Inference)

本番環境向けの高性能Embeddingサーバー。

# Dockerで起動
docker run --gpus all -p 8080:80 \
  ghcr.io/huggingface/text-embeddings-inference:latest \
  --model-id intfloat/multilingual-e5-large

# REST APIで埋め込みを生成
curl http://localhost:8080/embed \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{"inputs": "Dockerはコンテナ仮想化のプラットフォームです"}'

特徴:

  • 高スループット
  • バッチ処理対応
  • GPU最適化
  • OpenAI互換API

FastEmbed

ONNX Runtimeを使用した軽量・高速なEmbeddingライブラリ。

from fastembed import TextEmbedding

# モデルを初期化(自動ダウンロード)
model = TextEmbedding('BAAI/bge-small-en-v1.5')

# 埋め込みを生成
documents = ['Dockerはコンテナ仮想化のプラットフォームです']
embeddings = list(model.embed(documents))

特徴:

  • CPUでも高速
  • 軽量(依存関係が少ない)
  • PyTorchなしで動作

マネージド vs セルフホストの判断基準

マネージドサービスが適しているケース

条件理由
記事数が少ない(〜数千件)APIコストが無視できるレベル
開発速度を優先インフラ構築が不要
品質を最優先最新の高品質モデルを使用可能
運用リソースが限られているサーバー管理が不要

セルフホストが適しているケース

条件理由
大量のデータ(数百万件以上)APIコストが膨大になる
プライバシー要件が厳しいデータを外部に送信できない
オフライン環境インターネット接続がない
低レイテンシが必須ネットワーク遅延を排除

コスト比較(目安)

前提: 1記事 ≈ 1,000トークン

データ量OpenAI APIセルフホスト(GPU)
100記事$0.002オーバーキル
1,000記事$0.02オーバーキル
10,000記事$0.20オーバーキル
100,000記事$2.00検討の余地あり
1,000,000記事$20.00セルフホスト有利

検索クエリのコスト(月間):

検索回数/月OpenAI API
1,000回約$0.001
10,000回約$0.01
100,000回約$0.10
1,000,000回約$1.00

中小規模のサイトでは、ほぼ無料に近いコストで運用可能

実装のヒント

1. 埋め込みのキャッシュ

同じテキストに対して何度もEmbeddingを生成しないよう、ハッシュベースでキャッシュ:

import crypto from 'crypto'

function hashText(text: string): string {
  return crypto.createHash('sha256').update(text).digest('hex')
}

async function getEmbedding(text: string) {
  const hash = hashText(text)
  
  // キャッシュをチェック
  const cached = await cache.get(hash)
  if (cached) return cached
  
  // APIを呼び出し
  const embedding = await generateEmbedding(text)
  
  // キャッシュに保存
  await cache.set(hash, embedding)
  return embedding
}

2. バッチ処理

複数のテキストをまとめて処理することでAPI呼び出し回数を削減:

// OpenAI APIはバッチ処理に対応
const response = await fetch('https://api.openai.com/v1/embeddings', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'text-embedding-3-small',
    input: [
      'テキスト1',
      'テキスト2',
      'テキスト3',
      // ... 最大2048個まで
    ],
  }),
})

3. テキストの前処理

埋め込みの品質を向上させるための前処理:

function preprocessText(text: string): string {
  return text
    // HTMLタグを除去
    .replace(/<[^>]*>/g, '')
    // 連続する空白を1つに
    .replace(/\s+/g, ' ')
    // トークン数を制限(OpenAIは8191トークンまで)
    .slice(0, 8000)
    .trim()
}

4. 検索クエリと文書の区別

一部のモデル(Cohere、E5など)は検索クエリと文書で異なる処理を推奨:

# E5モデルの場合
# 検索クエリには "query: " プレフィックス
query_text = "query: Dockerの使い方"

# 文書には "passage: " プレフィックス
document_text = "passage: Dockerはコンテナ仮想化のプラットフォームです..."

関連トピック

参考リンク