对话笔记直发:8.13 公众号发布工作流v5 Hermes接手文档。分类:AI工程。


title: 公众号发布工作流v5 Hermes接手文档 tags: [公众号, Hermes, 接手文档, 对抗式审查, 测试验收, 排障, wechat-publish-workflow] date: 2026-08-13

公众号发布工作流 v5 —— Hermes 接手文档(对抗式审查后定稿)

本文是 jp(局域网IP(已脱敏))上 Hermes 接手公众号发布工作流的唯一权威对齐说明。所有命令可直接复制执行。核心编排源:/opt/data/skills/wechat-publish-workflow/SKILL.md(hermes 重启后第一个要读的文件)。


1. 系统与账号事实

项值
服务器jp,局域网IP(已脱敏),ssh root@局域网IP(已脱敏)“
hermes 用户uid/gid 10000,groups: hermes/openclaw/docker;HOME=/opt/data
微信 AppIDwx9312cd6cc49653f0
账号类型个人订阅号 → 无 freepublish,只能建草稿、人工后台群发
出口 IP已配微信白名单
生图模型step-image-edit-2(stepfun),base_url https://api.stepfun.com/step_plan/v1
Node/usr/bin/node v22.23.1(node:sqlite 可用,ExperimentalWarning 属正常)
Pillow12.2.0,装于 /opt/hermes/.venv/bin/python(系统 python3 无 PIL)
时区Asia/Shanghai (CST+8),与 token 缓存时钟一致

2. 关键路径总表

物路径
编排层(唯一权威)/opt/data/skills/wechat-publish-workflow/SKILL.md
封面 AI 生成/归一化/opt/data/skills/wechat-publish-workflow/scripts/gzh_cover.py
固定CSS渲染器/opt/data/skills/wechat-publish-workflow/scripts/render_fixed.py
占位符硬门/opt/data/skills/wechat-publish-workflow/scripts/check_placeholder.sh
主题存档(存档非源)/opt/data/skills/wechat-publish-workflow/references/fixed-business.css.md
v4 备份/opt/data/skills/wechat-publish-workflow/SKILL.md.v4.bak
peterpan 推送工具/opt/data/skills/wechat-publisher/wechat-publisher.mjs(1132 行)
微信凭证/opt/data/.wechat-publisher/config.json(600,勿外泄/勿入日志)
生图凭证/opt/data/.wechat-publisher/stepfun.json(600,勿外泄/勿入日志)
状态文件/opt/data/.wechat-publisher/{token.json,upload-cache.json,drafts.db}(hermes 可写)
gzh-design 备选排版 skill/opt/data/skills/gzh-design/SKILL.md + scripts/validate_gzh_html.py

3. 铁律(hermes 必须遵守)

  1. 单推送出口:微信副作用(建草稿/传素材)只允许经 peterpan 的 publish-file / upload-cover / upload-image。禁止 md2wechat --upload/--draft、禁止手写 curl 调微信 API(排除障探测)。
  2. 排版合规门:交付 HTML 必须 0 ERROR(validate_gzh_html.py)+ 全路径 {{占位符}} 硬门(check_placeholder.sh)过关。不得跳过。
  3. 封面必填:publish-file --thumb 只接受本地图片文件路径(peterpan 内部 existsSync 判断;传 media_id 字符串 → 静默回退成首张正文图或空 → 40007/40013)。封面 jpg 路径直接传 --thumb,peterpan 自动上传并按文件 hash 去重缓存(upload-cover 提前传也无害但非必需)。
  4. 去AI味必做:正式发文前必须 md2wechat humanize <draft.md>(等号形式)取回 prompt 由 LLM 执行后合并。

4. 标准执行步骤(默认路线,逐条命令)

Step 1 写稿

  • 产出 Markdown 初稿到 hermes 可写目录(如 /opt/data/工作流/_tmp/,或 /tmp)。
  • 初稿先发用户确认(铁律5)。
  • 正文(含代码示例)不要出现 {{作者名}}/{{简介}} 这两个保留 token,示例占位请改写为 {{cmd}} 之类一般 token。

Step 2 去AI味

md2wechat humanize 稿子.md --intensity=medium

必须等号形式。空格形式 --intensity medium 会报 accepts 1 arg(s), received 2。 解析 JSON:status=="action_required" 时取 data.request.content,LLM 按 prompt 重写正文,写回 稿子.humanized.md。 必须检查 success/status 字段,success!=true 视为失败(进程可能 exit 0)。

Step 3 排版

默认固定CSS确定性渲染:

/opt/hermes/.venv/bin/python /opt/data/skills/wechat-publish-workflow/scripts/render_fixed.py <稿.md> --out <dir> --name <名> [--author 作者名] [--intro 简介]
  • 产物命名:{名}_排版_固定商务(fixed-business).html
  • 自带 validate 0 ERROR + check_placeholder.sh 自检
  • 占位符 {{作者名}}/{{简介}} 未传对应参数 → fail-fast 退出、不产出文件
  • 用户消息中出现 skill排版 / 用skill → 走 gzh-design skill(产物同样要过硬门)

