AI 工具链

把知识发布做成流水线:Hermes + Hexo + 微信草稿箱实战

从资料整理、Markdown 源文、Hexo 静态站、图片复用到微信公众号草稿箱,构建一条可复刻、可审计、可持续维护的知识发布流水线。

#知识库 #Hexo #Hermes Agent #自动化发布 #微信公众号
把知识发布做成流水线:Hermes + Hexo + 微信草稿箱实战 封面图

📌 这篇文章不是 Hexo 入门教程,而是一套「知识从资料到多平台发布」的工程化流程。
🎯 目标是让 Hermes 负责整理和执行,Hexo 负责长期归档,微信公众号只进入草稿箱,最终发布仍由人工把关。

Hermes + Hexo 自动化知识发布流水线

一、为什么要把知识发布做成流水线?

很多知识库项目不是输在内容,而是输在流程。

一开始大家只是想把资料沉淀下来:会议纪要、接口文档、GitHub 项目、产品方案、部署经验、问题复盘。时间一长,内容会散落到不同平台:一部分在 Notion,一部分在 Word,一部分在聊天记录,一部分又被复制到公众号或博客里。

最后常见的问题是:

问题 表现 后果
内容源不统一 博客、公众号、内部文档各有一份 改了一处,其他地方忘记同步
图片重复生成 每个平台临时生成、临时上传 风格不一致,也难以追溯来源
发布靠人工记忆 今天用这个命令,明天换另一个脚本 新人接不住,自己过几周也忘了
密钥混在示例里 命令、代码、文档里顺手写真实配置 最容易造成安全事故
Git 提交太粗 git add . 把草稿、临时文件一起提交 知识库越用越脏

所以,这条流水线的目标不是「搭一个博客」,而是把下面这件事固定成可重复动作:

1
2
3
4
5
6
7
8
9
10
11
12
13
资料 / 链接 / 仓库 / 会议纪要 / 想法

Hermes Agent 提取、判断、重写、结构化

Hexo Markdown 源文

封面图与正文图生成一次

Hexo 静态站发布

Git 保存源文件与必要资产

微信公众号草稿箱复用同一份内容和图片

这条链路有五条硬约束:

  1. Markdown 是唯一可信源,HTML 只是构建产物。
  2. 图片只生成一次,Hexo 和公众号复用同一批图片。
  3. 密钥不进入文章、不进入 Git、不进入公开文档
  4. Git 只提交本次文章相关文件,不要使用 git add .
  5. 公众号只进草稿箱,最终群发必须人工确认。

这些约束看起来繁琐,但真正跑过几次就会发现,它们不是洁癖,而是发布系统的安全边界。

二、整体架构:五层流水线

这套方案可以拆成五层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌────────────────────────────────────────────┐
│ 输入层 │
│ PDF / Word / URL / GitHub / 会议纪要 / 想法 │
└──────────────────────┬─────────────────────┘

┌────────────────────────────────────────────┐
│ AI 整理层 │
│ Hermes Agent:提取、判断结构、改写为文章 │
└──────────────────────┬─────────────────────┘

┌────────────────────────────────────────────┐
│ 内容源层 │
│ Hexo Markdown + source/images/articles │
└──────────────────────┬─────────────────────┘

┌────────────────────────────────────────────┐
│ 发布层 │
│ npm run publish → public/ → 静态站目录 │
└──────────────────────┬─────────────────────┘

┌────────────────────────────────────────────┐
│ 分发层 │
│ GitHub 版本管理 + 微信公众号草稿箱 │
└────────────────────────────────────────────┘

对应到一个 Hexo 项目,大致目录如下:

1
2
3
4
5
6
7
8
9
10
11
12
/opt/blog/
├── source/
│ ├── _posts/ # Markdown 文章源文件
│ └── images/articles/<slug>/ # 文章封面和正文图
├── themes/<your-theme>/ # Hexo 主题
├── tools/
│ ├── publish.sh # Hexo 发布脚本
│ ├── cover-gen # 图片生成工具
│ ├── hexo-to-wechat.sh # Hexo + 微信草稿箱流程入口
│ └── wechat-sync.sh # 单篇或批量同步草稿箱
├── public/ # Hexo 构建产物,不作为内容源
└── package.json

这里的路径只是示例。公开文档可以写目录结构,但不要写真实服务器 IP、真实 Token、内部域名或私有仓库地址。

三、文章契约:先定 slug,再写内容

每篇文章都应该先满足一份固定契约。没有契约,后面的封面、路由、公众号摘要、Git 提交都会变得随缘。

