22 个文件、0 个 ERROR:怎么确认一个开源排版 Skill 真能用
一条 2.9 万浏览的推文说开源了公众号排版 Skill,但文末链接被折叠成短链。这篇记录完整的五步核查:推文还原、链接展开、仓库树核验、真实文件落盘、安全审计加冒烟测试——顺便查出推文说的 5 套主题实际是 6 套。
- 五步核查法:推文还原 → 链接展开 → 仓库树核验 → 真实文件落盘 → 安全审计加冒烟测试。缺少任何一步,「能用」都只是转述。
- 链接这一关最容易被跳过:推文正文里的仓库地址被折叠成 t.co 短链,文末真实 URL 抓取时被截断。最终靠一条微博转发坐实地址是 github.com/isjiamu/gzh-design-skill,署名「甲木 × 摸鱼小李」。
- 推文与仓库对不上账:推文说「5 套预设风格」,仓库实装 6 套主题;推文称 Obsidian 插件是自己的,但该插件真实作者是 Kianzzz。两处都需要在使用时按仓库口径更正。
- 落盘与安全:22 个核心文件落盘,源头检查 ERROR×0、WARN×2;四个脚本审计结论为无网络外联、无命令执行、无破坏性操作,仅本地写盘。
- 一个容易被误判的细节:脚本里命中三处 http 开头的字符串,是 docx 的 XML 命名空间,不是网络请求。grep 命中不等于有风险。
验证一个 Skill,需要五步而不是一步
看到一个开源工具,最常见的动作是「装上试试」。对 Agent Skill 这类会读本地文件、可能执行脚本的东西,这个动作太快了。
这次核查走的是一条五步链,每一步都在挡一类特定的错。
前三步是「它是它说的那个东西吗」,后两步是「它装上以后会不会出事、能不能跑」。五步缺一,结论就只能算传闻。
推文说的仓库,未必是那个仓库
这条推文的正文,本身就是用这个 Skill 排出来的。问题出在链接:正文里的仓库地址被折叠成短链,指向 X 文章页;文末真实 URL 抓取时被截断。光看推文,你拿不到仓库地址。
最后是靠一条微博转发坐实的:地址是 github.com/isjiamu/gzh-design-skill,仓库简介与推文描述(6 套模板、可生成新模板)吻合。
| 推文 / 传闻 | 实测结果 | |
|---|---|---|
| 仓库地址 | 文末 URL 被截断 | isjiamu/gzh-design-skill,经微博转发坐实 |
| 署名 | 暗示为推文作者本人 | 仓库署名「甲木 × 摸鱼小李」,归属待核实 |
| 主题数量 | 「5 套预设风格」 | 仓库实装 6 套主题 |
| Obsidian 插件 | 称自己做的 | 真实作者为 Kianzzz,MIT 协议 |
| 跨平台可用 | 「在 WorkBuddy 里也能用」 | 成立,README 列出多个 Agent 环境 |
两处出入值得记。一是「5 套」和「6 套」的差别——大概率写推文时第 6 套还没加。推文是某个时刻的快照,仓库是活的,以仓库为准。
二是插件的归属。推文说「我做过一个 Obsidian 的排版插件」,而该插件在公开检索里指向另一位作者。这可能是同一人的不同账号,也可能不是。在坐实之前,引用时应该写「据 isjiamu/gzh-design-skill(甲木×摸鱼小李)」,而不是直接归给推文作者。
22 个文件,字节数对得上才算数
仓库树看过了还不算完。落盘并核对字节数,能挡掉「README 写得很漂亮、实际文件是空的」这类情况。这次落盘的 22 个文件分五类:入口 SKILL.md(18.6KB)、主题库(theme-index 加 6 套主题,约 215KB)、辅助库(通用组件、归一化规则、主题生成器、回归用例)、四个脚本,以及预览模板与双语 README 等资源。
其中最有意思的是它的双关卡质量校验设计,这也是它区别于普通排版模板的地方。
| 作用 | 挡掉的问题 | |
|---|---|---|
| component_lint.py | 源头关卡,扫组件库反模式 | 改了组件却没验证,坏样式进入产物 |
| validate_gzh_html.py | 产物关卡,查平台禁用项 | 样式标签、脚本标签、class 与 id 属性等被平台吃掉 |
| wrap_preview.py | 生成带复制按钮的预览页 | 复制时把按钮本身一起复制进去 |
| extract_docx.py | 零依赖把 Word 转 Markdown | 用 Word 起稿时格式丢失 |
关键在于:它不试图让模型「记住」平台限制,而是把限制写成确定性检查。模型记不住的,脚本记得住。
装之前该查的四件事
对一个会被自动调用的脚本包,安装前的静态审计不是洁癖。这次定向扫了四项,结论是安全的。
| 结果 | 说明 | |
|---|---|---|
| 网络外联 | 无 | 未发现 urlopen、requests、socket 等调用 |
| 命令执行 | 无 | 未发现 subprocess、os.system、eval、exec |
| 破坏性操作 | 无 | 未发现递归删除类调用 |
| 文件写盘 | 有,但合规 | docx 图片与预览页均写本地,无越权路径 |
这里有个值得单说的判断细节:扫描时命中了三处 http 开头的字符串,看起来像外联。实际检查后确认,那是 docx 文件的 XML 命名空间字符串,用于解析,不是网络请求。
这像在行李箱里扫出一截电线就报警——电线确实在,但连的是吹风机。关键词扫描只告诉你「这里有个东西」,判断它是不是威胁得读上下文。自动化审计的误报往往比漏报更消耗注意力。
还有一条容易被忽略的:仓库用的是 AGPL-3.0。本地个人使用没问题,但如果修改后分发,或者基于它做网络服务,就必须同样以 AGPL-3.0 开源并保留署名。这是协议义务,不是道德倡议。
能用到什么程度,以及别拿它做什么
冒烟测试跑的是源头关卡:检 11 个组件库,ERROR 为 0,WARN 为 2(两套主题里可接受的虚线占位边框)。项目自己定的规矩是 ERROR 不清零不算完成,所以这个结果算通过。
| 形态 | 特点与取舍 | |
|---|---|---|
| isjiamu/gzh-design-skill | Agent Skill · AGPL-3.0 | 不碰微信 API,无凭证风险;专注粘贴不掉格式 |
| Kianzzz/obsidian-wechat-publisher | Obsidian 插件 · MIT | 插件内排版并发布到草稿箱,14 套主题 |
| iamzifei/wechat-article-publisher-skill | Agent Skill · 调 API | 直发草稿箱,需密钥与 IP 白名单,属凭证类操作 |
| NeverSight/wechat-publisher | Skill · Apache-2.0 | 封装 wenyan-cli,多主题加图床,风格偏轻量 |
选型上,如果需求只是「排成粘贴不掉格式的 HTML」,不碰 API 的那一版风险最小。自动发布更省事,但要求把公众号密钥交给开源脚本、还要把服务器 IP 加进白名单——这是另一类风险,不该顺手就配。
三处必须保留的边界:一、推文作者与仓库署名「甲木 × 摸鱼小李」、插件作者 Kianzzz 的关系未坐实,引用应按仓库口径署名。二、推文所述「5 套预设」与仓库实装「6 套主题」不一致,以仓库 theme-index 为准。三、AGPL-3.0 义务说明为本文对许可证文本的解读,不构成法律意见。文中「判断:」段落均为本文观点。