Step 4 合规门

  • render_fixed 产物自带;gzh-design 路径产物手动补跑:
bash /opt/data/skills/wechat-publish-workflow/scripts/check_placeholder.sh <产物.html>
  • validate_gzh_html.py 校验:报 ERROR 必须回头修。

Step 5 封面(三分支)

前置:凭证 /opt/data/.wechat-publisher/stepfun.json。

# 统一格式(务必带 --out/--name,默认会写 /tmp/gzh_cover_out/cover_*.jpg 也好用但建议显式)
/opt/hermes/.venv/bin/python .../gzh_cover.py --out <dir> --name <名> --hint "<一句话概要>"          # 默认:无文字+moren
/opt/hermes/.venv/bin/python .../gzh_cover.py --out <dir> --name <名> --text "<文字>"                 # 文字+moren
/opt/hermes/.venv/bin/python .../gzh_cover.py --out <dir> --name <名> --text ... --style minimal      # 文字+风格
/opt/hermes/.venv/bin/python .../gzh_cover.py --out <dir> --name <名> --style minimal...             # 无文字+风格
/opt/hermes/.venv/bin/python .../gzh_cover.py --out <dir> --name <名> --image <图>                    # 用户给图归一化
  • 输出 <out>/<name>_{no-text|with-text|user-image}.jpg(900x383 ≤1MB)
  • styles:minimal/tech/oilpaint/watercolor/ink/vintage(acts >moren 默认)
  • 带文字封面必须先发用户人工确认,确认后才准上传+发布;超时未回复默认中止(带文字 15 分钟 / 无文字 10 分钟)
  • --hint 仅对「无文字 + moren」档生效——带文字档 hint 被静默忽略
  • 图片放 hermes 可写目录,必须本地磁盘文件

Step 6 推送(推草稿箱)

export WECHAT_PUBLISHER_DATA_DIR=/opt/data/.wechat-publisher
node /opt/data/skills/wechat-publisher/wechat-publisher.mjs publish-file <html> \
  --thumb <封面本地路径>.jpg --title <标题> --digest <摘要> --author <作者>

三条硬约束:

  1. --thumb 传本地封面 jpg 路径(铁律3)
  2. 必须显式 --title/--digest:render_fixed 产物的 h1 被 <span leaf> 包裹,peterpan 提取不出 → 不传会产出 “Untitled” 草稿(已实测证实)
  3. --dry-run 不是零副作用:新图仍会上传占素材配额(上传发生在 dryRun 判定之前);长文预览截断为前 800 字符 —— 预览建议用 convert,dry-run 仅作冒烟

Step 7 回报

  • 给用户 media_id + 草稿标题,提示”已入草稿箱,请到公众号后台手动群发”
  • 发布前 round-trip 回读校验标题,确认非 “Untitled”

5. 封面生成内部参数(gzh_cover.py,调用者无需关心)

  • API size 转置(实测):请求 768x1360 才返回横版 1360x768;请求 1360x768 返回竖版。脚本内已固化 REQ_SIZE="768x1360"。
  • 目标 900x383(2.35:1,微信首图标准)≤1MB;quality high,超限循环降 q 到 ≤40 止
  • 裁剪:宽/高≥2.35 沿宽居中裁,否则沿高居中裁;绝不非等比缩放
  • 用户图归一化:宽>1360 限宽;竖图 WARN 提示确认;超 2.35:1 裁剪
  • 失败回退链:生图失败 用户指定图 → 正文首图 → 均无则中止告知,不建草稿
  • 重试:脚本内 1 次重试(共 2 次尝试)

6. 错误码速查(微信 API + 脚本 EC-)

错误码含义处置
40001access_token 无效/不是最新删 /opt/data/.wechat-publisher/token.json 后重试(多客户端并发刷新互作废)
40014token 过期同上,重新 auth
40164出口 IP 不在白名单不要反复重试;引导用户后台加白名单
40013参数错误(常见:缺封面 thumb)补 --thumb(传本地文件)后再试
40007invalid media_id(最常见踩坑)thumb 传了 media_id 字符串或空 → 改传本地封面路径
42001token 刷新过于频繁等待 1 分钟
48001个人号无 freepublish 权限属正常,只能建草稿人工群发(publish 命令对它永远 48001 且 exit 0)
45009API 调用超限等待配额恢复
EC-001生图失败(网络/超时/配额/qualit

注:本文涉及的服务器公网 IP / Tailnet / 局域网 IP 已脱敏,请替换为你自己的地址。


相关: 00-索引-AI工程索引 8.13 公众号发布工作流v5改造