摘要
我一直想解决一个非常具体的问题:不是“怎么写出一篇好文章”,而是“怎么让知识持续、稳定、低摩擦地进入我的 Obsidian 知识库,并且越积越值钱”。后来我把这件事拆成两条线:Hermes 负责每天稳定产出知识素材,Codex 负责同步、判断、清洗、入库和后续运营。最终我做出了一套可以每天自动运行的工作流:服务器定时生成内容,本地自动同步,正文保护优先,异常内容先进收件箱,确认无误后再入正式知识库。
这篇文章我不打算只写成“思路分享”,而是尽量把我实际落地的结构、判断逻辑、脚本组织、测试方式和后续运营规则全部讲清楚。你如果也在用 Obsidian 做长期知识沉淀,同时又希望让 AI 参与内容生成和知识运营,这套方法基本可以直接复用。
一、我为什么要做这套自动化知识库工作流
我做这套系统,不是为了“让 AI 帮我写几篇文章”这么简单,而是因为我遇到了一个非常典型、也非常顽固的问题:
我能持续产生内容,但我没有持续把内容沉淀成长期资产的能力。
这两个能力看起来很接近,其实完全不是一回事。
我以前也会记很多笔记、写很多文章、保存很多资料。问题在于,它们通常停留在三个状态里:
- 写完就写完了,没有继续组织
- 分类做了,但没有稳定入口
- 累积很多,但后续不复习、不回看、不迭代
一旦时间拉长,知识库就会进入一种很尴尬的状态:
- 新内容一直增加
- 旧内容越来越找不到
- 目录越来越多
- 进入路径越来越混乱
- 我自己都不知道“哪些是正式内容,哪些只是临时稿,哪些只是规划”
后来我想明白了一件事:
真正难的不是“有没有内容”,而是“有没有一套把内容持续送进知识库的稳定系统”。
于是我开始反过来设计:
Hermes不负责最终知识库结构,它只负责稳定生成Codex不负责凭空创造内容,它负责把内容接住、整理、判断、归档Obsidian不只是笔记存放地,而是知识资产的最终落点
当这三个角色被拆开之后,我才第一次感觉到:这件事可以被做成系统,而不是靠热情硬顶。
二、我的背景场景:Hermes 每日生成,Codex 负责知识库运营
我的实际场景很明确:
- 我有一台腾讯云轻量服务器
- 服务器上配置了
Hermes Hermes每天会按我预设的主题与结构持续生成内容- 生成出来的内容,会落在服务器上的一个
数字卢语目录中 - 这个目录的结构大致参考我的 Obsidian 知识库结构,但它不是最终版本
换句话说,服务器上那套目录更像“上游内容源”,不是最终知识库本体。
这点非常关键。
我一开始最容易犯的错误,就是想让服务器直接把文件写到我的 Obsidian 结构里。后来我发现这会带来很多问题:
- 远端生成逻辑并不真正理解我本地知识库的全部上下文
- 服务器上生成的文章,可能只是“可读文章”,还不是“合格知识资产”
- 有些内容是系列规划稿,有些是正文,有些是模板,有些是运营说明,不能一股脑入正式库
- 一旦远端直接写正式知识库,后续纠错和回滚成本很高
所以我最后确定的角色分工是:
1. Hermes 的职责
- 每天稳定生成知识素材
- 尽量按已有主题和系列组织输出
- 维护上游产出目录
2. Codex 的职责
- 通过 SSH 同步远端内容
- 判断哪些是正文、哪些是规划稿、哪些是模板或运营文件
- 保留原始正文,不做误改写
- 将异常内容转入待确认收件箱
- 在人工确认后再推进到正式知识库
3. Obsidian 的职责
- 承载正式知识资产
- 提供知识地图、系列页、专题页和复习入口
- 作为长期学习与迭代的中心
这个分工带来的最大变化是:
我不再把“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。
它的工作流程是:
- 进入知识库根目录
- 读取 SSH 目标、远端目录、本地 staging 目录
- 先测试 SSH 和远端目录是否存在
- 用
rsync执行同步 - 写入同步日志
你可以手工这样执行:
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 数组,每个元素包含:
pathsha256
标记已处理
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 '检测到下载文件与服务器版本存在重复追加差异,本次按待确认候选处理'
它会做这些事:
- 读取原文件
- 判断是否存在精确重复追加
- 如果能确定是整篇重复,就自动去重
- 生成待确认 frontmatter
- 写入
10-收件箱/hermes-待确认/ - 记录日志
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'
这个脚本会:
- 读取待确认文件
- 去掉收件箱说明块
- 保留正文全文
- 补正式 frontmatter
- 在正文开头加系列导航和知识地图链接
- 写入正式目录
- 删除待确认文件
- 记录正式入库日志
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 失败
这个问题我自己就遇到过。
第一次执行时可能会出现:
- 连接被服务端关闭
- 还没输入密码就断开
处理方式通常是:
- 先确认服务器 SSH 服务稳定
- 再重新执行:
ssh-copy-id -i ~/.ssh/hermes_id_ed25519.pub hermes@服务器IP
成功后,再用:
ssh hermes-tc
确认是否不再要求输入密码。
问题 3:同步成功,但内容不对
这种问题最容易误判。
我后来固定会做“三方比对”:
- 原始文件
- staging 文件
- 正式入库文件
常用命令:
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 私钥认证
按我前面写的顺序:
ssh-keygenssh-copy-id- 配
~/.ssh/config - 验证
ssh hermes-tc - 验证
ssh hermes-tc 'pwd'
第四步:准备自动化工作目录
至少建好:
.automation/hermes/
config.example.env
state.json
logs/
staging/
第五步:放入同步与处理脚本
至少需要:
hermes_sync.shhermes_inventory.pyhermes_quarantine_article.pyhermes_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.mddocs/plans/2026-04-20-hermes-obsidian-sync-runbook.md.automation/hermes/README.md
这些文档把工作流写成了明确规则,而不是存在我脑子里的“隐性经验”。
六、我如何设计自动化任务
我最后没有把它做成一条只会“拉文件”的定时任务,而是做成一个完整的 Codex 自动化对话任务。
定时点是每天下午 16:00。
自动化逻辑不是“同步完就结束”,而是:
- 执行同步
- 扫描候选
- 判断正文 / 异常 / 规划稿 / 跳过项
- 把正文转到待确认
- 把规划稿转到规划收件箱
- 写日志
- 等我在同一个对话里继续确认入库
也就是说,我故意把“自动化”和“对话确认”放在了同一个线程里。
这样做的好处非常明显:
- 自动化的上下文不会丢
- 我不用在多个地方找结果
- 我看完收件箱后,直接在同一个对话里说“把这几篇入库”就行
- 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-资源库 之后,我主要做三件事:
- 通过知识地图与系列页建立入口
- 通过
updated和next_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 自动化工作流搭起来,关注公众号【数字卢语】,私信我关键词:自动化工作流,把我整理好的脚本、配置文件和操作说明发你。