:案例拆解 Anthropic 官方 PDF Skill —— 内联代码、References、Scripts 的三层分工)
1. 从一次“打脸”说起PDF Skill 的真实结构长什么样如果你正在给 Claude Code 写自定义 Skill大概率会卡在同一个问题上哪些逻辑该写进 SKILL.md哪些该拆成独立脚本我最初的想法很朴素——SKILL.md 保持精简重活全丢给 scripts这样上下文干净、模型也省 token。直到我把 Anthropic 官方 PDF Skill 的目录完整翻了一遍才发现这个预设站不住脚。官方 PDF Skill 的真实布局是这样的SKILL.md 有 8KB里面塞满了可直接改写的 Python 代码片段REFERENCE.md 17KB讲高级特性和排障FORMS.md 12KB专门讲表单填写scripts/ 目录 22KB8 个 Python 脚本全部围绕表单填写这一个子领域。也就是说SKILL.md 一点都不“薄”它本身就是一本操作教科书而 scripts 只负责一个高风险子任务。这个结构回答了一个更本质的问题内联代码、References、Scripts 不是三选一而是三层分工。内联代码负责即时逻辑让模型按场景改写References 承载规范文档按需加载Scripts 执行重任务保证确定性。本文就按这个三层结构给你一份可复制的 SKILL.md 骨架和目录布局并用 TaoToken 统一 Key 接入后跑通一次 PDF 解析验证。适合谁看想自建 Skill 的开发者、正在纠结“代码放哪层”的工程师、以及被 token 账单和静默错误同时折磨过的人。2. 前置准备用 TaoToken 统一 Key 接入 Claude Code在动手写 Skill 之前先把接入层理顺。Claude Code 这类编码 Agent 的调用量不小如果每个项目、每个工具都单独配一套 Key管理和排查都会很痛苦。我的做法是用 TaoToken 做统一入口一个 Key 覆盖模型对话、编码 Agent、脚本调用等场景。TaoToken 在这里扮演的是统一接入层你拿到一个 Key配置好 base_urlClaude Code 和后续的脚本验证都走同一个出口。这样做的直接好处是——Skill 里调用的模型、你手动验证的模型、CI 里跑的模型行为一致出问题只需要查一个地方。具体操作分三步。第一步去官网注册并进入控制台创建 API Key官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址https://taotoken.net/api第二步在控制台里生成 Key建议按用途命名比如claude-code-pdf-skill方便后面排查时定位。第三步把 Key 写进环境变量不要硬编码进 SKILL.md 或脚本里export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意SKILL.md 和 scripts 都可能被提交到仓库Key 一律走环境变量或密钥管理别图省事写死在文件里。如果你还没创建 Key可以直接走 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys接入文档在这里配置项和兼容性说明都写得比较清楚https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc这一步做完你就有了一条稳定的调用通道。接下来写 Skill 时模型调用和脚本验证都复用这套配置不用再折腾第二遍。3. 三层分工的目录布局与 SKILL.md 骨架先把目录结构定下来。参考官方 PDF Skill 的思路我把它简化成一个可复制的模板你按自己的领域替换即可my-pdf-skill/ ├── SKILL.md # 主入口流程指引 内联代码模板 踩坑警告 ├── REFERENCE.md # 高级特性、罕见场景、排障手册 ├── FORMS.md # 子领域专题表单填写完整工作流 ├── scripts/ │ ├── extract_form_structure.py │ ├── check_bounding_boxes.py │ ├── fill_fillable_fields.py │ └── create_validation_image.py └── assets/ └── fonts/ # 字体、模板等不进 context 的资源三层各自的职责边界用一张表说清楚内容形态放置层判断原因灵活、参数多变的操作SKILL.md 内联代码模型需要按场景改写跨任务的踩坑警告、领域常识SKILL.md 文字段落进 context 才能影响代码生成高级 / 罕见的扩展操作REFERENCE.md普通任务用不上按需载入完整子领域工作流专题 reference如 FORMS.md拆出来不拖累主线复杂逻辑 / 反复调用 / 静默错误代价高scripts/需要确定性避免每次重写模板、字体、资源数据assets/不进 context被 scripts 引用SKILL.md 的骨架长这样注意 frontmatter 要写清楚触发条件正文用“说明 代码模板”的节奏--- name: my-pdf-skill description: Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text/tables, merging, splitting, rotating pages, adding watermarks, filling forms, encrypting, extracting images, and OCR. --- ## Quick Start ### 提取文本 python from pypdf import PdfReader reader PdfReader(document.pdf) print(fPages: {len(reader.pages)}) text for page in reader.pages: text page.extract_text()合并 PDFfrom pypdf import PdfWriter writer PdfWriter() for pdf in [a.pdf, b.pdf]: writer.append(pdf) writer.write(merged.pdf)OverviewThis guide covers essential PDF processing operations. For advanced features and detailed examples, see REFERENCE.md. If you need to fill out a PDF form, read FORMS.md and follow its instructions.IMPORTANT: Never use Unicode subscript/superscript characters in ReportLab PDFs. The built-in fonts do not include these glyphs, causing them to render as solid black boxes. Use ReportLabs XML markup tags in Paragraph objects instead.这里有两个细节值得单独拎出来。第一内联代码是“可改写的模板”不是“照抄的成品”。模型读到 document.pdf 后会按用户实际路径替换再拼装页码循环最后通过 Bash 执行。第二SKILL.md 里那段 IMPORTANT 警告本质是 prompt 工程——它传递的是文档里查不到、模型也不会自己知道的踩坑经验。Scripts 里也能写注释但脚本内容不进 context模型看不到只有写在 SKILL.md 里的经验才能影响代码生成。 ## 4. 可复制配置内联代码、References、Scripts 的落地写法 ### 4.1 内联代码什么时候留在 SKILL.md 判断标准是任务的“变化度”。每次参数都不同、组合方式千变万化就适合内联。比如“提取这个 PDF 的前 3 页文本”“把这两个 PDF 合成一个”“加水印到右下角”如果每种组合都做成脚本数量会爆炸做成模板让模型拼装反而灵活。 内联代码还有一个隐性价值token 友好。简单任务只加载 SKILL.md约 2000 token不用背整个 references。 ### 4.2 References按子领域拆分而不是按大小 官方 PDF Skill 有两个 references分工明确REFERENCE.md 讲高级特性FORMS.md 讲表单填写。SKILL.md 里显式指引“什么场景读哪个”而不是让模型猜。 拆分逻辑是 token 经济学。合并版大概 37KB ≈ 9000 token任何任务都要付这个启动成本。拆开后普通文本提取只读 SKILL.md约 2100 token高级 JS 集成读 SKILL.md REFERENCE.md约 25KB表单填写读 SKILL.md FORMS.md约 20KB。没有任务一次性背 29KB简单任务越多节省越大。 ### 4.3 Scripts三条判断标准 官方 scripts 几乎全部围绕表单填写为什么三个理由逻辑复杂容易写错几何判断、双重循环、边缘条件多次调用形成验证管线提取结构 → 决定值 → 验证 bounding box → 填充 → 渲染校验静默错误代价巨大表单填错用户可能提交后才发现。 总结成判断框架几何/数学/边缘条件密集、会被反复调用、错了代价大——三条满足任一条就考虑 scripts两条以上就一定是 scripts。表单填写三条全占所以整块拆成脚本merge/split/extract 三条都不占所以留内联。 一个脚本的调用示例注意脚本内容不进 context模型只传参看输出 bash python scripts/extract_form_structure.py input.pdf fields.json python scripts/check_bounding_boxes.py fields.json python scripts/fill_fillable_fields.py input.pdf fields.json output.pdf python scripts/create_validation_image.py output.pdf validation.png5. 验证请求跑通一次 PDF 解析配置写完必须验证。我习惯用一段最小可复现的请求确认 Skill 能被正确加载、模型能按内联模板生成代码、脚本能被调用。先准备一个测试 PDF然后用 TaoToken 的 Key 发起一次解析请求。如果你只是想快速验证模型行为可以直接用模型对话页面https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat在对话里输入“用 my-pdf-skill 提取 test.pdf 的文本并告诉我页数。” 预期结果是模型先读 SKILL.md找到 pypdf 的 extract_text 模板替换路径后通过 Bash 执行返回页数和文本片段。如果你想在本地脚本里验证用 curl 走一遍 APIcurl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [ {role: user, content: 提取 test.pdf 的文本并返回页数} ] }成功的结果应该包含两部分模型返回的页数信息以及它实际执行的 Python 代码片段。如果模型直接给出代码但没有执行说明 Skill 的触发条件或工具权限没配对如果报 401检查 Key 和环境变量如果报模型不存在检查 model 字段拼写。验证通过后再跑一次表单填写流程确认 scripts 能被正确调用python scripts/extract_form_structure.py test_form.pdf fields.json cat fields.json | head -20看到字段结构 JSON 输出说明 scripts 层通了。这一步别跳过很多问题都是脚本路径或参数传递导致的。6. 本篇常见错排查错误一SKILL.md 触发不了。最常见原因是 frontmatter 的 description 写得太窄。官方 PDF Skill 的 description 覆盖了 merge、split、rotate、watermark、form、encrypt、OCR 等几乎所有操作任务越多样越需要让模型知道“这个 Skill 能管这么多事”。如果你的 description 只写“处理 PDF”模型可能不触发。错误二内联代码被模型照抄路径没替换。这通常是模板里用了硬编码路径且没有提示模型改写。解决办法是在 SKILL.md 里明确写“根据实际路径调整代码”并在示例里用document.pdf这种明显需要替换的占位符。错误三scripts 调用报文件找不到。检查脚本路径是相对 SKILL.md 还是相对工作目录。建议在 SKILL.md 里统一用相对 Skill 根目录的路径并在调用前cd到正确位置。错误四表单填写后字段重叠。这是典型的静默错误说明跳过了check_bounding_boxes.py验证步骤。表单填写必须走完整管线提取结构 → 决定值 → 验证 bounding box → 填充 → 渲染校验少一步都可能出问题。错误五token 消耗异常高。大概率是把所有内容塞进了一个 SKILL.md。检查是否把高级特性和子领域工作流都内联了该拆到 REFERENCE.md 和专题 reference 的要拆出去。错误六Key 相关报错。401 检查 Key 是否过期或环境变量没生效403 检查权限范围429 检查调用频率。接入文档里有完整的错误码说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc7. 下一步按场景选对入口三层分工的判断框架可以浓缩成一句话灵活多变的操作放内联代码跨任务的经验放 SKILL.md 文字完整子领域工作流拆专题 reference复杂且高风险的逻辑固化成 scripts。如果你接下来要长期写编码 Agent、跑批量任务建议直接用 Coding Plan把 Key 和额度统一管理省得每个项目单独配https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan如果你只是想先验证模型对 Skill 的理解是否符合预期用模型对话页面最快https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat如果你要开始接入自己的项目先去创建 Key再对照接入文档配置https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc最后留一个我踩过的坑别一上来就模仿官方 PDF Skill 的三层结构。大多数 Skill 比它简单得多——只做一件事的直接写 SKILL.md任务多样但简单的SKILL.md 加内联代码就够任务单一但复杂的短 SKILL.md 加一个脚本即可。只有“任务多样 有高风险子领域”这种情况才需要 hybrid 三层结构。先问清楚输入输出是什么、副作用是什么、谁来决策形态自然就清楚了。