Abbeal

IA

Embeddings:その仕組みと企業向けRAGでの活用方法

ベクトル、意味的類似性、モデル選定、chunking、多言語対応の落とし穴(仏/日)。本番環境で機能するretrievalを構築するための実践ガイド。

10 min

初めてのRAGを構築し、LLMを社内ドキュメントに接続したものの、回答が的外れ。モデルが明らかにベースに存在する話題についてハルシネーションを起こしている。問題は?10回中9回、悪いのはLLMではなくretrievalだ。そしてretrievalの中核にあるのがembeddingsである。

Embeddingsは本番環境で稼働する全てのRAGの見えない背骨だ。ドキュメントをベクトルに変換し、意味的検索を可能にし、LLMのコンテキストに注入する内容の品質を左右する。設定を誤ると、チェーン全体が崩壊する。

このガイドでは、初めてのRAGを本番投入する前に知っておきたかったことをカバーする:embeddingsの背後にある直感、モデルの選び方、ドキュメントの分割方法、多言語対応(すべてを壊す日本語を含む)、そして何より、砂上の楼閣を建てていないかを評価する方法。

Embeddingとは具体的に何か?

Embeddingとは、テキストの一部の意味を表現する数値のベクトル(通常768〜3072次元)だ。意味的に近い2つの文は、単語を共有していなくても、ベクトル空間で近くに配置される。

例:「契約を解約するには?」と「サブスクリプション解除手順」は共通する単語がほぼないが、それらのembeddingsは近接する。これにより、ユーザーが質問を異なる方法で表現しても、RAGが正しいドキュメントを取得できる。

技術的には、embeddingモデルはテキストをこのベクトル空間に投影するよう訓練されたニューラルネットワーク(多くの場合transformer)だ。全てのドキュメントchunksに対して一度実行し(インデックス化)、その後各ユーザークエリで質問をエンコードし、コサイン類似度で最も近いchunksを検索する。

Embeddingモデルの選択:次元数、ドメイン、コスト

次元数が多い ≠ 自動的に優れている

MTEBリーダーボードで最も次元数の多いモデルを選ぶ誘惑は強い。実際には、決定する前に常に実際のビジネス質問で2-3モデルをベンチマークする。

あなたのドメイン(法律、医療、技術)に適した1024次元モデルは、汎用3072次元モデルを定期的に上回る。そしてインフラコストは無視できない:

  • ストレージ:3倍の次元数 = vector DBで3倍のストレージ
  • RAM:HNSWインデックスは全てをメモリにロードする;1000万chunksでは重要
  • レイテンシ:3072次元での類似度計算は遅く、特に大規模では顕著

検討すべきモデル(2024年末時点)

本番環境で使用している、ユースケース別のいくつかの選択肢:

  • text-embedding-3-large / text-embedding-3-small (OpenAI):堅実、多言語対応、managed API。オープンソースではなく、トークン課金。
  • intfloat/e5-mistral-7b-instruct:オープンソース、4096次元、複雑なタスクで優秀。self-hostは重い。
  • sentence-transformers/all-MiniLM-L6-v2:軽量(384次元)、高速、多くのシンプルな英語ケースに十分。
  • multilingual-e5-large:1024次元、真の多言語対応(日本語含む)、性能/コストの良いバランス。

切り詰めなしで実質的なchunksをembedできるよう、context window >= 512トークンのモデルを優先する。

Self-host vs managed API

OpenAI embeddings:シンプル、インフラ管理不要、予測可能な価格設定。ただしデータが外部に出て、rate limits/ダウンタイムに晒される。

Self-host (HuggingFace + vLLM / TEI):完全なコントロール、インフラ支払い後は固定コスト、データ漏洩なし。ただしスケーリング、モニタリング、バージョン管理を自前で行う。大量(10万クエリ/日以上)では、self-hostが採算に合う。

Chunking:意味を壊さずに分割する

Chunkingは我々が監査するRAGの90%のアキレス腱だ。Embeddingはchunk内にあるものしかエンコードしない。文を2つに切ったり、概念が3つの分断されたchunksに跨っていれば、retrievalは失敗する。

