看到标题里 700 星这个数字我先说一句实话能把公文格式这个最不起眼、又最折磨人的活儿做成开源项目还拿到这个关注度充分说明大家被手动调格式摧残得确实不轻。这段时间我一直在折腾一个开源 Skill它的核心用途非常简单——你给它一篇公文正文它按 GB/T 9704-2012《党政机关公文格式》把字体、字号、页边距、行距、页码、版记全部处理好直接吐出一份符合国标的 Word 文件。你不用打开 Word 逐项去调那 7 个页边距数值也不用记 2 号小标宋、3 号仿宋、28 磅行距这些零散参数更不用对着模板一处处数“这个标题字号到底够不够”。这篇文章就把这个项目的原理、部署、实操和避坑经验一次讲透不管你是办公室写材料的还是搞 AI Agent 二次开发的都能拿走直接用的东西。1. 一段简史公文排版为什么专门需要一个Skill先说一个朴素的现实公文格式的规则不算难但架不住琐碎。琐碎到一定程度人就容易出错出错就得返工返工就要加班。我见过太多同事为了把一个通知的标题字号调对反复选中文字、切字体、改字号最后还得拿尺子在屏幕上量页边距——这还是在有模板的情况下。1.1 那些年被格式逼疯的打工人绝大多数机关单位、国企和事业单位的公文写作场景其实是这个套路先在 WPS 或 Word 里新建一个空白文档然后打开某份老文件作为参考照着它的格式一边改一边调。这个过程有三个非常典型的坑。第一模板本身不一定规范。你手里的老文件可能是多年前的同事手工排的页边距、行距、页码格式是否完全符合国标没人验证过。照着错误模板调结果自然是错上加错。第二内容一多格式就散。写一个几十页的汇报材料时标题层级、表格、图片、落款混在一起手动调整的每一项都会牵动整体排版。经常是调完一个三段标题发现整个页面的行距全乱了又得退回上一步。第三知识只存在于少数人的脑子里。一套完整的国标参数从纸张尺寸到字号矩阵再到页码的一字线这种细节没专门学过的人根本不知道。新人接手时没有标签化的规范文档全靠口口相传这种隐性知识一旦断层只能重新踩坑。我算过一笔时间账一份 5 页左右的通知如果从空白文档开始手动排光调页面设置、字体字号、标题层级、行距页码快则 15 分钟慢则 30 分钟以上。如果这活儿要反复做好几十份浪费的时间就很可观了。所以当看到这个开源 Skill 出现时我的第一反应是这东西切中的痛点太真实了。1.2 国标到底规定了什么GB/T 9704-2012《党政机关公文格式》是这份 Skill 的规范基石。这份国标把公文版面的几乎所有视觉元素都做了量化规定我用表格把最核心的参数列出来项目国标要求换算成 Word 常用单位纸张A4210mm × 297mm210mm × 297mm上边距37mm ± 1mm约 104.9 磅下边距35mm ± 1mm约 99.2 磅左边距28mm ± 1mm约 79.4 磅右边距26mm ± 1mm约 73.7 磅正文3 号仿宋体16pt公文标题2 号小标宋体22pt一级标题一、黑体通常 3 号16pt二级标题一楷体通常 3 号加粗或 3 号三级标题1.仿宋加粗3 号行距一般固定值 28 磅固定值 28 磅页码4 号半角宋体阿拉伯数字左右各一条一字线4 号14pt这里有个容易混淆的地方公文排版中的字号用的是传统中文字号体系不是 Word 里默认的磅值。3 号字对应 16pt2 号字对应 22pt这个换算关系不熟的人经常会搞错。另外页边距的单位国标里写的是毫米但 Word 里更多显示为厘米或磅这个也需要换算。这还只是基础部分。一份完整公文的结构组件还包括份号、密级、紧急程度、发文机关标志、发文字号、签发人、红色分隔线、标题、主送机关、正文、附件说明、发文机关署名、成文日期、印章、附注、附件、抄送机关、印发机关和印发日期。每一个组件的字体、字号、位置都有具体规定这就是为什么纯靠手动排版容易漏项——不是你不认真是规则确实太多了。2. 这个 700 星的开源 Skill 是怎么工作的理解了痛点再来看方案。这个项目本质上做的事情是把上面那一整套规则固化成代码逻辑再通过Skill这种形式封装成 AI 可以直接调用的能力。它跟普通 Word 模板的最大区别是模板只是静态的样式壳子而这个 Skill 是动态的规则引擎。2.1 Skill 不是插件是操作手册 工具包先说一个背景Skill 这个形态是最近一年多 AI Agent 生态里流行起来的方案。它的思路很简单——把某一类任务的执行知识打包成一个固定目录结构里面包含一个主指令文件通常是 SKILL.md和若干配套脚本、资源文件。AI比如 Claude、Cursor 这类支持 Skill 的工具读到这个目录后就知道遇到这类任务该按什么流程操作、调用什么脚本、遵守什么规则。放在公文场景里这个 Skill 的目录结构大致是skill-root/ ├── SKILL.md # 主指令告诉 AI 如何识别输入、调用脚本、校验结果 ├── assets/ # 静态资源字体说明、国标参数表、示例公文模板 └── scripts/ ├── generate_docx.py # 核心生成脚本用 python-docx 操作 Word 文档 ├── validate.py # 校验脚本检查生成的文件是否满足国标参数 └── utils.py # 工具函数单位换算、文本清理等我建议你把 Skill 理解成一个老师傅代代相传的操作手册 一套现成的工具。普通模板是我帮你把样式定好你往里填内容就行而 Skill 是我不仅把样式定好还教会 AI 怎么根据内容类型自动选择样式并现场生成 Word 文件。它的核心能力有两个一是把非结构化的文字内容识别成公文结构二是把结构映射成符合国标的 Word 元素。2.2 一次完整的生成链路我实际跑通了一次完整流程后对整个链路有了直观感受。整个工作流大致分四步**第一步输入解析。**你只需要给 AI 一段文字比如通知正文、会议纪要、请示材料。AI 会先判断这段文字里哪些是标题、哪些是正文、哪些是主送机关、哪些是落款。这个判断过程依赖大模型的语义理解能力也就是通过 SKILL.md 里的指令引导 AI 来做结构化标注。**第二步格式映射。**AI 根据识别出的结构类型去 SKILL.md 和 assets 里的国标参数表查对应的样式。这个环节非常依赖参数的完整性和准确性。比如识别出这是第一个一级标题就查询到3 号黑体、顶格排布然后把信息传给脚本。**第三步脚本生成。**generate_docx.py 拿到结构和样式映射后逐段在 Word 文档中创建段落设置字体、字号、颜色、对齐方式、行距、段前段后距离。python-docx 这个库对 Word 文档的控制力很强能做到逐磅精调。这一步是纯代码执行不依赖 AI速度快且结果稳定。**第四步校验输出。**生成完后skill 里还有一个反向校验的逻辑检查事由、成文日期、页码是不是齐全页边距是不是精确落在规定范围内。如果发现偏差会给出提醒甚至直接自动修正。这四步听起来不复杂但每一步都藏着一些细节问题。比如 Word 里的磅和国标里的毫米怎么换算比如中文字体的设置为啥不能只设东亚洲字体、还要同步设置西文字体比如页码里的一字线到底是一段横线还是两个短横线。这些都是实操中才会遇到的问题后面我会在避坑章节展开。3. 国标公文格式核心参数拆解之前给的表格只是列了参数这节我把几个高频出错的细节展开讲也算是这份 Skill 解决的核心技术难题。3.1 页面三件套纸张、页边距、版心公文的物理载体是 A4 纸这个大家都知道。但很多人忽略了版心这个概念。版心就是除去页边距后一页纸中间实际能排文字的区域。按国标计算A4 纸宽度 210mm减去左 28mm、右 26mm版心宽度是 156mm高度 297mm减去上 37mm、下 35mm版心高度是 225mm。这个 156mm × 225mm 的版心区域才是公文的有效面积。手动排版时如果你只改了页边距而忘了检查版心内的实际行数和字数就可能出现版心内每行文字超过 28 字或每页超过 22 行的违规情况。国标规定一般每面排 22 行每行排 28 个字并且要求为准确计算版面可将版心宽度除以 28 个字宽版心高度除以 22 行行高。这个说法本身有点绕我给一个更直白的实操经验在 Word 里把正文设置为 3 号仿宋、固定值 28 磅行距后每行大概能排 28 个汉字每页大约 22 行。如果你的正文段落首行缩进两字符也就是缩进 2 个字宽那么每行实际有效文字在 26 字左右这个细节 Skill 生成时会自动帮你处理让整篇文档的版式呈现出行行确当、列列均匀的稳定感。3.2 字体字号矩阵公文标题使用 2 号小标宋体正文使用 3 号仿宋体这是整套格式里最广为人知的规则。但实际执行时比这复杂得多——标题、一级标题、二级标题、三级标题、四级标题用的字体各不相同。下面是实际公文排版中常用的标题与字体对应关系公文大标题2 号小标宋体居中排布回行时要做到词意完整、排列对称。一级标题一、二、三3 号黑体单独成行行末不加标点。二级标题一二三3 号楷体单独成行行末不加标点。三级标题1. 2. 3.3 号仿宋加粗可以单独成行也可以与正文连排。四级标题1233 号仿宋一般不单独成行跟在正文段首。正文3 号仿宋。这里我要特别提醒一个坑很多人在 Word 里设置中文字体时只改了字体下拉框里的中文字体但没动西文字体。Word 的默认西文字体是 Calibri 或 Times New Roman当正文里出现半角数字、英文缩写时西文字体跟中文字体不一致整段文字会显得很突兀。Skill 在生成时会把东亚洲字体和西文字体统一处理避免这个拼接感。还有一个隐藏问题是小标宋字体。仿宋、黑体、楷体都是系统自带或 Office 自带的但小标宋体尤其方正小标宋在很多电脑上根本没有。这个 Skill 的文档里通常会给出字体安装建议这一步跑不掉否则生成的 Word 在自己电脑上打开是好的发给别人一看字体就乱套。3.3 容易被忽略的细节页码、分隔线、版记页码是公文格式里最容易被低估的部分。国标规定页码用 4 号半角宋体阿拉伯数字数字左右各放一条一字线例如— 1 —单页码居右空一字双页码居左空一字。这里的难点在于奇偶页不同——奇数页页码靠右偶数页页码靠左而且页码要放在版心外下边缘。在 Word 里手动设置奇偶页不同的页脚、再去调整页码的左右位置操作路径非常绕很多人弄到一半就放弃了。再说红色分隔线。版头部分发文机关标志、发文字号等与主体部分之间有一条红色横线线宽通常是与版心等宽高度约为 0.35mm。这条线在手动排版时一般是用下边框线或一条水平线来模拟但线的颜色、粗细、位置很难精确Skill 生成时直接以固定尺寸画入这就保证了印刷效果的统一。最后是版记。版记部分包括抄送机关、印发机关和印发日期位于文件末页底部用两条水平线隔开。版记的字体通常用 4 号仿宋体但很多人因为不知道这个规定直接沿用了正文的 3 号仿宋整个末页的比例一下就失调了。4. 实操把这个 Skill 装进你的工具链这节我们做点正经事把项目部署起来真正生成一份公文。我分别讲本地部署、接入 Claude、用 Cursor 兜底这三条路径。4.1 本地部署三步走第一步准备环境。这个项目依赖 Python 环境和 python-docx 库。建议用 Python 3.9 以上版本然后安装依赖git clone 项目仓库地址 cd 项目目录 pip install python-docx装完后确认一下版本python-docx 的版本最好在 0.8.10 以上老版本对固定值行距的支持有些小 bug新版本里修掉了。第二步检查字体。前面说过小标宋字体不是系统自带。你可以在系统的字体目录里查一下有没有方正小标宋简体或类似名称。如果没有安装一套。这里有一个实操细节安装字体后如果 Word 或 python-docx 已经打开需要重启进程才能识别新字体别装完就急着跑脚本发现怎么还是找不到字体。第三步弄明白入口。这个 Skill 的调用通常有两种方式如果你只想快速生成可以直接运行生成脚本传入你的文本文件路径如果想让 AI 帮你处理结构识别就先把 Skill 目录挂到你的 AI 工具里。我测试时是先用脚本生成了一个小样本确认字体和页边距正常再接入 AI 流程的。4.2 在 Claude 中接入 Skill目前这个 Skill 最常见的载体是 Claude因为 Claude 的桌面版和 API 版都支持读取 Skill 目录。接入方法不复杂把 Skill 目录放到 Claude 能访问的路径比如~/skills/gongwen-format。写一段简短的提示词告诉 Claude你有一个公文排版 Skill放在 xxx 路径当你收到公文草稿时自动调用它。然后把你的文字内容直接发过去让它执行。这里有一点值得说接入之后Claude 并不是每次都主动去读 Skill 目录它需要被提示一下。所以我习惯在开头提示词里明确说明先读取 SKILL.md严格按它的规则处理这样能显著提高执行的稳定性。我实测的效果是给一段 800 字的会议纪要草稿Claude 通过 Skill 生成了完整的 Word 文件全程大约 40 秒。文档打开后我核对了页边距、字体、行距、页码全部符合国标参数。这个速度跟手动排版完全不是一个数量级。4.3 用 Cursor 或命令行兜底如果说你平时用的不是 Claude而是 Cursor 或者其他编程类 AI 工具也有办法。Cursor 本身支持读取仓库内的规则文件你可以把 SKILL.md 放进项目根目录然后在对话中直接要求它按规则生成让 Cursor 调用项目里的 generate_docx.py 脚本。还有一种更直接的兜底方案完全不依赖 AI就用手动方式调用生成脚本。比如你写了一个纯文本的公文草稿markdown 格式也行直接执行python scripts/generate_docx.py input.txt -o output.docx脚本会按默认规则把 input.txt 里的内容逐段识别、生成符合国标的 docx。对于一条比较有规律的内容这种命令行方式其实是最高效的因为完全避开了 AI 的上下文限制、输出延迟和可能理解偏差。我的习惯是第一稿让 AI 处理遇到复杂文件时直接切换到脚本直出双保险。5. 实现原理从文字到 docx 的每一步这节我们来拆解生成脚本的内部逻辑我会从如何识别结构和如何设置格式两个维度来讲配合一段简化版的代码示意帮你看懂它到底做了什么。5.1 模板脚本的分工整体思路是识别与渲染分离。也就是说AI 只负责把文字内容理解成结构化的节点清单而脚本只负责把节点渲染成符合格式的 Word 元素。这种分工有个很大的好处每一环出问题都能定位到具体环节调试起来轻松。我简化后的节点清单大概长这样[ {type: title, text: 关于印发《年度工作总结》的通知}, {type: main_send, text: 各科室、各直属单位}, {type: paragraph, text: 现将《年度工作总结》印发给你们请结合实际认真贯彻执行。}, {type: level1_title, text: 一、总体要求}, {type: paragraph, text: 坚持稳中求进工作总基调完整、准确、全面贯彻新发展理念。}, {type: signature, text: 某单位办公室, align: right}, {type: date, text: 2026年5月20日, align: right} ]AI 把原始文本整理成这种结构后生成脚本就变成了一个无脑遍历的过程。它根据每个节点的 type去样式表里找到对应的格式定义然后创建段落。这样做一方面保证了格式的一致性另一方面也让后续修改变得简单——想改所有一级标题的字号只需要改样式表里一处。5.2 结构识别与样式映射结构识别是整个流程的智能核心。AI 需要从一段没有标注格式的文本中判断哪些是标题、哪些是正文、哪些是主送机关这依赖的是大模型的语义理解能力而不是传统的关键词匹配。举个例子像各科室、各直属单位这种以冒号结尾且带称呼特点的短句AI 能自动归入主送机关而不是正文段落。一旦结构标注完成样式映射就变成了纯查表逻辑。脚本里通常维护一个样式字典类似于STYLES { title: { font: 方正小标宋简体, size: Pt(22), bold: False, alignment: CENTER, space_before: Pt(0), space_after: Pt(28), }, level1_title: { font: 黑体, size: Pt(16), bold: False, alignment: LEFT, space_before: Pt(14), space_after: Pt(14), }, # ... }这里有个关键参数行距。正文段落在公文里一般用固定值 28 磅这个设置用 python-docx 实现时需要同时设定 line_spacing_rule 为 WD_LINE_SPACING.EXACTLY并把 line_spacing 设为 Pt(28)。只设数值不设规则的话Word 可能把它理解成单倍行距的倍数而不是固定磅值。这个坑我在自己写脚本时踩过确认了 python-docx 的 API 语义后才绕开。5.3 关键代码与参数逻辑我用一个简化片段来演示核心逻辑完整代码仓库里都有这里只讲思想和关键命令from docx import Document from docx.enum.text import WD_LINE_SPACING, WD_ALIGN_PARAGRAPH from docx.shared import Pt, Mm def set_page_format(doc): section doc.sections[0] section.page_width Mm(210) section.page_height Mm(297) section.top_margin Mm(37) section.bottom_margin Mm(35) section.left_margin Mm(28) section.right_margin Mm(26) def add_paragraph(doc, text, style): p doc.add_paragraph() run p.add_run(text) run.font.name style[font] run._element.rPr.rFonts.set( qn(w:eastAsia), style[font] ) run.font.size style[size] run.font.bold style[bold] p.alignment style[alignment] p.paragraph_format.line_spacing_rule WD_LINE_SPACING.EXACTLY p.paragraph_format.line_spacing Pt(28) return p这里有两处最值得关注。第一个是run._element.rPr.rFonts.set(qn(w:eastAsia), style[font])。这行代码手动设置了 Word 文档底层 XML 里的w:eastAsia字体属性。如果缺少这一步python-docx 只设置了西文字体名中文字体在 Word 里不会生效。这种底层 XML 直接操作的做法是熟练使用 python-docx 的关键。第二个是section.page_width Mm(210)这类设置。python-docx 的 Mm 类会帮你把毫米转成英制单位EMU避免手动换算的精度丢失。你可能注意到Word 里显示的是厘米但代码里用的是毫米这里面有一个单位精度的细节设置 28mm 左边距时不推荐直接写Cm(2.8)因为Cm类底层换算为 EMU 时可能产生微小误差。虽然实际打印差异几乎察觉不到但既然做国标输出还是用毫米更严谨。6. 常见问题与避坑记录到这里项目大部分价值已经讲完了。最后我把自己实操过程中遇到的各种问题整理成一个速查表外加几个容易忽视的坑供你排查时对照。6.1 问题排查速查表问题现象可能原因解决方案生成的 docx 打开后字体不对系统缺少小标宋等中文字体安装字体后重启 Word/重新运行脚本页边距和国标不一致使用了 Cm 类而非 Mm 类改用Mm(28)的写法行距看起来不对只设置了 line_spacing 数值没设规则同时设置WD_LINE_SPACING.EXACTLY正文里的数字和英文与中文不协调未同步设置西文字体用 rFonts 同时设置 eastAsia 和默认字体一级标题没有顶格段落格式带缩进清除段落的首行缩进设置页码奇偶页位置不对Word 页脚设置没开奇偶页不同在 docx 的 section 里设置奇偶页不同页脚Skill 生成了 markdown 而不是 WordAI 没有正确调用脚本提示词中明确要求调用 generate_docx.py生成速度特别慢内容文本过长AI 输出上下文受限分段处理脚本直出最终 docx这里的核心排查逻辑是先分清问题发生在识别环节还是渲染环节。如果标题层级识别错了问题在 AI 语义理解如果字体、行距设置错了问题在脚本。用这个思路定位基本不会跑偏。6.2 踩坑经验字体、单位、编号我踩过的第一个人坑是字体。当时生成的 docx 在自己电脑上看一切正常发到另一个同事电脑上打开仿宋全部变成了宋体。排查后发现是对方机器上没装仿宋体Word 自动做了字体替换。这个问题没法完全靠代码解决所以在提交给外部单位之前最好先确认接收方有对应字体或者干脆用 PDF 输出打印版。这是公文流转里一个非常实际的流通性问题。第二个坑和单位有关。python-docx 里设置段前段后距离时如果使用Pt设置磅值跟国标里的毫米或者字的概念不是一一对应的。比如国标要求标题段前一般空一行这个一行在脚本里通常被近似成 28 磅或 16 磅具体取决于上下文。Skill 的作者一般会把这些换算关系写进注释但如果你自己改脚本很容易忘记这个换算是近似值。我建议不要轻易动这些近似值因为它们是经过多份公文验证过的稳定结果。第三个坑是编号。AI 在识别多级标题时偶尔会把一和1的层级搞混。尤其是当原文里没有严格遵循编号体系时AI 的推断就更不可靠。我的处理办法是输入给 AI 的文本本身尽量把标题层级标清楚比如用 markdown 的标题符号直接标注。原文越规范AI 的识别越准确这个规律屡试不爽。6.3 让输出更稳的小技巧最后分享三个让整个流程更稳定的小技巧。第一建立一套自己的输入规范。虽然 Skill 可以处理纯文本但在输入时用简单的 markdown 语法#表示标题、##表示一级标题等能明显提高 AI 的结构识别准确率。这就好比给 AI 一个路标它能少走很多弯路。第二生成后至少做一次抽查。虽然有校验脚本兜底但我仍然建议你抽查文件名和落款日期的正确性。AI 在处理成文日期时偶尔会直接把当天的日期写上而不是你原文里的日期。这种事没有任何技术能完美解决只能靠人眼确认。第三把整个 Skill 接入你的日常写作流。我现在的做法是写材料时不再同时开着格式参考文件和正在打的文档而是直接在对话里把内容丢给 Skill让它生成初稿我再基于初稿做内容层面的修改。排版这件事从脑力劳动中剥离后整个人写材料的节奏完全不一样了——脑子里只需要专注内容格式的问题交给规则和执行这大概就是这类工具最让人舒服的地方。根据我这段时间的实操体会这个 700 星的项目真正的价值不在于700 星这个数字而在于它把一套看似简单、实则繁琐的格式规范做成了可复用、可验证的工具。如果你也经常被公文格式折腾我的建议是别再手动调了花半小时把这个 Skill 部署起来后面省下的时间会远超投入。小到一次通知大到一份汇报材料它都能给你一个稳定的起点。