開発book-knowledge-baseアクティブ

やったこと

book-knowledge-base プロジェクトで、Dropbox 配下の「00連番フォルダ」に積み上がっている書籍PDF 957件から、奥付(巻末の書誌情報)を一括抽出して Turso DB に流し込むパイプラインの計画書を書き上げた。手は動かさず、設計と検証だけで一日を使い切った。実装は明日に積み残す。

背景

蔵書PDFは Dropbox の 00_books/ 配下に連番で積み上がっていて、ファイル数を数えたら 957件あった。ファイル名は /rename-pdf スキルで書名に正規化済みだが、出版社・初版発行日・ISBN・定価・著者複数名などは file system に乗っていない。書籍ビューアから「2010年以前の会計実務書だけ拾いたい」と思っても、ファイル名だけでは絞り込めない。奥付に書かれた書誌情報を構造化して DB に入れれば、Claude Code 経由の蔵書検索で論点 × 出版年 × 出版社の三軸が効くようになる。

蔵書の棚卸し

最初に蔵書フォルダ 842件を Amazon レビューの星評価 × レビュー数でランキング表示してもらった。漫画が上位に大量に出てきたので、漫画を除外して、会計・ファイナンス・ドキュメント設計系のコンテンツ関連書籍に絞り込んだ。リストを眺めながら「これだけ持っていて、内容が DB に入っていないのは勿体ない」と腹落ちした。

そのまま Claude Code に「全書籍の奥付情報を DB に入れたい。リネームPDFスキルに近いことをやる」と投げた。

計画書 v1 と Codex の致命指摘4件

Claude Code が memo/2026-05-10/colophon-extraction-plan.md に v1 を書いた。22項目(タイトル、サブタイトル、版表示、版番号、刷表示、刷番号、初版発行日、刷発行日、著者、編者、訳者、発行所、印刷所、ISBN、定価数値、定価表示、奥付生テキスト、抽出ページ番号、抽出ステータス、エラー、抽出日時、使用モデル)を Anthropic API を直接叩いて抽出する設計だった。

ルールに従って Codex レビューに回した。

codex exec -m gpt-5.5 "このプランをレビューして。瑣末な点へのクソリプはしないで。致命的な点だけ指摘して: memo/2026-05-10/colophon-extraction-plan.md"

「瑣末な点へのクソリプはしないで」を入れたおかげで、Codex は最初から太い指摘だけを返した。4件あった。

  1. 既存スキーマ番号と衝突しているmigrations/ の連番を確認せずに 005_ を振っていた。実際は 008_ まで埋まっていた
  2. Turso 接続コードを新規に書こうとしている — 既に src/db.py に Embedded Replica パターンが書いてあり、amazon_metadata テーブルで file_no を PK にした接続が動いている
  3. file_no の連携設計が抜けている — Amazon メタデータと奥付情報は file_no で 1:1 で紐付くべきだが、計画書には独立した surrogate key が振られていた
  4. Vision の実行方法が不明 — 「Claude Sonnet で Vision を叩く」とだけ書いてあって、どこから何のクライアントで叩くのかが宙に浮いていた

どれも実装に入る前に潰しておかないと、Phase 1 で全部詰む類の指摘だった。

v2 で既存資産に直結させる

計画書を v2 に巻き直した。マイグレーション番号を 008_book_colophons.sql に直し、file_no を PK にして amazon_metadata と FK で結ぶ設計に変えた。Turso 接続は src/db.pyget_db() を再利用する形に直し、新規にクライアントを書き起こさない方針を明記した。

CREATE TABLE IF NOT EXISTS book_colophons (
  file_no TEXT PRIMARY KEY REFERENCES amazon_metadata(file_no),
  title TEXT,
  isbn TEXT,
  -- ... 22項目
  raw_text TEXT,
  extraction_status TEXT,
  extracted_at TEXT,
  model_used TEXT
);

これで JOIN amazon_metadata USING (file_no) だけで Amazon の評価 × 奥付の出版年 × ISBN が同じ行に並ぶ。

再レビューに回した。今度は3件、追加で致命点が返ってきた。

codex exec resume --last -m gpt-5.5 "プランを更新したからレビューして。瑣末な点へのクソリプはしないで。致命的な点だけ指摘して"
  • 並列度の上限指定が抜けている(957件を全部同時に投げる設計に見える)
  • エラー時のリトライ条件が「失敗したら止める」しか書いていない
  • 中間ステートの保存粒度が file_no 単位ではなくバッチ単位になっている(部分失敗で全件やり直しになる)