推荐 frontmatter:

1
2
3
4
5
6
7
8
9
10
11
12
13
---
title: 文章标题
date: 2026-01-01 09:00:00
updated: 2026-01-01 09:00:00
categories:
- 技术方案
tags:
- Hexo
- 自动化发布
abbrlink: stable-english-slug
cover: /images/articles/stable-english-slug/cover.png
excerpt: 一句话摘要,用在首页卡片和分享场景。
---

其中最关键的是四个字段:

字段 作用 约束
abbrlink 稳定 URL 用英文短 slug,标题怎么改 URL 都不动
cover 首页卡片、文章页和公众号封面 路径跟 slug 绑定
excerpt 首页摘要和公众号 digest 控制在一两句话内
tags 标签页、知识图谱、后续检索 少而准,不要堆关键词

这篇文章的 slug 是:

1
hermes-hexo-automation-workflow

所以源文件和图片目录也随之固定:

1
2
source/_posts/hermes-hexo-automation-workflow.md
source/images/articles/hermes-hexo-automation-workflow/cover.png

这一步看似简单,但它决定了后续自动化能不能稳定运行。

四、Hermes 的角色:把资料改造成文章

AI 写作最容易翻车的地方,是把资料重新排版一下就发布。那样的文章看起来整齐,但读起来像拼贴出来的说明书。

在这条流水线里,Hermes 不只是「生成文字」,而是承担四类工作:

输入 Hermes 应该做的事
接口文档 拆成背景、鉴权、参数、示例、错误处理和联调建议
GitHub 仓库 读 README、docs、配置文件,整理部署方式和适用场景
会议纪要 提取决策、原因、行动项,而不是逐字转写
网页文章 保留事实和观点,重写为自己的结构
内部流程 脱敏后变成可公开复刻的方法论

一篇可发布的技术文章,最好围绕一条清晰主线展开:

1
2
3
4
5
6
7
8
9
10
11
为什么需要它

系统怎么拆

关键配置怎么放

命令怎么跑

发布后怎么验

出问题先查哪里

这比「背景、目标、方案、总结」更接近真实工程师的阅读路径。读者不是来欣赏排比句的,而是想判断:这套东西我能不能照着落地。

五、图片策略:生成一次,多端复用

图片生成必须管住。否则文章多了以后,很快会出现同一篇文章有三张封面、公众号和博客配图不一致、找不到原始图片来源等问题。

推荐约定:

图片 文件名 用途
封面图 cover.png 首页卡片、文章页头图、公众号封面
架构图 architecture.png 解释系统组件
流程图 pipeline.png 解释步骤顺序
对比图 comparison.png 解释选型差异

生成命令示例:

1
2
3
4
5
6
7
8
9
cd /opt/blog

# 根据文章元数据生成封面
tools/cover-gen cover hermes-hexo-automation-workflow

# 如果需要正文图,再生成到文章专属目录
tools/cover-gen img \
"A dark technical workflow illustration about AI writing, Markdown, static site deployment and WeChat draft publishing, no text" \
-o source/images/articles/hermes-hexo-automation-workflow/pipeline.png

图片生成工具只能从环境变量或本地密钥文件读取 API Key。公开文章里可以写变量名,但不能写真实密钥。

1
2
3
4
5
6
7
8
9
import os

api_key = os.environ.get("COVER_GEN_API_KEY")
if not api_key:
raise RuntimeError("COVER_GEN_API_KEY is required")

headers = {
"Authorization": "Bearer " + api_key
}

这里故意使用字符串拼接,而不是把密钥写进模板字符串或日志。真实 Key 不应该出现在 Markdown、脚本示例、Git 提交或构建产物里。

六、Hexo 发布:构建不是发布的全部

生产环境里的 Hexo 发布,不应该只运行一句 hexo generate。至少要完成四件事:

步骤 作用
备份 发布失败时可以回滚
构建 从 Markdown 生成静态 HTML
同步 public/ 同步到 Web 目录
记录 写入发布时间、源目录、目标目录等信息

一个精简版发布脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env bash
set -euo pipefail

BLOG_ROOT="${BLOG_ROOT:-/opt/blog}"
PUBLIC_DIR="${BLOG_PUBLIC_DIR:-/var/www/example.com}"
BACKUP_DIR="${BLOG_BACKUP_DIR:-$PUBLIC_DIR/../backups}"

cd "$BLOG_ROOT"

mkdir -p "$BACKUP_DIR"
mkdir -p "$PUBLIC_DIR"

