我把知识库自动化了:Hermes 负责生成,Codex 负责正式入库v

0 阅读31分钟

摘要

我一直想解决一个非常具体的问题:不是“怎么写出一篇好文章”,而是“怎么让知识持续、稳定、低摩擦地进入我的 Obsidian 知识库,并且越积越值钱”。后来我把这件事拆成两条线:Hermes 负责每天稳定产出知识素材,Codex 负责同步、判断、清洗、入库和后续运营。最终我做出了一套可以每天自动运行的工作流:服务器定时生成内容,本地自动同步,正文保护优先,异常内容先进收件箱,确认无误后再入正式知识库。

这篇文章我不打算只写成“思路分享”,而是尽量把我实际落地的结构、判断逻辑、脚本组织、测试方式和后续运营规则全部讲清楚。你如果也在用 Obsidian 做长期知识沉淀,同时又希望让 AI 参与内容生成和知识运营,这套方法基本可以直接复用。

一、我为什么要做这套自动化知识库工作流

我做这套系统,不是为了“让 AI 帮我写几篇文章”这么简单,而是因为我遇到了一个非常典型、也非常顽固的问题:

我能持续产生内容,但我没有持续把内容沉淀成长期资产的能力。

这两个能力看起来很接近,其实完全不是一回事。

我以前也会记很多笔记、写很多文章、保存很多资料。问题在于,它们通常停留在三个状态里:

  1. 写完就写完了,没有继续组织
  2. 分类做了,但没有稳定入口
  3. 累积很多,但后续不复习、不回看、不迭代

一旦时间拉长,知识库就会进入一种很尴尬的状态:

  • 新内容一直增加
  • 旧内容越来越找不到
  • 目录越来越多
  • 进入路径越来越混乱
  • 我自己都不知道“哪些是正式内容,哪些只是临时稿,哪些只是规划”

后来我想明白了一件事:

真正难的不是“有没有内容”,而是“有没有一套把内容持续送进知识库的稳定系统”。

于是我开始反过来设计:

  • Hermes 不负责最终知识库结构,它只负责稳定生成
  • Codex 不负责凭空创造内容,它负责把内容接住、整理、判断、归档
  • Obsidian 不只是笔记存放地,而是知识资产的最终落点

当这三个角色被拆开之后,我才第一次感觉到:这件事可以被做成系统,而不是靠热情硬顶。

二、我的背景场景:Hermes 每日生成,Codex 负责知识库运营

我的实际场景很明确:

  • 我有一台腾讯云轻量服务器
  • 服务器上配置了 Hermes
  • Hermes 每天会按我预设的主题与结构持续生成内容
  • 生成出来的内容,会落在服务器上的一个 数字卢语 目录中
  • 这个目录的结构大致参考我的 Obsidian 知识库结构,但它不是最终版本

换句话说,服务器上那套目录更像“上游内容源”,不是最终知识库本体。

这点非常关键。

我一开始最容易犯的错误,就是想让服务器直接把文件写到我的 Obsidian 结构里。后来我发现这会带来很多问题:

  • 远端生成逻辑并不真正理解我本地知识库的全部上下文
  • 服务器上生成的文章,可能只是“可读文章”,还不是“合格知识资产”
  • 有些内容是系列规划稿,有些是正文,有些是模板,有些是运营说明,不能一股脑入正式库
  • 一旦远端直接写正式知识库,后续纠错和回滚成本很高

所以我最后确定的角色分工是:

1. Hermes 的职责

  • 每天稳定生成知识素材
  • 尽量按已有主题和系列组织输出
  • 维护上游产出目录

微信图片_20260421092020.png

2. Codex 的职责

  • 通过 SSH 同步远端内容
  • 判断哪些是正文、哪些是规划稿、哪些是模板或运营文件
  • 保留原始正文,不做误改写
  • 将异常内容转入待确认收件箱
  • 在人工确认后再推进到正式知识库

image.png

3. Obsidian 的职责

  • 承载正式知识资产
  • 提供知识地图、系列页、专题页和复习入口
  • 作为长期学习与迭代的中心

image.png 这个分工带来的最大变化是:

我不再把“AI 生成内容”理解为自动写作,而是把它理解为一条受控的知识生产流水线。

三、我最终采用的工作流架构

我现在这套架构,可以用一句话概括:

Hermes 负责生产,Codex 负责运营,Obsidian 负责沉淀。

如果展开一点,可以拆成 6 个阶段。

