Fessのベクトル検索では、クロールした本文をチャンクへ分割し、埋め込みモデルでベクトルを作成します。ジョブが終了しても、すべての文書が検索に使える状態になったとは限りません。開発版では、チャンク生成結果の集計と埋め込みサービスの一時停止からの復旧を改善しました。
ジョブの成功件数を確認する
Content Chunk Vector Indexerの結果はfess-chunk.logのChunk vector processing result:で確認できます。従来は、文書へfailやskippedを書き込めた場合もSucceededに数えていました。修正後はベクトル生成に成功した件数だけを成功とし、失敗、スキップ、保留を分けて表示します。
Processed 11 documents. Succeeded: 7, Failed/Skipped: 4. Failed: 1, skipped: 3, left pending: 0.
これはPRで確認された集計例です。Failed/Skippedは成功していない件数の合計で、保留も含みます。left pendingは未処理の文書全体ではなく、この実行で処理を試みて完了状態を保存できずに残した件数です。
content_chunk_statusがdoneなら完了、failなら原因調査が必要な失敗、skippedなら対象本文やチャンク生成条件による除外です。空本文、生成チャンクなし、チャンク数上限超過、存在しないチャンク処理名などでもskippedになります。ジョブ結果だけでなく文書の状態分布も併せて確認します。
一時的なモデル停止と文書固有の失敗を分ける
OpenSearchの再起動直後は、モデル情報がDEPLOYEDでも実際のノードではまだモデルを読み込んでいない場合があります。従来、この間に処理した文書がfailとなり、通常の再実行では選ばれなくなることがありました。
修正後のOpenSearch埋め込みクライアントは、応答がない接続などを再試行し尽くした場合や、推論リクエストが拒否され、モデルのプロファイルでどのノードにもデプロイされていないと確認できた場合に、文書を保留へ残します。モデルが利用可能になった後、次のジョブ実行で再処理します。同じ実行中に自動で完了する保証ではありません。
モデルのプロファイルAPIには推論と同じ認証情報を使います。403などで読めない場合は、モデル未ロードと判断できず、従来どおり失敗になる場合があります。他の埋め込みプラグインへOpenSearch固有の判定が自動で広がるわけでもありません。
モデルが正常に動作しているのに本文を拒否した場合、応答を解析できない場合、ベクトルの件数や次元が一致しない場合は、引き続きfailです。まず原因を修正してから、次のシステムプロパティを一時的に設定してジョブを実行します。
content_chunker.job.retry_failed=true
初期値はfalseです。復旧のための1回の実行後は元へ戻します。skippedはこの設定では再選択されないので、原因を修正したうえで対象文書の状態を解除して再処理する必要があります。
モデルとインデックスの次元をそろえる
content_chunker.embedding.dimensionを未設定でインデックスを作成すると、マッピングは警告なしに768次元になります。一方、実行時の次元設定は未設定を同じようには補いません。モデルの次元を作成前から明示しておく必要があります。
次元を変えるには対応するインデックスの再作成が必要です。同じ次元の別モデルに変更した場合も、以前の文書ベクトルと新しい検索ベクトルは異なる空間になるため、次元チェックに通ることだけで互換性を判断せず、全文書のベクトルを作り直します。チャンクサイズは文字数ですが、モデルの入力上限はトークン数で、Fessがモデル上限へ自動切り詰めするわけではありません。
検索側の待ち時間と制限も確認する
埋め込みHTTP接続の上限は、CPU数から計算する標準の順位統合スレッド数に可用性チェック用の1接続を加え、最低5接続とするようになりました。16コアでは26接続です。少数の停止したリクエストが接続を占有する状況を緩和しますが、実行スレッドがすべて応答待ちになる問題は残ります。rank.fusion.threadsを独自に変更しても、この接続上限は追従しません。
Fess側での順位統合に使うrank.fusion.timeoutの初期値は10000ミリ秒です。初期値falseのrank.fusion.engine.enabledをtrueにして検索エンジン側で統合する場合、このタイムアウトは適用されません。OpenSearch埋め込みの応答タイムアウトは初期値60000ミリ秒、retry.maxは初回を含めて3回なので、応答待ちに再試行間の待機時間も加わる点に注意します。
検索エンジン側の統合が拒否されてFess側へ切り替わる場合、同じリクエスト内で検索語が同じなら作成済みの検索ベクトルを再利用する修正も入りました。別リクエスト間で共有するキャッシュではなく、再試行で検索語が変われば再計算します。
また、faissとcosinesimilを使う場合のcontent_chunker.search.min_scoreの換算を修正しました。たとえばコサイン類似度の下限を0.35と設定すると、OpenSearchへ送る下限スコアは0.675です。0.35は調整例で、innerproductやl2ではこのコサイン類似度の下限を適用せず警告します。