前置条件
- 已安装 Claude Code(本章主要在这个环境演示)
- Python 3.10+,装
pypdf、reportlab - 随便找一个带可填字段的 PDF(税表、报销单都行)
为什么从 Claude Code 开始
Claude Code 的 Skill 迭代最快——你改完文件保存,下一次调用就生效。API / Claude.ai 的 Skill 管理要上传打包,适合 Skill 成熟后再迁移。
Claude Code 的 Skill 迭代最快——你改完文件保存,下一次调用就生效。API / Claude.ai 的 Skill 管理要上传打包,适合 Skill 成熟后再迁移。
Step 1: 创建 Skill 目录
# 用户级 Skill(所有项目都能用) mkdir -p ~/.claude/skills/pdf-form-filler/scripts mkdir -p ~/.claude/skills/pdf-form-filler/references cd ~/.claude/skills/pdf-form-filler # 或项目级 Skill(只在当前项目生效) mkdir -p .claude/skills/pdf-form-filler/scripts
Claude Code 会自动扫 ~/.claude/skills/ 与项目的 .claude/skills/。项目级优先级更高——同名 Skill 会覆盖用户级。
Step 2: 写 SKILL.md
--- name: pdf-form-filler description: > 自动填写 PDF 可填表单(AcroForm)。 激活条件:用户提供 PDF 路径,且要求"填表"、 "fill form"、"自动填"、"签这个表"。 支持文本域、单选、多选、日期。不处理签字图片, 签字域只能留空或插入文字。 allowed-tools: Bash, Read, Write --- # PDF 表单填写 当用户需要填写 PDF 表单时使用本 Skill。 ## 工作流 1. 用 `scripts/detect_fields.py <pdf>` 列出所有字段,返回 JSON。 2. 根据用户给的数据,生成 `data.json`(字段名 → 值)。 3. 用 `scripts/fill.py <pdf> <data.json> <out.pdf>` 填充。 4. 打印 out.pdf 的路径给用户。 ## 边界 - 遇到 `FieldType: Signature` 的字段,按 `references/signature-guide.md` 处理。 - 金额字段务必按 `references/amount-format.md` 校验小数位。 - 输入 PDF 不是可填表单(AcroForm)时,明确告诉用户"这是扫描件,需先 OCR",不要自己硬填。
description 写法的关键
反例:
description 不只是介绍——它是 Claude 的激活判据。写清楚在什么输入下激活、不处理什么,Claude 会更准确地知道何时调用这个 Skill。反例:
description: PDF 工具——含糊,Claude 可能一见 PDF 就激活,但你的 Skill 只处理可填表单。
Step 3: 写 detect_fields.py
# scripts/detect_fields.py import sys, json from pypdf import PdfReader def main(pdf_path: str): reader = PdfReader(pdf_path) fields = reader.get_fields() or {} result = [] for name, f in fields.items(): result.append({ "name": name, "type": f.get("/FT", ""), "value": f.get("/V", ""), }) print(json.dumps(result, ensure_ascii=False, indent=2)) if __name__ == "__main__": main(sys.argv[1])
Step 4: 写 fill.py
# scripts/fill.py import sys, json from pypdf import PdfReader, PdfWriter def main(pdf_in, data_json, pdf_out): data = json.load(open(data_json)) reader = PdfReader(pdf_in) writer = PdfWriter(clone_from=reader) for page in writer.pages: writer.update_page_form_field_values(page, data) with open(pdf_out, "wb") as f: writer.write(f) print(f"OK: {pdf_out}") if __name__ == "__main__": main(*sys.argv[1:])
Step 5: 写两份 reference
references 不会默认加载,Claude 只在读到"签字域"、"金额"时才去 grep 读取,不占激活期 token。
# references/signature-guide.md PDF 签字域(FieldType=Sig)是特殊字段,pypdf 无法写入图片签名。 遇到时的策略: 1. 如果用户给了文字签名(如"张三"),插入文字,不插图片。 2. 如果用户要图片签,告知"需用 PyPDF2 + reportlab 叠加,超出本 Skill 范围"。 3. 保留字段为空,不要报错。 # references/amount-format.md 金额字段校验: - 保留 2 位小数:`f"{amount:.2f}"` - 不加货币符号(表单里一般有 $ 或 ¥ 的印刷符号) - 大于 999 的要加千分位:`f"{amount:,.2f}"`
Step 6: 在 Claude Code 里调用
# 启动 Claude Code,进入你有 PDF 的目录 claude # 对话: > 帮我填一下 expense.pdf,数据在 data.json
Claude 会做这些事:
- 扫描本地 Skills,看到
pdf-form-filler的 description 匹配"填表" - 激活 Skill,读完整的 SKILL.md
- 按工作流调用
detect_fields.py,拿到字段列表 - 对照
data.json生成映射 - 遇到"金额"字段,主动 read
references/amount-format.md - 运行
fill.py,把结果写到expense_filled.pdf - 返回文件路径
Claude 没激活你的 Skill?
最常见的原因:
最常见的原因:
description 太模糊。把它改明确,或者在 Claude Code 里直接说 "use pdf-form-filler skill to ..."——显式激活永远有效。
Step 7: 迭代
用几个不同的 PDF 测试,看哪里不对。常见迭代点:
- 字段名含空格或中文 → 在
detect_fields.py里 normalize - 复选框值不是
true而是/Yes、/Off→ 在 references 里记下映射 - 激活失败 → 改 description 的关键词命中率
- Claude 忘记某个规则 → 把规则从 reference 提升到 SKILL.md 正文(更早加载)
本章你已经掌握
Skill 目录结构、SKILL.md 的 YAML + 正文写法、脚本与 references 的分工、在 Claude Code 里的调用流程。这已经是一个能跑的最小闭环——下一章开始深入 SKILL.md 的规范细节。
Skill 目录结构、SKILL.md 的 YAML + 正文写法、脚本与 references 的分工、在 Claude Code 里的调用流程。这已经是一个能跑的最小闭环——下一章开始深入 SKILL.md 的规范细节。
本章小结
- Skill 放在
~/.claude/skills/<name>/或项目.claude/skills/<name>/ - SKILL.md 的 YAML frontmatter 里,
description是激活判据,写清楚适用条件 - 脚本放
scripts/,深度资料放references/,这两个目录按需加载 - Claude Code 是最快的迭代环境,保存即生效
- 迭代 Skill 的核心:让 description 精准、让 SKILL.md 覆盖主流程、让 references 兜底边界