为了让这件事真正可复现,我后来不再只用“分阶段”去理解它,而是把它画成一个明确的分层架构。因为只要架构没有清楚,后面脚本、自动化、排错和运营规则都会变成零散技巧。

这套自动化工作流的架构分层

我最终把整个系统拆成 5 层:

┌───────────────────────────────────────────────┐
│ 第 1 层:内容生产层                           │
│ Hermes 每日生成 Markdown、系列草稿、规划稿    │
└───────────────────────────────────────────────┘
                    │
                    ▼
┌───────────────────────────────────────────────┐
│ 第 2 层:同步拉取层                           │
│ SSH + rsync 将服务器内容拉到本地 staging      │
└───────────────────────────────────────────────┘
                    │
                    ▼
┌───────────────────────────────────────────────┐
│ 第 3 层:判定与隔离层                         │
│ 正文 / 异常正文 / 系列规划稿 / 模板与运营文件 │
└───────────────────────────────────────────────┘
                    │
          ┌─────────┼─────────┐
          ▼         ▼         ▼
┌──────────────┐ ┌──────────────┐ ┌────────────────┐
│ 待确认收件箱 │ │ 系列规划收件箱│ │ 跳过并记录日志 │
│ hermes-待确认│ │ hermes-系列规划│ │ 模板/MOC/总览  │
└──────────────┘ └──────────────┘ └────────────────┘
          │
          ▼
┌───────────────────────────────────────────────┐
│ 第 4 层:人工确认入库层                       │
│ 我在对话里确认,Codex 再正式推进到 30-资源库  │
└───────────────────────────────────────────────┘
                    │
                    ▼
┌───────────────────────────────────────────────┐
│ 第 5 层:知识库运营层                         │
│ MOC、系列页、Dataview、复习、持续迭代         │
└───────────────────────────────────────────────┘

这张图里最关键的不是技术名词,而是边界。

1. 为什么一定要有 staging 层

如果没有 staging 层,服务器产出的 Markdown 会直接落入正式知识库。这样一来,任何误判都会直接污染正式内容。

有了 staging 层之后,整个系统的判断空间就被打开了:

  • 文件可以先到本地,但还不是正式知识
  • 文件可以被检查、分类、隔离、记录
  • 就算 Hermes 输出了异常文件,也不会直接污染正式知识库

所以 .automation/hermes/staging/remote/ 不是“多余的一层”,而是整套工作流最重要的缓冲层。

2. 为什么我要把收件箱拆成两种

一开始我只想要一个待确认区,但后来发现内容类型差异太大。

比如:

  • 一篇完整但待确认的正文
  • 一篇存在整篇重复追加的异常正文
  • 一个“系列概述 + 待写清单 + 空链接占位”的规划稿

这三类内容如果放在同一个收件箱里,会把后续确认动作搞得非常混乱。

所以我最后把它们拆成:

10-收件箱/hermes-待确认/
10-收件箱/hermes-系列规划/

这样一来,我的后续动作就很清楚:

  • hermes-待确认 是未来可入正式库的正文候选
  • hermes-系列规划 是未来用于策划、补全系列路线图的素材

3. 为什么自动化任务和人工确认必须在同一个对话线程里

这是我后来非常确认的一条经验。

如果自动化只是每天跑完,然后让我去另一个地方看结果、再去第三个地方发命令、再去第四个地方查日志,这套系统虽然“自动”,但协作体验会很差。

我现在把整个流程都放在同一个 Codex 自动化线程里,带来的好处是:

  • 自动化结果就在这个线程里延续
  • 我确认哪几篇要入库,也在这个线程里说
  • Codex 可以直接沿用这次运行的上下文和日志
  • 不会出现“自动化在 A 地方跑,我在 B 地方确认,结果在 C 地方看”的割裂体验

这件事看起来只是交互细节,实际上直接决定了这套系统能不能长期用下去。

1. 远端生成阶段

服务器上的 Hermes 每天固定产出内容,按照我约定的主题和层级,写入远端 数字卢语 目录。

这一步我不追求“100% 完全符合本地知识库结构”,我只要求两件事:

  • 输出稳定
  • 尽量带上足够元信息

也就是说,Hermes 只要把内容写出来,后面的归类和运营工作交给 Codex 处理。

2. 同步阶段

Codex 通过 SSH 和 rsync 把服务器上的内容拉到本地暂存区,而不是直接写进 Obsidian 正式目录。

