Claudeでの埋め込み(Embeddings)

Claude API エンジニアリング 8分で読めます

テキスト埋め込み(embeddings)は、テキストを数値のベクトルとして表現し、意味的な近さを測れるようにするものです。この記事では、Anthropicが埋め込みをどう扱っているか、そして公式ドキュメントが案内している実装手順を解説します。

埋め込みとは

埋め込みは、テキストを数値のベクトルへ変換したものです。意味の近いテキストどうしはベクトル空間上でも近くに配置されるため、この距離を測ることで「意味が似ているか」を機械的に判定できます。

用途としては、検索(クエリに意味的に近い文書を取り出す)、推薦、異常検知などが挙げられます。RAG(検索拡張生成)で、質問に関連する文書を取り出してからClaudeに渡す、という構成もこの応用です。

埋め込みの提供元を選ぶときの観点として、公式ドキュメントは3つを挙げています。1つ目はデータセットの規模とドメイン適合性で、学習データが大きいほど、あるいは対象ドメインに近いほど、そのドメインでの埋め込み品質は上がります。2つ目は推論性能で、埋め込みの取得速度と全体のレイテンシです。大規模な本番運用ではとくに重要になります。3つ目はカスタマイズ性で、非公開データでの継続学習や、特定ドメインへの特化ができるかどうかです。独自の語彙を扱う場合に効いてきます。

Anthropicでの埋め込みの扱い

ここが最初に押さえるべき点です。Anthropicは自社の埋め込みモデルを提供していません。

Claude APIには埋め込みのエンドポイントがなく、埋め込みが必要な場合は外部のプロバイダを使うことになります。公式ドキュメントは、前述の3つの観点をすべて満たす選択肢の1つとしてVoyage AIを挙げ、以降の解説をVoyage AI向けに書いています。Voyage AIは金融や医療といった業界ドメイン向けのカスタムモデルや、個別顧客向けのファインチューンモデルを提供しています。

ただし公式ドキュメント自身が、「自分のユースケースに最も合うものを見つけるために、複数の埋め込みベンダーを評価すべきである」と明記しています。Voyage AIが唯一の選択肢として案内されているわけではない、という点は読み違えないようにしてください。

利用できるモデル

Voyageが推奨するテキスト埋め込みモデルは、最新世代のVoyage 4系です。いずれもコンテキスト長は32,000、埋め込み次元は既定1024で、256・512・2048も選べます。

前世代にはvoyage-3-largevoyage-3.5voyage-3.5-liteがあり、ドメイン特化としてvoyage-code-3(コード検索)、voyage-finance-2(金融)、voyage-law-2(法務・長文、コンテキスト長16,000)が用意されています。

マルチモーダル用にはvoyage-multimodal-3.5(テキスト・画像・動画を混在したままベクトル化。動画対応)とvoyage-multimodal-3(テキストと情報量の多い画像)があります。

また、チャンク単位のベクトルに文書全体の文脈を持たせる「文脈化チャンク埋め込み」としてvoyage-context-4voyage-context-3があります。いずれもコンテキスト長は120,000で、呼び出しはembed()ではなくcontextualized_embed()を使います。

さらに、クエリと文書リストを受け取って関連度順に並べ替えるリランカーとしてrerank-2.5(精度重視・多くの用途で推奨)とrerank-2.5-lite(レイテンシとコスト重視)があり、こちらはrerank()で呼び出します。

実装のクイックスタート

Voyage AIのサイトで登録し、APIキーを取得したら、環境変数に設定しておきます。

export VOYAGE_API_KEY="<your secret key>"

Pythonパッケージを使う場合は次のようになります。

pip install -U voyageai
import voyageai

vo = voyageai.Client()
# 環境変数 VOYAGE_API_KEY を自動的に使います

texts = ["Sample text 1", "Sample text 2"]

result = vo.embed(texts, model="voyage-4", input_type="document")
print(result.embeddings[0])

HTTP APIを直接叩くこともできます。

curl https://api.voyageai.com/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VOYAGE_API_KEY" \
  -d '{"input": ["Sample text 1", "Sample text 2"], "model": "voyage-4"}'

検索に使う場合の流れは、文書をベクトル化しておき、クエリもベクトル化して最近傍を探す、というものです。

import numpy as np

doc_embds = vo.embed(documents, model="voyage-4", input_type="document").embeddings
query_embd = vo.embed([query], model="voyage-4", input_type="query").embeddings[0]

# Voyageの埋め込みは長さ1に正規化されているため、内積とコサイン類似度は一致します
similarities = np.dot(doc_embds, query_embd)
retrieved_id = np.argmax(similarities)
print(documents[retrieved_id])

ここで重要なのがinput_typeです。検索用途では、文書にはinput_type="document"、クエリにはinput_type="query"を必ず指定してください。公式ドキュメントは「省略したりNoneにしたりしてはならない」と明記しています。指定すると内部で専用のプロンプトが先頭に付加され、検索向けのベクトル表現が良くなるためです。

選定と運用の注意点

類似度関数については、内積・コサイン類似度・ユークリッド距離のいずれも使えます。Voyage AIの埋め込みは長さ1に正規化されているため、コサイン類似度は内積と等価であり、内積のほうが高速に計算できます。またコサイン類似度とユークリッド距離は同じ順位を返します。実装では内積を使うのが素直です。

保存コストが問題になる場合は量子化を検討できます。output_dtypeで出力の型を指定でき、既定のfloat(32ビット単精度)に対して、int8uint8で4分の1、binaryubinaryで32分の1までストレージとメモリを削減できます。当然ながら精度と検索の正確さはfloatが最も高く、量子化はトレードオフです。

次元数を減らす手もあります。複数の出力次元に対応するモデルはMatryoshka学習によって、1つのベクトルの中に粗い表現から細かい表現までを含んでいます。そのため先頭側の次元だけを残して切り詰めることができ、切り詰めた後に正規化し直せば使えます。1024次元を256次元へ落とす、といった調整が可能です。

モデル選定の指針は、汎用なら品質重視でvoyage-4-large、レイテンシとコスト重視でvoyage-4-lite、バランス型でvoyage-4です。法務ならvoyage-law-2、コードやプログラミング文書ならvoyage-code-3、金融ならvoyage-finance-2、チャンク単位と文書単位の両方の検索が要るならvoyage-context-4が挙げられています。

料金は変動するため、Voyageの料金ページで最新をご確認ください。この記事は公式ドキュメントに基づく非公式の日本語解説です。仕様は更新されることがあるため、実装前に公式ドキュメントで最新の内容をご確認ください。