このエラーが発生する理由
Qdrantのコレクション作成時に 422 Unprocessable Entity エラーが発生する場合、通常は vectors の設定構造に問題があります。QdrantのRustベースのエンジンはスキーマに対して非常に厳格です。サーバーが特定のオブジェクト構造を期待しているのに、生の辞書や誤ってネストされたリストを受け取ると、即座にリクエストを拒否します。これは、古いクライアントバージョンからの移行時や、「単一ベクトル(Single Vector)」と「名前付きベクトル(Named Vector)」のロジックを混同した際によく起こります。
多くの場合、原因はJSONペイロードにあります。APIは構造化された VectorParams オブジェクト(またはそのマップ)を期待していますが、コードが内部のProtobufやREST定義に正しくマッピングされないプレーンなPython辞書を送信している可能性があります。
よくある落とし穴
1. 「プレーンな辞書」の罠
vectors 引数に生の辞書を渡したくなることがあります。クライアントが自動的にパースしてくれると思いがちですが、多くの場合バリデーションエラーにつながります。
# これはおそらく422エラーを引き起こします
client.create_collection(
collection_name="my_collection",
vectors={
"size": 1536,
"distance": "Cosine"
}
)
2. 名前付きベクトルの混同
テキスト用と画像用など、1つのポイントに対して複数のベクトルを使用する場合、すべてのキーが VectorParams インスタンスにマッピングされる辞書を提供する必要があります。マップが期待されている場所に単一のオブジェクトを提供すると、バリデーションに失敗します。
解決方法
方法1:単一ベクトルの正しい設定
1ポイントにつき1つのベクトルを使用する標準的なセットアップでは、 models.VectorParams クラスを使用します。これが、Pythonコードでサーバーが要求する正確なJSON構造を生成するための最も安全な方法です。
from qdrant_client import QdrantClient, models
client = QdrantClient("localhost", port=6333)
client.create_collection(
collection_name="my_docs",
vectors=models.VectorParams(
size=1536, # 例: OpenAIのtext-embedding-3-smallの場合は1536
distance=models.Distance.COSINE
)
)
方法2:名前付きベクトルを正しく扱う
プロジェクトでマルチモーダル検索が必要な場合は、各ベクトル設定を辞書内の VectorParams でラップします。これにより、どの次元がどの名前付きインデックスに属するかをQdrantに明示的に伝えます。
from qdrant_client import QdrantClient, models
client = QdrantClient("localhost", port=6333)
client.create_collection(
collection_name="multi_modal_collection",
vectors={
"text-features": models.VectorParams(size=768, distance=models.Distance.COSINE),
"image-features": models.VectorParams(size=512, distance=models.Distance.EUCLID)
}
)
方法3:REST APIペイロードのデバッグ
Pythonクライアントを介さずに curl や requests を使用している場合は、ネストを確認してください。単一ベクトルのセットアップは以下のようになります。
{
"vectors": {
"size": 1536,
"distance": "Cosine"
}
}
検索パイプライン全体で名前付きベクトルを使用することを意図していない限り、 vectors オブジェクト内に "my_vector" のような余計なキーを追加しないでください。
解決策の確認
コードを更新したら、以下のスニペットを実行してコレクションの状態を確認してください。
collection_info = client.get_collection(collection_name="my_docs")
print(f"ステータス: {collection_info.status}")
print(f"ベクトル設定: {collection_info.config.params.vectors}")
ステータスが green または yellow であれば、422エラーは解決され、コレクションへのデータアップサートの準備が整っています。
予防のためのヒント
- **次元数を確認する:** 常に `size` を使用するモデルに合わせてください。OpenAIの `text-embedding-3-small` は1536ですが、 `text-embedding-3-large` はデフォルトで3072です。HuggingFaceの `all-MiniLM-L6-v2` は384を使用します。
- **Enumを使用する:** "Cosine" のような文字列を手動で入力するのは避けましょう。タイポを防ぐために `models.Distance.COSINE` を使用してください。
- **複雑な設定を検証する:** HNSWや量子化(quantization)の設定を追加すると、JSONはすぐに複雑になります。デプロイ前に設定オブジェクトを [JSON Formatter & Validator](https://toolcraft.app/en/tools/developer/json-formatter) にかけることをお勧めします。これにより、422エラーの原因となるカンマの付け忘れやネストの誤りを見つけることができます。
- **クライアントを更新する:** Qdrantの進化は速いです。 `pip install -U qdrant-client` を実行して、ローカルライブラリが新しいサーバーバージョンに対して非推奨のペイロード構造を送信していないか確認してください。