我在本地专门留了一个暂存区:

.automation/hermes/staging/remote/

这一步的意义非常大。它让我获得了一个“缓冲层”:

  • 同步成功,不等于正式入库
  • 文件到本地了,不等于已经被认可
  • 我可以先检查内容,再决定后续动作

这一步真正运行时,底层依赖的是我本机的 SSH 私钥认证。也就是说,自动化不是靠“保存密码”工作的,而是靠“本机已经能够无交互 SSH 登录”工作。

四、SSH、私钥和同步链路是怎么配置起来的

这部分是整篇文章里最容易被省略,但实际上最影响复现成功率的部分。

如果你只看到“Codex 每天同步服务器内容”,却不知道 SSH 是怎么配好的,那这套方案基本没法第二次落地。

我一开始的服务器登录方式,是最普通的:

ssh hermes@服务器IP

然后手动输入密码。

这种方式对人工登录当然没问题,但对自动化完全不合适。原因很简单:

  • 自动化不能每天等我手输密码
  • 密码不应该写进脚本
  • 也不应该写进配置文件或自动化提示词里

所以正式方案一定要改成“本机私钥免交互登录”。

1. 生成私钥

我在本机执行:

ssh-keygen -t ed25519 -f ~/.ssh/hermes_id_ed25519

这条命令会生成两份文件:

  • ~/.ssh/hermes_id_ed25519
  • ~/.ssh/hermes_id_ed25519.pub

前者是私钥,只留在本机;后者是公钥,要装到服务器。

2. 把公钥装到服务器

因为我原本已经能用密码登录,所以最简单的方法就是:

ssh-copy-id -i ~/.ssh/hermes_id_ed25519.pub hermes@服务器IP

它会提示输入一次密码。成功后,服务器用户目录下的 authorized_keys 就会加入这把公钥。

3. 配本机 SSH 别名

接着我在本机 ~/.ssh/config 里加了一个主机别名:

Host hermes-tc
  HostName 服务器IP
  User hermes
  Port 22
  IdentityFile ~/.ssh/hermes_id_ed25519
  IdentitiesOnly yes

以后我就不需要每次都写整串 IP 和私钥路径了,而是直接:

ssh hermes-tc

4. 自动化为什么要默认用 SSH 别名

我后来把脚本默认目标也改成了 hermes-tc,而不是继续写死 IP:

SSH_TARGET="${HERMES_SSH_TARGET:-hermes-tc}"

这样做的好处是:

  • 私钥路径统一由 ~/.ssh/config 管理
  • 如果服务器 IP、用户或端口以后变化,只改 SSH 配置即可
  • 自动化和我手工测试使用的是完全同一套连接定义

5. 如何验证 SSH 是否真正可用于自动化

只会手动登录还不够,我后来更关注两种验证:

验证交互式登录

ssh hermes-tc

验证自动化真正需要的“远端命令执行”

ssh hermes-tc 'pwd'
ssh hermes-tc 'test -d /home/hermes/数字卢语 && echo OK'
ssh hermes-tc 'find /home/hermes/数字卢语 -maxdepth 2 -type d | head'

如果这三步能稳定执行,说明同步脚本依赖的 SSH 能力是成立的。

五、配置文件和目录是如何组织的

为了避免所有规则都散落在脚本里,我后来专门给 Hermes 自动化留了一个工作目录:

.automation/hermes/

这个目录里目前有几类关键文件。

1. 示例配置文件

.automation/hermes/config.example.env

内容大致是:

HERMES_SSH_TARGET=hermes-tc
HERMES_REMOTE_ROOT=/home/hermes/数字卢语
HERMES_STAGING_DIR=.automation/hermes/staging/remote
HERMES_LOG_DIR=.automation/hermes/logs
HERMES_STATE_FILE=.automation/hermes/state.json

这里面每一个变量都很重要。

HERMES_SSH_TARGET

定义用哪个 SSH 目标连接服务器。
我这里默认是 hermes-tc,也就是前面 ~/.ssh/config 配好的别名。

HERMES_REMOTE_ROOT

定义服务器上 Hermes 产出目录的根路径。
在我的场景里是:

/home/hermes/数字卢语

HERMES_STAGING_DIR

定义本地 staging 目录。
同步下来的文件不会直接进 30-资源库,而是先到这里:

.automation/hermes/staging/remote

HERMES_LOG_DIR

定义每天自动化运行的日志目录:

.automation/hermes/logs

HERMES_STATE_FILE

定义状态文件位置:

.automation/hermes/state.json

这个文件专门记录“哪些 staging 文件已经处理过”。

2. 状态文件

.automation/hermes/state.json

这个文件是为了避免重复处理。

它的逻辑并不复杂:

  • 以文件相对路径为 key
  • 以 SHA256 为值
  • 如果 staging 里的文件内容变了,SHA 变了,它就会重新成为候选
  • 如果内容没变,就不会被自动化反复处理

3. 日志目录

.automation/hermes/logs/

这里的日志不是可有可无的。
它会记录:

  • 同步是否成功
  • 哪些文件进了待确认
  • 哪些文件被判定为系列规划稿
  • 哪些文件被确认入库
  • 哪些文件被跳过

当这套系统出问题时,我第一反应不是猜,而是先看日志。

六、各个脚本到底是怎么用的

如果这篇文章只是告诉你“我有几个脚本”,但不告诉你怎么用,那它还是不够可复现。所以下面我把几个核心脚本分别拆开讲。

1. scripts/hermes_sync.sh

这个脚本负责从服务器把内容同步到 staging。

它的工作流程是:

  1. 进入知识库根目录
  2. 读取 SSH 目标、远端目录、本地 staging 目录
  3. 先测试 SSH 和远端目录是否存在
  4. rsync 执行同步
  5. 写入同步日志

你可以手工这样执行:

cd "/Users/jayce/Library/Mobile Documents/iCloud~md~obsidian/Documents/数字卢语"
./scripts/hermes_sync.sh

如果你想临时覆盖配置,也可以这样:

HERMES_SSH_TARGET=hermes-tc ./scripts/hermes_sync.sh

同步成功后,文件会出现在:

.automation/hermes/staging/remote/

2. scripts/hermes_inventory.py

这个脚本负责候选扫描和状态标记。

列出候选

python3 scripts/hermes_inventory.py list

输出会是 JSON 数组,每个元素包含:

  • path
  • sha256

标记已处理

python3 scripts/hermes_inventory.py mark "<staging 文件相对路径>"

例如:

python3 scripts/hermes_inventory.py mark '.automation/hermes/staging/remote/30-资源库/基础设施与运维/20-网络/20-系列/网络基础概念.md'

这一条只有在以下情况才应该执行:

  • 文件已经成功入正式知识库
  • 或者文件明确被记录为跳过、待确认、系列规划

3. scripts/hermes_quarantine_article.py

这个脚本负责把候选正文转入 hermes-待确认

它特别适合这类场景:

  • 正文要保留全文
  • 但我还不想直接让它入正式知识库
  • 或者正文存在整篇重复追加,需要先去重

典型用法:

python3 scripts/hermes_quarantine_article.py '/Users/jayce/Downloads/网络基础概念.md' --note '检测到下载文件与服务器版本存在重复追加差异,本次按待确认候选处理'

它会做这些事:

  1. 读取原文件
  2. 判断是否存在精确重复追加
  3. 如果能确定是整篇重复,就自动去重
  4. 生成待确认 frontmatter
  5. 写入 10-收件箱/hermes-待确认/
  6. 记录日志

4. scripts/hermes_promote_inbox_article.py

这个脚本负责把我已经确认的文章,从待确认收件箱推进到正式知识库。

它是整套系统里最重要的“最后一步”。

典型用法:

python3 scripts/hermes_promote_inbox_article.py \
  '10-收件箱/hermes-待确认/网络基础概念.md' \
  '30-资源库/基础设施与运维/20-网络/20-系列/网络基础/01-网络基础概念.md' \
  --series-name '网络基础' \
  --domain '基础设施与运维' \
  --moc-link '基础设施与运维-知识地图' \
  --module-tag '网络' \
  --topic-tag '网络基础' \
  --order '1'

这个脚本会:

  1. 读取待确认文件
  2. 去掉收件箱说明块
  3. 保留正文全文
  4. 补正式 frontmatter
  5. 在正文开头加系列导航和知识地图链接
  6. 写入正式目录
  7. 删除待确认文件
  8. 记录正式入库日志

5. 为什么我没有把“确认入库”完全自动化

因为这里就是整套系统最关键的人机边界。

我后来的结论非常明确:

同步、扫描、隔离这些动作可以完全自动化;“这篇是否应该成为正式知识”的判断,最好仍然由我来决定。

