Technical Guide
11. Skills 源码:Skill 如何被发现、加载和写入
从 skill_utils、prompt_builder 和 skills 工具看 Hermes 的 Skill 生命周期。
这篇解决什么问题
上一篇讲 Skill 的意义,这一篇看源码。
目标是看懂:Hermes 怎么找到 Skill,怎么决定哪些 Skill 出现在索引里,模型怎么读取完整 Skill,写入 Skill 时又有什么边界。
先看哪些文件
关键文件包括:
agent/skill_utils.py
agent/prompt_builder.py
tools/skills_tool.py
agent/skill_preprocessing.py
agent/skill_commands.py
agent/curator.py
不同版本文件名可能有细节变化,但主线基本是:发现、索引、加载、写入、维护。
Skill 存在哪里
默认用户 Skill 在:
~/.hermes/skills/
Profile 场景下则在:
~/.hermes/profiles/<name>/skills/
此外,Hermes 还可能加载 bundled skills、hub skills、OpenClaw 迁移来的 skills。
agent/skill_utils.py 里的 get_all_skills_dirs() 就是找这些目录的关键函数之一。
发现 Skill 时会跳过哪些目录
skill_utils.py 里定义了排除目录,例如:
.git
.github
.archive
.venv
node_modules
site-packages
__pycache__
.pytest_cache
这不是小细节。
如果不排除,扫描 Skill 时可能把依赖目录、归档文件、测试缓存里的 SKILL.md 当成真实技能。
references 为什么不被当成 Skill
references/、templates/、assets/、scripts/ 是 Skill 的支持目录。
源码里有 SKILL_SUPPORT_DIRS,并明确说明:这些目录里的文件是通过 skill_view(..., file_path=...) 显式加载的,不是独立 Skill 根目录。
这就是 progressive disclosure:主 Skill 先轻量加载,长资料按需读取。
platform 和 environment 过滤
Skill frontmatter 可以声明平台:
platforms: [linux, macos]
也可以声明环境相关条件。
源码里的注释强调:这是“展示/推荐时”的过滤,不是硬限制。也就是说,不匹配时可以不出现在索引里,但用户或系统显式 skill_view 时仍然可以加载。
这点很重要:显式加载代表明确意图。
skill_view 做什么
skill_view 是读取 Skill 的主要工具。
它可以读取:
SKILL.md
references/xxx.md
templates/xxx
scripts/xxx
所以一个复杂 Skill 不需要把所有内容塞进主文件。主文件只放流程和触发条件,长背景资料放 references。
skill_manage 做什么
skill_manage 用于创建、patch、编辑、删除或写入 Skill 支持文件。
它适合沉淀长期流程,不适合记录临时任务进度。
比如:
可以写:技术教程写作检查清单
不要写:今天修了某篇文章第 3 段
后者应该留在会话历史或 git commit 里,而不是 Skill。
Curator 是什么
Hermes 还有 curator 相关逻辑,用于维护 agent 创建的 Skill:使用统计、过期、归档、恢复等。
这说明 Skill 不是“写进去就永远不管”。Skill 会变旧,会重复,也会需要合并。
如果你要新增一个 Skill
最小路径是:
~/.hermes/skills/<category>/<skill-name>/SKILL.md
主文件建议包含:
name
description
when to use
workflow
pitfalls
verification
如果内容很长,把案例和参考拆到:
references/
下一篇看什么
下一篇看 Memory 和 Session。
Skill 是过程知识,Memory 是长期用户/环境事实,Session 是历史对话。三者不要混。