将 PDF 笔记内容抽取为结构化 Markdown 知识整理文档。
_知识整理.md 文件来拼凑、补充、参考或"借鉴"内容
[OCR原文:xxx],不得擅自猜测替换
[第X页 OCR 识别失败]
在开始任何处理之前,必须先询问使用者:
knowledge_md/ 子目录
images/ 子目录
不要假设输出目录,必须明确确认。
不同 agent 有不同的 PDF 读取能力。先检测当前环境,再选择最佳方式。
按以下顺序检测当前 agent 支持哪些 PDF 读取方式:
┌─────────────────────────────────────────────────────┐
│ 检测 1:原生 PDF 视觉阅读 │
│ 当前 agent 是否能直接"看"PDF 页面(作为图像)? │
│ │
│ 判断方法: │
│ - 有 Read/File 工具且支持 pages 参数? │
│ - 能读取 PDF 并以图像形式呈现内容? │
│ - 测试:读取 PDF 第 1 页,能否看到完整页面内容 │
│ (包括图片、表格、排版)? │
│ │
│ 若 YES → 使用方式 A(原生视觉阅读) │
│ 若 NO → 继续检测 │
└──────────────────────┬──────────────────────────────┘
│ NO
▼
┌─────────────────────────────────────────────────────┐
│ 检测 2:Python 库可用性 │
│ │
│ 检查命令: │
│ python -c "import fitz; print('PyMuPDF OK')" │
│ python -c "import pdfplumber; print('pdfplumber OK')" │
│ │
│ 若 PyMuPDF 可用 → 使用方式 B(文本+图片提取) │
│ 若仅 pdfplumber → 使用方式 C(文本+表格提取) │
│ 若都不可用 → 继续检测 │
└──────────────────────┬──────────────────────────────┘
│ NO
▼
┌─────────────────────────────────────────────────────┐
│ 检测 3:安装 Python 库 │
│ │
│ 尝试安装: │
│ pip install PyMuPDF pdfplumber │
│ │
│ 安装成功 → 使用方式 B 或 C │
│ 安装失败 → 告知使用者,请求手动处理 │
└─────────────────────────────────────────────────────┘
关键原则:能力检测必须实际验证,不能靠猜测。 不同 agent、不同环境的能力差异很大,必须通过实际测试确认。
适用条件: 当前 agent 能通过 Read/File 等工具直接"看"PDF 页面(作为图像渲染)。
这是最佳方式,因为:
操作方法:
Claude Code 示例:
Read(file_path="xxx.pdf", pages="1-20")
其他 agent: 使用各自平台提供的文件读取工具,只要能渲染 PDF 页面即可。
大文件处理策略:
对于超过 20 页的 PDF,按以下方式分批处理:
分批时注意:
页码获取:
若不确定 PDF 总页数,先用 Python 快速查询:
import fitz # PyMuPDF
doc = fitz.open("input.pdf")
print(f"总页数: {len(doc)}")
doc.close()
若 PyMuPDF 不可用,可通过读取工具尝试不同页码范围来推断总页数。
适用条件: 当前 agent 无法原生阅读 PDF,但可以运行 Python 脚本。
依赖检查:
python -c "import fitz; print(fitz.__version__)"
若未安装:pip install PyMuPDF
文本提取:
import fitz
doc = fitz.open("input.pdf")
for i, page in enumerate(doc):
text = page.get_text("text")
print(f"--- 第 {i+1} 页 ---")
print(text)
doc.close()
图片提取:
import fitz
import os
doc = fitz.open("input.pdf")
output_dir = "images"
os.makedirs(output_dir, exist_ok=True)
for i, page in enumerate(doc):
images = page.get_images(full=True)
for j, img in enumerate(images):
xref = img[0]
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]
image_ext = base_image["ext"]
image_path = f"{output_dir}/p{i+1:03d}-img{j+1:02d}.{image_ext}"
with open(image_path, "wb") as f:
f.write(image_bytes)
print(f"导出: {image_path}")
doc.close()
页面转图片(为无原生 PDF 阅读能力的 agent 提供视觉理解):
当 agent 无法原生阅读 PDF,但仍需要理解图表/流程图时,可将 PDF 页面转为图片,再让 agent 读取图片:
import fitz
import os
doc = fitz.open("input.pdf")
output_dir = "page_images"
os.makedirs(output_dir, exist_ok=True)
for i, page in enumerate(doc):
# 渲染页面为图片(200 DPI,平衡清晰度和文件大小)
pix = page.get_pixmap(dpi=200)
image_path = f"{output_dir}/page_{i+1:03d}.png"
pix.save(image_path)
print(f"导出: {image_path}")
doc.close()
然后使用 agent 的图片读取工具逐页查看,获得类似原生 PDF 阅读的效果。
适用场景: 通用备选方案,适用于所有能运行 Python 的 agent
适用条件: 方式 A/B 的表格提取效果不佳,且 PDF 中包含大量结构化表格。
import pdfplumber
with pdfplumber.open("input.pdf") as pdf:
for i, page in enumerate(pdf.pages):
tables = page.extract_tables()
for j, table in enumerate(tables):
print(f"--- 第 {i+1} 页 表格 {j+1} ---")
for row in table:
print(row)
适用场景: 表格密集的 PDF,其他方式无法正确提取表格时的补充手段
适用条件: 方式 A/B/C 均无法获得可读文本(扫描件/图片型 PDF /大面积乱码)。
环境检测:
检测 Tesseract 是否已安装:
where tesseract # 验证路径
tesseract --version # 验证版本
tesseract --list-langs # 验证语言包(必须有 chi_sim)
检测 Python 依赖:
python -c "import pytesseract; print('OK')"
python -c "from PIL import Image; print('OK')"
依赖安装引导(仅首次需要):
若 Tesseract 未安装,按以下顺序尝试安装,若所有方式均失败则告知使用者手动安装:
# 方式 1:winget(Windows 10/11 自带)
winget install UB-Mannheim.TesseractOCR
# 方式 2:choco(需安装 Chocolatey)
choco install tesseract
# 方式 3:引导使用者手动下载
# https://github.com/UB-Mannheim/tesseract/wiki
# 安装时务必勾选 "中文(简体)" 语言包
若 chi_sim(简体中文)语言包缺失:
# 下载中文语言包
curl -L -o "%TESSDATA_PREFIX%/tessdata/chi_sim.traineddata" ^
"https://github.com/tesseract-ocr/tessdata/raw/main/chi_sim.traineddata"
Python 依赖:
pip install pytesseract Pillow
OCR 执行:
import fitz
import pytesseract
from PIL import Image
import io
import os
doc = fitz.open("input.pdf")
output_dir = "temp_ocr_pages"
os.makedirs(output_dir, exist_ok=True)
for i, page in enumerate(doc):
# 步骤 1:页面渲染为图片(200 DPI)
pix = page.get_pixmap(dpi=200)
img_path = f"{output_dir}/page_{i+1:03d}.png"
pix.save(img_path)
# 步骤 2:Tesseract OCR 识别
try:
text = pytesseract.image_to_string(
Image.open(img_path),
lang="chi_sim+eng",
config="--psm 6" # 统一文本块模式
)
print(f"--- 第 {i+1} 页 OCR ---")
print(text if text.strip() else "[OCR 识别失败]")
except Exception as e:
print(f"--- 第 {i+1} 页 OCR 异常 ---")
print(f"[OCR 错误: {e}]")
doc.close()
PSM 参数速查:
| 参数 | 模式 | 适用场景 |
|------|------|----------|
| --psm 3 | 自动分页 | 通用,首次不确定 |
| --psm 6 | 统一文本块 | 干净笔记/文档页 |
| --psm 7 | 单行文本 | 标题、代码行 |
| --psm 8 | 单个词 | 关键词、标签 |
临时文件清理:
OCR 执行完成后:
temp_ocr_pages/ 目录
质量检查:
开始处理 PDF
│
├─ 步骤 1.0:能力检测
│ │
│ ├─ 有原生 PDF 视觉阅读能力?
│ │ │
│ │ ├─ YES → 使用方式 A,读取前 20 页测试
│ │ │ │
│ │ │ ├─ 内容清晰? → 继续方式 A 分批读完全文
│ │ │ │
│ │ │ └─ 内容混乱? → 回退到方式 B
│ │ │
│ │ └─ NO → 继续检测
│ │
│ ├─ 能运行 Python + PyMuPDF?
│ │ │
│ │ ├─ YES → 使用方式 B
│ │ │ │
│ │ │ ├─ 文本质量可接受? → 继续
│ │ │ │
│ │ │ ├─ 需要看图表? → 页面转图片(方式 B 的页面转图片功能)
│ │ │ │
│ │ │ └─ 表格提取差? → 补充方式 C
│ │ │
│ │ └─ NO → 继续检测
│ │
│ ├─ 能安装 Python 库?
│ │ │
│ │ ├─ YES → pip install PyMuPDF pdfplumber → 回到方式 B
│ │ │
│ │ └─ NO → 告知使用者环境限制,请求协助
│ │
│ └─ 需要导出图片? → 始终使用方式 B 的图片提取
│
└─ 以上所有方式文本质量均不可接受(扫描件/图片型 PDF)?
│
├─ YES → 进入方式 D:Tesseract OCR
│ │
│ ├─ Tesseract 已安装? → 执行 OCR
│ │
│ └─ 未安装? → 引导安装后执行 OCR
│ │ │
│ │ └─ 安装失败? → 告知使用者环境限制,请求协助
│ │
│ └─ OCR 文本质量可接受? → 进入步骤 2 知识抽取
│ │
│ └─ 仍不佳 → 如实告知,输出已提取部分并标注 `[OCR 识别失败]`
│
└─ NO → 继续流程
无论使用哪种方式,提取后必须检查:
若质量不佳,如实告知使用者并建议换用其他方式。
质量不佳时的正确处理流程:
[提取失败]
质量不佳时的禁止行为:
_知识整理.md 来"补充"缺失内容
PDF 中的图片往往承载关键知识点,不能忽略。
agent 直接在页面渲染中看到图片,无需额外操作。在知识整理时:
images/ 目录
```markdown
!图片说明
```
通过方式 D(OCR)提取时,图片已经在页面渲染中被 Tesseract 处理。此时:
temp_ocr_pages/ 目录
temp_ocr_pages/ 复制到 images/ 目录,使用标准 Markdown 图片语法引用
以下图片必须在知识整理中保留引用或描述:
alt 文本写清图片在原文中的作用
[待确认]
./images/[原PDF名]-p03-fig01.png
这是本 skill 的核心步骤。不是简单的文本搬运或格式转换,而是理解原文内容后重新组织。
根据原文内容的章节编号或标题层级,提取三级标题结构:
| 层级 | Markdown 语法 | 对应内容 |
|------|---------------|----------|
| 顶层 | # [N]标题 | 章节/主题编号+名称 |
| 中层 | ## 中文标题 | 大节标题 |
| 底层 | ### 中文标题 | 小节标题 |
[待确认] 并询问使用者
原文:
"CISC(复杂指令集):
- 特点:指令数量多、长度不固定、执行效率较低
- 实现:微程序控制(软件方式)
RISC(精简指令集):
- 特点:指令精简、长度固定、执行效率高
- 实现:硬布线逻辑+大量寄存器(硬件加速)"
整理后:
- CISC(复杂指令集):
- 特点:指令数量多、长度不固定、执行效率较低
- 实现:微程序控制(软件方式)
- RISC(精简指令集):
- 特点:指令精简、长度固定、执行效率高
- 实现:硬布线逻辑+大量寄存器(硬件加速)
关键:整理后的内容与原文含义完全一致,只是结构和格式更清晰。
原文表格:
┌──────────┬──────────┬──────────┐
│ 特性 │ CISC │ RISC │
├──────────┼──────────┼──────────┤
│ 指令数量 │ 多 │ 少 │
│ 指令长度 │ 不固定 │ 固定 │
│ 执行效率 │ 较低 │ 较高 │
└──────────┴──────────┴──────────┘
整理后(方式一:Markdown 表格):
| 特性 | CISC | RISC |
|------|------|------|
| 指令数量 | 多 | 少 |
| 指令长度 | 不固定 | 固定 |
| 执行效率 | 较低 | 较高 |
整理后(方式二:结构化列表,适合知识点密集时):
- CISC vs RISC 对比:
- 指令数量:CISC 多,RISC 少
- 指令长度:CISC 不固定,RISC 固定
- 执行效率:CISC 较低,RISC 较高
[章节号]--标题_笔记.pdf → [章节号]--标题_知识整理.md
若不确定命名规则,询问使用者。
默认输出到与 PDF 同目录的 knowledge_md/ 子目录。若使用者指定了其他目录,按指定目录输出。
# → ## → ###,不可跳级
- (不是 * 或 + )
术语 仅用于首次出现的重要术语,不要滥用
# [N]主标题
## 第一大节
### 第一小节
- 核心概念:描述内容
- 关键特性:
- 子特性1
- 子特性2
### 第二小节
- 对比关系:
- 类型A:特征描述
- 类型B:特征描述
## 第二大节
### ...
| 场景 | 格式 |
|------|------|
| 定义描述 | - 术语:一句话定义 |
| 分类列举 | - 分类名: + 4空格缩进子项 |
| 对比关系 | - X:特点 / - Y:特点 并列 |
| 流程步骤 | - 步骤1 → 步骤2 → 步骤3 |
| 例题分析 | - 例题:题目 + 4空格缩进 - 解析:过程 |
| 不确定内容 | - [待确认] 描述 |
| 表格 | Markdown 表格或结构化列表 |
当使用者指定处理某个 PDF 时,检查该 PDF 所在目录下是否还有其他 PDF 文件:
.pdf 文件
_知识整理.md 的)
对于批量处理,若当前 agent 支持并行任务执行或子代理派发(如 Claude Code 的 Agent 工具、Gemini 的并行任务等),可并行处理多个 PDF:
若当前 agent 不支持并行处理,则逐个串行处理。
所有 PDF 处理完成后,将输出目录下所有 _知识整理.md 文件整合为一个 Wiki 索引文件。
> 注意:Wiki 生成是在所有 PDF 都处理完成之后进行的,此时读取已完成的知识整理文件是为了建立索引和关联关系,这是合法行为。这与行为准则第 6 条禁止的"在处理某个 PDF 时借用其它文件内容"是完全不同的场景。Wiki 生成只能在所有 PDF 独立处理完成后才能开始。
_知识整理.md 文件
Wiki.md 文件,结构如下:
# 知识库 Wiki
## 目录
| 序号 | 章节 | 文件链接 |
|------|------|----------|
| 1 | 计算机系统基础知识 | [[1]计算机系统基础知识](./[2]--1.计算机系统基础知识_知识整理.md) |
| 2 | 操作系统概述 | [[2.1]操作系统概述](./[3]--2.1操作系统概述-进程管理-同步互斥_知识整理.md) |
| ... | ... | ... |
## 章节间关联
- 第2章(操作系统)是第1章(计算机基础)的深入展开
- 第3章(数据库)与第2章的文件管理相关
- ...
共 4 个版本