この記事ではLLMに特化して解説します。LLM全般は LLMとは?仕組みからローカル実行まで徹底解説【2026年完全ガイド】 をご覧ください。
AI reads booksとは何か
AI reads booksは、PDFファイルをページ単位でAIに分析させ、知識ポイントの抽出とプログレッシブなサマリー生成を自動化するPythonスクリプトだ。GitHub上で1,600スター以上を獲得している。
長いPDFをまとめてLLMに投げる際の問題は二つある。一つ目はトークン制限——GPT-4oやClaudeには最大コンテキスト長があり、300ページの技術書をそのまま渡すとトークン数が超過する。二つ目は内容の取りこぼし——大量のテキストを一度に処理すると、LLMが中盤の内容を十分に処理しきれず「Attention is spread thin」状態になりやすい。
AI reads booksはこれをページ単位の逐次処理で解決する。各ページを独立したAPIコールとして処理するため、どんなに長いPDFでもトークン制限に引っかかることなく、全ページを漏れなく分析できる。
技術書・学術論文・ビジネス書・教科書など、長めのPDFの内容を体系的に把握したいエンジニアや研究者に適したツールだ。RAGシステムを構築するほどではないが、「AIに本を読ませて要点を抽出させたい」というシンプルなニーズをコマンドラインで満たせる。
公式READMEには「各ページを個別に処理することで、書籍の文脈的な流れを維持しながら詳細な内容理解を実現する」と説明されている。ページをまたいだ知識の蓄積と定期的な中間サマリーにより、本を「通読」した結果を構造化されたデータとして保持できる。
処理アーキテクチャ:ページバイページの仕組み
全体フロー
AI reads booksの処理パイプラインは以下の順序で実行される:
(book.pdf)"] --> B["ディレクトリ初期化
book_analysis/の作成"] B --> C{"既存の知識ベース
が存在するか?"} C -->|"Yes"| D["Resume
(途中から再開)"] C -->|"No"| E["最初から処理開始"] D --> F["ページ読み込み
(PyMuPDF)"] E --> F F --> G{"目次・インデックス
ページ?"} G -->|"Yes(スキップ)"| F G -->|"No(処理)"| H["process_page()
LLMに知識ポイントを要求"] H --> I["知識ベースJSON更新
(永続化)"] I --> J{"ANALYSIS_INTERVAL
に達したか?"} J -->|"Yes"| K["analyze_knowledge_base()
中間サマリー生成"] J -->|"No"| F K --> L["save_summary()
Markdownファイル保存"] L --> F F -->|"最終ページ処理後"| M["最終総括サマリー生成"] M --> N["全ファイル保存完了"]
ページ解析(process_page)
各ページに対して以下のプロンプトをLLMに送信する(公式実装ベース):
- そのページのメインコンセプト
- 重要な定義・用語
- 実践的な知識ポイント
- 前のページとの繋がり・関連性
これをJSON形式で返させることで、後続の分析・検索・統計処理が容易になる。
中間サマリー(analyze_knowledge_base)
ANALYSIS_INTERVALで設定したページ数ごとに、それまでに蓄積した知識ベース全体を振り返り、中間サマリーを生成する。このサマリーは「ここまで何を学んだか」の棚卸しになり、長い書籍を処理する際の進捗確認にも使える。
セットアップと使い方
インストール
# リポジトリのクローン
git clone https://github.com/echohive42/AI-reads-books-page-by-page
cd AI-reads-books-page-by-page
# 依存パッケージのインストール
pip install -r requirements.txt
主な依存パッケージ:
openai— OpenAI APIクライアントPyMuPDF— PDFページの読み込みcolorama— カラーターミナル出力python-dotenv— 環境変数管理
環境変数の設定
# .envファイルの作成
cat > .env << 'EOF'
OPENAI_API_KEY=sk-xxxxx
EOF
スクリプトの設定
read_books.py内のトップレベル定数を編集する:
# read_books.py の設定例
# 処理対象のPDFファイル名(プロジェクトルートに置くか、パスを指定)
PDF_NAME = "my_book.pdf"
# ページ抽出モデル(各ページの知識ポイント抽出に使用)
MODEL = "gpt-4o"
# サマリー生成モデル(中間・最終サマリーに使用)
# 精度重視の場合は高性能モデルを使う
ANALYSIS_MODEL = "gpt-4o"
# 何ページおきに中間サマリーを生成するか(Noneで無効)
ANALYSIS_INTERVAL = 20
# テスト用:最初のN ページだけ処理(Noneで全ページ)
TEST_PAGES = None # 本番: None / テスト: 10
# 出力ディレクトリの設定
KNOWLEDGE_DIR = "book_analysis/knowledge_bases"
SUMMARIES_DIR = "book_analysis/summaries"
PDFS_DIR = "book_analysis/pdfs"
実行
# 通常実行
python read_books.py
# バックグラウンド実行(長時間かかる場合)
nohup python read_books.py > output.log 2>&1 &
# 進捗確認(別ターミナルで)
tail -f output.log
初回は TEST_PAGES = 5 と ANALYSIS_INTERVAL = 3 に設定して、少ないページ数で動作確認するのがよい。APIコストと処理時間を確認してから本番実行に移る。300ページの技術書を全ページ処理するとOpenAI APIのコストが数ドル〜十数ドル程度かかる場合がある。
出力ファイル構造
処理が完了すると、以下のディレクトリ構造でファイルが生成される:
book_analysis/
├── knowledge_bases/
│ └── my_book_knowledge.json # 全ページの知識ポイント
├── summaries/
│ ├── my_book_summary_p1_20.md # ページ1-20の中間サマリー
│ ├── my_book_summary_p21_40.md # ページ21-40の中間サマリー
│ └── my_book_final_summary.md # 全体の最終サマリー
└── pdfs/
└── my_book.pdf # 処理対象PDFのコピー
知識ベースJSONの構造
{
"book": "my_book.pdf",
"total_pages": 300,
"processed_pages": 300,
"pages": [
{
"page_number": 1,
"main_concepts": ["コンセプト1", "コンセプト2"],
"key_definitions": {
"用語A": "定義の説明",
"用語B": "定義の説明"
},
"knowledge_points": [
"重要な知識ポイント1",
"重要な知識ポイント2"
],
"connections_to_previous": "前のページとの関連"
}
]
}
このJSON構造により、後からPythonスクリプトで特定のトピックを検索したり、統計分析(最も多く登場する用語は何か、など)を実行したりできる。
実践的ユースケース
1. 技術書の体系的な学習補助
500ページのプログラミング言語仕様書や機械学習の教科書を、AI reads booksで処理する。各ページの知識ポイントが構造化されたJSONで保存されるため、後から「第3章に出てきた最適化手法は何だったか」という疑問を知識ベースで検索できる。
最終サマリーを見れば書籍全体の概要が掴める。章をまたいだ概念の繋がりも、中間サマリーを通じて把握しやすくなる。
2. 研究論文・技術文書の情報収集
学術論文PDFを複数処理し、各論文の知識ベースJSONを比較分析するワークフローが組める。共通して登場するキーワード、異なるアプローチ、引用関係などを構造化データとして整理できる。
3. 社内マニュアル・規程集の知識抽出
RAGFlowのような本格RAGシステムを構築するほどではないが、特定のPDFを処理して要点を把握したいケースに対応できる。人事規程や業務マニュアルを処理すれば、担当者が内容を把握するための補助資料として活用できる。
4. 書籍から自動でフラッシュカードを生成
知識ベースJSONから各ページの定義・用語をAnkiやNotion用のフラッシュカード形式に変換するスクリプトを追加できる。
# 知識ベースJSONからフラッシュカードを生成するカスタムスクリプト例
import json
with open("book_analysis/knowledge_bases/textbook_knowledge.json") as f:
kb = json.load(f)
# 全定義をフラッシュカード形式で出力
flashcards = []
for page in kb["pages"]:
for term, definition in page.get("key_definitions", {}).items():
flashcards.append({
"front": f"用語: {term}",
"back": definition,
"source": f"p.{page['page_number']}"
})
# CSVで保存(Ankiインポート用)
import csv
with open("flashcards.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["front", "back", "source"])
writer.writerows(flashcards)
print(f"{len(flashcards)}枚のフラッシュカードを生成しました")
5. 複数モデルでの比較分析
MODELとANALYSIS_MODELを変更することで、同じPDFに対してGPT-4oとGPT-4o-miniの結果を比較できる。コストと品質のトレードオフを評価するのに便利だ。
カスタマイズオプションの詳細
| 定数名 | デフォルト値 | 説明 |
|---|---|---|
PDF_NAME |
なし(必須設定) | 処理対象PDFのファイル名 |
MODEL |
"gpt-4o" |
ページ分析に使用するモデル |
ANALYSIS_MODEL |
"gpt-4o" |
サマリー生成に使用するモデル |
ANALYSIS_INTERVAL |
20 |
何ページごとに中間サマリーを生成するか |
TEST_PAGES |
None |
テスト用ページ数制限(Noneで全ページ) |
KNOWLEDGE_DIR |
"book_analysis/knowledge_bases" |
知識ベースJSONの保存先 |
SUMMARIES_DIR |
"book_analysis/summaries" |
サマリーMarkdownの保存先 |
PDFS_DIR |
"book_analysis/pdfs" |
PDFコピーの保存先 |
ページ数の多いPDFはOpenAI APIのトークン消費量が多くなる。300ページの書籍を処理すると、gpt-4o使用時に入出力合わせて数十万トークン消費することがある。事前にTEST_PAGES=10で小規模テストを行い、1ページあたりのコストを見積もってから全ページ処理を実行することを推奨する。
RAGとの比較:どちらを選ぶか
RAGFlowなどのRAGシステムとAI reads booksは、目的が異なるため競合するのではなく補完的な関係だ:
| 観点 | AI reads books | RAGシステム(RAGFlow等) |
|---|---|---|
| 処理方式 | 全ページ逐次処理(線形) | チャンキング+ベクトル検索(索引型) |
| 主な用途 | 全体像の把握・通読補助 | 特定質問への回答・検索 |
| セットアップ | Pythonスクリプト(軽量) | Dockerコンテナ(重め) |
| スケール | 単一文書向け | 大量文書の長期運用向け |
| インタラクション | バッチ処理→結果閲覧 | リアルタイムQ&A |
| コスト | APIコールがページ数分発生 | インデックス構築時のみ |
| 中断再開 | 対応(Resume機能) | 不要(常時アクセス可能) |
選択指針:
- 1〜数冊のPDFを一度読んで要点を把握したい → AI reads books
- 100以上の文書を常時検索できるシステムを構築したい → RAGFlow
- 複数文書を横断的に検索したい → RAGFlow
- 書籍のフローに沿った理解が必要 → AI reads books
他ツールとの組み合わせ
RAGFlowとの組み合わせ
AI reads booksで生成した知識ベースJSONをRAGFlowのナレッジベースにインポートすることで、「AI reads booksで抽出した構造化知識」を「RAGのベクトル検索」と組み合わせられる。AIが既に整理した知識ポイントをRAGに入れることで、生のPDFテキストをそのままRAGに入れるより検索品質が向上する可能性がある。
LangChainとの組み合わせ
生成された知識ベースJSONをLangChainのDocument形式に変換し、カスタムチェーンに接続できる:
from langchain.schema import Document
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
import json
# 知識ベースJSONをLangChain Documentに変換
with open("book_analysis/knowledge_bases/book_knowledge.json") as f:
kb = json.load(f)
docs = []
for page in kb["pages"]:
content = f"""
ページ {page['page_number']}
メインコンセプト: {', '.join(page.get('main_concepts', []))}
知識ポイント: {chr(10).join(page.get('knowledge_points', []))}
"""
docs.append(Document(
page_content=content,
metadata={"page": page["page_number"], "source": kb["book"]}
))
print(f"{len(docs)}ページ分のDocumentを作成しました")
よくある質問
Q: どのファイル形式に対応していますか?
A: PDFのみに対応している。WordやHTMLなど他の形式を処理したい場合は、事前に別ツールでPDFに変換するか、スクリプトを改変してPyMuPDF以外のパーサーを使う必要がある。
Q: スキャンPDFは処理できますか?
A: PyMuPDFはテキストレイヤーのないスキャンPDFの文字認識(OCR)には対応していない。スキャンPDFは事前にAdobe AcrobatやMinerUなどのOCRツールでテキストレイヤーを付与してから処理する必要がある。
Q: 日本語のPDFは処理できますか?
A: はい、PyMuPDFは日本語テキストのPDFを読み込めるため、日本語PDFの処理が可能だ。AIモデル(GPT-4o等)も日本語の入出力に対応している。ただし、日本語プロンプトを使いたい場合はread_books.py内のシステムプロンプトを日本語に書き換えることを推奨する。
Q: OpenAI以外のAPIは使えますか?
A: スクリプトはOpenAIのAPIクライアントを使用しているが、OpenAI互換APIエンドポイントを持つサービス(Azure OpenAI、Groq等)はbase_urlを変更することで対応できる。AnthropicのClaudeやGoogleのGeminiを使いたい場合はスクリプトのAPI呼び出し部分を書き換える必要がある。
Q: 処理時間はどのくらいかかりますか?
A: ページ数とAPIのレイテンシに依存する。GPT-4oを使用した場合、1ページあたり5〜15秒程度が目安だ。100ページの書籍で10〜25分、300ページで30〜75分程度と見積もれる。ANALYSIS_INTERVALのサマリー生成でも追加の時間がかかる。
関連記事: LLMとは?仕組みからローカル実行まで徹底解説【2026年完全ガイド】
まとめ
RAGFlowでRAGシステムを構築している場合は、AI reads booksで事前に知識を抽出・構造化してからRAGに投入することで、ドキュメント品質を高めることができる。LangChainと組み合わせることで、生成した知識ベースをさらに活用した応用パイプラインを組むことも可能だ。
コスト最適化:モデルとパラメータの選択指針
AI reads booksは各ページに対してLLMを呼び出すため、モデルとパラメータの選択がコストと品質に直接影響する。
モデル別コスト概算(300ページ書籍の場合)
| モデル | 入力コスト/1Mトークン | 300ページ概算コスト | 品質 |
|---|---|---|---|
| gpt-4o-mini | $0.15 | $0.5〜$1.5 | 高(コスパ最良) |
| gpt-4o | $2.50 | $8〜$25 | 最高 |
| claude-3-haiku | $0.25 | $0.8〜$2.5 | 高 |
| claude-3-5-sonnet | $3.00 | $10〜$30 | 最高 |
| gpt-4o-mini(サマリーのみ) | $0.15 | $0.1〜$0.3 | 高 |
推奨設定:
- ページ分析(
MODEL)にはgpt-4o-miniを使用(品質とコストのバランスが良い) - サマリー生成(
ANALYSIS_MODEL)にはgpt-4oを使用(より高品質なサマリーを生成)
# コスト最適化設定例
PDF_NAME = "textbook.pdf"
# ページ分析は軽量モデルで高速・安価に
MODEL = "gpt-4o-mini"
# サマリー生成は高品質モデルで精度を上げる
ANALYSIS_MODEL = "gpt-4o"
# サマリー頻度を下げてコスト削減(50ページに1回)
ANALYSIS_INTERVAL = 50
# 最初は10ページでテスト
TEST_PAGES = 10
ローカルモデルでのコストゼロ運用
OpenAI APIを使わずにローカルLLMで実行することも可能だ。OllamaのOpenAI互換APIを利用する:
# read_books.py の改変例(Ollama使用)
from openai import OpenAI
# Ollama の OpenAI互換エンドポイントを使用
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama", # Ollamaはダミーキーを受け付ける
)
MODEL = "qwen2.5:14b" # 日本語品質が高い14Bモデル
ANALYSIS_MODEL = "qwen2.5:14b" # サマリー生成も同じモデル
Ollamaでのローカル実行はAPIコストがゼロだが、処理速度はGPU性能に依存する。RTX 4090でqwen2.5:14bを動かした場合、1ページあたり10〜30秒程度が目安だ。
知識ベースJSONの高度な活用
全文テキスト検索スクリプト
生成した知識ベースJSONに対してキーワード検索を行うスクリプト:
# search_knowledge.py:知識ベースをキーワード検索するユーティリティ
import json
import sys
from pathlib import Path
def search_knowledge_base(kb_path: str, query: str) -> list[dict]:
"""知識ベースJSONをキーワードで検索する"""
with open(kb_path, encoding='utf-8') as f:
kb = json.load(f)
results = []
query_lower = query.lower()
for page in kb.get("pages", []):
page_num = page.get("page_number", 0)
# 知識ポイントの検索
for point in page.get("knowledge_points", []):
if query_lower in point.lower():
results.append({
"page": page_num,
"type": "knowledge_point",
"content": point
})
# 定義の検索
for term, definition in page.get("key_definitions", {}).items():
if query_lower in term.lower() or query_lower in definition.lower():
results.append({
"page": page_num,
"type": "definition",
"term": term,
"content": definition
})
return results
if __name__ == "__main__":
kb_file = sys.argv[1]
query = sys.argv[2]
results = search_knowledge_base(kb_file, query)
print(f"「{query}」の検索結果: {len(results)}件\n")
for r in results:
print(f"[p.{r['page']}] {r['content'][:100]}...")
# 使用例
python search_knowledge.py \
book_analysis/knowledge_bases/textbook_knowledge.json \
"機械学習"
複数PDFの統合知識ベース
複数の関連PDFを処理して、統合した知識ベースを作成するワークフロー:
# merge_knowledge.py:複数の知識ベースを統合する
import json
import glob
from pathlib import Path
def merge_knowledge_bases(kb_dir: str, output_path: str):
"""複数の知識ベースJSONを統合する"""
merged = {
"source_files": [],
"total_pages": 0,
"pages": []
}
for kb_file in glob.glob(f"{kb_dir}/*.json"):
with open(kb_file, encoding='utf-8') as f:
kb = json.load(f)
source = kb.get("book", Path(kb_file).stem)
merged["source_files"].append(source)
merged["total_pages"] += kb.get("total_pages", 0)
# ページデータに出典情報を追加
for page in kb.get("pages", []):
page_with_source = {**page, "source_file": source}
merged["pages"].append(page_with_source)
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(merged, f, ensure_ascii=False, indent=2)
print(f"{len(merged['source_files'])}ファイル、{merged['total_pages']}ページを統合しました")
merge_knowledge_bases("book_analysis/knowledge_bases", "merged_knowledge.json")
echohive42の他のAI活用ツール
AI reads booksの開発者echohive42は、AIを活用した様々なPythonスクリプトをGitHubに公開している。同様のアプローチ(シンプルなPythonスクリプトによるAI処理の自動化)で多くのツールを提供しており、AI reads booksはその代表的な一つだ。
このシリーズのツールは「特定の問題を解決するミニマルなPythonスクリプト」という設計哲学を持っており、複雑なフレームワーク依存なしに即座に使い始められる点が特徴だ。