所以我现在更偏向这样使用:

  • 自动化先把候选内容整理到收件箱
  • 我在对话里确认哪些要入库
  • Codex 再调用确认入库脚本推进正式知识库

七、我在排错时最常遇到的几类问题

这部分如果不写出来,很多人第二次复现时会直接卡住。

问题 1:SSH 连不上服务器

典型症状:

  • ssh hermes-tc 无法登录
  • Connection closed by ... port 22
  • 自动化日志里提示 SSH unavailable

排查顺序我现在固定是:

第一步:确认 SSH 别名配置是否正确

cat ~/.ssh/config

确认是否包含:

Host hermes-tc
  HostName 服务器IP
  User hermes
  Port 22
  IdentityFile ~/.ssh/hermes_id_ed25519
  IdentitiesOnly yes

第二步:确认私钥文件是否存在

ls -l ~/.ssh/hermes_id_ed25519 ~/.ssh/hermes_id_ed25519.pub

第三步:验证交互式和非交互式 SSH

ssh hermes-tc
ssh hermes-tc 'pwd'

如果第一条能进、第二条不能跑命令,那通常说明服务器 shell、权限或登录后环境有问题。

第四步:看详细调试日志

ssh -vvv hermes-tc 'pwd'

这一步可以看清楚是:

  • 认证失败
  • 主机断开
  • 远端命令执行失败
  • 还是 shell 初始化脚本导致退出

问题 2:ssh-copy-id 失败

这个问题我自己就遇到过。

第一次执行时可能会出现:

  • 连接被服务端关闭
  • 还没输入密码就断开

处理方式通常是:

  1. 先确认服务器 SSH 服务稳定
  2. 再重新执行:
ssh-copy-id -i ~/.ssh/hermes_id_ed25519.pub hermes@服务器IP

成功后,再用:

ssh hermes-tc

确认是否不再要求输入密码。

问题 3:同步成功,但内容不对

这种问题最容易误判。

我后来固定会做“三方比对”:

  1. 原始文件
  2. staging 文件
  3. 正式入库文件

常用命令:

wc -c 原始文件 staging文件 正式文件
sed -n '1,200p' 文件路径
tail -n 60 文件路径

如果 staging 和远端一致,那就不是 rsync 截断;
如果正式文件比 staging 短很多,那通常是入库逻辑改写了正文。

问题 4:文件其实是规划稿,却被当成正文

这是我后来非常重视的一类误判。

典型特征:

  • 大量“系列概述”
  • 大量“系列目录”
  • 目录表里全是 ⏳ 待写
  • 链接一列全是 -
  • 末尾有“上级索引”

这种文件如果进正式知识库,会让目录看起来很满,但实际全是规划占位,不是真正的知识文章。

我后来对此的处理原则是:

  • 不删
  • 不当正文
  • 转入 10-收件箱/hermes-系列规划/

问题 5:正文里出现重复标题

这个问题也是在确认入库脚本里踩出来的。

原因通常是:

  • 收件箱文件外面有一个包装标题
  • 原文正文里本身又有自己的标题
  • 推进正式知识库时,如果没有正确去掉包装层,就会出现两个 H1

这个问题虽然不影响正文内容完整性,但会严重影响阅读体验,所以我后来把确认入库脚本专门修了一次。

八、如何一步一步复现这套系统

如果今天让我重新从 0 搭一次,我会按下面这个顺序来,不会跳步。

第一步:准备本地知识库结构

至少先有这几层:

00-总览
10-收件箱
20-领域
30-资源库
99-模板

并确保有:

  • 文章模板
  • 系列模板
  • 知识地图

第二步:准备 Hermes 上游目录

确保服务器上有一个固定输出目录,例如:

/home/hermes/数字卢语

并让 Hermes 稳定往这里生成内容。

第三步:打通 SSH 私钥认证

按我前面写的顺序:

  1. ssh-keygen
  2. ssh-copy-id
  3. ~/.ssh/config
  4. 验证 ssh hermes-tc
  5. 验证 ssh hermes-tc 'pwd'

第四步:准备自动化工作目录

至少建好:

.automation/hermes/
  config.example.env
  state.json
  logs/
  staging/

第五步:放入同步与处理脚本

至少需要:

  • hermes_sync.sh
  • hermes_inventory.py
  • hermes_quarantine_article.py
  • hermes_promote_inbox_article.py

第六步:先手工全链路测试

按顺序跑:

