改了 SOUL.md,老会话还在按旧规矩办事?一条命令热刷新


你花半小时把 SOUL.md 改顺了,又给技能补了两条新规矩,重启 gateway,切回那个已经跑了两天的会话,让它再干一遍刚才的活。结果它还是老样子:旧口吻、旧流程、旧禁区,好像你刚才改的是别人电脑上的文件。你把配置文件打开确认了三遍,改动确实在。最后没别的办法,只能 /new,然后眼睁睁看着几十轮上下文一起消失。

这个坑不是配置没生效,而是 Hermes 为了省钱故意这么做的。现在有了一条专门的命令,可以只刷新指令、不碰对话。

为什么改了文件,老会话却“看不见”

大模型的 API 有个省钱机制:如果每次请求开头那一大段完全一样,服务商可以直接复用上次算好的结果,价格和延迟都会低不少。这段开头就是 system prompt——里面装着 SOUL.md 的人设、技能清单、AGENTS.md 的项目约定、记忆和 USER.md。

为了让这份“开头”始终一模一样,Hermes 的做法是:会话第一次建好 system prompt 后,把它存进数据库;之后每一轮都原样重放这一份。gateway 重启后会从会话记录里把这份旧的读回来,一直挂在内存里的“热”会话更是压根不去看磁盘。

所以只有新会话(/new)才会重新读文件。老会话继续按存下来的旧指令跑——这正是你看到的现象。

一条命令:hermes sessions refresh-prompts

# 这个 profile 下的所有会话
hermes sessions refresh-prompts

# 只刷新某一个会话(ID 或唯一前缀)
hermes sessions refresh-prompts --session a1b2c3

# 指定另一个 profile
hermes sessions refresh-prompts -p work

# 机器可读输出,适合塞进升级脚本
hermes sessions refresh-prompts --json

它做的事情非常克制:在 profile 的 state.db 里记下一个“刷新请求”,然后打印有多少会话存了 prompt。真正干活的是每一轮开始的时候。

输出大致长这样:

Requested a system prompt refresh for every session in this profile (12 session(s) with a stored prompt).
Each rebuilds its prompt from the current SOUL.md, skills and context files on its next turn (one prompt-cache miss per session); conversation history is kept.

如果你给了 --session,它还会顺带处理一个边界情况:一个被压缩过的长对话,续写其实发生在压缩后的“新头”上,刷新请求会落到那个位置上,而不是落到早就结束的原始会话。

下一轮到底重建了什么

  • 重建:整个 system prompt 走一遍正常的构建流程,所以 SOUL.md 的新版本、技能的增删、AGENTS.md 和上下文文件都会在这一轮生效;记忆与 USER.md 块也会重新从磁盘读一次。
  • 不动:对话历史、session id,以及会话绑定的工具列表(tools[] pin)都保持原样。on_session_start 钩子不会触发,所以你不会看到“会话刚启动”那套副作用。
  • 成本:每个被刷新的会话,在重建的那一轮付一次前缀缓存失效的钱。之后又恢复正常命中。
  • 落地:新 prompt 连同它的版本标记一起写回 state.db,后面每轮照旧原样复用。所以这不是“每轮都重建”,只重建一次。

不需要重启 gateway,重启也不影响:请求存在数据库里,进程起来后照样读得到。升级脚本可以在替换 gateway 之前或之后调用它,两种顺序都成立。

它怎么判断“该刷新了”

Hermes 在 state.db 的 state_meta 里维护一个自增的 epoch(可以理解成“指令修订号”),每个会话则在 model_config 里记着自己已经满足到哪一版。每一轮开始前,agent 做一次单点查询:库里的 epoch 比会话记录的大,就在这一轮重建;否则什么都不做。

没有发出刷新请求的时候,唯一的额外开销就是这一次读。没有任何后台进程去盯文件变化,也不会在一轮对话中途突然换掉指令。

哪些情况该用,哪些不必

你刚做了什么 要不要 refresh-prompts
改了 SOUL.md、技能、AGENTS.md、USER.md 要,正是为这个场景做的
只换了模型、改了 temperature 之类的采样参数 不用
增删了内置工具或工具权限 新会话自然生效,老会话的工具绑定不会因此变化
想彻底换个话题从零开始 用 /new,这条命令不负责清空历史
会话记录本身坏了、prompt 被写坏 用 hermes sessions repair-prompts,是另一条命令

两点提醒。第一,刷新不重放历史,也不修复已经写坏的会话——它只换掉“开头那段指令”。第二,当你手上有几十上百个长会话、并且按 token 付费时,--session 单刷比全量刷更省:每个会话一次缓存失效,累积起来不是小数目。

如果你更关心“压缩之后指令为什么会过期”,那是另一个机制:压缩时 Hermes 会重建 system prompt。想弄明白两者关系,可以读 压缩后提示词重建的来龙去脉;如果你刚把技能放进仓库里,先看项目级技能与信任门禁,刷新只是让运行中的会话跟上它。多会话共享同一份前缀缓存的机制,在跨 profile 的缓存共享里有完整说明。命令本身的参数表在 hermes sessions 命令参考。

版本状态

这条命令在 2026 年 10 月 29 日合并进 main(PR #143581)。当前最新的正式版本 v0.22.5(2026-10-23)还不包含它——hermes sessions --help 里查不到 refresh-prompts 就说明你手上是旧版。想现在就用,可以跟 main 分支安装;否则等下一个版本发布即可。

改完文件、跑一条命令、下一轮生效——不用再拿对话历史去换一次生效。