584ページのスキャンPDFをOCRしてナレッジベースに入れ、サイトの解説コンテンツに変えるまで
584ページのスキャンPDFをOCRしてナレッジベースに入れ、サイトの解説コンテンツに変えるまで
584ページのスキャンPDFをOCRにかけたら、25分で終わった。 見積もりは30分弱だったので、想定より早い。 この日いちばん時間を食ったのは、そのあとに続いた「成功したように見える失敗」のほうだった。
ダウンロードフォルダに落としてあった専門技術書のPDFを1本、OCRしてナレッジベースのDBに入れる。 そこまでは前からある手順をなぞるだけのはずだった。
3ページで測ってから584ページを流す
作業マシンは Apple Silicon の Mac で、この経路を通すのは初めてだった。 見つけたPDFは175MB、584ページのスキャンで、テキストレイヤーは入っている。 いきなり584ページを投げず、まず3ページだけ流させて速度と品質を測らせた。 MPS で動いて約2.7秒/ページ、584ページなら30分弱で終わる計算だった。 出力の品質にも問題がなかったので、本番をバックグラウンドに投げた。
待ち時間に前提を潰す
OCRが回っているあいだは待ち時間になる。
後続工程の前提を先に確認させたら、図版をオブジェクトストレージへ上げるための rclone がこのMacに入っていなかった。
1.75.0 を導入した。
.env の中身を表示せず、環境変数経由で認証情報を渡して接続だけ確かめた。
既存の354冊分が見えた。
PDF内蔵のテキスト層は精度が低かったので、章立ても書店ページの目次で裏を取らせた。 公式の全16章が取れて、PDFから抽出した各章の初出ページとも合った。
途中で進捗を聞いた。 293/584ページで半分、図671枚。 20:41 の時点で最新ファイルの更新が止まっていない。 最終的に584/584ページ、欠番ゼロ、図1,464枚、処理時間25分だった。
終了コード0の見せかけ
図1,464枚を正規名にリネームさせ、アップロードとDB格納を実行した。
「取り込みが完了しました」と返ってきたので結果を確認したら、DBには1行も入っていない。
| tail を挟んだせいでパイプ末尾の終了コードが返っており、失敗が0に見えていた。
原因は、cwd が src/ でないために db モジュールを解決できなかったことだった。
cwd 非依存に直させ、MD_DIR も絶対パスにして再実行した。
書き込みだけが403で返る
今度は exit 1 で止まった。 rclone のコピーが403で拒否されている。 ただし一覧取得のほうは通っている。 単一ファイルで詳細ログを取らせて切り分けたところ、GET と LIST は成功し、PUT だけが403だった。
.env に入っているキーが読み取り専用だった。
1Password 側も値を出さずに確認させたが、書き込み権限を持つ別の認証情報はなかった。
取り込みスクリプトは、アップロードの成功をDB格納の前提としてハードコードしていた。 プロジェクト側は触らず、取り込みスクリプト側だけ「アップロードに失敗しても本文は格納する」形に変えさせた。 図版は1,464枚ともローカルに残っているので、書き込み用のキーを発行すればあとから投入できる。
584ページが493チャンクとして入った(62グループ統合、スキップ0)。 全文検索も引ける状態になった。
ページを章と節に畳み直す
ページ単位のチャンクを目次に沿ってセクション単位へ統合する。 章の境界を機械的に検出させたら、16章のうち6つの章タイトルページがOCRの揺れで拾えなかった。 タイトル文字列で直接探させて、全16章の開始ページを確定させた。
セクション名を目視で確かめると、図のキャプションが見出しとして混ざっている。 節の切れ目ではないので、除外して前の節へ吸収させた。 450セクションで確定して統合を実行し、493チャンクが450チャンクになった。
章立ては目次と合った。 ただ最終章の末尾だけが妙に長い。 中を見たら、p560以降は本文ではなく付録だった。 最終章から切り離して後付に分類し直した。
動いていないものを15分待つ
再分類のあとに全文検索インデックスのリビルドを走らせたら、5分でタイムアウトした。 UPDATE 自体は反映されていたので、リビルドだけ単独で流し直した。
15分経っても戻ってこない。 プロセスを見ると、CPUをほとんど使わないまま止まっている。 そのくせ書き込みロックは握ったままで、他の更新まで止めていた。
調べさせたら、インデックスは INSERT / UPDATE / DELETE のトリガで自動更新される構成だった。 手動リビルドはそもそも要らない。 待っていた15分は、必要のない処理がハングするのを眺めていた時間だった。
図を装飾と情報に仕分ける
図のコンタクトシートを61枚作らせた。 サブエージェント5つを並列で走らせて、装飾図と情報図を判定させる。 バッチごとに結果が戻ってきて、装飾図は14件だった。 本文から除去したところで、取り込みから再構造化、クリーンアップまでの3工程が通った。
書棚のメタデータが同シリーズの別書籍に誤って紐づいていたのも、この待ち時間に直した。 書影を目視して正しい表紙であることを確認し、手動登録用のステータスに合わせて上書きさせた。
アプリを立ち上げて描画を見ようとしたら、ブラウザでの自動確認が使えなくなっていた。 原因はDevTools用の専用プロファイルのChromeが残っていたことで、それだけ終了させたら復旧した。 左の書棚に「済」バッジが付き、章と節が目次として効いている。
DBの知識をサイトの読みものにする
ここで方向を変えた。 DBに入れた知識を、別リポジトリで動かしている地域密着サービス業のサイトのコンテンツとして組み込みたい。 その分野の歴史を扱う読みものと、仕組みを可視化するページを増やす。 あわせて、サイト全体のキーワード設計とAI経由の流入を含む改善計画もまとめさせる。
サイトの現状を調べさせると、Cloudflare 配信の静的HTMLが1枚(36KB)だけだった。 構造化データもaltも既に入っている。 弱いのは、1ページ構成であること、情報系のコンテンツが皆無であること、sitemap が1URLしかないことだった。 2026-03 のSEOレポート(88/100)が残課題に挙げていたのも「コンテンツ追加」で、今回やりたいことと重なっていた。
歴史のページと、仕組みの可視化ページを作らせた。 歴史のほうは日本語の中に別言語の単語が1箇所混じっていたので直させた。 可視化のほうは、機構の断面を描く構成にした。 部品が所定の位置に揃ったときだけ次の段階へ進む様子を3状態で切り替える。
描画を確認したら、図の重なり順が違っていた。 境界をまたいでいるはずの部品が手前の塗りに隠れて見えない。 描画順とJS側の参照を直させて、3状態とも意図どおりになった。
トップページから読みものへの導線とsitemapも整えた。 新しいセクションのカードにスタイルが当たらず、CSSファイルを確認させたら括弧は181対181で整合している。 ブラウザキャッシュだった。
出来上がりが物足りなかった
計画書をHTML化してブラウザに出したところで、可視化を見た感想を伝えた。 思っていたよりレベルが低い。 3状態を切り替えるだけでは、部品が噛み合う瞬間が見えない。
モデルを上位のもの(Fable 5)に切り替えて、図解と描写を作り直させた。 注文は「手で少しずつ動かせて、部品が順に乗り上げて所定の位置にはまり、そのあと次の段階まで動く」こと。
スライダーを付けて、操作量を手で変えられるようにさせた。 中盤では、先に条件を満たした部品だけが持ち上がる。 奥まで進めるとすべての部品に一致の印が付いて、次の操作が有効になる。
最終段階の見せ方で一度破綻した。 断面図をそのまま動かすと、部品どうしが斜めに突き抜けてしまう。 最終段階の動きは正面図だけで表し、断面図は「動ける状態になった」ことだけを示す形に分けさせた。 余白の取りすぎ、ラベルの重なり、正面図の形状、端の見切れも順に詰めた。
同じ注文を上位モデルに投げ直しただけで、最初の版には出てこなかった動きが出てきた。
文字数をバイト数で数えていた
並行して走らせていた競合調査が戻ってきて、計画書の前提に誤りがあると指摘された。 自分で検証できる2点を確かめさせた。
本文は1,762文字だった。 前に書いた「14,261」はバイト数を数えた誤りだった。 robots.txt にAIクローラーのブロックが元々入っていないことも確かめた。
本文量を8倍に見誤ったままなら、そこから導いた「コンテンツは足りている」という判断ごと逆になる。 計画書は全面的に書き直させた。
残っていること
- 図版1,464枚のアップロード(書き込み権限を持つキーの発行が要る。値の入力は自分でやる)
- 書き直した改善計画のレビュー
- 可視化ページをモバイル幅で確認する