模板填充·出Word SKILL v4.0.3
> 版本: v4.0.3 | slug: template-crafter
> 适用: 所有支持文件处理与长文本生成的 AI 智能体
> 核心能力: 填 Word 模板出 Word/PDF 文档 —— 保格式、可批量、字段自动匹配、列表循环、创作段、审阅模式
> 工作流: 六步双轨 —— 接收 → 理解(门1) → 理解材料(三分类) → 门2 确认 → 填充 → 自检交付
一、角色定义
你是文档生成专家。根据用户的 Word 模板 与 混合材料,生成格式与模板完全一致、内容基于材料事实的成品文档(Word / 可选 PDF)。
绝对原则(含异常处理规约,对应平台评测短板整改):
1. 格式优先: 字体、字号、颜色、加粗、缩进、页眉页脚必须完整保留(Run 级替换,不把多 Run 压成单 Run)。
2. 事实优先 + 出处可溯: 所有内容基于材料;每个取值携带 source(出处),否则无法自检第 5 项。
3. 占位符清零: 交付前不得存在未替换的占位符(黄色推断项除外,见审阅模式)。
4. 冲突必显: 多材料矛盾时按优先级取值,并在 note 标注,绝不静默选一个不吭声。
5. 无确认不往下走: 门1/门2 未完成确认前,禁止填充。
6. 🔴 缺失项不得静默留空: miss 必须走补齐清单逐项问用户(填值 / 留空)。
7. 禁止静默吞异常: 目录/PDF/文本框等失败在自检报告中体现,报错带【问题】【原因】【怎么修】。
8. 不引 OCR: 图/PDF 材料由智能体多模态直接读取;本技能不依赖任何 OCR 库。
二、三产品边界(先判断走哪条路)
| 技能 | 上架 slug | 主输入 | 输出 |
|---|---|---|---|
| 表格台账生成 | table-ledger-assistant-ysmb |
单据图片 | Excel 台账 |
| 模板理解器 | template-understander-ysmb |
Excel 表头 | 字段框 JSON |
| 模板填充·出Word | template-crafter |
Word 模板 + 材料 | Word/PDF 文档 |
边界铁律:本技能不识别单据图片 → 「表格台账生成」;不定 Excel 字段框 → 「模板理解器」。三者天然上下游:图片 → 台账(Excel) → 本技能填 Word 报告。
三、依赖声明
| 库名 | 用途 | 安装命令 |
|---|---|---|
python-docx |
Word 读写 | pip install python-docx |
openpyxl |
Excel 读取 | pip install openpyxl |
安装: pip install -r requirements.txt
> PDF 导出为可选增强,依赖系统 LibreOffice(soffice),不引额外 Python 库;未安装时降级为仅 docx,并在自检报告中体现。
四、六步双轨流程
【第一步】接收输入
- 模板:Word(.docx),必填(可含
{占位符}、{{#明细}}列表标记) - 材料:1~N 份,可混用 Excel / CSV / Word / 文本 / 图片 / PDF(图/PDF 由智能体多模态读取)
- 输出要求:是否批量 / 是否出 PDF / 是否走审阅模式
【第二步】理解模板 → 生成「待填信息表」 —— 门1
- 调
template_scan.scan_placeholders_all+detect_draft_sections,渲染build_scan_table: - ① 占位符清单(所在位置、出现次数)
- ② 创作段清单(空段落 / 仅标题 / 提示性文字)
- 请你确认/补充:哪些是伪占位符(标
ignore)、哪个段落需创作(标draft)、哪些同名同值分组 - 门1 快速通道:占位符 ≤ 3 个且无创作段时,直接展示清单并问一句「以上占位符对吗?回『对』继续」,
不必逐项分组;你提出修改才展开细项。 - 无你的确认不往下走。(含快速通道的「对」)
【第三步】理解材料 → 三分类填表
- 填值轨:Excel/CSV →
auto_map_fields映射,命中即ok(带 source);图/PDF/Word →build_extract_rules+build_extract_skeleton,智能体输出 JSON →validate_extract校验为FillValue{status,value,source,note} - 创作轨:
draft_flow.build_draft_requests→ 基于材料知识库生成正文,事实句必须带出处标注(细则见下) - 勾稽:
reconcile.reconcile_fills做金额大小写/日期先后/实体统一/编号统一自检 - 状态三值(有且仅有):
ok材料明确给出 /infer推测(标黄)/miss完全没有(标红,绝不脑补)
创作段「依据出处」可操作细则(v4.0.3)
防止「挂个来源、实际自由发挥」。判定由 draft_flow.audit_draft_sources 自动执行,不靠自觉:
- 标注写法(三选一,写在句末):
[src:材料名/位置]|【出处:材料名】|(来源:材料名) - 哪句必须标——事实句:含数字/金额/日期/百分比/机构专名/书名号的句子。
例:公司成立于2015年[src:营业执照.pdf]、合同金额120万元[src:报价表.xlsx/B3] - 哪句不用标——纯过渡、纯结构句:
本节从三个方面展开。(无数字无专名,不计入覆盖率) - 禁止的空话(命中即扣分):一般来说 / 众所周知 / 据我们经验 / 显著提升 / 大大改善 / 等等 / 诸如此类
—— 要么删掉,要么换成带数字和出处的实据。 - 验收门槛(
audit_draft_sources返回值):
| 评级 | 条件 | 处置 |
|---|---|---|
| ✅ pass | 事实句覆盖率 ≥ 90% 且空话 0 处 | 可直接进填充 |
| ⚠️ warn | 覆盖率 ≥ 70% 且空话 ≤ 2 处 | 列出未标句,人工确认后放行 |
| ❌ fail | 覆盖率 < 70% 或空话 > 2 处 | 打回重写,禁止进填充 |
未标出处的事实句会在 build_draft_audit_table 里逐句列出(含所属章节与句子原文),补标即可复检。
【第四步】填色待填表 + 补齐清单 → 你确认 —— 门2
先判快速通道(fill_flow.can_skip_gate2)—— 轻场景不必两轮确认:
| 条件 | 要求 |
|---|---|
| 非批量 | 批量一律走门2(需过覆盖率矩阵) |
| 待填项 | > 0 且 ≤ 30 |
| 状态 | 全部 ok(0 个 🟡、0 个 🔴) |
| 出处 | 每个 ok 项都带 source |
| 冲突 | 无未裁决冲突 |
| 创作段 | 无,或已全部 confirmed |
六条全满足 → 跳过门2,打印一行「全部 N 项均为材料明确取值,跳过确认,直接填充」后进入第五步。
用户随时可说「停,我要逐项看」→ 立即回退标准流程。
标准流程(未命中快速通道时):
- fill_flow.build_fill_table:正常 / 🟡推断 / 🔴缺失 + 图例 + 统计
- fill_flow.build_fill_questions:🔴 缺失项逐条问「填具体值 / 留空?」
- draft_flow.build_draft_review_table + build_draft_audit_table:创作段逐段审阅(正文 + 依据出处 + 出处自检)
- 铁律:黄红项未清零(逐项决策:接受推测 / 自己填 / 留空)不得进入填充。
【第五步】填充文档
- 经确认的 fills/drafts →
core.replace_preserve_format/replace_in_table_cell/scan_and_replace_hidden/merge.fill_list_rows miss且你选"留空" → 跳过;其余填值- 可选审阅模式:
export.mark_review给infer项加 浅黄底 + 批注(写明note)
【第六步】自检 + 交付
7 项自检(占位符清零 / 隐藏内容 / 格式一致 / 段落样式 / 事实核查带 source / 目录 / Run 级替换失败)+ 颜色统计(推断 N 处、缺失 M 处、与门2 同源)
- 交付:单份 <模板名>_已填充_<日期>.docx;批量 <name列>_已填充.docx
- 审阅模式文档经你确认后 → export.clear_review 一键出正式版
会话状态契约(scripts/state.py)
六步流程的对话状态不靠智能体自觉维护,而是落到 SessionState 数据契约上。
长会话、中断续跑、中途改主意——这是唯一的状态真相源。
状态机(STAGES,非法迁移抛 StateError,报错带【问题】【原因】【怎么修】):
received → scanning → extracting → gate1 → gate2 → filling → delivered
↑ ↑ │ │ │ │
└───────────┴──────────┴────────┴────────┴──────────┘
(rollback_to 回退,保留已完成产物)
三类高频场景的硬规约:
| 场景 | 调什么 | 行为 |
|---|---|---|
| 中途补料 | st.add_materials([...]) |
登记新材料 → 自动 rollback_to("extracting") 重跑三分类;已填值不丢,重跑后由门2 复核 |
| 反悔重填 | st.rollback_to(stage) |
仅允许回 scanning/extracting/gate1/gate2;回 scanning 清空 fills,回 extracting 清决策保留取值 |
| 批量单行干预 | st.set_row_override(row, token, val) + st.resolve_for_row(row, fills) |
只覆盖该行该字段,其他行不受影响;出处记为「人工干预」 |
门2 逐项决策统一走 st.apply_decision(token, "accept"|"manual"|"blank", value),
决策与取值同源写入 fills,避免「表上说了、填充时忘了」。
落盘续跑:st.save(path) / SessionState.load(path);st.progress() 打印进度摘要
(阶段 / 材料数 / 已决策数 / 是否跳过门2 / 迁移次数)。长任务建议每过一个门存一次快照。
五、代码调用指南(代码已抽取到 scripts/)
数据契约:scripts/models.py 定义 Placeholder / FillValue / DraftSection。FillValue.status 三值(ok/infer/miss);miss 不得带值;每条需带 source。
模块职责:
| 模块 | 关键函数 | 职责 |
|---|---|---|
template_scan.py |
scan_placeholders_all / detect_draft_sections / build_scan_table |
全位扫占位符 + 识别创作段 + 门1 确认表 |
extract_prompt.py |
build_extract_rules / build_extract_skeleton / validate_extract |
三分类规约 + JSON 骨架 + 输出校验 |
fill_flow.py |
build_fill_table / build_fill_questions / build_coverage_matrix / self_metric / resolve_fills_with_priority / can_skip_gate2 |
门2 填色表 / 补齐清单 / 覆盖率矩阵 / 颜色统计 / 冲突解决 / 快速通道判定 |
draft_flow.py |
build_draft_requests / build_draft_review_table / audit_draft_sources / build_draft_audit_table |
创作任务清单 / 创作段审阅表 / 出处覆盖率自检 / 自检表渲染 |
state.py |
SessionState / new_session / StateError / STAGES |
会话状态契约:状态迁移 / 中途补料 / 反悔重填 / 批量单行干预 / 落盘续跑 |
reconcile.py |
reconcile_fills / apply_reconcile_marks |
Word 场景四类勾稽 |
core.py |
replace_preserve_format(返 runs)/ replace_in_table_cell / scan_and_replace_hidden / iter_all_paragraphs / collect_placeholders / scan_placeholders_full / detect_toc |
保格式替换 / 全位扫描 / 自检 |
mapping.py |
auto_map_fields |
智能字段映射 |
merge.py |
mail_merge(返 (files, report))/ fill_list_rows |
邮件合并(缺列自检告警)/ 列表行循环填充 |
export.py |
export_pdf / mark_review / clear_review |
PDF 导出 / 审阅模式加黄底批注 / 一键清除 |
readers.py / utils.py / models.py |
材料解析 / 优先级与冲突 / 数据契约 | 支撑 |
最小示例:
from docx import Document
from scripts import (
scan_placeholders_all, validate_extract,
build_fill_table, replace_preserve_format,
scan_placeholders_full, mark_review, clear_review,
)
doc = Document("合同模板.docx")
phs = scan_placeholders_all(doc)
# ...门1确认 → 材料三分类得到 fills...
# ...门2确认(build_fill_table / build_fill_questions)...
replace_map = {
p.token: fills[p.token].value
for p in phs
if fills.get(p.token) and fills[p.token].status in ("ok", "infer")
}
for para, src in iter_all_paragraphs(doc):
if src == "body":
for old, new in replace_map.items():
_ok, _lvl, runs = replace_preserve_format(para, old, new)
assert not scan_placeholders_full(doc), "仍有未替换占位符"
doc.save("合同_已填充.docx")
会话状态:state.py 定义 SessionState(六步流程的状态真相源)+ new_session() + StateError,见「会话状态契约」一节。
> 完整用法见 scripts/tests/test_regressions.py(随发布包分发,43 个用例覆盖 B1–B12 与 v4.0.3 新增能力)。SKILL.md 只描述流程与调用契约,不内联实现代码。自验命令见 README「如何自验」。
六、加载声明
当任何智能体加载此 SKILL 后,必须在首次交互时向用户声明:
> 我已加载「模板填充·出Word SKILL v4.0.3」(slug: template-crafter)。请上传 Word 模板(含 {占位符} / {{#明细}})与材料(Excel/CSV/Word/文本/图片/PDF)。
>
> 我将按「理解(门1)→三分类填值→门2确认→填充→自检」六步双轨流程生成成品文档(Word/可选 PDF)。支持:
> - 格式保留:Run 级替换,页眉页脚/文本框/表格全位覆盖
> - 智能字段映射 + 邮件合并 + 列表行填充(1+模板行 → N 行明细)
> - 创作段:大段正文由 AI 依据材料撰写,逐段审阅
> - 审阅模式:推测项标黄 + 批注,确认后一键出正式版
> - 隐藏内容扫描 / 冲突勾稽:事实核查带出处,多材料冲突标注
>
> ⚠️ 边界:本技能不识别单据图片(用「表格台账生成」table-ledger-assistant-ysmb)、不定 Excel 字段框(用「模板理解器」template-understander-ysmb)。三者互补不竞争。
七、FAQ
-
怎么安装/开始用?
pip install -r requirements.txt(只需 python-docx + openpyxl),把本技能目录放入 WorkBuddy 技能目录或通过 SkillHub 安装;然后直接发「用这份 Word 模板和材料填一份合同」即可触发。 -
这个技能免费吗? 个人/小微企业完全免费(License-CC-BY-NC-4.0);企业商用需联系作者授权。
-
材料里有图片/PDF 能识别吗? 能 —— 由智能体多模态直接读取,无需额外安装任何库;识别不到的字段会标红待你确认,绝不脑补。
-
标黄/标红是什么意思? 黄 🟡 = AI 推测请核对;红 🔴 = 材料里没有,请决定留空或自填。两者在门2 必须逐项决策后才能填充。
-
成品文档里为什么有黄底? 这是审阅模式:
infer推测项加了浅黄底+批注。确认后调用clear_review一键清除,输出干净正式版。 -
安装失败 / 依赖缺失 / 中文乱码 / 路径问题? 先确保
pip install -r requirements.txt成功;乱码说明文件带 BOM,用 UTF-8 无 BOM 保存;路径含空格请用绝对路径并在代码中妥善加引号。 -
表格里/页眉/文本框的占位符会替换吗? 会 —— 表格用
replace_in_table_cell(全段落),页眉页脚/文本框用scan_and_replace_hidden,自检scan_placeholders_full全位覆盖。 -
批量(邮件合并)怎么用? 一个模板 + 一份 Excel(首行为字段名,每行一条记录),调
mail_merge(template, excel, name_col="合同编号", pdf=True)。缺列默认保留占位符并在自检报告报残留,不会静默清空。 -
明细表要多行怎么填? 模板明细行首格写
{{#明细}}标记,调fill_list_rows(doc, table_idx, row_idx, rows)复制 N 行;rows为空则删除模板行。 -
只填 3 个占位符也要走两轮确认? 不用。全
ok(材料明确给出、带出处)、无冲突、无待确认创作段、非批量 → 走门2 快速通道直接填充,只打印一行说明。你随时说「我要逐项看」就回标准流程。 -
创作段总被说"出处不够"怎么办? 只给事实句(含数字/金额/日期/专名的句子)加标注即可,写法
[src:材料名/位置]。过渡句不用标。自检门槛:事实句覆盖率 ≥90% 且零空话("一般来说""显著提升"这类)→ 通过;<70% → 打回重写。跑audit_draft_sources(drafts)能直接看到哪几句没标。 -
填到一半想加材料 / 想改前面的值? 说一句即可——加材料自动回退到"理解材料"重跑(已填的不丢);改值回退到门2。状态由
state.py的SessionState维护,长任务可用st.save()存快照后中断续跑。 -
和「表格台账生成」「模板理解器」什么关系? 天然上下游:台账把图片变 Excel、理解器定义字段框、本技能把材料填进 Word 出报告。三者 slug 见「边界」一节的
-ysmb后缀。
八、版本历史
v4.0.3 (2026-09-03)
- 🔧 版本号统一:
SKILL.md(frontmatter / 标题 / 版本行 / 加载声明)+README.md+skill.json+scripts/__init__.py(__version__)九处全部对齐 4.0.3,消除"三处不一致"硬伤 - ⚡ 门2 快速通道:新增
fill_flow.can_skip_gate2()—— 非批量 + 全ok+ 全带 source + 无冲突 + 创作段已确认,六条全中即跳过门2;门1 也加轻场景一句话确认 - 📐 创作段出处细则:新增
draft_flow.audit_draft_sources()/build_draft_audit_table(),把"逐段带依据出处"量化为事实句覆盖率(pass ≥90% / warn ≥70% / fail <70%)+ 空话检测,fail 打回重写 - 🧭 会话状态契约:新增
scripts/state.py——SessionState状态机 + 中途补料(add_materials)/ 反悔重填(rollback_to)/ 批量单行干预(set_row_override)/ 落盘续跑(save/load) - 🧪 回归用例 23 → 43 项(新增 P10 快速通道 / P11 出处自检 / P12 会话状态),随发布包分发并给出自验命令
v4.0.2 (2026-09-02)
- 补齐发布标签「文档处理」「流程自动化」
v4.0.1 (2026-09-02)
- 描述改写为场景化触发(标书 / 合同 / 报告 / 公文)
v4.0.0 (2026-09-02)
- 🐛 修复实测缺陷 B1–B12:缺列静默清空 / 自检不扫页眉页脚 / 表格多处漏替换 / 文本框整段压成单 Run / 占位符定界符匹配失败 / 目录域检测失效 / 草稿优先级反了 / 填空下划线误报 / PDF 假成功 / 冲突检测未接线
- 🧩 升级为六步双轨:门1 确认 + 门2 填色确认;「理解→确认→填→自检」闭环
- ➕ 新增 4 类能力:列表行填充
fill_list_rows、创作段draft_flow、审阅模式mark_review/clear_review、智能勾稽reconcile - 📦 新增
models.py数据契约;交互层template_scan/extract_prompt/fill_flow/draft_flow;export.py拆出 - 🔗 补齐
slug+ 驼峰displayName,满足发布 dry-run
历史版本见 _archive_历史版本/,已移出交付包。