1实现原理 · 为什么它能做到
核心卖点是『修订感知』:python-docx 裸读会漏修订插入(w:ins 包装的子 run)与整段删除(w:del 包段落标记),所以引擎不走 python-docx,而用官方 OpenXML SDK 的 csx 脚本把 ins/del/move 当一等公民读。
python-docx 的 `paragraph.text` 走 `paragraph.runs`,runs 只取直接子 `<w:r>`、不递归 `<w:ins>` 包装——**对方用修订模式插入的所有内容都会被漏读**
架构 = Python 编排壳 + C# dotnet-script 引擎:docx_bridge_client.py 无状态直读 docx,subprocess 调 csharp/tasks/*.csx(list_comments/list_revisions/extract_views),结果按 (路径+mtime) 做内存 LRU 缓存。
cmd = ["dotnet-script", str(script), "--", str(docx), *extra_args] proc = subprocess.run(cmd, capture_output=True, text=True, env=env)
三个 csx 都基于 DocumentFormat.OpenXml 3.2.0(#r nuget 声明),输出 JSON/NDJSON 给 Python 渲染——解析全部在 C# 侧,Python 只编排。
#r "nuget: DocumentFormat.OpenXml, 3.2.0" using System.Text.Json; using DocumentFormat.OpenXml.Packaging;
输出是带空白『处置』列的对账表(markdown 或 --json):谁批的/批在哪段/内容/状态 + 修订逐段删改,锚定段落截断 60 字,--json 给全文。
产出表格自带空白「处置」列——它的用途就是拿去逐条裁决。引擎提炼自作者一个真实图书出版项目的审阅工具链(2026-02 起生产验证:单文件 96 条编辑批注、整书修订处理、输入含 WPS 云文档导出件)
空结果被设计成『大声提示』而非静默空表:无批注无修订时输出「这份 docx 没有携带任何审阅痕迹」+ 两个常见原因(导出丢批注/在线未导出)——防『拿到丢了批注的副本还以为对方没意见』。
无批注无修订时输出一段明确提示(「这份 docx 没有携带任何审阅痕迹」+两个常见原因),不会静默输出空表——拿到丢了批注的副本还以为对方没意见,比读错内容更危险。
只读纪律写死:不提供接受/拒绝修订、回复批注或改稿再导出——对账后的改动落在用户自己的正稿源再重新生成。
本 skill 只读。它不提供「接受/拒绝修订」「回复批注」「改正文再导出」——对账后的改动应落在你自己的正稿源(合同草案 SSOT、书稿源文件)再重新生成
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | dotnet-script(csx 运行时,dotnet tool install -g) |
| package | DocumentFormat.OpenXml 3.2.0(NuGet,csx 首跑自动 restore 需网络 10-30s) |
| cli | dotnet SDK(brew install dotnet,宿主需装) |
4风险提醒 风险提醒:蓝色 · 知晓即可
- 环境门槛:需要 .NET SDK + dotnet-script + 首次联网 NuGet — SKILL 自述首跑 10-30s、离线失败;无 .NET 环境则整套引擎不可用(无 python 侧回退,属刻意设计)。
- 只读边界也意味着不闭环 — 只能读+对账,接受/拒绝/回复/改稿需回到正稿工具链——期望『一条命令处理完审阅』的用户会失望。
- 解析文档型输入 — docx 是 zip+XML,经 OpenXML SDK 解析;恶意构造的 docx 依赖官方库安全性,宿主应把外部来的审阅稿当不可信输入。
- 索引语义边界(不递归表格内段落) — 与 python-docx 对齐的 body 直接子段索引意味着表格内批注锚定需另行处理,reference 已声明但用户需知晓。
5第二遍独立确认
- [ok] 修订感知引擎(csx + OpenXML SDK) — 三个 csx 均 #r 'nuget: DocumentFormat.OpenXml, 3.2.0' 并引用 WordprocessingPackage API;list_revisions/list_comments 输出 JSON。
- [ok] Python 编排壳零第三方依赖 — docx_bridge_client.py import 仅 stdlib(subprocess/json/pathlib/functools 等);SKILL 'Python 侧纯 stdlib' 属实。
- [ok] dotnet-script 调用链 + ROLL_FORWARD/PATH 处理 — _ensure_dotnet_script_on_path 追加 ~/.dotnet/tools、env.setdefault('DOTNET_ROLL_FORWARD','Major') 均在源码。
- [ok] 无状态只读 + (路径,mtime) 缓存 — _cache_key 返回 (str(p), st_mtime);lru_cache 装饰器在三个读取函数上;无写 docx 代码路径。
- [ok] python-docx 漏读叙事(w:ins/w:del) — SKILL 对 python-docx runs 直子与 w:del 段落的描述与 OpenXML 结构一致(技术事实,非夸大);reference csharp-tasks-spec 补充语义。
- [ok] 批注双锚定(WPS 兼容) — list_comments.csx 头注释记录 CommentRangeStart 首选 + CommentReference 回退及 WPS 96 条中 6 条实测。
- [ok] 空结果提示防假阴性 — SKILL 声明 + extract_review.py 输出契约(无批注无修订时输出提示段)。
- [ok] 无网络外发(除 NuGet 首跑) — 脚本全量扫描无 requests/urllib/http/curl;SKILL 明示 NuGet restore 需网络且仅首次。
6结论
5d26333cd2cde9a9…d5c4678cb5