./scripts/hermes_sync.sh
python3 scripts/hermes_inventory.py list

然后挑一篇文章做:

  • 隔离测试
  • 待确认测试
  • 正式入库测试

第七步:再挂自动化

不要在没跑通手工流程前就直接上自动化。
自动化应该是“放大已验证流程”,不是“替代未验证流程”。

第八步:把确认入库保留在对话里

最终使用时,最自然的方式就是:

  • 自动化每天 16:00 跑
  • 新内容进入收件箱
  • 我在同一个对话里说“把这几篇入库”
  • Codex 执行确认入库

这一步会让整套系统真正变得顺手。

3. 候选识别阶段

同步完成后,Codex 会扫描暂存区,识别新增或变更的 Markdown 文件。

我用一个状态文件来记录哪些 staging 文件已经处理过:

.automation/hermes/state.json

这样做的目的,是避免每天自动化重复处理同一批内容。

4. 内容判定阶段

这是整套系统里最关键的一步。

我后来非常明确地把文件分成了四类:

第一类:完整正文

这种文件是真正的文章正文,可以作为正式知识内容进入知识库,只是还需要判断归属。

第二类:异常正文

这种文件内容看起来像正文,但存在一些问题,比如:

  • 疑似整篇重复追加
  • 正文版本冲突
  • 结构异常
  • 需要人工确认是否完整

这类文件不能直接进正式知识库。

第三类:系列规划稿

这类文件最容易被误判。

它们通常有这些特征:

  • 明显的“系列概述”
  • 大量“系列目录”
  • 一堆 ⏳ 待写
  • 目录表里都是占位文章
  • 末尾有“上级索引”之类项目化说明

这种内容对知识库当然有价值,但它不是正文文章,而是策划素材。后来我专门给它们单独分了一个区域:

10-收件箱/hermes-系列规划/

第四类:模板/运营文件

例如:

  • 00-总览
  • 10-收件箱
  • 99-模板
  • 远端 00-MOC.md

这些都不应该覆盖本地已有正式结构,所以应该跳过,不作为正文处理。

5. 待确认阶段

对“可用但仍需人工确认”的文章,我统一放进:

10-收件箱/hermes-待确认/

这里的原则是:

  • 正文保留全文
  • 不改写、不压缩、不重述
  • 只做必要的清洗,比如检测整篇重复追加时去重保留一份
  • 让人先确认内容无误,再决定是否入正式库

这是我后来最满意的一层。它把“自动化处理”和“人工判断”结合起来了。

6. 正式入库阶段

当我在对话里确认“这几篇可以入库”后,Codex 再执行最后一步:

  • 放到正确的领域、系列或专题目录
  • 补 frontmatter
  • 加系列导航
  • 加所属知识地图链接
  • 保留原始正文全文

这样,正式知识库里留下来的,都是已经确认过的内容。

四、为什么我坚持“正文保护优先”

这部分是我后来踩坑之后才真正加上的规则。

一开始我天真地以为,既然 Codex 已经理解了我的知识库结构,那么它在入库时顺手把文章“整理得更像知识库文章”应该也不错。

结果很快就出问题了。

最典型的问题就是:

  • 原文是完整的
  • 自动整理时却被改写成了一版更短、更像摘要的内容
  • 从知识结构上看似乎更整齐
  • 但原始信息量被损坏了

这件事让我很快意识到:

知识库运营的第一原则不是“美观”,也不是“统一风格”,而是“保护原文信息量”。

所以我后来把规则改成了硬约束:

1. 原始正文是最高优先级资产

只要正文还没被人工确认,自动化绝不能以“帮你整理”为理由去重写它。

2. 自动化只允许附加结构

例如:

  • frontmatter
  • 系列导航
  • 知识地图链接
  • 目录定位
  • 少量相关链接

而不允许动正文主内容。

3. 有问题就先进收件箱

自动化不是为了“强行完成所有动作”,而是为了尽可能在不损坏内容的前提下提高效率。

如果不能确认,就不要猜。

这个原则后来让我整个工作流稳定了很多。

五、我是如何实现这套流程的

这套流程的实现其实不算复杂,但关键是每一层职责要清楚。

我本地知识库里主要有这几类文件:

1. 同步脚本

scripts/hermes_sync.sh

它负责:

  • 使用 SSH 连远端服务器
  • rsync 拉取服务器目录
  • 把内容同步到暂存区
  • 记录同步日志

2. 候选识别脚本

scripts/hermes_inventory.py

