Claude Code Skill 完整工作流,从零构建一个 PDF 生成技能 Claude Code Skill 完整工作流从零构建一个 PDF 生成技能本文以一个真实场景为线索完整拆解 Claude Code Skill 的设计原理、数据流转机制和开发实践。一、什么是 Skill在 Claude Code 的体系中Skill 不是插件不是 API也不是自动化脚本。它是一份结构化的「操作手册」——写给大模型看的说明书。当你在 Claude Code 中安装了一个 Skill你并没有安装一个会自动运行的程序。你安装的是一份指令文档它告诉大模型「当用户遇到某类问题时你应该按照这个流程、用这些工具来完成工作。」用一个类比Skill 一本菜谱 大模型 厨师 用户的需求 顾客点的菜 脚本/工具 厨房里的锅碗瓢盆厨师拿到菜谱后会根据顾客点的菜选择对应的菜谱然后使用厨房里的工具做菜。菜谱本身不会自动做菜——它只是一张纸。Skill 的文件结构一个标准的 Skill 目录长这样my-skill/ ├── SKILL.md # 核心指令文件必须有 │ ├── YAML frontmatter # name description触发条件 │ └── Markdown 正文 # 工作流程、命令参考、技巧等 ├── scripts/ # 可执行脚本按需调用 ├── references/ # 参考文档按需加载 └── assets/ # 静态资源模板、字体、图片等其中SKILL.md的 frontmatter 是关键---name:my-skilldescription:这个 Skill 做什么、什么时候该用它。这段文字是大模型决定是否调用的唯一依据。---description字段是触发机制的核心。大模型在每次对话开始时会扫描所有已安装 Skill 的 name 和 description判断当前用户的请求是否匹配。如果匹配就加载完整的 SKILL.md 正文然后按照里面的指令行动。二、Skill 的三层加载机制Skill 不是一次性全部塞进大模型上下文的。它采用了渐进式加载避免浪费 token层级内容加载时机大小第一层name description始终在上下文中~100 词第二层SKILL.md 正文当 Skill 被触发时 500 行第三层scripts/、references/大模型按需读取无限制这意味着即使用户安装了 100 个 Skill日常对话也只加载每个 Skill 的 ~100 词描述总共约 1 万词不会撑爆上下文窗口。只有当用户真正需要某个 Skill 时才会加载详细指令。三、从零构建PDF Generator Skill接下来我用一个完整的实战案例来展示如何构建一个 Skill。3.1 明确需求我们的目标是构建一个 PDF 生成 Skill支持输入Markdown 文本 结构化数据JSON/CSV功能图文混排、封面页、页眉页脚、页码、数据表格技术栈Python fpdf2纯 Python 库无需系统依赖3.2 创建目录结构mkdir-p~/.claude/skills/pdf-generator/{scripts,references,assets}3.3 编写 SKILL.md这是 Skill 的灵魂。一份好的 SKILL.md 应该包含以下要素---name:pdf-generatordescription:从 Markdown 文本、结构化数据JSON/CSV或二者混合生成专业 PDF 文档。 当用户要求创建、生成、导出或保存 PDF 时使用此技能 或当用户提到报告、发票、证书、简历时也应使用——即使他们没有明确说PDF。---注意 description 的写法——它需要覆盖尽可能多的触发场景但不能过度泛化。一个好的 description 应该像搜索引擎的 SEO 描述精确命中目标查询同时不误伤无关请求。正文部分按工作流组织## 工作流程 ### 第 1 步了解用户需求 从上下文中判断或询问内容类型、风格、特殊部分、输出路径 ### 第 2 步准备输入 根据内容来源准备 Markdown 文件或 JSON/CSV 数据文件 ### 第 3 步生成 PDF 运行脚本传入合适的命令行参数 ### 第 4 步验证和交付 打开 PDF 确认效果告诉用户文件保存位置3.4 编写核心脚本脚本是 Skill 的「手」——它把大模型的意图转化为实际的输出。我们的generate_pdf.py核心架构如下# 三大核心组件classPDFDocument(FPDF):PDF 文档类 —— 管理页面、页眉页脚、封面classMarkdownParser:Markdown 解析器 —— 把 Markdown 转换为 PDF 绘制指令defparse(self,markdown_text):# 逐行解析标题 → _render_heading()# 列表 → _render_bullet()# 段落 → _render_paragraph()# 图片 → _add_image()# 分页 → add_page()classDataTableRenderer:数据表格渲染器 —— 把 JSON/CSV 渲染为带样式的表格defrender_from_file(self,filepath):# 读取 JSON 或 CSV# 计算列宽# 渲染表头主色背景 白色文字# 渲染数据行交替背景色# 自动跨页断行 表头重复脚本的命令行接口是大模型和实际功能之间的桥梁python generate_pdf.py\--outputreport.pdf\# 输出路径--content-file report.md\# Markdown 文本来源--data-file metrics.json\# 数据表格来源--title年度报告\# 文档标题--cover\# 生成封面--themeprofessional# 配色主题3.5 编写参考文档references/style-guide.md提供详细的样式定制说明字体、颜色、间距等只有在用户需要深度定制时才被读取。四、核心问题Skill 如何接收和处理用户的语料这是理解 Skill 最关键的部分。很多人误以为 Skill 会自动扫描用户的文件或自动识别内容。实际上整个数据流转的桥梁是大模型本身。4.1 完整的数据流┌─────────────────────────────────────────────────────────┐ │ 用户对话 │ │ │ │ 用户帮我写一篇技术分析报告 │ │ 大模型生成 Markdown 内容 │ │ 用户把上面的内容生成 PDF │ │ │ ├─────────────────────────────────────────────────────────┤ │ Skill 触发阶段 │ │ │ │ 1. 大模型扫描已安装 Skill 的 description │ │ 2. 发现 pdf-generator 的描述匹配 生成 PDF │ │ 3. 加载 SKILL.md 正文 │ │ 4. 按照 SKILL.md 中的工作流执行 │ │ │ ├─────────────────────────────────────────────────────────┤ │ 数据准备阶段 │ │ │ │ 大模型从对话上下文中提取之前生成的 Markdown │ │ ↓ │ │ 写入临时文件如 /tmp/extracted-content.md │ │ 或者直接作为 --content 参数传入 │ │ ↓ │ │ 如果有数据文件直接使用文件路径 │ │ │ ├─────────────────────────────────────────────────────────┤ │ 脚本执行阶段 │ │ │ │ python generate_pdf.py \ │ │ --content-file /tmp/extracted-content.md \ │ │ --data-file /data/metrics.json \ │ │ --output report.pdf \ │ │ --cover --theme professional │ │ │ │ 脚本接收的是命令行参数文件路径或字符串 │ │ 脚本不知道对话上下文、Skill、大模型的存在 │ │ │ ├─────────────────────────────────────────────────────────┤ │ 结果交付阶段 │ │ │ │ 大模型验证 PDF 文件已生成 │ │ 告诉用户PDF 已生成保存在 /path/to/report.pdf │ │ │ └─────────────────────────────────────────────────────────┘4.2 三种语料来源的处理方式场景 A语料在对话上下文中用户之前的对话中已经生成了 Markdown 内容 ↓ 大模型从上下文中提取该内容 ↓ 方案 1直接作为 --content 参数传入 python generate_pdf.py --content # 标题\n\n段落内容... 方案 2写入临时文件再用 --content-file 传入内容较长时推荐 echo ... /tmp/content.md python generate_pdf.py --content-file /tmp/content.md场景 B语料是磁盘上的文件用户把 /data/report.md 生成 PDF ↓ 大模型直接使用用户提供的文件路径 ↓ python generate_pdf.py --content-file /data/report.md场景 C语料是混合来源用户做一份报告文字内容我来写数据在 sales.json 里 ↓ 大模型将用户提供的文字 读取用户的文件合并传入 ↓ python generate_pdf.py \ --content # 销售报告\n\n## 概述\n... \ --data-file /data/sales.json \ --title Q4 销售报告 \ --cover4.3 关键认知常见误解实际情况Skill 会自动扫描我的文件不会。是大模型根据对话内容决定读哪些文件Skill 会自动识别语料格式不会。是大模型判断内容类型选择对应的脚本参数脚本能访问对话上下文不能。脚本只接收命令行参数和文件路径我需要记住脚本的命令行参数不需要。你只需用自然语言描述需求五、设计一个好的 Skill 的核心原则在构建 PDF Generator 的过程中我总结了几条关键原则原则 1描述要「强势」但不能泛滥# 太弱 — 大模型经常不会触发description:生成 PDF 文档# 太泛 — 什么文档相关的请求都会触发description:处理各种文档生成需求# 合适 — 精准覆盖目标场景description:从 Markdown 或 JSON/CSV 生成专业 PDF。 当用户要求创建、导出 PDF或提到报告、发票、证书时使用。 即使他们没说PDF也应使用。原则 2解释 Why而不是堆砌 MUST与其写## 必须在生成 PDF 前先安装依赖不如写## 快速开始 首次使用需要安装依赖fpdf2 库否则脚本会报 ModuleNotFoundError大模型足够聪明当你解释了「为什么」它能更好地判断在什么情况下需要跳过、在什么情况下必须执行。原则 3脚本是桥不是门脚本应该是一个纯粹的「输入 → 输出」转换器。它不应该关心数据从哪来、谁来调用它。这种无状态设计让脚本可以被 Skill 调用也可以被用户直接在命令行使用还可以被其他工具链集成。原则 4让大模型做它擅长的事大模型擅长理解意图、提取上下文、准备输入、判断用哪个参数。脚本擅长精确的文件处理、格式转换、排版计算。不要试图让脚本理解自然语言也不要试图让 SKILL.md 里的指令精确到每行代码。各司其职效果最好。六、总结用户需求自然语言 │ ▼ 大模型判断 → 匹配 Skill 的 description → 加载 SKILL.md │ ▼ 大模型理解工作流 → 从对话/文件中提取语料 → 准备输入 │ ▼ 调用脚本 → 脚本执行纯函数式参数入文件出→ 生成 PDF │ ▼ 大模型验证结果 → 交付给用户Skill 的本质是一套协作协议它定义了大模型、脚本和用户之间的分工。大模型负责理解和调度脚本负责精确执行用户负责表达需求。三者之间通过文件路径和命令行参数传递数据没有魔法只有清晰的数据流。掌握了这个框架你就可以构建任何类型的 Skill —— 不仅是 PDF 生成还可以是 Excel 导出、PPT 制作、代码生成、自动化测试…… 原理都是一样的。