if [ -d "$PUBLIC_DIR" ] && [ "$(ls -A "$PUBLIC_DIR" 2>/dev/null || true)" ]; then
tar -czf "$BACKUP_DIR/site-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$PUBLIC_DIR" .
fi

npm install
npx hexo clean
npx hexo generate

rsync -a --delete public/ "$PUBLIC_DIR"/

cat > PUBLISH_INFO.md <<INFO
# Publish Info

- Published at: $(date -Iseconds)
- Source: $BLOG_ROOT
- Target: $PUBLIC_DIR
INFO

实际使用时,入口命令保持简单:

1
2
cd /opt/blog
npm run publish

发布后不要只看命令退出码。至少检查两件事:

1
2
curl -I https://example.com/posts/hermes-hexo-automation-workflow/
test -f /var/www/example.com/posts/hermes-hexo-automation-workflow/index.html

如果文章里有大量代码块和表格,还要额外检查移动端横向溢出。技术文章最常见的问题不是打不开,而是表格或代码块把手机页面撑宽。

七、Git 提交:精确提交,不要全量 add

知识库仓库通常同时存在多篇草稿、主题改动、临时图片和工具脚本。这个场景里最危险的命令是:

1
git add .

它太方便,也太容易把没审过的东西一起提交。

推荐流程是:

1
2
3
4
5
6
7
8
9
cd /opt/blog

git status --short

git add source/_posts/hermes-hexo-automation-workflow.md \
source/images/articles/hermes-hexo-automation-workflow/cover.png

git commit -m "docs: rewrite hermes hexo automation workflow"
git push origin main

如果本次确实改了主题、脚本或图片,也要显式列出来。知识库长期维护靠的不是「这次没事」,而是每次提交都能解释清楚。

八、微信公众号:不是复制 Markdown,而是适配最终 HTML

公众号不是博客页面。它的屏幕更窄,样式限制更多,草稿箱预览和实际阅读环境也更接近移动端。

因此,公众号发布不能简单理解成「把 Markdown 直接同步过去」。更可靠的流程是:

1
2
3
4
5
6
7
8
9
10
11
Hexo Markdown

wenyan 原生 phycat 渲染 HTML

后处理最终 HTML 的 inline style

上传图片到微信素材或图床

调用 draft/add 进入草稿箱

人工预览后再决定是否群发

这里有两个坑要避开:

错误做法 问题
wenyan -c custom.css 会替换原生主题,导致 phycat 的细节样式被阉割
Markdown 顶部写 <style> 微信草稿里可能被剥离或无法覆盖最终 inline style

当前推荐标准是:保留原生 phycat 的薄荷绿层级,再对最终 HTML 做 inline-style 级别的专业排版适配。

关键参数如下:

元素 公众号最终样式方向
正文 15px,行距 1.78,字距 0.3px
H2 保留薄荷绿渐变,约 18px,上方留足间距
H3 16px,保留左边框,但不要压过 H2
引用块 左侧与图片/标题对齐,13px,行距 1.75
列表 左缩进 18px,不要双重缩进
表格 table-layout: auto; width: auto,按内容适配
表格文字 从默认小字提升到约 12px
代码块 保留 github-dark,减轻阴影和过大行距

这样做的好处是:博客端仍然以 Markdown 为源,公众号端则针对最终阅读环境做样式适配,两边不会互相污染。

九、草稿箱优先:自动化不等于自动群发

公众号这边,推荐进入草稿箱,而不是自动群发。

发布方式 适合场景 风险
草稿箱 技术文章、长文、需要人工预览 多一步人工确认
自动群发 已认证账号、固定日报类内容 一旦排版或内容错了,会直接发出去

如果是未认证订阅号,通常也没有 freepublish 权限,只能走草稿箱。这不是脚本缺陷,而是微信公众号权限模型决定的。

自动化的边界应该很清楚:

1
2
机器负责:整理、排版、上传、生成草稿
人工负责:预览、判断、最终群发

这样既能减少重复劳动,又不会把发布风险完全交给脚本。

十、密钥管理:公开文档只写占位符

这类流程最容易泄露的不是正文,而是命令示例。

公开文章里可以出现:

1
2
3
4
COVER_GEN_API_KEY=replace-with-your-image-api-key
WECHAT_APP_ID=replace-with-your-wechat-app-id
WECHAT_APP_SECRET=replace-with-your-wechat-app-secret
BLOG_PUBLIC_DIR=/var/www/example.com