Chunking戦略

  1. Fixed-size + overlap:512トークンのchunksに50トークンのoverlap。シンプル、汎用的、技術ドキュメントには十分なことが多い。
  2. Semantic chunking:トピックの遷移(連続するembeddingsが乖離)を検出して分割。より綺麗だが、インデックス化が遅い。
  3. Structure-aware:markdown境界(headers、lists)、PDFセクション、段落を尊重。階層的コンテキストを保持。
  4. Hybrid:文境界へのフォールバック付きfixed-size。速度/品質の妥協点。

実際には、fixed-size + overlapから始め、recallを測定し、必要に応じて反復する。構造化されたコーパス(社内wiki、技術ドキュメント)では、structure-awareが明確な利得をもたらす。

Overlapとコンテキスト

Overlapは、2つに分割された文が決して取得されない事態を避ける。chunk サイズの10-20%が良い出発点だ。過度のoverlap = chunksの数の爆発 = ストレージ/レイテンシコスト。

また、embeddingが「このchunkは請求について、サポートではない」を捉えられるよう、chunk内に親コンテキスト(セクションタイトル、ドキュメント名)を追加することが多い。単純なプレフィックスで可能:[請求] <chunkのコンテンツ>

Vector databases:ストレージと検索

Embeddingsを計算したら、それらを保存し、<50msでコサイン類似度によりクエリできる必要がある。これがvector DBの仕事だ。

どのvector DBを使うか?

選択肢は増えている。コンテキストに応じて使用しているものは以下:

  • pgvector (Postgres):Postgres拡張、既にPostgresがあれば完璧、リレーショナルメタデータ + ベクトルが同じDB内。〜100万ベクトルまで問題なくスケール。
  • Qdrant:オープンソース、高速、self-hostが容易(Docker)、豊富なフィルタ、良好なモニタリング。self-hostのデフォルト選択。
  • Pinecone / Weaviate cloud:managed、自動スケール、良好なDX。保存ベクトル + クエリ課金、すぐに高額になりうる。
  • Milvus:非常にスケーラブル(clusters)、1000万ベクトル未満ではオーバースペック、数億を目指す場合に有用。

企業向けRAGの80%(500万chunks未満)では、pgvectorまたはQdrantで十分だ。

HNSWインデックスとフィルタ

主流の検索アルゴリズムはHNSW (Hierarchical Navigable Small World)だ。log(n)時間での近似検索のため多層グラフを構築する。ef_constructionef_searchで精度/速度のトレードオフを設定可能。

本番環境では、ベクトル類似性 + メタデータフィルタを組み合わせることが多い:「財務部門のドキュメント、フランス語、1年以内」でretrieval。Vector DBはパフォーマンスを殺さずにこれらのフィルタをサポートする必要がある(DBに応じてpre-filteringまたはpost-filtering)。

多言語対応:仏、英、日…そして日本語の落とし穴

多言語コーパスは、英語中心のRAGパイプラインの暗黙の前提の多くを破壊する。

多言語embeddingモデル

対象言語で訓練された真の多言語モデルが必要だ。英語中心モデルは、フランス語を劣化したサブスペースに投影することが多く、日本語は…さらに悪い。

言語横断retrievalを常に検証する:フランス語の質問が、それが正しいコンテキストであれば英語ドキュメントを取得できるべきだ。一部のモデルは言語間でベクトル空間を正しく整列しない。

日本語が全てを壊す

日本語にはスペースがなく、byte-levelのtokenizer(GPT型)は過度にセグメント化し、文ごとのchunking戦略には専用のセグメンタが必要(信頼できる終止符がない)。

  • Tokenizer:適応されたtokenizerを持つモデルを使用(SentencePiece多言語、または日本語tokenizer統合)。
  • Chunking:文境界を検出するためfugashisudachipyのようなsplitterを使用。
  • Overlap:日本語ではより重要、複合語の途中で切ると意味が破壊される。

仏/英/日コーパスの最近のプロジェクトで、text-embedding-ada-002(日本語性能が平凡)からmultilingual-e5-large + 言語別カスタムchunkingに移行する必要があった。日本語質問のrecall@5は45%から78%に向上した。

Retrievalの品質を評価する

Embeddingは絶対的に良いか悪いかではない。それが可能にするretrievalの品質を測定する。評価なしでは、2つのモデル、2つのchunking戦略を比較したり、変更後の回帰を検出することは不可能だ。