它负责:

  • 扫描 staging 中的 Markdown
  • 对比 state.json
  • 输出新增或变化的候选文件
  • 在处理完成后标记对应文件为已处理

3. 隔离脚本

scripts/hermes_quarantine_article.py

这个脚本是后面补出来的,也是我觉得很值的一步。

它负责:

  • 把候选文章转入 hermes-待确认
  • 检测是否存在整篇重复追加
  • 如果能确定是精确重复,就自动去重,只保留一份正文
  • 写入待确认说明和来源信息
  • 记录到日志

4. 确认入库脚本

scripts/hermes_promote_inbox_article.py

它负责:

  • 读取我已经确认的收件箱文章
  • 按目标领域/系列/专题落到正式目录
  • 补 frontmatter、导航链接、知识地图链接
  • 保留正文全文
  • 从待确认收件箱移除
  • 写日志

5. 自动化说明文件

我还专门维护了几份文档,目的不是为了“文档完整”,而是为了让未来每次自动化都能按同一套规则运行:

  • docs/plans/2026-04-20-hermes-obsidian-sync-design.md
  • docs/plans/2026-04-20-hermes-obsidian-sync-runbook.md
  • .automation/hermes/README.md

这些文档把工作流写成了明确规则,而不是存在我脑子里的“隐性经验”。

六、我如何设计自动化任务

我最后没有把它做成一条只会“拉文件”的定时任务,而是做成一个完整的 Codex 自动化对话任务。

定时点是每天下午 16:00。

自动化逻辑不是“同步完就结束”,而是:

  1. 执行同步
  2. 扫描候选
  3. 判断正文 / 异常 / 规划稿 / 跳过项
  4. 把正文转到待确认
  5. 把规划稿转到规划收件箱
  6. 写日志
  7. 等我在同一个对话里继续确认入库

也就是说,我故意把“自动化”和“对话确认”放在了同一个线程里。

这样做的好处非常明显:

  • 自动化的上下文不会丢
  • 我不用在多个地方找结果
  • 我看完收件箱后,直接在同一个对话里说“把这几篇入库”就行
  • Codex 可以基于之前的日志和规则继续执行,而不是重新猜

这套设计本质上把“自动化任务”从一个定时器,升级成了一个持续工作的知识库运营线程。

九、这套流程我是怎么测试的

我后来发现,测试这类自动化不能只测“脚本能不能跑”,而要分层测试。

第一层:SSH 连接测试

最先要确认的是:

ssh hermes-tc

能不能稳定登录服务器。

如果这一步不通,后面的同步、自动化和入库全部没有意义。

第二层:同步测试

我会直接执行:

./scripts/hermes_sync.sh

确认服务器内容是否真的拉到了本地 staging。

第三层:候选识别测试

然后执行:

python3 scripts/hermes_inventory.py list

确认 staging 文件是否被识别为候选。

第四层:正文保护测试

这是我后来加进去的。

我会拿一篇实际文章去对比三份内容:

  • 原始文件
  • staging 文件
  • 正式入库文件

只要发现正文内容被压缩、改写或错乱,就必须回滚。

第五层:异常文件测试

我专门测试过一篇存在“整篇重复追加”的文章。

预期动作不是直接入库,而是:

  • 先检测重复
  • 去重保留一份
  • 转入 hermes-待确认
  • 由我确认后再入正式库

这一步非常关键,因为它证明自动化不只是“能跑通”,而是“能在异常场景下仍然可控”。

第六层:整批复跑测试

最后我会重新执行整批自动化,看是否满足:

  • 正文进待确认
  • 规划稿进规划收件箱
  • 模板与总览跳过
  • 候选清单最终清空
  • 状态文件更新正常

只有这一层通过,我才会认定自动化流程真正可用。

十、我如何做后续的知识库运营

很多人做完自动化就觉得任务结束了,但我后来发现,自动化只是开始,真正决定知识库能不能长期变好的,是后续运营方式。

我现在基本按三类内容来运营。

1. 待确认正文

这些内容我会优先检查:

  • 正文是否完整
  • 标题是否合理
  • 系列归属是否正确
  • 有没有明显版本冲突

确认无误后,我就直接在自动化对话里说:

把 hermes-待确认 里的这几篇入库

然后由 Codex 执行。

2. 系列规划稿

这类内容我不会把它们当文章入库,而是把它们看成未来选题和系列结构素材。