ここまでで設計は実装可能な形に近づいた。

筆者からのコスト指摘で v3 に書き換える

Codex のレビューは通り抜けつつあったが、計画書を読み返したらコスト見積もりの欄が妙に膨らんでいた。957件 × 5ページ × Vision API 単価で「概算 $XX」と書かれていて、桁感が腹落ちしない。Claude Code に投げた。

コストの見込みが意味わかんないんですけど、このクロードコードの中でやればコストそんなかかんないですよね

Anthropic API を直叩きする前提で計算していた、と Claude Code が返してきた。/rename-pdf スキルは Claude Code の中で完結していて追加課金ゼロで回っているのに、なぜか奥付抽出だけ外部APIを呼ぶ設計になっていた。サブエージェントを並列起動すれば haiku で 10並列回せるし、Claude Code のサブスクリプション内で完結する。

v3 に書き換えた。

  • PDFの末尾5ページを pymupdf で dpi=200 のPNGに書き出す
  • Claude Code のサブエージェントを 10並列で起動して、各エージェントが画像から22項目をJSONで返す
  • メインが JSON を集約して INSERT OR REPLACE INTO book_colophons で書き込む
  • 追加API課金ゼロ

3周目の Codex レビューに回したら、今度は OK が返ってきた。

Codex のクソリプ防止指示に救われた話

3周のレビューを通じて、「瑣末な点へのクソリプはしないで」の一文がずっと効いていた。これを入れないと Codex は「変数名の命名規則」「コメントの語尾」「マイグレーションファイルの著作権ヘッダ」みたいな表面の話で行を埋めてくる。致命点だけに絞らせると、出てくる指摘が全部「実装前に潰さないと Phase 1 で詰む」レベルに揃う。

計画レビューにおいては、Codex に何を言わせるかではなく、何を言わせないかで精度が決まる。

v3 で実装に手を付けた範囲

計画が固まったので、明日すぐ Phase 0 が走るところまでだけ手を入れた。

  • DBスキーマ migrations/008_book_colophons.sql を書いた
  • スキーマ適用スクリプト scripts/apply_colophon_schema.py を書いた(既存の src/db.pyget_db() を呼び出すだけの薄いラッパー)
  • Phase 1 対象10件のリストを memo/2026-05-10/phase1-targets.md に確定した

Phase 1 の10件は、奥付フォーマットが標準的な技術書・実務書・教科書から選んだ。スキャン品質のばらつきが少ない順に並べてある。

設計のポイント

  • DBスキーマ: book_colophons テーブル(file_no を PK で amazon_metadata と1:1紐付け)
  • 抽出フロー: PDF末尾5ページを dpi=200 でPNG化 → Claude Code 内でサブエージェント並列起動(haiku想定、10並列)→ JSON返却を集約 → Turso へ INSERT OR REPLACE
  • 追加API課金ゼロ: Claude Code サブスクリプション内で完結
  • 漸進的: Phase 1(10件)→ 結果確認 → Phase 2(100件)→ Phase 3(全件)

学び

AI レビュアー(Codex)は構造的な指摘は鋭いが、ビジネス的に意味のある指摘は人間の方が鋭い。「コスト見積もりの桁感がおかしい」を Codex は最後まで指摘しなかった。Anthropic API を呼ぶ前提のコード断面を見せても「妥当な単価です」と返してくる。一方、筆者が「Claude Code 内でやればコストかからないですよね」と一言投げただけで、設計が根本から書き直しになった。

計画策定は Codex レビュー → 人間チェック → Codex 再レビュー の3点測量が一番効く。AI 同士のレビュー往復だけで閉じると、ビジネスの臭いが取れない。

明日やること

  • Phase 0: python scripts/apply_colophon_schema.pybook_colophons テーブルを Turso に作成する
  • Phase 1: 対象10件のPDF末尾5ページを dpi=200 でPNG化して tmp/colophon-images/{file_no}/ に書き出す
  • Phase 1: サブエージェント10並列を起動して22項目を JSON で抽出させる
  • Phase 1: 集約した JSON を INSERT OR REPLACE INTO book_colophons で Turso に書き込む
  • Phase 1: 10件の抽出結果を目視確認して、フィールド欠損・誤抽出のパターンを記録する