1. 为什么我要把 PDF 生成做成 Claude Code Skill
我平时写技术文档、周报、项目复盘,最后一步总是要导出 PDF。以前的做法是:Markdown 写完,手动打开编辑器导出,或者写个一次性脚本,每次改参数改到烦。后来我把这套流程固化成了一个 Claude Code Skill,现在只要在对话里说一句「把刚才的内容导出成 PDF」,它自己就会走完整个流程。
先说清楚这个 Skill 到底是什么。Claude Code 里的 Skill 不是插件,也不是会自动跑的后台程序,它更像一份写给大模型看的操作手册。你安装一个 Skill,本质上是往它的技能库里放了一份结构化说明:遇到什么类型的请求、按什么步骤做、调用哪个脚本、传什么参数。大模型在每轮对话开始时会扫描所有已安装 Skill 的 name 和 description,判断当前请求是否匹配,匹配上了才加载完整正文。
所以「Claude Code Skill 完整工作流」这件事,核心不是写代码,而是设计一份让大模型能准确理解、稳定执行的说明书,再配一个职责单一的脚本。这篇就聚焦 PDF 生成这个具体场景,从目录结构、触发词设计、依赖安装,到本地调试和报错排查,把端到端流程跑通。适合已经在用 Claude Code、想把自己的重复操作沉淀成 Skill 的人,也适合刚接触 Skill 机制、想找一个完整案例跟做的读者。
我试过把 PDF 生成直接写成一个普通脚本,问题是每次都要自己记参数、自己拼命令。做成 Skill 之后,参数由大模型根据上下文填,我只需要用自然语言描述需求。这个差别在内容长、格式要求多的时候特别明显。
下面按「先讲清机制 → 再给可复制配置 → 再验证 → 再排错」的顺序展开,每一步都能直接跟做。
2. TaoToken 统一 Key 接入 Claude Code 的前置准备
在写 Skill 之前,得先让 Claude Code 能正常调用模型。这里用 TaoToken 的统一 Key 和 API 通道接入,好处是一个 Key 走通对话、编码、Agent 几类场景,不用为每个工具单独配一套凭证。
先明确几个地址,后面配置里会反复用到:
- 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- API 基址:https://taotoken.net/api
- 模型对话页:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
- Coding Plan:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
- 控制台:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
- API Keys 管理:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
- 接入文档:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
拿到 Key 的路径是:进控制台,在 API Keys 页面创建一个新 Key,复制出来。这个 Key 就是后面所有配置里的ANTHROPIC_AUTH_TOKEN或OPENAI_API_KEY的值。注意 Key 只在创建时完整显示一次,先存到本地环境变量或配置文件里,别直接写进会提交到 Git 的文件。
Claude Code 走的是 Anthropic 兼容协议,所以配置里要设ANTHROPIC_BASE_URL指向 TaoToken 的 API 基址,ANTHROPIC_AUTH_TOKEN填你的 Key。如果你用的是 Codex 这类走 OpenAI 协议的工具,就对应OPENAI_BASE_URL和OPENAI_API_KEY。三件套永远是:Base URL、Key、Model ID,缺一个都连不上。
Model ID 这块,Claude Code 场景一般填 Claude 系列模型标识,具体可用的模型名在接入文档里有列表,按文档填就行。别自己猜模型名,填错了会直接返回模型不存在的错误。
环境变量配置示例(Linux/macOS,写进~/.zshrc或~/.bashrc):
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="sk-你的Key" export ANTHROPIC_MODEL="你的ModelID"Windows PowerShell 用$env:ANTHROPIC_BASE_URL="https://taotoken.net/api"这种写法,或者写进系统环境变量面板。配完记得重开终端,让变量生效。
验证连通性最直接的方式是发一条最小请求:
curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_AUTH_TOKEN" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{"model":"你的ModelID","max_tokens":64,"messages":[{"role":"user","content":"ping"}]}'返回里有正常的content字段就说明通道通了。如果返回 401,先检查 Key 有没有复制完整、有没有多余空格;如果返回模型相关错误,检查 Model ID 是否和文档一致。这一步通了,再往下写 Skill 才有意义,否则后面所有报错都会混在一起,很难定位。
3. 可复制的 PDF Generator Skill 配置片段
这一节是全文最核心的部分,给出可以直接复制落地的目录结构、SKILL.md、脚本和配置片段。路径统一用~/.claude/skills/pdf-generator/,和 Claude Code 默认扫描路径保持一致。
先建目录:
mkdir -p ~/.claude/skills/pdf-generator/{scripts,references,assets}目录结构如下:
pdf-generator/ ├── SKILL.md ├── scripts/ │ └── generate_pdf.py ├── references/ │ └── style-guide.md └── assets/ └── (字体、模板等静态资源)SKILL.md的 frontmatter 是触发机制的核心,name 和 description 决定大模型会不会调用它。description 要精准覆盖目标场景,又不能泛化到误伤无关请求。可复制版本:
--- name: pdf-generator description: 从 Markdown 文本、JSON/CSV 结构化数据或二者混合生成专业 PDF 文档。当用户要求创建、生成、导出、保存 PDF,或提到报告、发票、证书、简历、周报时使用,即使没有明确说"PDF"也应使用。 --- ## 工作流程 ### 第 1 步:确认需求 从上下文判断内容类型、风格、输出路径;信息不足时向用户确认。 ### 第 2 步:准备输入 内容来自对话上下文时,写入临时文件;来自磁盘文件时直接使用路径。 ### 第 3 步:生成 PDF 调用 scripts/generate_pdf.py,传入对应参数。 ### 第 4 步:验证交付 确认文件已生成,告知用户保存路径。脚本scripts/generate_pdf.py用 fpdf2,纯 Python 依赖,不需要系统级库。核心命令行接口:
python scripts/generate_pdf.py \ --output report.pdf \ --content-file /tmp/content.md \ --data-file /data/metrics.json \ --title "年度报告" \ --cover \ --theme professional脚本本身保持无状态:只接收命令行参数和文件路径,不关心对话上下文。这样它既能被 Skill 调用,也能被你在终端直接跑。
如果你用 Cline MCP 或 CC Switch 管理多个模型通道,配置里同样要写全三件套。以 CC Switch 的配置片段为例:
{ "provider": "taotoken", "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的Key", "model": "你的ModelID" }Codex 的auth.json结构类似,把 base URL、Key、Model ID 三项填全即可。Cline MCP 的 settings 里也是同样三个字段,别只填 Key 漏掉 Base URL,否则会走默认地址导致连不上。
references/style-guide.md放深度定制说明,比如字体、颜色、间距、页眉页脚规则。它不会在 Skill 触发时全部加载,只有用户明确要求定制样式时,大模型才会按需读取,这样能省 token。
依赖安装放在脚本首次运行前:
pip install fpdf2装完可以单独测脚本,不经过大模型:
python scripts/generate_pdf.py --content "# 测试\n\n这是一段测试内容" --output /tmp/test.pdf能生成文件,说明脚本这一层没问题,剩下的就是 Skill 触发和参数传递的事了。
4. 验证请求与成功结果:从输入到产出 PDF
配置写完,得有一条完整的验证链路,确认「对话 → Skill 触发 → 脚本执行 → PDF 产出」整条路是通的。这一步别跳,很多人卡在「以为配好了其实没触发」。
先做脚本层验证。准备一个 Markdown 文件:
cat > /tmp/demo.md <<'EOF' # 季度技术复盘 ## 概述 本季度完成了三个核心模块的重构。 ## 数据 见附表。 EOF再准备一个 JSON 数据文件:
cat > /tmp/metrics.json <<'EOF' [ {"模块": "鉴权", "状态": "完成", "耗时": "5d"}, {"模块": "导出", "状态": "完成", "耗时": "3d"} ] EOF执行生成命令:
python scripts/generate_pdf.py \ --content-file /tmp/demo.md \ --data-file /tmp/metrics.json \ --output /tmp/report.pdf \ --title "季度技术复盘" \ --cover \ --theme professional成功时终端会输出类似PDF generated: /tmp/report.pdf,用ls -lh /tmp/report.pdf能看到文件大小非零。打开确认封面、正文、表格都在,脚本层就算过了。
再做 Skill 层验证。回到 Claude Code 对话,输入:
把 /tmp/demo.md 和 /tmp/metrics.json 生成一份带封面的 PDF,标题叫季度技术复盘预期行为是:大模型扫描到 pdf-generator 的 description 匹配「生成 PDF」,加载 SKILL.md 正文,按工作流提取文件路径,拼出脚本命令并执行,最后告诉你文件保存位置。如果它没触发,说明 description 没命中,回到第 3 节调整措辞。
验证模型通道是否正常,可以顺手在模型对话页发一条测试请求,确认 Key 和 Model ID 都对。这一步和 Skill 无关,但能帮你把「模型连不上」和「Skill 没触发」两类问题分开。
整条链路跑通后,你会看到这样的结果:自然语言输入 → 大模型判断并调度 → 脚本执行 → PDF 文件落地 → 大模型回报路径。中间没有魔法,全是清晰的数据流。脚本不知道对话上下文的存在,大模型也不关心 PDF 内部怎么排版,各司其职。
如果要做长期编码或 Agent 类任务,把这类 Skill 和 Coding Plan 配合用会更顺,通道稳定了,Skill 的触发和执行才不会被网络问题打断。
5. 本篇常见错误排查:401、local proxy failed 与 reading choices
这一节按真实报错来对,遇到问题直接查表。
401 Unauthorized:最常见。原因通常是 Key 没填、填错、有多余空格,或者环境变量没生效。排查顺序:先echo $ANTHROPIC_AUTH_TOKEN看变量是否为空;再确认 Key 有没有复制完整;最后确认 Base URL 是不是https://taotoken.net/api,地址写错也会返回鉴权失败。改完环境变量记得重开终端。
local proxy failed:这个报错一般出现在本地有代理层或转发层的时候。先确认没有多余的本地转发配置在拦截请求,检查环境里有没有残留的HTTP_PROXY、HTTPS_PROXY指向本地端口。清掉这些变量再试。如果用了 CC Switch 之类的通道管理工具,检查它的配置里 Base URL 是否指向 TaoToken 的 API 基址,而不是某个本地地址。
Error reading choices / reading choices 相关报错:这类通常出现在走 OpenAI 兼容协议的客户端上,返回体结构和客户端预期不一致。排查方向是确认 Model ID 填的是文档里列出的可用模型,别填了不存在的名字;再确认请求走的是正确的协议端点。Claude Code 走 Anthropic 协议,Codex 类走 OpenAI 协议,别混用。
OAuth 相关报错:如果客户端提示 OAuth 失败或 token 过期,说明它没走 API Key 而是走了 OAuth 流程。检查配置里是不是同时存在 OAuth 凭证和 API Key,两者冲突时优先清了 OAuth 那套,统一用 Key 接入。
Skill 不触发:不是报错但很常见。表现是你说了「生成 PDF」但大模型没调用 Skill。原因基本是 description 写得太弱或太泛。回到第 3 节,把触发场景列具体,比如把「报告、发票、证书、简历」都写进去。
脚本报 ModuleNotFoundError: No module named 'fpdf':依赖没装。pip install fpdf2即可。注意包名是fpdf2,导入名是fpdf,别装错。
PDF 生成但内容为空:多半是--content-file路径不对,或者临时文件没写成功。先cat一下那个文件确认有内容,再跑脚本。
排查时记住一个原则:先分层,再定位。模型通道问题(401、proxy、OAuth)和 Skill 逻辑问题(不触发、参数错)和脚本问题(依赖、路径)是三层的,别混在一起查。每层单独验证通过,再串起来。
6. 把 Skill 沉淀成可复用资产:接入文档与后续扩展
跑通 PDF 生成之后,这套方法可以直接迁移到别的场景。Excel 导出、PPT 制作、代码模板生成,原理完全一样:一份 SKILL.md 定义触发和工作流,一个无状态脚本负责精确执行,中间靠文件路径和命令行参数传数据。
几个我踩过的坑,供你参考。第一,description 别偷懒,它是唯一的触发依据,写的时候想象用户在什么场景下会说出什么话,把这些话的关键词覆盖进去。第二,脚本保持纯粹,别让它去读环境变量里的对话状态,一旦脚本有状态,复用和调试都会变难。第三,临时文件路径用/tmp这类明确位置,别用相对路径,否则大模型拼命令时容易找不到。
后续要扩展的话,可以在references/里加更多样式文档,在assets/里放公司模板和字体,让生成的 PDF 直接符合内部规范。也可以把多个 Skill 组合起来,比如一个负责内容整理,一个负责排版导出,大模型会根据 description 自动选。
需要查模型可用列表、Key 管理、接入细节,走接入文档和 API Keys 页面;想先验证模型通道是否正常,用模型对话页发一条测试请求最快;如果要把这类 Skill 用在长期编码或 Agent 任务上,Coding Plan 的通道更稳。地址都在第 2 节列全了,按需取用。
最后一步,把~/.claude/skills/pdf-generator/整个目录备份一份,换机器时直接拷过去,改一下 Key 就能用。Skill 的价值就在于一次沉淀、长期复用,别让它只活在当前这台机器上。