它们的价值不在于“今天就能进入正式知识库”,而在于:

  • 帮我规划系列完整性
  • 帮我提前看到知识图谱里还缺哪些坑位
  • 帮我区分“已经写了什么”和“计划还要写什么”

换句话说,规划稿更像运营资产,而不是正文资产。

3. 正式知识文章

正式文章进入 30-资源库 之后,我主要做三件事:

  • 通过知识地图与系列页建立入口
  • 通过 updatednext_review 做回顾
  • 逐步把相关文章连起来,而不是孤立堆放

我后来越来越确信:

知识库不是文件仓库,它更像一个有运营节奏的内容系统。

十一、这套系统为什么对我有效

如果只看工具,这套方案其实不复杂:

  • Hermes
  • Codex
  • Obsidian
  • SSH
  • 若干脚本

但它真正有效的原因,不是工具组合,而是我终于把“知识生产”拆成了可运营的阶段。

以前我的问题是:

  • 生成和沉淀混在一起
  • 规划和正文混在一起
  • 草稿和正式内容混在一起
  • 自动化和人工确认没有边界

现在我把它拆成了非常明确的几层:

  • 远端生成
  • 本地同步
  • 候选识别
  • 内容分类
  • 收件箱确认
  • 正式入库
  • 后续复习与运营

这让整个系统开始具备几个我以前没有的特性:

1. 可持续

不是今天写了一篇,而是明天、后天还能继续稳定进入知识库。

2. 可回滚

出了问题,我知道该回滚哪一层,而不是整套都乱掉。

3. 可协作

Hermes 和 Codex 不再互相抢活,而是各自承担不同职责。

4. 可演进

当规则不对时,我可以改脚本、改 runbook、改自动化提示,而不是推倒重来。

十二、如果让我从头再做一次,我会怎么设计

如果现在让我从零再做一次,我会直接遵守下面这些原则,不再重复前面的坑。

原则 1:不要让远端直接写正式知识库

远端只负责生成,正式知识库必须有本地缓冲层。

原则 2:正文保护优先

自动化可以补结构,但绝不能随意改写正文。

原则 3:规划稿和正文必须分流

系列规划、选题清单、待写目录不能混进正文体系。

原则 4:收件箱不是失败区,而是审核区

先进收件箱,不代表有问题,而是代表它要经过确认,才能变成长期资产。

原则 5:自动化不是替代人,而是把人的判断放在最关键的节点

真正应该由我决定的是:

  • 这是不是正式知识
  • 这篇文章该不该入库
  • 这是不是规划稿

而不是让我去手动做同步、搬文件、补 frontmatter、写日志这些机械动作。

十三、我接下来还会怎么继续迭代

虽然这套系统现在已经能稳定跑起来,但我很清楚它还不是终点。

我后面还会继续做这几件事:

1. 提升正文判定质量

现在已经能区分正文、异常正文和规划稿,但还可以继续优化判断精度。

2. 让“确认入库”更顺手

目前我已经能在自动化对话里直接说“把这几篇入库”,这已经很好用了。但后续还可以进一步批量化。

3. 增加复习与回流机制

真正成熟的知识库,不能只有“进入”,还要有“回看”和“再利用”。

4. 让系列规划稿反哺正式系列页

系列规划不该只是被存起来,它还应该帮助我补齐正式系列的未来路线图。

十四、结语:我终于不再把知识库当文件夹,而是当系统

做完这套流程后,我最大的变化不是“多了几个脚本”,也不是“自动化更炫了”,而是我终于不再把知识库看成一个堆文件的地方。

我现在更愿意把它理解成一个长期运行的系统:

  • Hermes 持续生成知识素材
  • Codex 持续运营、整理、归档
  • Obsidian 持续承载、复习、连接和进化

这套系统并不会让我一夜之间变得更聪明,但它会持续帮我把“今天学到的东西”变成“以后还能反复调用的资产”。

对我来说,这就是它真正的价值。

如果只问一句这套方法最核心的原则是什么,我现在会回答:

不要让知识只是被生成,而要让知识被稳定接住、被正确判断、被持续运营,最后被沉淀成真正属于我自己的长期资产。

而这,正是我用 Hermes + Codex 搭这套自动化知识库工作流的原因。

如果你也想把这套 Hermes + Codex + Obsidian 自动化工作流搭起来,关注公众号【数字卢语】,私信我关键词:自动化工作流,把我整理好的脚本、配置文件和操作说明发你。