取り込みパイプライン — 検索できる形に整える前工程
検索精度の問題が実は取り込みの失敗であるケースを見抜けるようになる。PDF抽出・表・更新の反映・削除の伝播という、地味だが破壊的な4つの落とし穴を潰せる。
- 「検索が当たらない」の相当数は、そもそも文書が正しくテキスト化されていない。PDFの段組みが混線し、表が意味不明な文字列になり、画像内の文字が丸ごと欠落している。
- 更新の反映は追加より難しい。古い版を消さずに新しい版を足すと、埋め込みがほぼ同じ2つが並び、どちらが返るか制御できない。「たまに古い情報を答える」の主因。
- 削除の伝播を忘れると、権限を剥奪された文書や削除済みの文書が検索され続ける。これは精度の問題ではなくセキュリティの問題になる。
RAG の議論は検索アルゴリズムに集中しがちですが、現場で最も多く精度を壊しているのは、その手前の取り込み工程です。どれだけ優れた検索を組んでも、索引に入っているテキストが壊れていれば何も引けません。
そして厄介なことに、取り込みの失敗は静かに起きます。エラーも出ず、それらしいテキストが入り、検索も動く。ただ答えが合わないだけです。
横にスクロール
落とし穴1: 抽出が壊れている
PDF は特に危険です。PDF は「文字をページのどこに置くか」の指示の集まりであって、文章の構造を持っていません。素朴な抽出ライブラリは、この配置情報から読み順を推測します。
2段組のPDFで起きること
実際のレイアウト 素朴な抽出結果
┌────┬────┐ 「左段1行目 右段1行目
│左段 │右段 │ 左段2行目 右段2行目 …」
└────┴────┘ → 行ごとに左右が交互に混ざり意味が崩壊
ヘッダー・フッター・ページ番号が本文に混入する、図表のキャプションが本文中に割り込む、といった問題も日常的に起きます。
必ずやるべきは、抽出結果を人間の目で確認することです。数十ページを目視するだけで、段組みの混線や表の崩壊はすぐ分かります。この確認を飛ばして「検索精度が出ない」と悩むのは、時間の使い方として最悪です。
紙をスキャンしただけのPDFは画像であり、テキスト層がありません。抽出すると空文字列が返るか、ごくわずかな断片だけになります。エラーは出ないので、パイプラインは正常に完了したように見え、索引には空のチャンクが入ります。取り込み時に「抽出した文字数がページ数に対して極端に少ない文書」を検出して警告する仕組みを入れておくと、この事故を自動で捕まえられます。OCRが要る場合は、OCRの誤認識が検索精度に直結する点も覚悟が要ります。
落とし穴2: 表が壊れる
表は「行と列の対応」が意味のすべてですが、テキスト化するとこの対応が失われます。
元の表
| プラン | 上限 | 価格 |
| 無料 | 100 | 0円 |
| 標準 | 1000 | 980円 |
素朴な抽出
「プラン 上限 価格 無料 100 0円 標準 1000 980円」
→ 「標準プランの上限は?」に答えられない
対策は、表をテキストに落とすときに構造を保つ形式へ変換することです。Markdown のテーブル記法や、行ごとに「列名: 値」の形へ展開する方法があります。
行ごとに展開した形
「プラン: 標準 / 上限: 1000 / 価格: 980円」
→ 1行1チャンクにすれば、この行だけで意味が完結する
チャンク分割で触れたとおり、表は行単位で切るのが自然です。固定長で機械的に切ると、ヘッダーと値が分離して完全に無意味な断片になります。
落とし穴3: 更新が反映されない
追加は簡単ですが、更新は難しい。ここが取り込みパイプラインで最も事故が多い箇所です。
よくある壊れ方
1. 文書Aのv1を取り込む → チャンク10個が索引に入る
2. 文書Aがv2に更新される
3. v2を取り込む → チャンクがさらに10個入る(v1が残ったまま)
4. 検索すると、v1とv2のチャンクが両方ヒットする
埋め込みはほぼ同じなので、どちらが返るか制御できない
→ 「たまに古い情報を答える」の完成
正しくは、更新時に古い版のチャンクを削除してから新しい版を入れます。そのためには「この文書に由来するチャンクの一覧」が引ける必要があり、チャンクのメタデータに文書IDを持たせておくことが前提になります(メタデータ設計)。
差分だけを再処理したい場合は、文書の内容ハッシュを保存しておき、変わっていなければスキップします。埋め込みの計算はコーパスが大きいほど高くつくので、この最適化は実利があります。
取り込み時の判定
ハッシュが同じ → スキップ(埋め込みを再計算しない)
ハッシュが違う → その文書のチャンクを全削除 → 再分割 → 再埋め込み
元文書が消えた → その文書のチャンクを全削除
落とし穴4: 削除が伝播しない
最後の行が特に重要です。元の文書が削除・非公開化・権限変更されたとき、索引側にそれが伝わらないと、消えたはずの情報が検索され続けます。
これは精度の問題ではなくセキュリティの問題です。退職者の文書、公開停止した資料、権限を絞った機密文書が、RAG 経由で読めてしまう。しかも RAG は要約して返すので、元文書へのアクセス制御を通らずに内容だけが漏れます。
対策は2段構えです。
- 削除イベントを受けて即座に索引から消す。 理想形ですが、連携が切れると漏れます。
- 定期的な全件突き合わせ。 索引にあるチャンクの文書IDを列挙し、元ソースに存在しないものを削除します。イベント連携の漏れを拾う保険で、これが最後の砦になります。
権限については、索引側に権限スコープを持たせて事前フィルタで強制するのが基本ですが、権限変更が索引に反映されるまでの遅延が残ります。機密度の高いコーパスでは、検索でヒットしたチャンクについて生成前に元ソースへ権限を再確認する、という二重チェックが要る場合もあります。
取り込みは非同期のバッチで動くことが多く、失敗が見えにくい工程です。最低限、次を記録しておくと調査が段違いに楽になります——文書ごとの抽出文字数、生成されたチャンク数、埋め込みの成功・失敗件数、スキップした件数とその理由、削除した件数。「なぜかこの文書だけ検索に出てこない」という問い合わせに対し、取り込みログを見れば即座に答えられる状態を作っておくことが、長期的には最も効きます。
まとめ
- 「検索が当たらない」の相当数は取り込みの失敗。しかもエラーが出ず静かに壊れるので、抽出結果は必ず目視で確認する。
- PDFは2段組の混線・ヘッダーの混入・スキャンPDFの空抽出が典型。抽出文字数がページ数に対して極端に少ない文書を自動検出すると事故を捕まえられる。
- 表は行単位で切り、列名と値の対応を保つ形へ展開する。固定長で切ると無意味な断片になる。
- 更新は「古い版を消してから入れる」。消し忘れが「たまに古い情報を答える」の主因。内容ハッシュで差分だけ再処理すると埋め込みコストを抑えられる。
- 削除の伝播は精度ではなくセキュリティの問題。イベント連携に加えて、定期的な全件突き合わせを最後の砦として置く。
- 取り込みログ(抽出文字数・チャンク数・スキップ理由・削除件数)を残しておくと、調査コストが桁で変わる。
RAG設計パターンの記事ガイド
取り込みパイプライン — 検索できる形に整える前工程を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
RAG
比較で見る軸
難易度: advanced / カテゴリ: RAG設計パターン / タグ数: 5
導入後に効く点
更新の反映は追加より難しい。古い版を消さずに新しい版を足すと、埋め込みがほぼ同じ2つが並び、どちらが返るか制御できない。「たまに古い情報を答える」の主因。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- RAG設計パターン
- タグ数
- 5
判断チェックリスト
- 自社の用途が「RAG / 取り込み」に近いか確認する。
- 強みである「「検索が当たらない」の相当数は、そもそも文書が正しくテキスト化されていない。PDFの段組みが混線し、表が意味不明な文字列になり、画像内の文字が丸ごと欠落している。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。