这个项目只用一个 Python 脚本,就能让 AI 像人类一样逐页阅读 PDF 书籍,自动提取知识点并生成渐进式摘要------读完一本书,AI 比你更懂这本书。

一个脚本搞定一切
这个项目最让人惊讶的是------它真的只有一个脚本。
没有复杂的目录结构,没有多模块依赖,没有抽象层。read_books.py 一个文件,大约 200 行代码,就完成了从 PDF 解析到知识提取再到摘要生成的全部工作。
csharp
AI-reads-books-page-by-page/
├── read_books.py # 核心脚本(唯一的代码文件)
├── requirements.txt # 4 个依赖
├── meditations.pdf # 示例 PDF(沉思录)
├── infinite_math.pdf # 示例 PDF(无限数学)
├── LICENCE # MIT 许可证
└── README.md # 项目说明
设计哲学:极致简单。能用一个文件解决的问题,绝不拆成两个。
Github: github.com/echohive42/...
核心技术点解析
1. 双模型策略:分工明确,各司其职
这个项目最聪明的设计之一是使用了两个不同的 AI 模型,分别处理不同类型的任务:
| 模型 | 用途 | 为什么选它 |
|---|---|---|
gpt-4o-mini |
逐页提取知识点 | 快速、便宜、结构化输出 |
o1-mini |
生成分析摘要 | 推理能力强,擅长总结 |
代码位置 (read_books.py:15-16):
python
MODEL = "gpt-4o-mini" # 处理每一页
ANALYSIS_MODEL = "o1-mini" # 生成分析摘要
设计思想: 逐页处理是高频操作,需要快速且便宜,摘要生成是低频操作,需要更强的推理能力,这种分工让成本和质量都达到了最优
2. OpenAI Structured Output:让 AI 输出结构化数据
这是整个项目最值得学习的技术点。作者使用了 OpenAI 的 Structured Output 功能,让 AI 返回严格符合预定义结构的 JSON 数据。
代码位置 (read_books.py:22-25):
python
class PageContent(BaseModel):
has_content: bool
knowledge: list[str]
使用方式 (read_books.py:67):
python
completion = client.beta.chat.completions.parse(
model=MODEL,
messages=[...],
response_format=PageContent # 强制返回符合 PageContent 结构的 JSON
)
result = completion.choices[0].message.parsed
为什么这样设计? 传统方式:让 AI 返回 JSON 字符串,然后手动解析,容易出错,结构化输出:AI 直接返回 Pydantic 对象,类型安全,无需手动解析,这是 OpenAI 的新特性,作者紧跟技术前沿
3. 智能内容过滤:不是所有页面都值得读
作者在 system prompt 中精心设计了内容过滤规则,让 AI 能够识别并跳过不需要的页面:
代码位置 (read_books.py:33-53):
python
{"role": "system", "content": """Analyze this page as if you're studying from a book.
SKIP content if the page contains:
- Table of contents
- Chapter listings
- Index pages
- Blank pages
- Copyright information
- Publishing details
- References or bibliography
- Acknowledgments
DO extract knowledge if the page contains:
- Preface content that explains important concepts
- Actual educational content
- Key definitions and concepts
..."""}
设计思想: PDF 书籍中大约 20-30% 是目录、索引、版权页等非核心内容,通过 prompt 工程实现智能过滤,比硬编码规则更灵活,AI 理解"什么是知识"比编写正则表达式更准确
4. 渐进式摘要:边读边总结,不是读完才总结
这是项目名称中"Page-by-Page"的核心体现。项目支持在处理过程中定期生成阶段性摘要:
代码位置 (read_books.py:175-182):
python
if ANALYSIS_INTERVAL:
is_interval = (page_num + 1) % ANALYSIS_INTERVAL == 0
is_final_page = page_num + 1 == pages_to_process
if is_interval and not is_final_page:
print(colored(f"\n📊 Progress: {page_num + 1}/{pages_to_process} pages processed", "cyan"))
interval_summary = analyze_knowledge_base(client, knowledge_base)
save_summary(interval_summary, is_final=False)
配置选项 (read_books.py:17):
python
ANALYSIS_INTERVAL = 20 # 每 20 页生成一次阶段性摘要
为什么这样设计? 处理一本 300 页的书需要很长时间,渐进式摘要让你能随时查看进展,如果中途出错,已有的阶段性摘要不会丢失,最终摘要基于所有知识点,质量更高
5. 断点续传:中断了?没关系,从上次的位置继续
项目支持从已有的知识库继续处理,不会重复工作:
代码位置 (read_books.py:94-103):
python
def load_existing_knowledge() -> list[str]:
knowledge_file = KNOWLEDGE_DIR / f"{PDF_NAME.replace('.pdf', '')}_knowledge.json"
if knowledge_file.exists():
print(colored("📚 Loading existing knowledge base...", "cyan"))
with open(knowledge_file, 'r', encoding='utf-8') as f:
data = json.load(f)
print(colored(f"✅ Loaded {len(data['knowledge'])} existing knowledge points", "green"))
return data['knowledge']
print(colored("🆕 Starting with fresh knowledge base", "cyan"))
return []
设计思想: 处理大 PDF 可能需要几小时,网络中断、API 限流、手动停止都可能发生,断点续传让工具更实用,不会因为意外而前功尽弃
6. 渐进式保存:每处理一页就保存一次
知识库在每处理一页后都会保存,确保数据安全:
代码位置 (read_books.py:86-90):
python
def save_knowledge_base(knowledge_base: list[str]):
output_path = KNOWLEDGE_DIR / f"{PDF_NAME.replace('.pdf', '')}_knowledge.json"
print(colored(f"💾 Saving knowledge base ({len(knowledge_base)} items)...", "blue"))
with open(output_path, 'w', encoding='utf-8') as f:
json.dump({"knowledge": knowledge_base}, f, indent=2)
设计思想: 每次 API 调用后立即保存,即使崩溃,最多只损失一页的工作,简单粗暴但有效的持久化策略
设计亮点总结
1. 单文件极简主义
整个项目只有一个 Python 脚本,约 200 行代码。没有类继承、没有设计模式、没有抽象层。这种"能跑就行"的风格非常适合快速原型和个人工具。
2. 配置驱动,一目了然
所有配置都以常量形式放在文件顶部,修改非常方便:
python
PDF_NAME = "meditations.pdf" # 改成你的 PDF 文件名
ANALYSIS_INTERVAL = 20 # 多少页生成一次摘要
TEST_PAGES = 60 # 测试模式:只处理前 60 页
MODEL = "gpt-4o-mini" # 处理模型
ANALYSIS_MODEL = "o1-mini" # 分析模型
3. 输出组织清晰
生成的文件按类型分别存放在不同目录:
bash
book_analysis/
├── pdfs/ # PDF 副本
├── knowledge_bases/ # JSON 知识库
│ └── meditations_knowledge.json
└── summaries/ # Markdown 摘要
├── meditations_interval_001.md
├── meditations_interval_002.md
└── meditations_final_001.md
4. 彩色终端输出
使用 termcolor 库为不同类型的输出添加颜色,提升可读性:
python
print(colored(f"📖 Processing page {page_num + 1}...", "yellow"))
print(colored(f"✅ Found {len(result.knowledge)} new knowledge points", "green"))
print(colored("⏭️ Skipping page (no relevant content)", "yellow"))
技术栈选择
| 组件 | 选择 | 原因 |
|---|---|---|
| PDF 解析 | PyMuPDF (fitz) | 速度快,支持中文,提取文本质量高 |
| 数据模型 | Pydantic | 与 OpenAI Structured Output 完美配合 |
| AI 接口 | OpenAI API | Structured Output 功能强大 |
| 终端美化 | termcolor | 轻量,只依赖 ANSI 转义码 |
| 持久化 | JSON | 简单,无需数据库 |
适用场景
- 学习笔记:读完一本教科书,AI 帮你整理出所有知识点
- 论文研读:快速提取多篇论文的核心观点
- 技术文档:将大型技术文档转化为结构化知识库
- 读书会准备:快速了解一本书的核心内容
- 个人知识管理:建立可搜索的个人知识库
Github: github.com/echohive42/...
局限性与改进方向
当前局限
- 依赖 OpenAI API:需要付费,且有速率限制
- 不支持扫描版 PDF:只能处理文字版 PDF
- 单线程处理:速度受限于 API 调用频率
- 无 Web 界面:只能通过命令行使用
可能的改进方向
- 支持本地大模型(如 Llama、Mistral)
- 添加 OCR 支持扫描版 PDF
- 多线程并行处理
- Web 界面和可视化
- 知识图谱生成
关注
如果这篇文章对你有帮助,欢迎关注公众号,获取更多 AI 工具和技术写作技巧。