不能出现:

  • 真实 API Key
  • 真实 AppSecret
  • Bearer Token
  • 私有 Git Token
  • 服务器公网 IP
  • 内网域名
  • 私有仓库地址
  • Web UI Token
  • 数据库密码

真实配置应该放在 .env、系统环境变量或部署平台的 secret 管理里。仓库只提交 .env.example

1
2
3
4
5
6
7
8
9
node_modules/
public/
db.json
.deploy_git/
.env
*.key
*.pem
*.crt
*.p12

发布前最好做一次敏感信息扫描。它不能替代安全审计,但可以拦住最常见的低级事故。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
python3 - <<'PY'
from pathlib import Path
import re

p = Path('source/_posts/hermes-hexo-automation-workflow.md')
s = p.read_text()

patterns = {
'openai_key': r'\bsk-[A-Za-z0-9_-]{20,}',
'api_key': r'\bak-[A-Za-z0-9_-]{20,}',
'bearer': r'Bearer\s+[A-Za-z0-9._-]{20,}',
'private_key': r'-----BEGIN [A-Z ]*PRIVATE KEY-----',
'ipv4': r'\b\d{1,3}(?:\.\d{1,3}){3}\b',
}

for name, pattern in patterns.items():
hit = re.findall(pattern, s)
if hit:
raise SystemExit(f'{name}: {hit[:3]}')

print('sensitive scan passed')
PY

如果这一步扫出了服务器 IP 或真实 token,先停下来处理,不要想着「发布完再删」。公开页面一旦被爬走,后补救会很被动。

十一、一次完整运行顺序

完整跑一次,可以按下面顺序执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cd /opt/blog

# 1. 写入或更新 Markdown 源文
vim source/_posts/hermes-hexo-automation-workflow.md

# 2. 生成或确认封面图存在
test -f source/images/articles/hermes-hexo-automation-workflow/cover.png \
|| tools/cover-gen cover hermes-hexo-automation-workflow

# 3. 发布 Hexo
npm run publish

# 4. 校验页面
curl -I https://example.com/posts/hermes-hexo-automation-workflow/

# 5. 生成公众号草稿箱版本
# 推荐:原生 phycat → 最终 HTML inline-style 后处理 → draft/add
/opt/blog/tools/wechat-sync.sh --file source/_posts/hermes-hexo-automation-workflow.md

# 6. 精确提交
git status --short
git add source/_posts/hermes-hexo-automation-workflow.md \
source/images/articles/hermes-hexo-automation-workflow/cover.png \
PUBLISH_INFO.md
git commit -m "docs: rewrite hermes hexo automation workflow"
git push origin main

如果交给 Hermes Agent 执行,任务描述应该写得足够硬:

1
2
3
4
5
6
7
8
9
10
11
12
将资料整理成一篇 Hexo 文章并发布:

1. 先提取资料中的核心信息,不要原样贴资料。
2. 写入 /opt/blog/source/_posts/<slug>.md。
3. 使用稳定英文 slug。
4. 图片只生成一次,Hexo 和公众号复用。
5. 执行 npm run publish。
6. 校验线上文章 HTTP 状态。
7. 公众号必须走原生 phycat → 最终 HTML inline-style 后处理 → 草稿箱。
8. 不直接群发。
9. Git 只提交本次文章、图片和必要发布信息,不要 git add .。
10. 发布前扫描敏感信息,不暴露 Key、Token、IP、AppSecret。

这类任务越明确,Agent 越不容易做出「看起来聪明、实际上危险」的自动化动作。

十二、最值得保留的经验

第一,Markdown 源文件是根。只改线上 HTML,后面一定会丢;只改公众号草稿,博客和 Git 也会失真。

第二,slug 要稳定。标题可以为了传播效果调整很多次,但 URL 最好不要变。

第三,图片目录要跟 slug 绑定。文章越多,这条规则越重要。

第四,公众号要单独适配最终 HTML。博客文章适合网页阅读,公众号适合移动端长文;两者共享内容源,但不共享最终排版。

第五,密钥泄露通常发生在顺手写示例时。公开文章里只写占位符,真实配置永远留在运行环境里。

第六,自动化的终点不是无人值守发布,而是稳定地产生可审阅草稿。真正有价值的是把重复劳动交给流水线,把判断权留给人。

当这套流程跑顺以后,写文章会从「手工发布」变成「内容生产线」。Hermes 负责把资料变成结构化文章,Hexo 负责长期归档,微信公众号负责触达读者,Git 负责留下可追溯记录。省下来的不是几分钟排版时间,而是一整套容易出错的重复操作。