Caduceus /kəˈdjuːsɪəs/ — Hermes 那柄两条蛇缠绕的赫尔墨斯杖。这个工具就是 Hermes Agent 的赫尔墨斯杖:你拿着它,就能看见 agent 在地下做了什么。
一个本地的、只读的可视化 dashboard,用来审计你的 Hermes Agent 吸收了哪些知识、形成了哪些习惯、在每次会话中产出了哪些 skill / patch。 把
~/.hermes/里散落的 Soul、Memory、Skills、Sessions、tool_calls 等数据汇聚到一处,互相可跳转,方便溯源和修改。
两条相交的蛇 = skill 的 lineage(创建/补丁/覆写两条线交织展开)。这个 dashboard 做的事情,就是把那些被层层覆写的笔迹翻出来给你看。
关键词: Hermes Agent · Hermes Dashboard · Hermes Audit · Agent Observability · Skill Lineage · Local-only
Hermes Agent 在使用过程中会自己写新 skill、patch 旧 skill、把"用户偏好"和"环境约定"塞进 memory、自动排队 task 在你不看的时候执行、装载 plugin 提供新工具——这些都是会长期影响 agent 行为的状态。但它们以裸 markdown / JSON / SQLite 的方式分散在 ~/.hermes/ 下,没有统一的视图:
- agent 创建了哪个 skill —— 在哪次 session 创建的?什么时候?
- 一个 skill 被哪些 session 引用过 —— 它真的有用吗?
- session 的 tool_calls 里到底跑了什么?花了多少 token?
- agent 在我不看的时候排了什么 task?哪些跑崩了?错在哪里?
- 装了哪些 plugin?暴露了什么工具?env 配齐了吗?
- Soul 改了没?Memory 里都记了我什么?
这个 dashboard 把以上问题全部摊到桌面上,只读,不会动 agent 的任何文件。
cd hermes-dashboard
npm install
npm start
# → http://localhost:5273项目目录还叫
hermes-dashboard(保持仓库 URL 稳定),但产品命名是 Caduceus。
环境变量:
| 变量 | 默认 | 说明 |
|---|---|---|
HERMES_HOME |
~/.hermes |
数据根目录 |
PORT |
5273 |
dashboard 端口 |
总览看板:4 张统计卡(skills 总数 · sessions · tokens IO · soul 字节)+ 域分布柱状图 + 会话来源饼图 + 最近 14 条产物。
还顺手汇总了 tasks 状态分布、plugins 数量与 missing-env 计数,但目前这些数字以 /api/overview JSON 的形式返回,前端 UI 还没有专门的卡片暴露——后续会补。
渲染 SOUL.md 全文(Manrope 正文,与 skill 描述一致)。一键打开编辑器或在 Finder 中显示。
列出 ~/.hermes/memories/ 下的每条记忆,可折叠预览。当前如果是空的会有友好提示。
- DOMAIN MAP:treemap 视图,19 个分类矩形按 skill 数量大小排列,点 tile 联动下方 grid filter
- AGENT EDITS strip(仅当存在改写痕迹时显示):两类信号合并的药丸列表
- patched(sage):通过
skill_manage(action=edit)改的,有完整 rationale + 内容历史 - drifted(clay):SKILL.md md5 ≠ shipped md5 但没有
skill_manage记录 —— 说明 agent 是用 Write/Edit/sed 等"普通"工具直接改的文件,没有 rationale 留下来,但内容差异仍可 diff - patched-and-drifted:两条都中
- 点击任意药丸进入"Skill History"专属抽屉
- patched(sage):通过
- SKILLS GRID:按 mtime 倒序的卡片列表,最近 7 天修改过的 skill 右上角有绿点
- 被 agent patch 过的 skill:卡片左缘 sage 色条 +
patch ×N药丸 - 仅有 md5 漂移的 skill:卡片左缘 clay 色条 +
~ drift药丸,点击直跳 history 抽屉做 shipped vs current diff
- 被 agent patch 过的 skill:卡片左缘 sage 色条 +
- 点击任意卡片打开 skill drawer,含:
- LINEAGE 时间轴(核心可视化):横向时间线展示这个 skill 从被创建到后续每次引用/修改的全过程
- CREATE:金绿发光大圆点 + ✦ 星标 + 脉冲动画(agent 自创的关键事件)
- VIEW:青绿小圆点
- PATCH/EDIT:琥珀
- DELETE:玫瑰
- 头部标签
SELF-AUTHORED/IMPORTED一眼看出来源 - 每个节点点击跳到对应 session
- AGENT EDITS 块(仅当 patch_count > 0 或 md5 漂移时显示):把每一次自动改写直接展开成"前后对比 + 关联 session"的可折叠条目
- 每条记录:
#N · EDIT/CREATE · 时间戳 · ↗ session 药丸 · +X −Y头部 - 点击展开行级 LCS diff(绿底 = 新增、红底 = 删除)
- 默认折叠保持简洁;展开后可看 agent 当时的 rationale(折叠在 details 里,serif italic 引用块)
- 点击
↗ session药丸直接跳转到当时执行这次改写的 session drawer - 没有
skill_manage记录但 md5 漂了的 case,渲染为单独的 DRIFT 块(clay 色 marker),明确标注"这次没经过skill_manage所以没有 session 关联和 rationale",仍然给出 shipped vs current 的完整 diff
- 每条记录:
- 完整 SKILL.md 渲染
- 标签、版本、作者、license
- 一键打开 SKILL.md / 显示目录
- LINEAGE 时间轴(核心可视化):横向时间线展示这个 skill 从被创建到后续每次引用/修改的全过程
Hermes 通过
skill_manage(action=edit)tool 自动改写 SKILL.md 时不会在文件系统留 git 痕迹,但每次改写的完整新内容、时间戳、session id、改之前 agent 的推理都被几条独立的信号同时记录下来。Caduceus 把这些信号拼起来还原一条 shipped → patch ×1 → patch ×2 → … → current 的修订链,和 git diff 一样可比对,但还附带 agent 当时的"为什么这样改"。
抽屉布局:
- META 三栏:
SHIPPED(V0 基线)/CURRENT(当前在盘版本)/PATCHES(.usage.json里patch_count计数)。每栏含 md5 前 12 位(同色即一致)和定位到 Finder 的链接。Skill 已不在盘上时显式标注— no longer on disk - CHAIN 时间链:纵向节点序列,圆形 marker
V0 / #1 / #2 / NOW,每个 patch 节点附:- timestamp + sid(点击跳到对应 session)
- rationale 折叠块:
skill_manage调用之前最近的一条 assistant 消息内容(≤1500 字符),即 agent 当时为何要做这次改写 diff base/diff target两枚 ghost 按钮,把当前节点设为对比的起点或终点
- DIFF 视图:纯客户端 LCS 行级 diff(无库依赖,3000 行/侧 上限),
+ 新增用 sage 绿底,− 删除用 clay 红底,等行=用淡灰前景,头部带+N / −M统计
下方信号合流逻辑(两条独立通道,互补):
| 信号 | 作用 | 触发方式 |
|---|---|---|
~/.hermes/hermes-agent/skills/<group>/<name>/SKILL.md |
shipped baseline(V0),出厂版原文 | — |
~/.hermes/skills/.bundled_manifest |
每个 skill 出厂内容的 md5(用作旁证,但实测会因 hermes-agent 升级而 stale) | — |
~/.hermes/skills/.usage.json |
patch_count / last_patched_at / created_at —— "哪些 skill 被改过、改了几次、最近一次什么时候" |
仅 通过 skill_manage API 才会自增 |
state.db.messages.tool_calls(skill_manage action=edit|create) |
完整改后内容 + 时间戳 + session_id;同 message 之前最近的 assistant 文本即 agent 当时的推理 | 仅 通过 skill_manage 调用 |
| md5(live SKILL.md) vs md5(shipped SKILL.md) | drift 检测 —— "文件被改了但没走 skill_manage,估计是 Write/Edit/sed 直改" |
任何改文件的方式都会触发 |
~/.hermes/skills/<group>/<name>/SKILL.md |
current(在盘版本,可能与最后一次 edit 的内容一致也可能继续被 agent/手动 改过) | — |
为什么需要两条通道:实测发现 hermes-agent skill(autonomous-ai-agents/hermes-agent/SKILL.md)被改了但 .usage.json 里没有它,因为这次改写没走 skill_manage。只看 patch_count 会漏掉这种 case;md5 漂移检测把它捞回来。
来自 ~/.hermes/kanban.db 的 agent 任务队列。纯审计视角——不创建、不暂停、不重跑,只回答"agent 在我不看的时候做了什么、哪次崩了、错在哪里"。
- TASKS 表:每行一个 task + 当前 status pill + 最近一次 run 的 outcome
ok / active / warn / danger / neutral五档配色crashed/timed_out/failed用斜体红色 pill——眼睛先抓到出错的
- task drawer:
- meta 行:
id · status · workspace · profile · skills(这 task 在什么"身份"下跑的) - RUN HISTORY 表:每次 run 的 outcome / duration / profile / summary(失败行带浅红底)
- EVENTS 列:task_events 流(kind / payload / 时间)
- meta 行:
- 空状态友好提示:当 kanban.db 不存在或 0 task 时显示"agent 还没排队任何后台工作"
来自 ~/.hermes/plugins/<name>/ 的已装插件。每个插件的 manifest(plugin.yaml)、暴露的 tools/hooks、env 状态、调用过它们的 session,全部在一处。
- PLUGIN GRID:每个插件一张卡片
- 头:
v<version> · <author> - 名称:
Source Serif 4大标题 - 描述:来自 manifest 的
description - TOOLS chips(sage 墨绿):插件
provides_tools列表 - HOOKS chips(clay 暖棕):插件
provides_hooks列表 - 底脚:env 状态(
✓ env ok/✕ N missing+ optional 计数) + 使用统计(X calls · Y sessions)
- 头:
- plugin drawer:
- PROVIDES:tools / hooks 完整列表
- ENV grid:每个 env 一格——
✓ configured/✕ required/○ optional,绝不读 env 值,只读 key 名比对~/.hermes/.env是否包含 - CALLED IN sessions:扫
messages.tool_calls.function.name,反向匹配本插件提供的 tool name → 哪些 session 调用过本插件 → chip 群组,点击跳到对应 session drawer - 完整 README.md 渲染
来自 state.db 的会话列表(in-progress 未持久化的会话不算入总数,避免数据混淆)。点击行打开 session drawer:
- SKILLS TOUCHED chip 区:本次会话用过的所有 skill 药丸式列表
- CREATE 操作的 chip 用 绿色发光 突出(agent 在这次会话学到了新东西)
- 点击 chip 跳到对应 skill drawer
- 完整消息流(含 tool_calls JSON 缩进显示)
合并 sessions / skills / soul / skill-create / tasks(created/completed/crashed) / plugins(installed) 的全部修改事件,按时间倒序。
每行末尾都有一枚 → audit 主按钮,按事件类型路由到对应 drawer,把时间线变成"审计入口"而不是"只能看时间戳的 log":
| event type | → audit 跳到 |
|---|---|
skill / skill-create |
Skill drawer(含 LINEAGE 时间轴:哪几次 session 引用过这个 skill) |
session |
Session drawer(完整消息流 + SKILLS TOUCHED) |
task / task-crash |
Task drawer(run history + events) |
plugin |
Plugin drawer(manifest + tools/hooks + CALLED IN sessions) |
soul |
直接打开文件(没有 drawer) |
Skill 事件还会内联一行 ↘ N uses 斜体小标签,告诉你这个 skill 在 state.db.messages.tool_calls 里被多少个 session 引用过——一眼判断"值不值得点进去看"。Task-crash 事件用 clay 斜体 outcome tag(CRASHED / TIMED_OUT / FAILED)告警。
顶部 filter chips 都带计数标签:all 98 / sessions 6 / skills 89 / tasks 0 / plugins 2 / soul 1,没事件的类型按钮自动 disabled——避免点空。crashes 单独一枚 warm 色按钮,仅在存在 task crash 时出现。
skill-create 事件用绿色脉冲圆点 + 斜体 italic 标签,从一堆 modified 中一眼能看出来。task-crash 事件用红色 outline + outcome 文字,帮你快速定位"什么时候开始连环崩"。
整个视觉是 editorial × technical:cream 羊皮纸底 + 近黑墨字 + sage 墨绿做主调色,像研究期刊或学者笔记本,但每个 mono 标签、tabular figure、hairline 分割线又都是技术控制台的语言。
右上角 ◐ edition / ◑ console 切换:
- EDITION(默认):cream
#f6f6f3+ 墨黑 + sage#1e9974+ clay#b8714e。白天用,editorial-OpenAI 范儿 - CONSOLE:近黑
#0c0c0b+ 米白 + 同样的 sage / clay 强调。夜里看终端、做长 session 审计
切换状态写入 localStorage,ECharts 图表会重绘适配新调色板。
字体三支家族:
- 正文 / UI:DM Sans(temperate、tight)
- 大标题 / 大数字:Source Serif 4 italic(editorial 主角)
- 技术标签 / 时间戳 / 代码:JetBrains Mono(small caps + tracking)
Skill domain map 和 Overview 的柱状图共享 20 色 earthy palette(sage / terracotta / dusty blue / mustard / wine / olive ……),按排名跑 6+6 / 4+4+4 / 3+3+3+3 / 2 ×6 的栅格档位,每行严丝合缝填满 12 列。
- 后端:Node.js + Express + better-sqlite3,零编译
- 前端:单页 HTML + Alpine.js(CDN)+ 纯手写 CSS 变量驱动主题 + ECharts(饼图/柱图)+ marked(markdown 渲染)。skill domain map 是纯 HTML CSS Grid,没用 canvas
- 构建:无。
node server.js即跑
| 视图 | 数据源 |
|---|---|
| Soul | ~/.hermes/SOUL.md |
| Memory | ~/.hermes/memories/* |
| Skills | ~/.hermes/skills/<group>/<name>/SKILL.md(递归) |
| Sessions 列表 | ~/.hermes/state.db 的 sessions 表 |
| Session 详情 | state.db 的 messages 表 + ~/.hermes/sessions/session_*.json 兜底 |
| Skill 使用记录(lineage) | 扫描 messages.tool_calls + 所有 session JSON 文件,提取 skill_view / skill_manage(action=...) 调用 |
| Skill 修订链(git-less 溯源) | ~/.hermes/hermes-agent/skills/<group>/<name>/SKILL.md(shipped 基线)+ state.db.messages.tool_calls 中每个 skill_manage(action=edit) 的完整新内容 + 紧邻它的 assistant 消息(rationale)+ ~/.hermes/skills/<group>/<name>/SKILL.md(current) |
| Skill 自动改写计数 | ~/.hermes/skills/.usage.json 的 patch_count / last_patched_at |
| Tasks | ~/.hermes/kanban.db 的 tasks / task_runs / task_events / task_comments 表(readonly) |
| Plugins | ~/.hermes/plugins/<name>/plugin.yaml + README.md(每个插件目录的 mtime 作为"安装/更新时间") |
| Plugin env status | 仅读 key 名 —— ~/.hermes/.env 与每个插件目录的 .env.template 对照,绝不读 value |
| Plugin 使用记录(lineage) | 扫描 messages.tool_calls.function.name,匹配每个插件 manifest 里的 provides_tools |
| Timeline | 上面所有源合并 |
- 所有
/api/open与/api/file都校验路径必须落在HERMES_HOME内,越权直接 403 state.db与kanban.db都以 readonly 模式打开- 没有任何"写入 / 修改 / 删除
~/.hermes"的接口 .env严格只读 key 名:plugins 面板需要知道 env 是否齐全,但 server 端只解析KEY=左侧的标识符,不读 value、不返回 value、永不向前端透出 value- 没有外网调用、没有遥测
| 端点 | 说明 |
|---|---|
GET /api/overview |
全局统计(含 tasks / plugins 汇总) |
GET /api/soul |
SOUL.md 内容 + 元数据 |
GET /api/memories |
memories 目录列表 |
GET /api/skills |
所有 skill 元数据列表(不含 body) |
GET /api/skill/:name |
单个 skill 全文 + 该 skill 的使用记录 + patch_count |
GET /api/skill-usage |
完整的 skill ↔ session 双向映射 |
GET /api/skill-history |
所有被 agent patch 过的 skill 摘要(按 last_patched_at 倒序) |
GET /api/skill/:name/history |
单个 skill 的修订链:shipped 基线 + 每次 skill_manage edit 的完整内容与 rationale + 当前在盘版本 |
GET /api/tasks |
任务列表(含每个 task 最近一次 run 的 outcome) |
GET /api/task/:id |
单个任务详情 + 完整 run history + events + comments |
GET /api/plugins |
所有插件 + manifest + env 状态 + 使用计数 |
GET /api/plugin/:name |
单个插件详情 + README + 完整 session lineage |
GET /api/plugin-usage |
完整的 plugin ↔ session 双向映射 |
GET /api/hooks |
hooks 目录脚本列表(前端面板待补) |
GET /api/sessions |
会话列表(仅 db 里持久化的) |
GET /api/session/:id |
单个会话详情(含消息流 + 用过的 skill) |
GET /api/timeline |
合并时间线事件(skill-create / session / task / plugin install) |
POST /api/open |
{target, reveal?} 在系统编辑器或 Finder 中打开 |
GET /api/file?path=... |
读原始文件文本(路径必须落在 HERMES_HOME 内) |
GET /api/health |
健康检查 |
已完成:
- Tasks 面板 —— kanban 任务队列与 run history 审计
- Plugins 面板 —— 插件 manifest / env 状态 / tool ↔ session lineage
- Timeline 合并 task / plugin 事件
- Skill History 抽屉 —— git-less 自动改写溯源:shipped → patch → current 修订链 + 行级 diff + agent rationale
接下来:
- Hooks 面板(
/api/hooks端点已就绪,等~/.hermes/hooks/有内容时补 UI) - Config snapshot 视图 —— 渲染
config.yaml+auth.json(去 secret)+gateway_state.json+channel_directory.json - 跨 session 全文搜索 ——
state.db的messages_fts_trigram已就绪 - Skills 修改频率热力图(一年视图)
- Memory 的写入/替换/删除事件追溯(从 tool_calls 提取)
- 导出报告 —— 把"agent 在哪次 session 学到了什么"导出 JSON / Markdown
- Overview 加 Tasks/Plugins 卡片 —— 后端数据已经在
/api/overview里,前端只差 UI
主题切换后所有视图都会重绘。两套主题概念对偶:
- EDITION(昼):学者笔记 / editorial 期刊 — 阅读 · 整理 · 复盘
- CONSOLE(夜):操作员控制台 — 调试 · 审计 · 排错
MIT