- 人工智能
- AI 应用
- AI 技能
- RAG
- MCP 服务
- 网页爬虫
【免费下载链接】Skill_Seekers
Convert documentation websites, GitHub repositories, and PDFs into Claude AI skills with automatic conflict detection
本文以 Skill_Seekers 仓库中 tests/golden/phase2/pdf_chapters/references/section_p1-p2.md 为切入口,系统讲解 PDF 文档抓取器(PDFToSkillConverter)在"章节分类"路径下生成的参考文件(reference file)的完整格式规范。读完本文,你将掌握 Skill_Seekers 如何把 PDF 按章节切分、为每个章节生成带页码锚点与代码示例的 Markdown 参考文件,以及这套输出如何被字节级 golden 测试所固化。
一、这份文件在项目中扮演什么角色
section_p1-p2.md不是一份普通的教程文档,而是Phase 2 DocumentSkillBuilder 重构的 golden 输出规范(golden artifact)。它位于测试夹具树tests/golden/phase2/pdf_chapters/下,与 SKILL.md、index.md、section_p3-p3.md、section_p4-p4.md 共同构成"按章节分类"这条构建路径的期望输出快照。
golden 测试的协议由 tests/phase2_golden_utils.py 定义:重构前先从旧代码捕获输出(UPDATE_GOLDENS=1 pytest <test>写入 tests/golden/phase2/ 目录),重构后同一测试以比对模式运行,任何字节差异都会导致测试失败。测试文件 tests/test_phase2_golden_pdf.py 的模块 docstring 明确说明:golden 树来自重构前的代码,用于证明移植后输出与旧实现字节级一致(byte-identical)。
从内容看,这份规范文件本身是虚构的"manual.pdf"(元数据 title 为 "The Manual"、author 为 "Jane Doe")经过抓取后的产物——它演示的不是真实产品文档,而是输出格式的规范化样例。
二、章节分类:三类路由与一个兜底分支
section_p1-p2.md对应标题为 "Chapter 1: Basics"、覆盖 PDF 第 1~2 页的章节。分类逻辑实现在 pdf_scraper.py 的 categorize_content,按优先级走四条路径:
- 单源快速路径:配置了
pdf_path时,整份 PDF 作为一个分类,不拆章(避免错误章节检测把内容切碎)。此路径没有chapters时直接返回单分类。 - 章节范围路径:
extracted_data携带chapters列表(每项含title、start_page、end_page)时,逐页匹配start_page <= page_number <= end_page归入对应章节;任何章节都不覆盖的页面进入uncategorized分类,标题固定为 "Additional Content"。 - 关键词路径:无
chapters但有categories配置时,按关键词对每页text与headings列表做加权打分(PDF 页没有顶层heading键,必须对headings列表逐条匹配),得分最高者胜出;无命中则落入 "Other" 桶。若categories的值已是"页列表"格式则原样采用。 - 全量兜底:以上都不满足时,所有页归入 "Content" 单分类。
第 2 条路径在 test_pdf_chapter_categorization_matches_golden 中被精确验证:测试数据定义了Chapter 1: Basics (1-2)与Chapter 2: Advanced (3-3),并额外追加一页 page 4(标题 "Appendix material outside any chapter.")来触发 "Additional Content" 桶——这正是 section_p4-p4.md 的内容来源。测试通过converter.extracted_data = data注入数据并断言快照与 golden 完全一致。
三、参考文件的逐行生成格式
section_p1-p2.md的每个元素都由 _generate_reference_file 生成。以该文件为标本,逐块对照源码:
# Chapter 1: Basics **Pages**: 1-2- 首行
# {cat_data['title']}:分类标题,取自 chapters 配置中的title; - 次行
**Pages**: {min}-{max}:取该分类所有页的page_number最小/最大值。
**📄 Source: PDF Page 1** ## Getting Started Guide- 每个页面以
---分隔,并写入**📄 Source: PDF Page {page_number}**溯源标记; - 只取每页
headings列表的第一项作为该页##小节标题(源码中f.write(f"## {page['headings'][0]['text']}\n\n")); - 随后写入整页
text内容(源码注释注明已移除 1000 字符上限)。
### Code Examples ```python print('hello')pip install thing- 代码块读取**双键兼容**逻辑:`page.get("code_samples") or page.get("code_blocks")`,后者是为兼容旧格式(raw-bytes 时代)保留的回退键,[PAGES 夹具](https://link.gitcode.com/i/336dd7edce941b1c938a5c2da0072ea6#L19-L58) 中第 3 页只用 `code_blocks` 键来覆盖该分支; - 代码块按 `language` 字段原样包裹为 ` ```{lang} ` 围栏,不做转义或截断。 图片部分分两种格式(见下文第五节),第 2 页对应 `[](https://link.gitcode.com/i/8897a681df80b463af096672b653cb66)`,指向 golden 树中 [assets/page_2_img_0.png](https://link.gitcode.com/i/b377e49fb77538f63f0dca993d709654)。 ## 四、参考文件命名规则:p1-p2 从何而来 文件名为 `section_p1-p2.md`,命名由 [scraper_utils.py 的 reference_filename](https://link.gitcode.com/i/6a316ac47efcbc8453ea7b84f0701c0b) 统一生成: - 分类内无页面时回退为 `section_{序号:02d}.md`; - 只有一个分类且提供了源文件名时用 `{源文件名}.md`; - 多分类时取 `{base_stem}_{prefix}{min}-{prefix}{max}.md`。PDF 路径中 `NUMBER_KEY="page_number"`、`NUMBER_PREFIX="p"`([pdf_scraper.py 类属性](https://link.gitcode.com/i/29fb4e640249613bfacf059f7aad4c9e)),于是第 1~2 页生成 `section_p1-p2.md`,第 3 页生成 `section_p3-p3.md`,第 4 页生成 `section_p4-p4.md`;其它抓取器(Word/EPUB/HTML/PPTX 等)使用 `section_number` + 前缀 `s`。 该函数是"单一事实来源"(DOC-07 设计约束):文件写入、`index.md` 分类行、[SKILL.md 的 Navigation 块](https://link.gitcode.com/i/fa9053eed54d23db417cdd024af230a2#L143-L151) 三处都调用同一函数取文件名,保证链接永不漂移([document_skill_builder.py 的 _reference_filename](https://link.gitcode.com/i/098b8a804278e0fe30fadfa90b819f2f))。 ## 五、图片处理的两种格式 `_generate_reference_file` 对图片分两种来源处理: - **extracted_images(预落盘格式)**:图片已在提取阶段由 `PDFExtractor` 保存到 `{skill_dir}/assets/images/`,参考文件只写链接 `Image from page {n}`,不重复写文件。第 1 页的 `manual_page1_img1.png`(100×80,宽高取自夹具)即属于此类——注意 golden 树中并未包含该 PNG,它只作为格式样例被链接; - **images(raw-bytes 旧格式)**:图片数据以字节随页面数据存在,生成时写入 `assets/page_{页号}_img_{索引}.png` 再链接。第 2 页夹具数据为 `b"\x89PNG-fake-bytes"`,源码对 `data` 键做了**防御性校验**([L329-L331](https://link.gitcode.com/i/696d7e1761d5e370652aa35f6397fe13)):缺失 `data` 键、非 bytes 或空值都会直接跳过,避免 KeyError/TypeError 或写出 0 字节坏图导致整个参考文件写入中断——这是从实际崩溃中修复得来的健壮性设计。 提取阶段的相关参数([extract_pdf](https://link.gitcode.com/i/1bc4834cd0157cbb77fe4499a7c0646a))包括 `chunk_size`(默认 10)、`min_quality`(默认 5.0)、`extract_images`(默认 True)、`min_image_size`(默认 100),均可通过配置的 `extract_options` 覆盖。 ## 六、数据模型、统计与 SKILL.md 联动 `section_p1-p2.md` 背后的数据模型([_extracted_data 夹具](https://link.gitcode.com/i/336dd7edce941b1c938a5c2da0072ea6#L61-L70))包含:`pages`(每页 `page_number`/`text`/`headings`/`code_samples`)、`total_pages`、`total_code_blocks`、`total_images`、`metadata`、`languages_detected`、`quality_statistics`。这些字段会传导到三层输出: - **index.md**([索引生成与统计钩子](https://link.gitcode.com/i/69aa012c49ab02643b7b35ccfcda5c10)):列出各分类链接、页数,以及 Total pages / Code blocks / Images / Average code quality / Valid code blocks; - **SKILL.md**([_generate_skill_md](https://link.gitcode.com/i/13cc45e06b611437511348c62b69eed1)):生成 YAML frontmatter(name 转小写连字符、description 截断 1024 字符)、Chapter Overview 内容占比、Key Concepts(headings 按 h1/h2 分组,跳过 ≤3 字符的短标题)、Quick Reference(11 个模式关键词匹配 headings 并标注页码)、Code Examples(**全局按 quality_score 降序取 Top 15,每语言再取前 5,代码超过 500 字符截断加省略号**)、语言分布与质量统计、Navigation 链接清单、页脚 "Generated by Skill Seeker | PDF Documentation Scraper"; - **参考文件**:即本文解析的 `section_p1-p2.md` 等。 本夹具中的排序效果可验证:第 2 页 60 行 `long_example()`(quality 9.5)排在示例第一位,第 1 页 `print('hello')`(8.5)与 `pip install thing`(6.0)随后,与 [SKILL.md 的 Code Examples 区块](https://link.gitcode.com/i/fa9053eed54d23db417cdd024af230a2#L59-L123) 完全对应。 ## 七、如何复现与验证这套输出 在仓库根目录运行对应测试即可逐字节验证: ```bash # 比对模式:任何与 golden 的字节差异都会失败 pytest tests/test_phase2_golden_pdf.py -v # 仅在确有意图时重新捕获 golden(会覆盖已提交的规范文件) UPDATE_GOLDENS=1 pytest tests/test_phase2_golden_pdf.py三条用例分别覆盖三种构建路径:test_pdf_build_matches_golden(单源)、test_pdf_keyword_categorization_matches_golden(关键词,含 "other" 桶与空分类 "deployment")、test_pdf_chapter_categorization_matches_golden(章节,含 "Additional Content" 桶),并复用 tests/phase2_golden_utils.py 的build_snapshot(递归快照 skill_dir 全部文件字节)与assert_matches_golden(集合与逐字节双重比对)。生产环境下,PDF 转 Skill 的入口为 pdf_scraper.py 的命令行:python3 pdf_scraper.py --pdf manual.pdf --name myskill,或通过--config指定含pdf_path、extract_options、categories、chapters等键的 JSON 配置。
八、小结
section_p1-p2.md虽表面简洁,却是 Skill_Seekers PDF 抓取器"章节分类"路径的输出契约:它同时锁定了参考文件的标题/页码范围/溯源标记/首标题/全文/代码示例/图片链接的排版顺序,文件名p1-p2的生成规则,以及 SKILL.md 与 index.md 的统计联动。理解这份 golden 规范,等于掌握了 PDFToSkillConverter 从chapters数据到最终 Skill 产物的全部转换细节——这也是 Phase 2 重构保证输出字节级不变的根基所在。
- 人工智能
- AI 应用
- AI 技能
- RAG
- MCP 服务
- 网页爬虫
【免费下载链接】Skill_Seekers
Convert documentation websites, GitHub repositories, and PDFs into Claude AI skills with automatic conflict detection
相关推荐
Skill_Seekers PPTX 抓取器输出格式全解析:Golden 参考索引与演示文稿技能生成规范
Skill_Seekers PPTX 抓取器输出格式全解析:Golden 参考索引与演示文稿技能生成规范 本篇技术指南聚焦 Skill_Seekers 项目中
人工智能AI 应用AI 技能RAGMCP 服务网页爬虫Skill_Seekers PDF 文档转 Skill 参考文件格式规范:从 golden 输出到源码实现深度解析
Skill_Seekers PDF 文档转 Skill 参考文件格式规范:从 golden 输出到源码实现深度解析 本篇技术指南以仓库 tests/golden
人工智能AI 应用AI 技能RAGMCP 服务网页爬虫Skill_Seekers HTML 爬虫关键词分类输出解析:从 golden 基准文件 section_s2-s2.md 看文档转 Skill 的规范管线
Skill_Seekers HTML 爬虫关键词分类输出解析:从 golden 基准文件 section_s2 s2.md 看文档转 Skill 的规范管线 导
人工智能AI 应用AI 技能RAGMCP 服务网页爬虫
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考