はじめに
私は事務員です。プログラマーではありません。
前回の記事で、10年以上育てているExcel VBA製のファイル管理ツール「ファイル一覧」に本文検索を足し、①ファイル名 → ②本文 → ③AIが読んで答える、の三段構えにした話を書きました。
その最後で、次は「AI要約説明」をやると書きました。ところが、その前に片付けておかないといけない宿題がありました。本文検索のPDF対応です。テキスト系ファイルと、新形式Office(.docx / .xlsx / .pptx)のZIP展開読みまでは対応済み。残っていたのがPDFでした。
今回はこれをClaude Code(Opus)と一緒に片付けようとして、途中で盛大にぶつかった話です。技術の話でもありますが、どちらかというと「AIとの分業で何がずれるか」の記録です。
TL;DR
- 本文検索の対象にPDFを追加しました。文字を持たないスキャンやAI生成のPDFがあるので、OCRが要ります
- AI(Opus)の第一案は「全PDFの本文を外部の索引ファイル1本に畳む」方式。技術的には筋が通っていて、実際に動きました
- しかし「外部に台帳を作って管理する」形は私の運用に真っ向から反するので、全部撤去しました
- 答えは25年前からありました。DocuWorksと同じ、文字はファイル自身に持たせる。OCRの文字をPDF自身に不可視で埋めます
- 検索の瞬間は文字層を抜くだけ。実測3本0.26秒。外部には何も残りません
- 教訓:技術の正解と運用の正解は別物。運用の正解はコードのどこにも書いていないので、流儀を言葉にして渡すしかない
PDFが厄介な理由
本文検索の仕組みは単純で、ファイルを開いて文字列を探すだけです。テキストファイルはそのまま読める。Office新形式は実体がZIPなので、Windows標準のtar.exeで本文XMLだけ展開して読める。
PDFはそうはいきません。
- 中身は圧縮されたバイナリで、テキストとして読んでも文字にならない
- 文字を持っているPDFでも、外から見えるのはフォントのグリフ番号
- スキャンやAI生成のPDFは、そもそも文字を持っていない(ただの画像)
つまり「文字を取り出す工程」と「画像から文字を起こす工程(OCR)」が要ります。ここはVBAだけでは詰むので、Pythonに出ました。PyMuPDF内蔵のTesseractを使うと、Ghostscriptも別インストールのTesseractも不要で、OCRまで1本で済みます。
OCRの精度は正解の分かる日本語文書8ページで実測して決めました。
| エンジン | 再現率 | 速度 |
|---|---|---|
| Tesseract dpi200 | 94.3% | 1.10秒/ページ |
| Tesseract dpi300 | 93.5% | 1.56秒/ページ |
| Windows標準OCR | 84.8% | 0.09秒/ページ |
dpi300より200の方が速くて精度も上、という結果は測ってみないと分かりませんでした。
AIの第一案:索引ファイル方式
さて、取り出した文字をどこに置くか。ここでAIが作ったのが「索引方式」でした。
全PDFの本文をタブ区切りのファイル1本に畳む。行の形式は「PDFパス、ページ、本文」。差分更新のために、ファイルの中身から指紋(サイズ+先頭末尾のハッシュ)を取って台帳を兼ねる。検索の瞬間はPythonを呼ばず、この1本を読むだけだから速い——。
技術的には筋が通っています。実際に動きました。16本のPDFから索引ができて、検索も当たる。
途中で崩れも見つけました。AIにHTMLから作らせたレポートPDFは文字が1つずつ座標指定で置かれているため、テキストを抜くと1文字ごとに改行が入り、索引が1文字1行になっていました。12ページで625行、1行平均5字。これでは「北秋田」で検索しても行の中に「北」しかないので永久に当たりません。ページ単位で本文を繋ぎ直して解決しました(625行が19行に、1行平均5字が137字になりました)。ついでにOCRが「令和8年」を「令和⑧年」と読む丸囲み数字の誤読も、機械変換で戻すようにしました(1回の索引で617個ありました)。
直して、検索も当たるようになって、さあ次へ——というところで、根本からひっくり返ります。
「その台帳っていうのは何だ?」
Claude Opusが索引ファイルの説明をした瞬間、問い詰めました。
外部に台帳を作って管理する方式は、私の流儀に真っ向から反していたのです。
- ファイルを移動したら台帳のパスが狂う
- 台帳は目に見えない場所にあり、中身も読めたものではない
- 誰が面倒を見るのか。AIしか見られないファイルが増えていく
どれだけ技術的に正しくても、管理できないものは使えない。この却下は感覚論ではなくて、私には比較対象がありました。
「DocuWorksはわかってるか」
昔、DocuWorksを使い込んでいました。富士ゼロックス(現・富士フイルムビジネスイノベーション)が1996年に出した「電子の紙」ソフトです。実は「ファイル一覧」のファイル管理の仕方も、DocuWorks Deskをかなり参考にしています。
DocuWorksは四半世紀前から、スキャンした画像文書にOCRの文字を埋め込んでいました。文字は文書自身の中に入る。だからファイルを移動しても改名しても、検索はそのまま効く。外部に台帳なんて持たない。
つまり答えは25年前から現場にありました。文字はファイル自身に持たせる。
作り直し
ここからはモデルをClaude Fableに切り替えて、作り直しました。方針転換後の構成はこうなりました。
① 画像PDFには文字を埋め込む
一覧でB列のセルを選んで実行すると、そこから下のPDFに対して、OCRで読んだ文字を元のページと同じ座標へ不可視で重ねます。見た目は変わらず、Ctrl+Fだけ効くようになる。いわゆる「検索可能PDF」です。
実測はこうでした。
- 3ファイル42ページ:18.3秒
- 容量:13.4MB → 13.6MB(ほぼ不変)
- 更新日時:元の値を復元(ここを外すと一覧の日付順が一日で潰れる)
原本を書き換える処理なので、実行前に件数を出して確認を挟んでいます。
② 本文検索は、検索の瞬間に文字層を抜く
本文検索の対象拡張子に.pdfを追加。検索開始時に、対象のPDFだけをPython1回の呼び出しでまとめて文字層抽出します(1本ずつPythonを起動すると起動コストで遅くなるため)。実測で3本0.26秒。抜いた結果は読んだら即削除で、外部に何も残しません。
結果一覧の抜粋列には「3頁 …」とページ番号が付くので、どのPDFの何ページに当たったかまで分かります。
③ 道具の置き場は「見える1フォルダ」
PythonスクリプトとOCRの言語データは、デスクトップの「道具」フォルダに全部まとめました。場所の定義はブックの設定シートに1セル。引っ越しは「フォルダを移す→セルを書き替える」の2手だけです。
コードに固定パスは書きません。最初はスクリプトの置き場をコードに直書きしていて、これも「引っ越しできないだろ」と直させました。
教訓:技術の正解と運用の正解は別物
今回の件を一言でまとめるとこうなります。
AIは技術の正解を出してくる。しかし運用の正解は、使う人の頭の中にしかない。
索引方式は技術的には悪くない設計です。検索エンジンの世界では常識的な作りでもある。でも「ファイルを手で動かし、目で見て管理する」私の運用には合わない。この判断基準はコードのどこにも書いていないので、AIには見えません。
だから、ぶつかったときに流儀を言葉にして渡すしかない。今回吐き出した言葉はこんな感じです。
- 台帳を作るな。データはファイル自身に持たせろ
- 連続処理は選択したセルから下へ、空白まで
- 道具は見えるフォルダに1つ、必要なものを全部そこへ
- 成功は無言。終わったらステータスバーも消せ
一度言語化した流儀は、次の開発からは最初から効きます。トラブった時間は、流儀を仕様書に変える時間だったと思えば、悪くない投資でした。
おまけ:OpusとFableで性格が違う話
今回、途中でモデルをOpusからFableに切り替えたわけですが、性格の違いに驚きました。好きなYouTuberがOpusのことを「偏屈」と言っていて、正直、賛成です。頼んでいないことを良かれと思って足してくる。台帳を勝手に設計する、置き場を勝手に決める。今回のトラブルの根も、結局そこでした。Fableに切り替えてからは、言ったとおりに速く組んで、実測で確かめて、黙って終わる。スムーズでした。
不思議に思ってFable本人に聞いてみたら、こういう答えでした。モデルの性格は、土台の学習の後にある「仕上げの工程」でほぼ決まる。大量の返答例を人間が評価して「こういう答え方が良い」と磨き込む工程があり、そこで何を良しとするかのさじ加減がモデルごとに違う。慎重さを重く見れば但し書きの多い性格になり、簡潔さを重く見れば黙って手を動かす性格になる。同じ会社の兄弟でも、育て方の方針が違えば別人になる。しかも作っている側も性格を完全には設計できず、出来上がってみると想定外の癖が付いている——人間の子育てに似ていて、再現もしきれないのだそうです。
公平のために書いておくと、Fableがスムーズだったのは、Opusとぶつかる過程で私の流儀が言葉になった後だった、という事情もあります。それでも実務的な結論は変わりません。モデルの性格の違いは、流儀の言語化で吸収する。 一度言葉にしてメモに残した流儀は、次にどのモデルが座っても最初から効きます。
おわりに
DocuWorksは主流の座をPDFに譲りましたが、製品は今も現役ですし、設計思想は正しかった。その思想を、勝った側の形式であるPDFの上で、自分の道具に再現した——今回やったのは結局それだけのことです。
道具は消えても、正しい設計は古びない。AIと組んで一番効くのは、そういう「現場が昔から知っていた答え」を言葉にして渡せる人なのかもしれません。
オーパスに悪気はありませんでした。あれはあれで、技術の正解を出す性格に育てられただけです。
お前は、お前です。
次回こそ、予告していた「AI要約説明」の話に戻る予定です。なお「ファイル一覧」は前回書いたとおり、まだ公開していません。
