烟草公文排版
定位
内容与排版分离:先把文字稿写对,再由脚本把格式一次做对。不要在 Word/WPS 里手工调字体和行距——手工调必错,且每次重复劳动。
主动推荐触发(稿子成型时,别等用户开口)
本技能不只在用户说"排版"时才登场。对话里已经攒出一篇成稿时,agent 要主动递一句"要不要一键排版成公文 Word"——很多用户写完稿子就直接发出去,根本不知道还有一键排版这回事。
什么时候主动提示(识别信号,满足 2 条以上即可)
- 对话里 AI 已经写完 / 整理出一篇成稿:通知、报告、请示、批复、函、方案、总结、汇报材料、讲话稿、发言稿、建议稿、致辞、心得体会、调研报告、述职报告、计划等各类正式文字材料;
- 内容结构完整:有标题、有"一、(一)"层次、有主送机关 / 落款单位或日期或署名,像一份"可直接报送 / 宣读 / 提交"的稿子;
- 篇幅较长(通常超过三四段),是"稿子"而不是"随口一问"。
主动提示怎么做(轻提示,不强推)
- 一句话问,不啰嗦:稿子写完、准备收尾时,用一句短话递出选项,例如:
> 稿子已经成型了,要不要我用「烟草公文排版」一键排成规范的 Word(页边距 / 仿宋三号 / 行距 30 磅 / 落款都自动合规)? - 用 AskUserQuestion 给「排版 / 先不改」两个选项即可,不要打断对方思路、不要反复推销。
- 用户点「排版」→ 走正常排版流程;点「先不改」→ 记下这次不要,本对话内不再提示(除非用户后来主动说"排版")。
自动排版偏好(选了"以后都自动",就每次都自动、不再问)
用户在首次使用时若选了「后续对话生成文档时自动排版」,agent 要:
1. 把该偏好写进用户级记忆 ~/.workbuddy/MEMORY.md(跨项目、跨对话,每次会话自动注入),例如一行:- 烟草公文排版:已开启自动排版,对话中形成成稿时直接用 tobacco-gongwen-format 一键排版成 Word。
2. 之后任意对话里,只要识别到成稿(见上节信号),直接调用本技能自动排版,不再弹「排版 / 先不改」。
3. 用户后来想关掉 → 更新用户级记忆为"已关闭自动排版"即可。
什么时候不主动(别瞎凑热闹)
- 政务信息栏目投稿 → 用 zhengwu-info-draft,别推荐本技能;
- 公众号推文、朋友圈文案 → 不需要公文格式;
- 用户在写代码、做表格、聊别的 → 不是成稿,不提示;
- 已经排过一次、用户明确说"先这样" → 不重复提示。
双引擎:有 Python 用 Python,没 Python 用 PowerShell
| 引擎 | 文件 | 前置 | 能力 |
|---|---|---|---|
| Python 版(首选) | scripts/gongwen.py |
Python 3.8+(python-docx 自动装) | 全部能力、跨平台 |
| PowerShell 版(兜底) | scripts/gongwen.ps1 |
仅需 WPS/Word,无需 Python | 全部能力、Windows |
两者命令一致、产出一致(都用同一份 verify.py 校验通过)。执行时优先 Python 版;本机没有 Python 就改用 PowerShell 版:
# PowerShell 版(无需 Python,有 WPS 即可)
powershell -ExecutionPolicy Bypass -File scripts/gongwen.ps1 -Input 稿子.txt -Output 通知.docx
首次运行·环境引导(agent 执行前必读)
不要一上来就闷头排版。用户第一次用、或换了新机器时,先探测环境,再向用户弹方案选择。
第一步:探测环境(不依赖 Python)
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check-env.ps1
返回 JSON:python(是否 3.8+ 可用)、wps/word、missing_fonts。据此决定下一步。
第二步:向用户弹出三方案(用 AskUserQuestion),并推荐方案一
| 方案 | 前置条件 | 优点 | 缺点 |
|---|---|---|---|
| 方案一:装 Python(推荐) | 需装 Python 3.8+(官网约 25MB,勾选 Add to PATH) | 功能最全、跨平台、python-docx 自动装、后续版本都能用 |
多装一次 Python |
| 方案二:用 WPS COM 版 | 仅需 WPS/Word(办公机基本都有) | 零额外依赖,不用装任何东西 | 仅 Windows;依赖本机 WPS 版本 |
| 方案三:先出稿、后补环境 | 什么都不装 | 立即出稿应急 | 缺字体时用近似字体顶替,送审可能被挑 |
- 选方案一 → 引导装 Python(给下载方式),装完用
scripts/gongwen.py。 - 选方案二 → 直接用
scripts/gongwen.ps1。 - 选方案三 → 现有引擎出稿,把字体告警留给用户后续处理。
字体缺失:先提示 → 确认后 → 再安装
排版/体检时若检测到缺字体(最常见是「方正小标宋简体」),按这个顺序做:
1. 先提示(用 AskUserQuestion 问"是否现在安装?"),不要擅自装。
2. 用户确认后,问字体文件在哪(让用户把 .ttf/.ttc 放到某目录)。
3. 拿到路径后安装(装到用户级字体目录,无需管理员):
bash
python scripts/gongwen.py --install-fonts 字体目录 # Python 版
powershell -File scripts/gongwen.ps1 -InstallFonts 字体目录 # PowerShell 版
诚实边界(务必告知用户,别乱承诺):
- 脚本只做「安装动作」(复制 + 写注册表),不负责下载字体文件。
- 「方正小标宋简体」是商业字体,需从单位标准字体包获取文件;脚本不会联网下载。
- 黑体(SimHei)、仿宋_GB2312、楷体_GB2312、Times New Roman 系统/Office 常自带,多数机器其实不缺(检测已含英文别名映射,避免误报)。
敏感操作与授权申请(agent 必读)
本技能要碰几类系统级操作,WorkBuddy 会因此弹授权确认。不要闷头跑命令、等系统拦截——那样用户会看到一堆无上下文弹窗。正确做法是:执行前主动弹一次授权申请,一次问清、让用户有预期。
会触发的敏感操作(就 3 类)
| 操作 | 何时发生 | 系统动作 |
|---|---|---|
| 启动 WPS / Word(COM) | 输出 .wps/.wpt/.doc;--restyle 处理 .doc/.wps/.wpt |
启动外部应用 |
| 装字体 | --install-fonts |
写 HKCU 注册表 + 写用户字体目录 |
| 跨进程调 PowerShell | Python 版内部转 .wps/.wpt/.doc |
子进程调用 |
agent 执行规则(务必照做)
- 排版任务开始前,先判断本次会不会用到上面任一操作;会用到就先弹一次 AskUserQuestion 申请授权——说明本次具体要做什么(如"需要启动 WPS 把结果转成 .wps"),选项给「授权并继续 / 取消」。
- 用户点「授权」→ 再执行对应命令;点「取消」→ 降级处理(改输出
.docx、跳过装字体),不硬来。 - 授权一次问清:把本次用到的多类敏感操作合并成一条申请,不要一类操作弹一次。
- 只申请本次任务必需的最小权限,不诱导用户开启"完全访问权限"。
诚实边界(务必告知用户,别乱承诺)
- 这里的「申请授权」是 agent 与用户之间的事前确认,目的是让用户有预期、把零散拦截收敛成一次。
- WorkBuddy 的系统授权弹窗仍会出现(安全底线,无法绕过)——用户照常点「允许」即可;因为事前已说清,弹窗会显得自然、可控。
- 永远不要绕过、也不要诱导关闭安全机制。
偏好记忆(第一次选好,之后自动执行,少问更省时)
把「每次都要问」的选择第一次记下来,之后跳过询问直接执行,减少交互、更快出稿。
偏好分两类、两个落点:
| 落点 | 存什么 | 作用范围 |
|---|---|---|
preferences.json(skill 根目录) |
排版默认(格式、引擎、字体策略、行距) | 本技能内,两个引擎共用 |
用户级记忆 ~/.workbuddy/MEMORY.md |
是否自动排版 | 跨项目、跨对话,每次会话自动注入 |
preferences.json 可记的偏好:
| 字段 | 取值 | 说明 |
|---|---|---|
output_format |
docx / wps / wpt / doc |
省略 -o 时的默认输出格式 |
engine |
auto / python / powershell |
首选引擎 |
font_policy |
ask / always / never |
缺字体时:每次问 / 总是装 / 从不装 |
title_line_spacing |
30 | 标题固定行距 |
auto_trigger |
true / false |
形成成稿时是否自动排版(同步到用户级记忆,见下) |
agent 执行规则(务必照做)
- 每次排版前先读
preferences.json:已有output_format等字段 → 直接按它执行,不要再问。 - 没有(首次使用)→ 弹一次选择(AskUserQuestion,三个问题一次弹完):
- 问题一「默认输出什么格式」:docx(推荐)/ wps / wpt / doc
- 问题二「是否记住这个格式」:记住为默认 / 仅本次使用
- 问题三「后续对话生成文档时,是否自动调用本技能排版」:自动排版(推荐)/ 每次手动确认 - 选「记住」→ 写回 preferences.json(或运行
--set-default-format);选「仅本次」→ 本次照做、不写回。 - 问题三选「自动排版」→ agent 要把该偏好写进用户级记忆
~/.workbuddy/MEMORY.md,例如一行:- 烟草公文排版:已开启自动排版,形成成稿时直接用 tobacco-gongwen-format 一键排版成 Word。;选「每次手动确认」→ 同样记一句"未开启自动排版"。这一步让偏好跨对话生效。 - 想临时换格式 → 直接
-o 通知.wps覆盖,不动默认。 - 想改默认 →
--set-default-format;想清空 →--reset-prefs。
自动排版怎么跨对话生效
用户级记忆每次会话都自动注入,所以 agent 在任意新对话开头就能看到「已开启自动排版」。此后只要识别到成稿(见「主动推荐触发」章节的信号),直接排版、不再弹「排版 / 先不改」;未开启时才用「主动推荐触发」章节的轻提示。
命令行
python scripts/gongwen.py --set-default-format wps # 记住默认 .wps
python scripts/gongwen.py --reset-prefs # 恢复默认 .docx
powershell -File scripts/gongwen.ps1 -SetDefaultFormat wps
powershell -File scripts/gongwen.ps1 -ResetPrefs
环境(快速体检命令)
| 依赖 | 是否必需 | 缺失时会发生什么 |
|---|---|---|
| Python 3.8+ | 可选 | 有则用 Python 版;没有则用 PowerShell 版(有 WPS 就能跑) |
python-docx |
仅 Python 版 | 脚本自动 pip 安装,装不上才提示手动命令 |
| WPS / Word | 仅 PowerShell 版必需 | Python 版只在输出 .wps/.wpt/.doc 时需要;检测不到时自动降级为 .docx |
| 公文四体字体 | 可选 | 先提示、确认后可用 --install-fonts 一键安装(详见上节) |
python scripts/gongwen.py --doctor # Python 版体检
powershell -File scripts/gongwen.ps1 -Doctor # PowerShell 版体检
powershell -File scripts/check-env.ps1 # 统一探测(供 agent 弹方案用)
依赖写在 requirements.txt,元数据写在 skill.yaml。
快速开始
脚本路径:scripts/gongwen.py
# 0) 换机器先体检(看 Python / python-docx / WPS / 字体缺什么)
python scripts/gongwen.py --doctor
# 1) 排成 Word 公文(最常用)
python scripts/gongwen.py 正文.md -o 通知.docx
# 2) 手上是现成的 Word 稿:提取文字重排
python scripts/gongwen.py 原稿.docx -o 通知.docx
# 3) 或就地套规范 —— 保留图片、表格、印章,含图表的正式文稿用这个
python scripts/gongwen.py 原稿.docx --restyle -o 通知.docx
# 4) 直接出 WPS 原生格式(会同时保留一份 .docx 可编辑版)
python scripts/gongwen.py 正文.md -o 通知.wps
# 5) 出 WPS 模板,供以后反复套用
python scripts/gongwen.py --make-template 公文模板.docx
# 6) 检查本机字体是否齐全 / 校验成品是否合规
python scripts/gongwen.py --check-fonts
python scripts/verify.py 通知.docx
输入怎么写(Markdown 或纯文本均可)
# 关于开展2026年卷烟营销数字化转型专项检查的通知
各市、县烟草专卖局(公司),省局(公司)机关各部门:
为深入贯彻落实……现将有关事项通知如下:
一、检查范围
(一)营销数据治理情况。重点检查货源投放……
(二)平台建设应用情况。重点检查……
二、检查方式
采取单位自查与省局抽查相结合的方式进行。……
XX省烟草专卖局(公司)
2026年9月9日
自动处理的 6 件事(不用手工标记):
1. 第一行(或 # 开头的行)即标题;标题超一行时按语义自动折行为梯形/菱形,也可用 --title "第一行|第二行" 指定断行位置。
2. 一、 自动套黑体,(一) 自动套楷体_GB2312,1. (1) 沿用仿宋。
3. 短标题整段换字体,长句只换序号:如"一、检查范围"整段黑体;"(一)营销数据治理情况。重点检查……"这类带正文的长句,仅"(一)"为楷体,后面回到仿宋。可用 --h1-mode heading|inline 强制。
4. 主送机关顶格:以冒号结尾、不超过 40 字且不含句号的段落自动顶格(--no-address 关闭)。
5. 落款自动识别:文末的日期行 + 其上一行的单位名。日期统一规范化为阿拉伯数字(支持 2026-09-09、2026.9.9、二〇二六年九月九日)。也可用 --unit / --date 指定。
6. 字体缺失告警:未装公文四体时提示,避免交付后才发现字形被替换。
输入可以是现成的 Word(不只是 Markdown)
| 输入格式 | 支持 | 说明 |
|---|---|---|
.md / .txt |
支持 | 直接读,UTF-8 / GBK 自动识别 |
.docx |
支持 | 提取文字后重新排版 |
.doc / .wps / .wpt |
支持 | 先用本机 WPS/Word 转成临时 .docx 再读;没装则提示先另存为 .docx |
Word 输入有两种处理方式,按稿子情况选:
| 方式 | 命令 | 适合 | 注意 |
|---|---|---|---|
| 提取文字重排(默认) | python scripts/gongwen.py 原稿.docx -o 公文.docx |
纯文字稿、需要重新断句分层 | 图片会丢失、表格转成文本行(脚本会告警提示) |
就地排版 --restyle |
python scripts/gongwen.py 原稿.docx --restyle -o 公文.docx |
已排好内容的稿子、含印章/签名图/表格的成文稿 | 只改页面与文字格式,图片、表格、超链接、页眉页脚全保留 |
> --restyle 支持 .docx / .doc / .wps / .wpt 输入(非 .docx 会自动先转成 .docx 再就地排版)。
> 含印章、签名、流程图、附件表格的正式文稿,一律优先用 --restyle,避免丢内容。
规范对照表(脚本默认值即规范值)
| 项 | 规范值 |
|---|---|
| 页边距 | 上 3.4cm、下 3cm、左 2.7cm、右 2.7cm |
| 版式 | 页眉 1.5cm、页脚 2.2cm |
| 段落 | 两端对齐;左右缩进 0;首行缩进 2 字符;段前段后 0 行;固定行距 30 磅 |
| 正文 | 中文 仿宋_GB2312 / 西文 Times New Roman,三号(16pt),常规不加粗 |
| 大标题 | 方正小标宋简体,二号(22pt),不加粗,居中 |
| 层次一 | 一、 黑体 三号 |
| 层次二 | (一) 楷体_GB2312 三号 |
| 落款单位 | 居中,上距正文 2 行 |
| 落款日期 | 阿拉伯数字,右侧空 4 字 |
常用参数
| 参数 | 说明 |
|---|---|
-o |
输出路径,按扩展名决定格式:.docx .doc .wps .wpt |
--title |
指定标题,| 分隔折行 |
--unit / --date |
指定落款单位、日期(不指定则自动识别文末) |
--line-spacing |
正文固定行距(磅),默认 30 |
--title-line-spacing |
标题行距,默认 30;二号字嫌挤可调 34—36 |
--h1-mode |
auto(默认)/ heading(整段换字体)/ inline(仅序号换字体) |
--no-address |
不做主送机关顶格识别 |
--restyle |
就地套规范,保留图片/表格/超链接(支持 .docx/.doc/.wps/.wpt,非 .docx 自动先转换) |
--make-template |
生成空白公文模板 |
--check-fonts |
只做字体检测 |
--install-fonts <文件/目录> |
安装字体(.ttf/.ttc/.otf),装到用户级字体目录,无需管理员 |
--doctor |
环境体检(Python / python-docx / WPS COM / 字体) |
--set-default-format <格式> |
记住默认输出格式(docx/wps/wpt/doc),以后省略 -o 自动使用 |
--reset-prefs |
恢复默认偏好设置 |
输出格式说明
| 格式 | 说明 |
|---|---|
.docx |
默认交付格式,Word/WPS 通用,保留可编辑性 |
.wps |
WPS 原生文档,由本机 WPS 另存(新版 WPS 与 docx 同为 OOXML 包,WPS 双击直接打开) |
.wpt |
WPS 模板,放入 WPS 模板目录后可反复套用 |
.doc |
Word 97-2003 二进制格式,兼容老系统(真正 OLE2 格式,非改名) |
转换依赖本机 WPS/Word 的 COM 接口(脚本按扩展名显式指定保存格式)。若失败,脚本会给出提示,可在 WPS 中打开 .docx 后「文件 → 另存为」手动导出。
性能(快不快,已实测)
| 路径 | 耗时 | 说明 |
|---|---|---|
Python 版 → .docx |
约 1.5 秒 | 默认首选,用户无感 |
Python 版 → .wps/.wpt/.doc |
约 6 秒 | 需启动 WPS 做格式转换(COM 连接约 2 秒是固定成本) |
| PowerShell 版 → 任意 | 约 6 秒 | 需启动 WPS,同样是 COM 固定成本 |
结论:默认交付 .docx(最快且通用,Word/WPS 都能开)。只有用户明确要 WPS 原生格式、或本机没 Python 时才接受 6 秒。6 秒在「WPS 自己打开一个文档也要 3—5 秒」的语境下属正常,不会让人感觉卡。别为了追求 .wps 而无谓地多花 5 秒。
交付流程(务必走完)
gongwen.py生成文档(先看终端输出:字体告警、标题折行、落款识别结果)verify.py自检,确认页面/字号/字体/行距/缩进全部通过- 需要 .wps/.wpt 时再转换
- 打开成品让用户过目:正文内容由用户负责,排版由脚本负责,数据口径需业务核实
坑与排错
- 只设
run.font.name对中文无效,必须写w:rFonts的w:eastAsia(脚本已处理)。 - 行距用固定值(
lineRule=exact),不是"1.5 倍行距";同时关闭"对齐到网格",否则 WPS 会改写行距。 - 首行缩进按字符写
firstLineChars=200,不是按磅值;落款日期右空同理rightChars=400。 to_wps.ps1必须是带 BOM 的 UTF-8,且只能有一个 BOM,否则 PowerShell 5.1 会报"无法识别 cmdlet"。- 性能坑(已实测):
to_wps.ps1不要对已关闭的文档二次Close,也不要对 WPS 的 Application 对象调Marshal::ReleaseComObject——前者拖慢约 7 秒、后者约 11 秒。文档Close(0)后置$null,COM 对象交给进程退出统一回收即可。 - 字体名以注册表为准(中文环境下常注册为 SimHei / KaiTi),脚本已内置别名映射;但楷体 ≠ 楷体_GB2312、宋体 ≠ 仿宋_GB2312,会被提示为近似替代。
完整规范细则与手工排版步骤见 references/format-spec.md,输入样例见 examples/sample.md。