OpenClaw nano-pdf Skill 实战指南:用自然语言编辑 PDF 页面,及其 Skill 门控与安装机制
OpenClaw 的 nano-pdf Skill 为 Agent 接入 nano-pdf 这个 PDF 编辑 CLI:你只需给出"第几页 + 一句自然语言指令",即可对 PDF 的单页内容做修改。本篇以该 Skill 文档为骨架,逐段讲解其命令用法、页码陷阱,并结合 OpenClaw 源码拆解 SKILL.md frontmatter 中 requires.bins 门控与 uv 安装声明是如何被解析、校验与执行的,读完后你既会直接使用这个 Skill,也能理解 OpenClaw Skill 从"声明依赖"到"自动安装"的完整链路。
什么是 nano-pdf Skill
nano-pdf 是 OpenClaw 内置在 skills/ 目录下的一个 Skill,定义文件为 skills/nano-pdf/SKILL.md。它的作用可以一句话概括:
Use
nano-pdfto apply edits to a specific page in a PDF using a natural-language instruction. (用nano-pdf通过自然语言指令,对 PDF 的指定页面应用编辑。)
也就是说,它不是通用 PDF 处理工具,而是聚焦于单页自然语言编辑这一场景:标题改写、错字修正、内容替换等都可以通过一句英文指令完成。Skill 的 name 为 nano-pdf,description 为 "Edit PDFs with natural-language instructions using the nano-pdf CLI",homepage 字段指向 nano-pdf 在 PyPI 上的项目页面(OpenClaw 会在 Skill 元数据中解析该字段,见后文 frontmatter 解析部分)。
快速上手:一条 edit 命令
Skill 文档给出的 Quick start 用法如下,这也是 nano-pdf 的核心入口:
nano-pdf edit deck.pdf 1 "Change the title to 'Q3 Results' and fix the typo in the subtitle"
三个位置参数各司其职:
| 参数 | 示例 | 含义 |
|---|---|---|
| 文件路径 | deck.pdf |
待编辑的 PDF 文件 |
| 页码 | 1 |
要修改的目标页面 |
| 自然语言指令 | "Change the title to 'Q3 Results' and fix the typo in the subtitle" |
描述要做的具体编辑 |
文档特别给出了两条实战 Notes,务必保留在操作习惯里:
- 页码基线随版本/配置而变:Page numbers are 0-based or 1-based depending on the tool's version/config; if the result looks off by one, retry with the other.(页码是 0 起始还是 1 起始取决于工具版本/配置;如果结果差一页,换另一种基线重试。)
- 发送前必须人工核验:Always sanity-check the output PDF before sending it out.(输出 PDF 在发出前一定要做 sanity-check,确认改对了页、改对了内容。)
这两条提示对 Agent 自动化尤其重要:页码 off-by-one 是最常见的出错模式,而自然语言编辑的结果天然不可完全预测,所以"编辑 → 检查 → 再发送"是必要闭环。
SKILL.md 的 frontmatter 逐字段拆解
nano-pdf 的 SKILL.md 使用 YAML frontmatter 声明 Skill 元数据,这是 OpenClaw Skill 契约的核心部分。完整结构如下(homepage 为指向 nano-pdf PyPI 项目页的外部地址,此处以注释替代):
---
name: nano-pdf
description: "Edit PDFs with natural-language instructions using the nano-pdf CLI."
homepage: # 指向 nano-pdf 在 PyPI 上的项目页面
metadata:
{
"openclaw":
{
"emoji": "📄",
"requires": { "bins": ["nano-pdf"] },
"install":
[
{
"id": "uv",
"kind": "uv",
"package": "nano-pdf",
"bins": ["nano-pdf"],
"label": "Install nano-pdf (uv)",
},
],
},
}
---
各字段的实际行为都可以从 OpenClaw 源码中得到印证:
name/description:Skill 的身份标识与摘要,用于在 Agent 侧展示与检索。homepage:homepage: readStringValue(metadataObj.homepage)在 frontmatter 解析器 中被读取为字符串字段。metadata.openclaw.emoji:📄,供 UI 展示。requires.bins: ["nano-pdf"]:门控条件,要求系统PATH上存在nano-pdf可执行文件,详见下一节。install:一条安装声明。kind: "uv"属于 OpenClaw 定义的 5 种安装方式之一,src/skills/types.ts 中的类型定义为kind: "brew" | "node" | "go" | "uv" | "download"。解析入口在 frontmatter.ts:parseOpenClawManifestInstallBase(input, ["brew", "node", "go", "uv", "download"]),对uv类型还会做完整性校验——frontmatter.ts 中明确要求spec.kind === "uv" && !spec.package时声明不合法,即 uv 安装必须给出package。
门控(Gating):requires.bins 如何决定 Skill 是否可见
requires.bins: ["nano-pdf"] 是 nano-pdf 能被加载的前提。OpenClaw 的门控规则在 docs/tools/creating-skills.md 有完整表格:
| 字段 | 语义 |
|---|---|
requires.bins |
所有列出的二进制必须存在于 PATH |
requires.anyBins |
至少一个二进制存在于 PATH |
requires.env |
每个环境变量必须存在于进程或配置中 |
requires.config |
每个 openclaw.json 路径必须为真值 |
os |
平台过滤:["darwin"]、["linux"]、["win32"] |
always |
即使 requires.* 检查失败,在兼容 OS 上仍包含该 Skill |
从源码结构看,二进制检测由 src/skills/discovery/bins.ts 承担(status.ts 中即通过 hasBinary(...) 判断 brew 等命令是否可用)。对 nano-pdf 而言,语义很直接:PATH 里没有 nano-pdf 时,该 Skill 不会被视为"就绪",OpenClaw 转而提示安装——这正是下面 install 声明发挥作用的地方。
安装链路:从声明到 uv tool install nano-pdf
当门控不满足时,OpenClaw 会依据 install 声明执行安装。nano-pdf 声明了 uv 方式(package: "nano-pdf",安装标签 "Install nano-pdf (uv)"),其执行命令的构造位于 src/skills/lifecycle/install.ts:
case "uv": {
if (!spec.package) {
return { argv: null, error: "missing uv package" };
}
const err = assertSafeInstallerValue(spec.package, "uv package", SAFE_UV_PACKAGE);
if (err) {
return { argv: null, error: err };
}
return { argv: ["uv", "tool", "install", spec.package.trim()] };
}
即最终执行的是 uv tool install nano-pdf,且包名会先经过 assertSafeInstallerValue 白名单式安全校验,防止 frontmatter 注入恶意参数。
安装方式的选择并非只看声明本身。src/skills/discovery/status.ts 中有一条表驱动(table-driven)的偏好链,"first match wins":
- 用户偏好 brew 且系统存在 brew 时用 brew 声明;
- uv 声明(nano-pdf 命中的就是这一级);
- node 声明;
- 系统存在 brew 时的 brew 声明(避免在 Linux/Docker 上 brew 必然失败);
- go 声明;
- download 声明;
- 最后兜底到 brew 并给出描述性错误。
nano-pdf 只有 uv 一种安装声明,因此必然落在第 2 级。此外 install-types.ts 定义了 SkillInstallSkipReason = "brew" | "go" | "uv",说明某些环境下 uv 安装可能被整体跳过(例如无 uv 运行时),此时 Agent 侧会收到手动安装提示。
这套链路的端到端证据在 src/commands/onboard-skills.test.ts 中:onboarding 流程以 nano-pdf 为夹具构造 Skill 条目(bins: ["nano-pdf"]、installLabel: "Install nano-pdf (uv)"),用户多选 nano-pdf 后,安装备注会输出 uv: nano-pdf。作为对照,内置的 weather Skill 使用 kind: "brew"、formula: "curl" 声明安装,直观展示了同一 frontmatter 契约下不同安装方式的差异。
使用建议与边界
结合文档原文与仓库证据,使用 nano-pdf Skill 时注意三点:
- 页码语义以实测为准:不同版本可能是 0 起始或 1 起始,编辑结果差一页时换基线重试即可(见 Quick start 的 Notes)。
- 输出必检:自然语言编辑的结果在发出前必须 sanity-check 输出 PDF;自动化流程中应把"检查产物"作为固定步骤。
- 第三方 Skill 视为不可信代码:OpenClaw 官方文档在 docs/tools/skills.md 的安全章节明确警告 "Treat third-party skills as untrusted code. Read them before enabling."——nano-pdf 本身是内置 Skill,但同样的原则适用于你引入的任何外部 Skill;对不可信输入与高风险工具,优先在沙箱中运行。
延伸阅读
- skills/nano-pdf/SKILL.md:本文的源文档,nano-pdf Skill 的完整定义。
- docs/tools/skills.md:Skill 系统的总览,含门控(Gating)、命名冲突、安全等完整参考。
- docs/tools/creating-skills.md:如何编写自己的 Skill,frontmatter 字段与
{baseDir}用法。 - src/skills/loading/frontmatter.ts:frontmatter 与
metadata.openclaw的解析实现。 - src/skills/lifecycle/install.ts:各安装方式(brew/node/go/uv/download)的 argv 构造与安全校验。
- src/commands/onboard-skills.test.ts:onboarding 场景下 nano-pdf 安装提示的测试证据。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00