Retrieval指標

  • Recall@k:返されたトップk chunksのうち、正解を含む割合は?Recall@5が標準。
  • MRR (Mean Reciprocal Rank):平均して、最初の正しいchunkは何位に現れるか?高いほど良い。
  • NDCG:結果の順序を考慮、段階的な関連性(関連/非常に関連)がある場合に有用。

Recall@5 + MRRを好む:POに理解しやすく、技術的選択肢を判断するのに十分な識別力がある。

評価セットの構築

評価セットは、50-200ペアの(質問、期待されるchunks参照)だ。実際のユーザー質問(サポートログ、FAQ、ユーザーリサーチ)から始めて、ビジネス専門家と共に構築する。

最小フォーマット:CSV 質問 | doc_id | chunk_id | 言語。各質問をretrievalに通し、期待されるchunksがtop-kに含まれるかを測定する。

py
# 簡略化されたrecall@k評価例 def evaluate_recall(questions, vector_db, k=5): hits = 0 for q in questions: results = vector_db.search(q['text'], top_k=k) retrieved_ids = [r['chunk_id'] for r in results] if q['expected_chunk_id'] in retrieved_ids: hits += 1 return hits / len(questions)

Embeddingモデル、chunking戦略、コーパス更新の各変更時にCIでこの評価を実行する。Recallの>5ポイントの回帰 = アラート。

典型的な落とし穴と現場からのフィードバック

メタデータをembeddingする…それともしない?

タイトル、著者、日付をembeddingされるテキストに追加する人もいる。利点:embeddingが「このchunkはHRについて」を捉える。欠点:メタデータが反復的または非意味的(技術ID)な場合の汚染。

メタデータを別途保存し、vector DBのフィルタを使用することを好む。Embeddingは純粋に意味的なまま、部門/言語/日付で後からフィルタリング。

Reranking:第2パス

Vector retrievalは〜20-50候補を高速に返す。その後reranker(cross-encoder)を適用し、各(質問、chunk)を細かくスコアリングしてtop-5を保持できる。

Rerankerは遅いがより正確。複雑な質問でMRRを10-20%改善する。モデル:cross-encoder/ms-marco-MiniLMjina-reranker-v1、またはCohere Rerank API経由。

コーパスのドリフトとembeddingsのリフレッシュ

コーパスは進化する(新しいドキュメント、更新)。変更されたchunksを再embeddingする必要がある。doc_id + コンテンツハッシュを追跡し、フル再インデックスではなく差分で再インデックス化する。

注意:embeddingモデル変更 = 全コーパスの再インデックス化。2つのモデルのベクトルは同じ空間に存在せず、混在できない。

コストとサイジング

100万chunks(512トークン/chunk、embedding 1024次元)のコーパスでのいくつかの目安:

  • ワンショットインデックス化:GPU V100で〜4-8時間(self-host)またはOpenAI embeddings APIで〜50-100ドル。
  • Vector DBストレージ:RAM〜4-6 GB(HNSWインデックス)、ディスク〜2-3 GB(Qdrant)。
  • Retrieval latency:標準インフラ(16 vCPU、32 GB RAM)でtop-20を<30ms @ p95。

1000万chunksへのスケール:QdrantまたはMilvusクラスタに移行、sharding付き。インデックスが分散RAMに収まればlatencyは<50msのまま。

実際、RAGは80%がretrieval

最終的なLLMは、retrievalが提供するものを再定式化するだけだ。返されたchunksが話題外なら、GPT-4でもハルシネーションを起こす。堅牢なretrieval(適応されたembeddings、綺麗なchunking、継続的評価)が、デモで印象を与えるPOCと、負荷とエッジケース下で本番で耐えるシステムの違いだ。

Abbealでは、要求の厳しい環境向けにRAGを構築している:多言語、大規模コーパス、厳しいレイテンシ、データコンプライアンス。RAGをスケールしていてretrievalや多言語chunking、継続的評価の落とし穴に直面しているなら、[相談しましょう](https://abbeal.com/contact)。我々は既にあなたの代わりに失敗を経験済みだ。

似たような案件がありますか?

アーキテクトと話す