摘要

我做 Caduceus 的直接原因很简单:Hermes Agent 越用越顺手之后,我反而开始不放心。

不是不放心它某一次回答,而是不放心它在多轮对话之后留下来的东西。它会记住偏好,会沉淀工作流,会把某些经验写进 skill,也可能把旧 skill 改掉。一次对话错了,关掉重来就行;长期状态错了,它会在后面的很多次任务里继续生效。

官方文档里,Hermes 的 skill 被描述成按需加载的知识文档,存放在 ~/.hermes/skills/,并且 agent 可以修改或删除 skill。文档还单独列出 skill_manage:agent 可以用它创建、更新、删除自己的 skill,用来保存已经跑通的工作流。

参考资料:

Caduceus 项目源码(GitHub)

长期状态不应只依赖信任

如果一个 agent 只是在当前窗口里回答问题,审计重点大多落在输入、输出、工具调用上。Hermes 的有趣之处在于,它不只是当前会话里的助手。

官方文档把 memory 拆成 MEMORY.mdUSER.md 两类,前者存环境事实、项目约定、踩坑经验,后者存用户偏好和沟通习惯。这些内容在会话开始时注入系统提示词。文档也明确写到,agent 通过 memory 工具管理自己的记忆,可以 add、replace、remove。

skill 更像程序化记忆——它不是一句偏好,而是一套任务操作手册。文档把”何时该沉淀”拆成四类触发条件,其中只有一条是量化阈值:

  • 量化阈值 完成一次 **5+ tool calls** 的复杂任务并成功收尾
  • 撞过错误或死路、最终找到可行路径之后
  • 用户纠正了它的做法之后
  • 发现了一条非平凡的工作流之后

写入与修改都走 skill_manage 工具,结果统一落到 ~/.hermes/skills/

action 用途
create 从零新建 skill,需要完整 content
patch 局部修改 SKILL.md,按 old_string / new_string 增量替换,文档列为首选
edit 整篇结构性重写,等价于完整覆盖 SKILL.md
delete 删除整个 skill
write_file / remove_file 增删 skill 目录下的辅助文件(references、scripts、templates)

这套机制让 agent 能把经验落到磁盘、在下一次会话里复用。问题在于,能力一旦变成长期状态,就需要回答几个很朴素的问题:

  • 它什么时候创建了一个 skill?
  • 它为什么改了某个 skill?
  • 改完之后和出厂版本差了多少?
  • 某个 skill 被哪些 session 用过?
  • memory 里到底记了什么,哪些会影响后续行为?
  • 后台任务、cron、plugin hook 有没有在我不看的时候做过事?

这些问题靠 ls ~/.hermes 可以查,但很难连续地看。文件散在不同目录,SQLite 里有 session 和 tool call,skill 的 shipped baseline、当前版本、usage 计数又来自不同地方。Caduceus 做的就是把这些痕迹合到一个只读的审计台里。

Caduceus Overview

上面这张 Overview 截图是入口页。它先不急着展示文件树,而是把总数摆出来:skill 数、session 数、token IO、Soul 大小、tasks、cron、plugins。对我来说,这页的价值不是漂亮,而是先确认这个 agent 已经积累了多少长期状态。

数据来源与读取范围

Caduceus 没有引入新的数据库,也不向 Hermes 写任何东西。它只读 ~/.hermes 下面已经存在的数据,把不同来源拼成可以跳转的视图。

几类数据尤其关键:

数据 作用
~/.hermes/skills/<group>/<name>/SKILL.md 当前正在生效的 skill 内容
~/.hermes/hermes-agent/skills/.../SKILL.md bundled skill 的 shipped baseline,用来和当前版本做 diff
~/.hermes/skills/.usage.json patch_countlast_patched_atcreated_at 等使用痕迹
state.db.messages.tool_calls 找出 skill_viewskill_manage、plugin tool call 和对应 session
~/.hermes/memories/* agent 的 memory 与 user profile
kanban.db 后台 task、run history、失败原因
plugins/<name>/plugin.yaml plugin 暴露的 tool、hook、env 要求

这里有一个设计取舍:Caduceus 不试图取代 Hermes 自己的管理命令。它只是把可疑点摊开。看到 drift、patch、某个 session、某个 task crash 之后,真正的修改仍然应该回到编辑器、Hermes CLI 或版本控制里做。

Skill 视图:patch 与 drift 的双线追踪

我最先想看的就是 skill。

Hermes 的 skill 目录越用越多之后,单纯的列表不够用。Caduceus 的 Skills 页先用 domain map 让你看到分类规模,再用卡片展示每个 skill 的描述、mtime、版本、标签、patch 状态和 drift 状态。

Skills Domain Map

这里的两个状态很重要:

  • patched:有 skill_manage 记录,可以关联到具体 session,通常能还原 agent 当时为什么改。
  • drifted:当前 SKILL.md 和 shipped baseline 的 md5 不一致,但没有 skill_manage 记录。它可能是人手改的,也可能是 agent 用普通文件编辑工具改的。

第二种更值得警惕。只看 patch_count 会漏掉它,因为它没有走 skill_manage。所以 Caduceus 同时走两条线:一条看 usage 和 tool call,一条直接算 shipped/current md5。

skill_manage 留下的是结构化审计线索;普通文件编辑只留下文件差异。两种都应该看,不然会把“没有记录”误读成“没有变化”。

Skill 详情:lineage 与修订链

点开一个 skill 之后,抽屉里会把 lineage、view 次数、agent edits 摘要和完整 SKILL.md 放在一起。下面这张图里,stock-monitor 这个 skill 有 8 次 patch 计数,抽屉里还能看到 10 条 recorded edits、跨 7 个 session,以及进入 edit history 的按钮。

Skill Drawer Audit

这块的设计目标是把 skill 的变化看成一条修订链,而不是一个孤立文件。一个 skill 被创建、被引用、被 patch、最后变成当前版本,中间每一步都应该能回到 session 里看上下文。

Timeline:跨数据源的统一审计入口

单页看 skill 还不够。很多时候我想知道的是某一天 agent 到底做了什么。

Timeline 页把 sessions、skills、tasks、cron、plugins、soul 合在一起,按时间倒序展示。每条事件后面都有 audit 入口:skill 跳 skill drawer,session 跳消息流,task 跳 run history,plugin 跳 manifest 和调用记录。

Timeline Audit Entry

这比打开文件更接近审计流程。因为真正的问题通常不是“某个文件是什么内容”,而是“这个内容为什么变成这样”。时间线给了一个入口,drawer 给证据链。

只读约束:审计层与执行层分离

Dashboard 很容易长出管理功能:点一下恢复 shipped 版本、点一下删除 memory、点一下禁用 cron。

我暂时不想做。

审计台最怕两件事:一边看证据,一边改证据。Caduceus 的定位是本地只读,后端对 state.dbkanban.db 用 readonly 模式打开,读取 .env 时也只读 key 名,不读 value。/api/open/api/file 会校验路径必须在 HERMES_HOME 里面。

如果要修改 skill,我宁愿在编辑器里改,或者用 Hermes 自己的命令改,再让 Caduceus 重新扫描。这样审计层和执行层分开,出了问题也更容易归因。

我更希望 Caduceus 成为一张“证据桌”,而不是另一个会改状态的控制面。

视图全景

现在的 Caduceus 已经不只是 skill viewer。它覆盖了这些视图:

视图 看什么
Overview 总量、分布、最近产物
Soul SOUL.md 全文
Memory ~/.hermes/memories/ 下的记忆
Skills skill 分类、patch、drift、lineage
Tasks kanban 后台任务和 run history
Cron 定时任务和下一次执行
Plugins manifest、tools、hooks、env 状态、调用 session
Sessions 消息流和 tool calls
Timeline 所有事件的统一入口

Plugin 详情:tools、hooks、env 与调用记录

插件不是只列一个名字就够了。点进 plugin drawer 后,Caduceus 会展示这个插件声明的 tools、hooks、env 配置状态,以及被哪些 session 调用过。env 这里刻意只显示 key 是否配置,不读取 secret value。

Plugin Drawer Audit

结语

Agent 会写代码并不稀奇。真正改变工程习惯的是,它开始写自己的操作手册,记自己的偏好,排自己的后台任务,还能通过 plugin 和 hook 接进更多系统。

这时候我们需要的不是更强的信任感,而是更便宜的回看能力。

Caduceus 就是为这个目的做的:把 ~/.hermes 里那些会长期影响 agent 行为的状态摆出来,让每一次自我改写都有地方可查。