- name
- pdf-editing
- display_name
- PDF 文档作业手册
- description
- **生成、合并、拆分、抽取页、填表单、读取或重排 .pdf PDF 文档 / 报告 / 表单 / 印刷品 / 标书 / 白皮书** 时使用。既覆盖从零生成印刷级 PDF(含封面·图表)、把 markdown/docx/txt 重排成正式 PDF,也覆盖对已有 PDF 的操作:多份按序合并 / 按页范围或章节拆分 / 抽取指定页 / 填 AcroForm 表单字段 / 提取全文文本或目录。仅当用户要 .pdf 产物、或改/读既有 PDF(含读取大段 PDF 文本)时触发;查阅网页正文、总结文章观点、解释 PDF 概念、修打印机、推荐阅读器、压缩图片 时不要触发。
- tags
- pdf, document, office, print, cli
# PDF 文档作业手册
本 skill 是处理 .pdf 文件的**唯一权威入口**。所有 PDF 能力都收敛成单一 CLI——**`pdf-cli`**——的 6 个子命令。
**目标只有一个**:每次操作 .pdf 都选对子命令、写对参数。
---
## 进入本技能前先停一秒:别走偏
只有在用户明确需要 **PDF / .pdf** 文件产物,或要求生成、合并、拆分、填表、读取
PDF 内容时,才进入这份 SKILL。下面几件事看上去能"完成任务",实际是失败:
1. **「先做 Word 再转 PDF」不可互换替代 `pdf-cli create`**。用户要的是
"从零生成一份印刷级 PDF 报告"时,**首选** `pdf-cli create` 的 spec→PDF
引擎(含设计感封面、图表、流程图、数学公式)。用户要的是"先做 Word 再附带
PDF 副本"时,那是 `officecli-docx` 出 .docx、再用沙盒里的
`soffice --headless --convert-to pdf` 转一份副本,主产物还是 .docx。
**别用一个工具兜底另一个工具。**
2. **不要塞 markdown 回 chat 让用户"自己另存为 PDF"**。这是 hard fail。
markdown 草稿写完 → `pdf-cli reformat --input draft.md --output out.pdf`
生成正式 PDF,再 `sandbox_get_artifact` + `pin_to_workspace` 交付。
3. **不要拿 `space_list_myspace_files` 返回的旧 artifact 当作"新生成的 PDF"再 pin
一遍**。`sandbox_put_artifact` 是把"用户**这一轮上传的**原始 PDF"送进沙盒;
它不是 artifact 复制器、不是"我把以前生成过的同名文件再用一次"的捷径。
4. **`pdf_create` 老 MCP 名已下线**。如果模型记忆里还有 `pdf_*` 工具名,那是
过时记忆——一律转写成 `pdf-cli <subcmd>`。
5. **改完中间稿(`pdf-cli create` 的 spec JSON / 待重排的 markdown 草稿 /
`fill-form` 的 fields JSON)就停手,忘了重新跑 `pdf-cli` 出最终 .pdf**。
常见现场:你把 spec 调了一轮,回复就说"已经把 X 章节改成 Y,spec 保存在
`./spec.json`"——然后收尾。**这些 spec / markdown / fields 都不是
用户要的东西,`.pdf` 才是**。中间稿每改一轮都得重新跑 `pdf-cli create` /
`pdf-cli reformat` / `pdf-cli fill-form` 把新版 `.pdf` 产出来,再走
`sandbox_get_artifact` + `pin_to_workspace` 把最新文件推给用户。stop 在
spec / markdown 草稿上 = 这一轮没交付。
6. **`pdf-cli` 跑完了,只在回复里说"PDF 已生成,路径 `./xxx.pdf`"
就收尾**。沙盒磁盘对用户**完全是黑盒**——你告诉他"沙盒里有个文件在这里",
等同于没交付:用户的对话区 / 我的空间不会自动出现这个文件,他没办法点开、
下载、看里面的内容。CLI 跑完后必须接 `sandbox_get_artifact` 拿 `file_id`,
再 `pin_to_workspace` 钉到工作区,用户那边才会看到 .pdf 卡片。
什么时候**应该**离开这份 SKILL:用户明确说要 **Word / 报告(要 .docx)** →
走 `officecli-docx`;用户要 **Excel / 工作簿** → 走 `officecli-xlsx`;用户要
**PPT / 演示文稿 / 幻灯片** → 走 `officecli-pptx`。
---
## 运行模型(必须先理解这个,再谈调命令)
下面的 `pdf-cli` 表示本次加载技能的 `"{baseDir}/scripts/pdf-cli"`。
执行命令时使用这个带引号的脚本路径;保持当前会话工作目录,输入输出使用相对路径。
不要切换到技能目录运行作业。
LLM 没有 `pdf_*` 工具可以直接调。每次 PDF 操作是 **3 步组合 + 1 步交付**:
```
# Step 1:如果用户上传过原始 pdf(有 file_id),把它送进沙盒
sandbox_put_artifact(artifact_id="<原始 pdf 的 file_id>",
dest_path="./in.pdf")
→ {"ok": true, "artifact_id": "...", "dest_path": "./in.pdf"}
# Step 2:bash 跑 pdf-cli
Bash("pdf-cli <subcmd> --input ./in.pdf \
--output ./out.pdf \
<子命令特定参数>")
→ stdout 返回 JSON 结果({"ok": bool, "meta": ...})
# Step 3:把沙盒里的成稿提取出来登记成 artifact
sandbox_get_artifact(src_path="./out.pdf",
name="终稿.pdf")
→ {"ok": true, "file_id": "<新 file_id>", "url": "/files/...", ...}
# Step 4(必做):交付给用户
pin_to_workspace(file_ids=["<新 file_id>"])
```
读取类子命令(`read` 的 text/outline/metadata/overview/form-fields 模式)只
有第 1、2 步,没有第 3、4 步(没有新文件交付)。
---
## 6 个子命令速查(详见 references/cli-commands.md)
| 子命令 | 用途 | 典型场景 |
|---|---|---|
| `pdf-cli read --mode text` | 全文文本(可指定页号列表) | "提取这份 PDF 的全文" |
| `pdf-cli read --mode outline` | 书签 / 目录 | "看看 PDF 有哪些章节" |
| `pdf-cli read --mode metadata` | 元数据(页数、标题、作者、加密) | 第一眼快速判断 PDF 规模 |
| `pdf-cli read --mode overview` | metadata + outline 合并 | 用户上传 PDF 后的"第一眼" |
| `pdf-cli read --mode form-fields` | 列出 AcroForm 字段 | 填表前必先 form-fields 拿字段名 |
| `pdf-cli merge` | 多份 PDF 合并 | "把这 5 份 PDF 合成一个" |
| `pdf-cli split` | 按页范围拆成 N 个 PDF | "100 页 PDF 按章节拆成 5 份" |
| `pdf-cli fill-form` | 填 AcroForm 字段 | "把这份表单填好" |
| `pdf-cli create` | spec→印刷级 PDF(封面/图表/数学公式) | "从零生成一份正式 PDF 报告" |
| `pdf-cli reformat` | md/docx/txt → 设计感 PDF | "把这份 markdown 重排成 PDF" |
---
## 渐进式加载:什么时候去看哪份 reference
- **写 `pdf-cli create` 的 spec** → 必读 `references/cli-commands.md` 的
create 段,里面有 19 种 content block 类型(h1/h2/h3 / body / bullet /
numbered / callout / table / image / figure / code / math / chart /
flowchart / bibliography / divider / caption / pagebreak / spacer)的完整字段表。
- **填 AcroForm 表单** → 看 `references/form-fields.md`:字段类型与值的语义
(checkbox 接受 yes/no/true/false;dropdown 必须 match choices;radio 加
斜杠前缀等)。
- **要查一份完整配方**(如"用户传 PDF → 我要提取文本 + 拆分 + 填表")→ 看
`references/workflows.md`。
- **报错 / 行为反直觉** → 看 `references/pitfalls.md`,含 LibreOffice / node /
pypdf 缺失等常见底层报错。
---
## 大 payload 兜底
`pdf-cli create --spec '<inline json>'` 的 JSON 很容易很大(一份带图表 + 流
程图的报告 spec 轻松破 10KB)。bash 命令行有 ~128KB 上限,触发 `Argument
list too long` 就直接报错。
**永远的兜底**:先 `Write` 把 JSON 写到 `./spec.json`,再用
`--spec-file`:
```bash
Write(file_path="./spec.json", content="<json>")
Bash("pdf-cli create --output ./report.pdf --spec-file ./spec.json")
```
`fill-form` 的 `--fields-file` 是同理兜底。
---
## 一句话自检(交付前)
每次回复用户之前,按这个列表 5 秒过一遍。任何一项没满足 = 这一轮**没交付**,
回去补,不要发:
- 用户要的是 **.pdf**,我交付的也是 .pdf 吗?(不是偷偷换成了 .docx /
「贴在回答里的 markdown 文字让用户自己复制粘贴 / 另存为 PDF」?)
- 是不是用 `pdf-cli create`(从零)/ `pdf-cli reformat`(从 md/docx 改造)/
`pdf-cli merge` / `pdf-cli fill-form` 真的产出过 `./<...>.pdf` 这个
文件?(没跑过这条命令 = 没有 .pdf,必返工)
- 中途如果改过 spec JSON / markdown 草稿 / fields JSON 这类中间稿,**改完之后
有没有再跑一次 `pdf-cli` 把最新版 .pdf 重新生成出来**?(停在改完 spec / md
上 = 没交付)
- `sandbox_get_artifact(src_path="./<...>.pdf", name="...")` 跑了,
拿到了 `file_id` 了吗?
- **`pin_to_workspace(file_ids=["<file_id>"])` 调了吗?**
—— 这一步不可省:没 pin,文件只是后端 artifact 存储里的一条匿名记录,
用户在对话区 / 我的空间里**完全看不到**,等于这一轮任务从没存在。
- 一次 chat 产出多个 PDF(例如批量拆分、批量合并出多份)时:所有 file_id 都进
同一次 `pin_to_workspace(file_ids=[...])` 调用了吗?(一次 pin 多个,别多次 pin)
- 用户指定了"放到我的空间里 XX 文件夹":`name=` 参数填了贴切的中文文件名
吗?(不是 `out.pdf` / `draft.pdf` 这种)
---
## 一句话回顾
> 看见 PDF/.pdf 任务 → 进沙盒 → 选对 `pdf-cli <subcmd>` → 出文件 → pin。
> 读 PDF 内容首选 `read --mode text/outline/overview`;生成新 PDF 首选
> `create`(带封面与图表)或 `reformat`(从 md/docx 改造);表单填写前必先
> `read --mode form-fields` 看字段。
GitHub에서 보기