Databricks Certified Generative AI Engineer Associate 教科書
第2章 データ準備(Data Preparation, 14%)
🎯 この節の学習目標
2-2で抽出、2-3・2-4でチャンキングを学びましたが、その間にもう1つ重要な工程があります。抽出したテキストを索引化に値する状態に磨く前処理です。Databricks AI Search(旧 Vector Search)は「入っているものの中から」最も類似したチャンクを返すだけなので、ノイズ・重複・古い情報がインデックスに入っていれば、それがそのまま検索結果に現れ、LLMの回答を汚染します。前処理は地味ですが、モデルやプロンプトの改善よりも先に効く、費用対効果の高い品質改善手段です。
文書には本文の理解に寄与しない定型要素(ボイラープレート)が含まれます。代表例は次のとおりです。
これらを残すと、①チャンクの意味密度が下がり埋め込みの質が落ちる、②全文書に共通する文言が「どの質問にもそこそこ似ている」チャンクを量産し検索を汚染する、③プロンプトに入って無駄なトークンを消費する、という三重の害があります。PDFなら「全ページに同一行が現れる」ことを手がかりにヘッダー・フッターを機械的に検出・除去できます。
企業コーパスには重複がつきものです。同一文書の複数版(ファイルサーバーの「最終版」「最終版v2」問題)、部署ごとのコピー、テンプレート文の繰り返し(全文書に同じ定型章が入っている)などです。
重複を放置すると、検索結果のtop-kがほぼ同じ内容のチャンクで埋まるという実害が出ます。top-k=5がすべて同一文書の版違いなら、LLMに渡る情報の多様性は実質1件分です。また、版ごとに内容が微妙に異なると、矛盾した情報が同時にプロンプトへ入り、回答の一貫性を損ないます。
対策は、①完全一致の重複はハッシュ(例:テキストのMD5/SHA)で検出して1件に絞る、②「ほぼ同じ」近似重複は正規化後のハッシュや類似度で検出する、③同一文書の版違いは最新版のみをインデックス対象にするルールをメタデータ(更新日時・版番号)で実装する、が基本です。
💼 例:top-kが同じ文書で埋まる
社内規程ボットで「出張旅費の上限は?」と質問すると、top-5の検索結果がすべて「旅費規程」の2019年版・2021年版・2023年版・部門コピー2件でした。しかも2019年版と2023年版で上限額が異なり、LLMは古い金額を答えてしまいました。対策として、①文書IDと版をメタデータ化し最新版のみ索引化、②ハッシュで完全重複のコピーを排除、を実施したところ、top-5に多様な関連規程が入り、金額も最新版に基づくようになりました。重複排除は検索の多様性と正確性の両方に効きます。
「何をインデックスに入れないか」の設計も前処理の一部です。
| フィルタ対象 | 理由 | 実装の手がかり |
|---|---|---|
| 古い版・廃止済み文書 | 誤った(現在は無効な)情報で回答してしまう | 更新日時・有効期限・ステータスのメタデータ |
| 対象外言語の文書 | アプリの対象言語と異なる文書はノイズになる(または別インデックスにする) | 言語判定ライブラリで言語タグ付け |
| 機密文書・権限外文書 | インデックスに入れてしまうと検索経由で漏えいする | 機密区分メタデータ、UCの権限設計(2-1)と連動 |
| 本文が実質空の文書 | 抽出失敗(スキャンPDF等)の産物。無意味なチャンクを生む | 抽出テキスト長の下限チェック |
あわせて、テキストの正規化も行います。連続する空白・改行の圧縮、文字コードの統一(Unicode正規化。全角/半角の揺れなど)、制御文字の除去といった地道な整形は、埋め込みの安定性とトークンの節約に寄与します。またメタデータでの鮮度管理(更新日時を持たせ、古い文書を除外・降格できるようにする)は、フィルタリングを一度きりの作業ではなく継続的な運用にするための土台です。
なお、個人情報(PII)のマスキング・スクラビングも索引化の前に行うべき前処理です。インデックスに入った後から消すのは困難だからです。手法の詳細は6-1で扱います。
📝 試験のポイント
「検索結果が同じ内容のチャンクばかりになる→重複排除」「古い情報で回答してしまう→版・鮮度メタデータによるフィルタリング」「見せてはいけない文書が回答に出た→索引化前の除外と権限設計」という症状と対策の対応が問われます。いずれも共通する考え方は「生成側ではなくデータ側(インデックスに入る前)で対処する」です。
ここまでの前処理は、1回のスクリプト実行ではなく、Deltaテーブルを段階的に磨いていくパイプラインとして構成するのがDatabricksの定石です。構造化データで使われるメダリオンアーキテクチャ(ブロンズ→シルバー→ゴールド)の考え方を、文書データに当てはめます。
| レイヤー | 内容(RAG文書パイプラインでの対応) |
|---|---|
| ブロンズ(Bronze) | 生データ。Volume上の原本ファイルと、抽出したままの生テキスト(加工なし) |
| シルバー(Silver) | クレンジング済み。ボイラープレート除去・正規化・重複排除・フィルタリング・PIIスクラビングを適用したテキスト |
| ゴールド(Gold) | 利用形。チャンク化済みでメタデータが付与された、インデックスのソースとなるテーブル(CDF有効) |
段階を分ける利点は2-1で述べたとおりです。前処理ロジックを変更したときにブロンズから再生成できる(原本を汚していないから)、各段階の品質を検査できる、リネージで追跡できる。前処理は一度で完成せず改善を繰り返すものなので、この「やり直せる構造」が特に効きます。
# シルバー層の例:正規化・フィルタ・重複排除をDeltaテーブルに適用
import re
from pyspark.sql import functions as F
bronze = spark.table("prod.hr_qa.docs_bronze")
silver = (bronze
.withColumn("text", F.regexp_replace("text", r"\s+", " ")) # 空白の正規化
.filter(F.length("text") > 200) # 実質空の文書を除外
.filter(F.col("status") == "active") # 廃止文書を除外
.dropDuplicates(["content_hash"])) # ハッシュで重複排除
silver.write.mode("overwrite").saveAsTable("prod.hr_qa.docs_silver")
✅ この節のまとめ
問1. RAGボットの検索結果を調べたところ、top-5がすべて同一マニュアルの旧版・コピーで占められ、しかも版によって記載が異なるため回答が不安定になっていた。最も適切な対処はどれか。
正解:B
原因はインデックス内の重複と版の混在なので、データ側での重複排除と「最新版のみ索引化」が根本対処です。Aは重複が上位を占める構造を変えず、無駄なトークンも増えます。Cは矛盾した情報をプロンプトに入れ続ける弥縫策で、どれが正しい版かをLLMは判断できません。Dは原因(データ品質)と無関係です。
問2. 全ページに社名・文書管理番号・ページ番号が印字されたPDF群をチャンク化したところ、多くのチャンクにこれらの定型文字列が混入した。この状態がRAG品質に与える影響として最も適切な説明はどれか。
正解:B
ボイラープレートは埋め込みベクトルに含まれてしまい(Aは誤り)、全チャンクに共通するため「どの質問にもそこそこ似ている」ノイズとして検索を汚染します。さらに検索されたチャンクと共にプロンプトに入り、トークンを浪費します。Cのスキーマ強制は列構造の検証であり、テキスト内容のクレンジング機能ではありません。Dのような速度向上効果はありません。
問3. 廃止済みの旧規程が検索されて誤った回答が生成される問題を、継続的に防ぎたい。最も適切なアプローチはどれか。
正解:B
「継続的に」防ぐには、鮮度・ステータスをメタデータとして管理し、パイプラインの前処理で機械的に除外する仕組みが必要です。Aは誤答の発生自体を防ぎません。Cは場当たり的で、文書が更新されるたびに問題が再発します。Dは出力の決定性を上げるだけで、古い情報が検索される構造は変わりません。
問4. RAG文書パイプラインをメダリオンアーキテクチャ的に構成する場合、各レイヤーの割り当てとして最も適切なのはどれか。
正解:B
メダリオンは「生(ブロンズ)→クレンジング済み(シルバー)→利用形(ゴールド)」と段階的に品質を上げる整理法です。Aは順序が逆です。Cは前処理ロジック変更時に原データから再生成できず、デバッグも困難になります。Dは機密区分の分類であり、メダリオンのレイヤー概念(データの精製度)とは別物です。