Table of Contents
12 GB のノートPCで機密 PDF をローカル検索する方法——RAG を作り込みすぎないために
日々のログがプレーンテキストで残っており、PDF も大量にある。メモリは 12 GB、専用 GPU はなく、資料は外部に出せない。このような場合、最初からローカル LLM、ベクトルデータベース、複雑な RAG フレームワーク、チャット UI を組み合わせたくなるかもしれません。
しかし本当に必要なのが「考えている内容に近いファイルを見つけ、該当箇所を読むこと」であれば、まず LLM を止めても使える検索を作る方が確実です。
まず「検索」の意味を分ける
次の四つは別の機能です。
- ファイル検索:関連するファイルと一致箇所を返す。
- 箇所検索:関連するページや節を、出典パスとともに返す。
- 質問応答:検索した箇所を材料に回答文を作る。
- 文書分析:多数の資料を比較、分類し、構造化した事実を抽出する。
最初の二つだけなら、文章生成は不要かもしれません。CPU だけの小さなマシンでは、決定的な検索結果の方が速く、監査しやすく、問題の切り分けも容易です。
インストールを始める前に、実際に調べたい質問を 20〜30 個書き出し、それぞれで見つかるべきファイルやページを記録します。これが検索のテストセットになります。これがなければ、構成が豪華になるほど本当に良くなったのか分からなくなります。
1. コレクションを棚卸しする
少なくとも、ファイルパス、形式、言語、文字 PDF かスキャンか、利用権、機密度を記録します。
原本は読み取り専用で保存し、抽出テキスト、OCR 結果、インデックス、キャッシュは別の派生データ用フォルダに書き出します。検索インデックスにも資料本文の多くが含まれ得るため、原本と同じく機密データとして扱う必要があります。
2. AI より先に文字を抽出する
選択可能な文字を含む PDF なら、Poppler の pdftotext が小さく予測しやすい出発点です。
pdftotext -layout input.pdf output.txt
-layout は物理的な配置を保とうとします。ただし、索引には単純な読み順の方が合う場合もあります。代表的な資料で両方を比較してください。Poppler と `pdftotext` のマニュアルも参照できます。
スキャン PDF では OCR を別工程として扱います。OCRmyPDF はスキャン PDF に検索可能な文字層を追加します。原本は残し、新しいファイルを作ります。
ocrmypdf --skip-text input.pdf searchable.pdf
pdftotext -layout searchable.pdf searchable.txt
混在 PDF では --skip-text が便利ですが、人名、日付、表、珍しい文字、多言語ページは必ず目で確認します。カスタム OCR は文書プロジェクトで最も大きな作業になりやすいため、必要なページ数を先に測るべきです。
3. 普通の全文検索を試す
既製のデスクトップ UI が欲しければ、Recoll は文書本文を索引化して関連ファイルを返します。対応形式や外部ヘルパーはユーザーマニュアルにまとまっています。
小さな自作ツールなら SQLite FTS5 で十分なことが多いです。FTS5 はフレーズ、接頭辞、近接、論理演算、順位付け、ハイライト、抜粋を扱えます。
CREATE VIRTUAL TABLE docs USING fts5(
path UNINDEXED,
page UNINDEXED,
text,
tokenize = 'unicode61'
);
SELECT
path,
page,
snippet(docs, 2, '[', ']', ' … ', 24) AS excerpt,
bm25(docs) AS rank
FROM docs
WHERE docs MATCH ?
ORDER BY rank
LIMIT 20;
重要なのは、どの結果にもファイル、ページまたは節、抜粋、再現可能なクエリが残ることです。
ここで 20〜30 個の質問を実行し、期待するファイルが上位 5 件に入るかを記録します。普通の検索で十分なら、そこで止めて構いません。目的を達成した小さな検索システムは、未完成の RAG ではありません。
4. 測定した失敗にだけ意味検索を追加する
質問と本文で違う言葉が使われるために全文検索が失敗するなら、埋め込みを二つ目の信号として追加します。完全な置き換えにはしません。
実用的な順序は、語彙検索、短い重複区間の意味検索、結果の統合、出典表示です。デバッグ用に「完全一致のみ」を残します。
小さなマシンでは、埋め込みをバッチで作り、インデックスを保存します。毎回すべてを再計算しないでください。オフライン利用のために一度モデルを取得した後、検索時に外部通信が発生しないことも確認します。
言語の選択も重要です。英語専用モデルは中国語、日本語、混在資料には適さない可能性があります。利用者が実際に入力する言語、人名、略語、専門語で試してください。
コンテキスト窓を保管庫ではなく予算として扱う
オフラインモデルのプロンプトにコーパス全体を入れる必要はありません。コレクションは検索インデックスに置き、現在の質問に関係する少数の区間だけをコンテキストへ渡します。これは検索拡張生成(RAG)の基本構造です。明示的な外部メモリから検索し、取得した証拠をモデルに処理させます。
コンテキストは長ければよいとは限りません。*Lost in the Middle* は、関連情報が長い入力の中ほどにあると、モデルがそれを安定して利用できない場合があると報告しています。公称コンテキスト長が大きくても、すべての検索結果を詰め込む理由にはなりません。
次を固定値ではなく、最初の実験として使います。
- 全文検索と意味検索から、たとえば 20 件の候補を取得する。
- 重複を除き、一つの文書から採用する区間数に上限を設ける。
- 再順位付け後、余裕を持って収まる短い 4〜8 区間だけを渡す。
P1、P2、P3のような安定した出典 ID を付ける。- その区間だけに基づく回答を求め、「証拠不足」を明示的な結果として許す。
先に作った 20〜30 問で、検索再現率、引用の正しさ、証拠不足時の停止を別々に測ります。期待する証拠が欠ける場合だけ区間数を増やし、無関係な区間が回答を乱すなら減らします。有用なコンテキスト長は、必要な証拠を安定して含む最小値であり、モデルの最大 token 数ではありません。
小規模言語モデルを使う場所
小規模言語モデルには三つの異なる役割があります。別々に評価してください。
| 役割 | 使う条件 | 測るべき主な失敗 |
|---|---|---|
| クエリ書き換え | 短い質問、略語、語彙のずれで検索漏れが起きる。 | 書き換えが利用者の本来の質問からずれる。 |
| 再順位付け | 正しい区間は見つかるが、順位が低すぎる。 | 正確な一致が下がり、遅延が増える。 |
| 回答生成 | 少数の区間を比較・統合する必要がある。 | 根拠のない主張、または文を支えない引用が生じる。 |
rewrite–retrieve–read の研究では、小さな学習可能モデルをクエリ書き換えに使っています。非公開のローカルシステムでは、元の質問を保存し、元の質問と書き換えの両方で検索し、書き換えの記録もローカルに置いて結果を比較します。流暢な書き換えで利用者の原文を黙って置き換えてはいけません。テスト集合で検索が改善しなければ、その層を外します。
この構成なら、控えめなコンテキスト窓でも扱えます。検索がコーパスを証拠へ絞り、小規模モデルは一つの境界ある仕事だけを行います。
5. 生成が必要になってから LLM を加える
LLM は、複数箇所の要約、比較、回答文の作成が必要なときに役立ちます。ただし、証拠を見る唯一の入口にしてはいけません。
- LLM がなくても検索できる。
- 生成した主張からファイルとページを開ける。
- 「見つからない」を正しい結果として扱える。
- 生成文を原資料へ自動的に書き戻さない。
CPU だけでも小さな量子化モデルで文章を整えられる場合はありますが、最初に考えるべきなのはモデルサイズではなく、検索品質と出典追跡です。
派生データまで含めたプライバシー確認
「ローカル」という表示だけでは不十分です。
- 原本と派生インデックスの両方に適切なアクセス制御を設定する。
- ブラウザ UI は、意図して保護しない限り
127.0.0.1にバインドする。 - 抽出、埋め込み、再順位付け、生成がクラウド API を呼ばないことを確認する。
- ログ、サムネイル、OCR サイドカー、ベクトル索引、バックアップも機密として扱う。
- 必要ならバックアップを暗号化する。
- インデックスを再構築できるよう、モデルと抽出設定を記録する。
- 原資料を削除する必要がある場合、派生インデックスも削除する。
インストール後にネットワークを切り、小さなサンプルを再構築してみると、意図しない外部依存を多く発見できます。
最小で役に立つ構成
読み取り専用の原本
↓
文字抽出 / 必要なページだけ OCR
↓
パスとページ情報を持つ区間
↓
Recoll または SQLite FTS5
↓
原文を開ける順位付き抜粋
テストで語彙のずれが確認されたときだけ意味索引を追加し、利用者が統合を必要とするときだけ生成を追加します。新しい層にはそれぞれ測定可能な理由が必要です。
コレクション適合確認が役立つ場合
難しいのは流行の RAG 構成を選ぶことではなく、資料を抽出できるか、何を非公開にすべきか、どの言語と読者が対象か、引用がどこを指すべきか、今のマシンで何が現実的かを決めることです。
資料を共有する前に、LKT 自身の文書化された参照コレクションを使った完全なサンプル適合レポートを確認できます。データ・プライバシー設計、代表的なブラウザ実証、go/no-go の境界を示しています。これはプロジェクト自身の検証資料であり、顧客事例や推薦文ではありません。
私は Local Knowledge Terminal を保守しており、その判断のための無料・プライバシー優先のコレクション適合確認を用意しています。このページはブラウザ内でメール下書きを作りますが、回答を自動的にアップロード、保存、送信しません。
コレクションが適合し、双方が範囲に同意した場合のみ、任意の創設期スプリントは 250 米ドルです。対象は、顧客が提供する一つのコレクション、一つの言語目標、一台の既存マシンです。文書化したデータ・プライバシー・引用設計、利用可能な代表サンプルでの小さなブラウザ実証、拡張すべきかの go/no-go 提案を納品します。
ハードウェア、配送、カスタム OCR、本番導入は含みません。支払いより先に適合確認を行い、資料を利用する権利が必要です。
このサービスを利用するかどうかにかかわらず、基本は同じです。まずファイルを検索可能にし、失敗を測り、必要な場所にだけ知能を追加します。
