PDF 文档(profy-pdf)
PDF 能力分两条互不相干的路径,先分清你在哪条路上,后面的一切都取决于此:激活方式
profy-pdf 是 user_selectable: false——自动可用,不需要勾选。
contracts 只有 skills: ["skills/"],没有 tools。这个插件带两个技能:builtin/pdf(通用处理)与 builtin/kami(精排引擎),后者单独一节讲。
创建路径:WeasyPrint 是唯一选择
WeasyPrint 的路子是写 HTML + CSS 再渲染成 PDF,于是排版由 CSS 布局引擎负责,你得到的是声明式排版而不是手工定位。页眉页脚与分页
@page 规则是 PDF 特有的 CSS 能力,浏览器里用不上但这里很关键:
counter(page) / counter(pages) 由渲染器在分页后填充——这是手工坐标方案给不了的东西。
排版要点
- 复杂布局用 CSS Grid / Flexbox(卡片、多栏)
- 页面尺寸、页边距、页眉页脚全走
@page - 分页控制用
page-break-before/page-break-after - 中文用
font-family: 'Noto Sans CJK SC', sans-serif(沙箱已预装) - 品牌报告:设主色,用 CSS 背景形状
什么时候不用 WeasyPrint
处理路径:命令行工具
pdftotext(poppler-utils)
-layout 很重要:不带它,多栏排版会被读成交错的乱序文本。
qpdf
pdftk(若可用)
表单处理
技能自带一组表单脚本:extract_form_field_info.py / extract_form_structure.py / check_fillable_fields.py / fill_fillable_fields.py / fill_pdf_form_with_annotations.py,以及验证用的 check_bounding_boxes.py / create_validation_image.py / convert_pdf_to_images.py。
流程是先探测再填:不同 PDF 的表单字段命名毫无规律,直接猜字段名必错,所以先 extract 出真实字段结构。
扫描件 OCR
扫描版 PDF 里没有文字层,pdftotext 提取出来是空的。需要 pytesseract + pdf2image 走 OCR。
kami · 紙:精排引擎
builtin/kami 是 pdf 插件里的第二个技能,专门做有设计感的交付物:暖米色纸面、墨蓝强调色、衬线主导的层级、紧凑的编辑节奏。
九种文档类型
选型靠决策树而不是问用户,只有两类真的都合适时才反问:
Landing Page 不产出 PDF——它是屏幕优先的交互模板,含画廊轮播、首屏入场动画、响应式断点(880px / 480px)与
prefers-reduced-motion 支持,交付物是可直接托管的 .html。字体
中文字体是商用字体。构建中文文档前先跑一次字体自愈脚本:
模糊反馈处理
用户说”看着不对""太挤了""不够优雅”时,技能规定不许猜,而要带着当前数值反问。这条设计的价值在于把一次主观争论变成一次参数调整——“行高现在是 1.6,要调到 1.8 吗”比”我再改改”有效得多。边界与失败态
- 生成 PDF 只有 WeasyPrint 一条路,坐标绘制库被明确禁止。
- 扫描件必须走 OCR,否则文字提取是空的。
- 表单字段必须先探测,直接猜字段名会静默填不进去。
- kami 的中文字体是商用字体,不随分发包携带,靠
ensure-fonts.sh现取。 - Landing Page 没有 PDF 输出,别指望它导出 PDF。
排错
验证你的产出
- 生成后转成图片逐页看:
convert_pdf_to_images.py。光看代码看不出排版事故。 - 中文文档搜一遍有没有方框字符——这是字体没生效最典型的症状。
- 多页文档翻到最后一页,确认
共 N 页的 N 是真实页数而不是字面量。
相关页面
办公文档总览
四类文档能力的定位与选型
演示文稿
需要 PPT 而非 PDF 时走这条
核对日期 2026-08-11。来源:
services/agent-runtime/src/plugins/builtin/pdf/plugin.json、skills/pdf/SKILL.md、skills/kami/SKILL.md、skills/pdf/scripts/、skills/kami/scripts/ensure-fonts.sh。
