開発book-knowledge-base

朝6時17分。「積み残しがあったと思うんだけど何でしたっけ」と Claude Code に投げたら、「税務系PDF書籍バッチ取り込みの続き」と即答が返ってきた。memo を漁ってくれていた。じゃあ順次やっていってと指示して、その日の取り込み祭りが始まった。

朝の部: 積み残し11冊を順次 OCR

最初に困ったのは、前セッションで scratchpad に置いていた PDF が全部消えていたことだった。.gitignore で除外されていて、セッションが切れたタイミングで蒸発したらしい。Dropbox 本体から探し直すところから始めた。

着手順は「小さい順」で固定した。6MB → 59MB → 57MB → ... と並べて、最大級の 361MB(前セッションでメモリ不足でリトライ送りにしていたリカバリ対象)を最後に回す。先に小さい本で型を確立してから、長時間 OCR に突入するほうが事故が少ない。

サイズページOCR時間DBチャンク
国税庁の公式手引6MB5993秒32
会計の教科書57MB231281秒190
税務の実務書59MB205数分205
CPA系の試験テキスト145MB数百13分前後381
法人税の別表逐条解説361MB84728分38秒723
相続税の Q&A 集445MB1131約40分1037

最大級の本は1冊 OCR に40分かかる。普通に待っていたら昼までに2〜3冊しか進まない。そこで「OCR がバックグラウンドで走っている間に、次の本の表紙ページだけ画像化して書誌情報を先取りする」運用に切り替えた。OCR が完了通知を吐いた瞬間に DB 格納へ即移行できるので、手が止まらない。

巨大 PDF(100MB 超)は Read で先頭ページが拾えない。これは pymupdf で表紙だけ画像化して、Claude の画像認識でタイトル・出版社・ISBN を確定する迂回路で乗り切った。/yomitoku スキルの定形フローに乗せれば、OCR → 図画像のリネーム → Turso DB への chunks 投入まで一直線で流れる。

「リストラクチャーが終わってないんじゃ?」

11冊全部の OCR が片付いて、進捗 memo を更新して、Nuxt 起動して「終わったよ」と報告した直後だった。「あとね、今見たんですけど、例えば自己啓発書系の1冊、リストラクチャーうまくいってない気がするんで、これでリストラクチャー全部終わってますか?」とユーザーから刺された。

該当の本を /shelf で開き直して気づいた。chapter 欄に「私の両親」「ローラ・ローデン」「本文中の〔 〕は訳注」など、本来は本文の中の一行にすぎない文字列が見出しとして並んでいる。本の本来の構造(4ステップ × 16章)に整理されていない。

ここで自分の中の理解が一段更新された。/yomitokuOCR → chunks 投入までしかやらない。chunks を本来の章節構造に統合し直すのは /restructure-book の仕事で、これは別フェーズだった。両者を切り分けずに「取り込み完了」と言っていたら、Q&A の精度が下がる。書籍横断で「この論点は何ページの何節か」を AI に聞いたときに、変な見出しに引っ張られて関係ない箇所が返ってくる。

すぐに restructure フェーズに入った。並列で投げたかったが、SQLite の WAL モードは同一ファイルへの並列直接書き込みで衝突する。プロジェクトの CLAUDE.md にも「subagent 並列は WAL 衝突するため直列必須」と書いてある。1冊ずつ subagent に投げて直列で回した。自己啓発書系の1冊をパイロットにして 422 → 39 チャンクに整理。型が固まったので、残り10冊を同じ流れで流した。

昼の部: 追加19冊を5並列で

12時18分、ユーザーから次の指示が飛んできた。/shelf のスクショ付きで「直近取り込み分の税務・組織再編まわりの実務書、まだ restructure 済んでないので全部やって」。直近の取り込み分が一気に並んだ画像で、19冊が範囲だった。

19冊を TaskCreate でトラックして、subagent 5並列で投げた。並列にできた理由は1点だけ。各 subagent から DB へは HTTP で接続する設計だからだ。SQLite のファイルを直接掴むのではなく、Turso の HTTP API に書き込みリクエストを送る。HTTP 層で順序が直列化されるため、WAL 衝突は表面化しない。

バッチ1(5冊)が完走した。SQLITE_BUSY が1件出たが、retry ロジックで吸収して全冊が緑になった。バッチ2に進める判断ができたのは、CLAUDE.md と HTTP 経路の前提を意識的に分けていたからだった。

今日の学び

  • /yomitoku/restructure-book は別フェーズ。前者は chunks 投入まで、後者は目次整形+セクション統合まで。混同するとシェルフは埋まるが Q&A の精度が落ちる。今後のチェックリストに「restructure 走らせたか」を必ず入れる
  • SQLite WAL の並列衝突は接続レイヤで切り分ける。直接ファイルアクセスする CLI 並列は NG、HTTP 経由なら並列 OK。subagent を量産するときは「どの経路で DB を叩いているか」を必ず確認する
  • OCR の長時間待ちは「次のメタ情報先取り」で潰せる。361MB の本で28分、445MB の本で40分。普通に待っていたら半日溶ける。表紙画像化 → 書誌情報確定の作業を OCR 裏で回せば、完了通知の瞬間に DB 格納に移れる
  • scratchpad は揮発する前提.gitignore 除外ディレクトリは、セッションが切れた瞬間に消えても文句が言えない。長期に置きたいものは別ディレクトリに退避する習慣をつける

税理士・会計士フォロワー視点での応用

クライアントから預かるスキャン PDF(紙の請求書束、過年度の決算書、契約書のコピー)を Turso のような検索可能 DB に流し込んでおけば、「あの取引、どの月の何の書類だっけ」を自然文で AI に投げて当てられる。yomitoku のような日本語特化 OCR と HTTP 経由の DB を組み合わせれば、自分が SQL を書かなくても本棚と書類棚に AI から質問できる構図が手元で作れる。書類の山を整理する苦痛が、AI への問いかけに置き換わる。

関連

  • ~/.claude/skills/yomitoku/ — OCR から chunks 投入までの定形フロー
  • ~/.claude/commands/restructure-book.md — chunks を本来の章節構造に整える
  • mdx-playground/CLAUDE.md — subagent 並列の WAL 衝突注意事項