はじめに
ruri-v3は cl-nagoya チームが開発した日本語特化の埋め込みモデルで、JMTEB ランキングでも上位水準です。RAG(Retrieval-Augmented Generation)で活躍するこのモデルですが、プレフィックスルールを忘れると検索精度が激減します。
エラーにならないから気づきにくい、この落とし穴について解説します。
ruri-v3 のプレフィックスルール
ruri-v3 を使う際の必須ルール:
-
クエリ埋め込み時:
"クエリ: "プレフィックスを付ける -
ドキュメント埋め込み時:
"文章: "プレフィックスを付ける
このプレフィックスがないと、ベクトル空間での距離計算がズレます。
実装例(完全版)
from sentence_transformers import SentenceTransformer
# ruri-v3-310m を読み込み
model = SentenceTransformer("cl-nagoya/ruri-v3-310m")
# ❌ NG: プレフィックスなし(エラーにはならないが精度が下がる)
query_embedding_wrong = model.encode("褥瘡の処置手順を教えてください")
# ✅ OK: クエリには「クエリ: 」プレフィックスを付ける
query_embedding = model.encode("クエリ: 褥瘡の処置手順を教えてください")
# ✅ OK: ドキュメント登録時には「文章: 」プレフィックスを付ける
doc_embedding = model.encode("文章: 褥瘡(床ずれ)の処置手順は以下の通りです...")
# バッチ処理の場合
queries = ["クエリ: " + q for q in query_list]
docs = ["文章: " + d for d in doc_list]
query_embeddings = model.encode(queries)
doc_embeddings = model.encode(docs)
精度の落ちを確認する
プレフィックスありとなしで、コサイン類似度を比較してみましょう:
from sklearn.metrics.pairwise import cosine_similarity
# プレフィックスなしのクエリ
q_no_prefix = model.encode("褥瘡の処置手順を教えてください")
# プレフィックス付きのクエリ
q_with_prefix = model.encode("クエリ: 褥瘡の処置手順を教えてください")
# ドキュメント(プレフィックス付き)
doc = model.encode("文章: 褥瘡(床ずれ)の処置手順について説明します")
# 類似度を計算
sim_without = cosine_similarity([q_no_prefix], [doc])[0][0]
sim_with = cosine_similarity([q_with_prefix], [doc])[0][0]
print(f"プレフィックスなし: {sim_without:.4f}") # 低い値
print(f"プレフィックスあり: {sim_with:.4f}") # 高い値(正しい)
実際に実行すると、プレフィックス付きの方が明らかに高い類似度が得られます。
実装時の注意点
- プレフィックスは ruri-v3 の公式仕様 — HuggingFace のモデルカードに明記されています
- ruri-v3 専用 — multilingual-e5 など他のモデルには不要(むしろ邪魔になる可能性)
- 既存ベクトルDB の再埋め込み — Qdrant など既に登録済みのドキュメントも、プレフィックス付きで再埋め込みが必要
- 検索時も統一 — クエリもドキュメントも同じルールで埋め込み、同じプレフィックスで統一する
環境
- Python 3.10+
- sentence-transformers 3.x
- cl-nagoya/ruri-v3-310m
参考資料
プレフィックスは一行の追加で済みますが、忘れると RAG の精度が大きく下がります。実装時は必ずチェックリストに入れておきましょう!