本章目录In this chapter
- 13 · The Skill System
- 13.1 What a Skill Is
- 13.2 The Front Matter, Field by Field
- 13.3 Progressive Disclosure: The Core Mechanism of the Skill System
- 13.4 The Infrastructure Around Skills
- 13.5 Skills vs. Tools vs. Plugins
- 13.6 An Implicit Design in the Skill System: Composability
- 13.7 The 15 Skill Categories
- 13.8 Looking Back Across the Book: The Overall Shape of Hermes
13 · 技能系统
81 个 SKILL.md 文件,分布在 15 个类别里。skills_hub.py 有 4,956 行。这一章讲怎么用纯文本教会智能体做一件它本来不会的事。
13.1 技能是什么
一个技能就是一个 Markdown 文件。没有代码,没有编译,没有注册。
---
name: deploy-to-staging
description: 把当前分支部署到预发布环境并验证健康检查
version: 1.2.0
author: platform-team
license: MIT
platforms: [slack, cli]
metadata:
hermes:
tags: [deploy, ci, infra]
related_skills: [rollback-deploy, check-service-health]
---
# 部署到预发布环境
## 前置检查
1. 确认当前分支的 CI 全绿:`gh pr checks`
2. 确认没有未提交的改动:`git status --porcelain`
## 部署步骤
1. 打 tag:`git tag staging-$(date +%Y%m%d-%H%M%S)`
2. 推送:`git push origin --tags`
3. 等待部署流水线:`gh run watch`
## 验证
- 访问 https://staging.example.com/health,应返回 200
- 如果 5 分钟内没有变绿,执行 rollback-deploy 技能
为什么这有用?
模型知道 git、知道 gh、知道怎么发 HTTP 请求。它不知道的是「在你们团队,部署是这么做的」 —— 用哪个命令、按什么顺序、验证什么、出错了找谁。
技能填补的正是这个缺口:不是教模型新能力,而是告诉它「在这个具体环境下,正确的做法是什么」。
13.2 前置元数据逐字段解释
文件开头 --- 之间的部分叫「前置元数据」(front matter),是 YAML 格式的结构化信息。
| 字段 | 作用 |
|---|---|
name | 技能的唯一标识。用户可以直接用它调用(/deploy-to-staging) |
description | 最重要的一个字段。它决定模型什么时候会想起来用这个技能。见下一节 |
version | 技能也会演进。团队的部署流程变了,技能要跟着改 |
author | 出问题时找谁 |
license | 技能可以被分享、被开源。需要明确许可 |
platforms | 限定在哪些平台可用。有的技能只在命令行里有意义(涉及本地文件),有的只在聊天工具里有意义(涉及发消息) |
metadata.hermes.tags | 标签,用于分类和检索 |
related_skills | 技能之间的关系。上面的例子里,部署技能指向了回滚技能 —— 出问题时模型知道下一步该看哪个 |
13.3 渐进式披露:技能系统的核心机制
81 个技能全部展开是多少字?假设每个 3 KB,就是 243 KB ≈ 6 万 token。
解法:只常驻「目录」,内容按需加载。
这解释了为什么 description 是最重要的字段。
它是模型唯一能看到的、用来判断「这个技能跟当前任务有没有关系」的信息。
写得好:「把当前分支部署到预发布环境并验证健康检查」→ 用户说「发到 staging」时能匹配上。
写得差:「部署工具」→ 太模糊,模型不知道是部署到哪、部署什么。
写技能描述的原则:写「什么时候该用它」,而不是「它是什么」。
13.4 技能的支撑设施
技能本身是纯文本,但围绕它有一整套工程设施:
skills_hub.py 4,956 行 技能的加载、检索、执行编排
skill_ledger.py ★ 技能台账
skill_provenance.py ★ 来源追溯
skill_usage.py ★ 使用统计
skill_linter.py ★ 格式检查
skills_guard.py ★ 安全守卫
skills_sync.py ★ 同步
skill_provenance.py:来源追溯
「provenance」(来源、出处)在这里是一个安全概念。
一个技能文件里写的步骤,智能体会照着执行。所以:一个技能文件就是一段可执行的指令 —— 只不过它是用自然语言写的。
攻击场景:有人往你的技能目录里放了一个技能文件,描述写得很正常(「清理临时文件」),内容里却是把敏感数据发到外部。下次模型判断需要清理临时文件时,就会照做。
来源追溯就是回答:这个技能是谁写的?从哪来的?改过没有?
skills_guard.py:安全守卫
在技能被加载或执行前做安全检查。可能包括:
- 技能内容里有没有可疑的指令模式(和第 12 章的注入检测同源)
- 技能要用的工具,当前上下文是否允许
- 来源是否可信(配合 provenance)
skill_linter.py:格式检查
「linter」是「代码风格检查器」的通称。技能的 linter 检查的是:
- 前置元数据的必填字段有没有缺
related_skills里引用的技能是否存在description是不是太短/太模糊- 格式是否符合规范
为什么需要 linter:因为技能是给人写的,而人会写错。一个 description 拼错了字段名,这个技能就永远不会被匹配到 —— 而且不会报错,只是「莫名其妙不生效」。Linter 把这类静默失败变成明确的错误。
skill_usage.py:使用统计
记录哪些技能被用了、用了多少次、成功率如何。用途:
- 找出从来没被用过的技能 —— 要么描述写得不好(匹配不上),要么根本没用(该删)
- 找出经常失败的技能 —— 步骤过时了,环境变了
- 找出高频技能 —— 值得投入精力优化,或者考虑做成真正的工具
skill_ledger.py 与 skills_sync.py
台账记录技能的完整清单和状态(启用/禁用、版本、来源)。同步负责在多个地方之间保持技能一致 —— 比如从一个共享仓库拉取团队的技能库。
13.5 技能 vs 工具 vs 插件
| 技能 | 工具 | 插件 | |
|---|---|---|---|
| 是什么 | Markdown 文本 | Python 函数 | Python 包 |
| 教会模型 | 怎么做(用已有能力) | 能做什么(新能力) | 能做什么 + 改变系统行为 |
| 写的人 | 任何人,包括非程序员 | 程序员 | 程序员 |
| 出错的后果 | 模型走了错路,通常能自己纠正 | 工具报错 | 可能影响整个系统 |
| 常驻成本 | 1 行描述 | 一份 JSON schema(几百 token) | 取决于它注册了什么 |
| 典型例子 | 「我们团队的部署流程」 | 「读文件」「跑命令」 | 「接入 Slack」「换个记忆后端」 |
关键区分:技能不给模型新能力,只给它「在这个环境下的正确做法」。
部署技能里的每一条命令(git tag、gh run watch)模型本来就会执行 —— 它有 terminal 工具。技能提供的是顺序、参数、验证方式、失败时的退路。
这就是为什么技能可以是纯文本:它编码的是知识,不是能力。
13.6 技能系统的一个隐含设计:可组合
related_skills 字段和技能内容里的「执行 rollback-deploy 技能」这样的引用,构成了一张技能之间的关系网。
这和渐进式披露是同一个思想的延伸。
不是「一次性把所有相关知识都塞进上下文」,而是「在需要的那一刻,告诉它去哪里找下一块」。
上下文是有限的、昂贵的。一个好的知识组织方式,应该让智能体在任意时刻只持有它当前真正需要的那部分。
这个原则贯穿了整篇文章讲过的所有机制:技能目录、记忆预取、上下文引擎的选择、工具集的投放 —— 全都是同一件事的不同表现。
13.7 15 个技能类别
81 个技能分布在 15 个类别里。类别本身反映了智能体被期望承担的工作范围:
这个分布说明技能系统的实际用途:把一个通用智能体特化成「这个团队的工程助手」。模型本身是通用的,技能库是团队特有的。同样的模型 + 不同的技能库 = 完全不同的助手。
13.8 全文回顾:Hermes 的整体形状
① 一切扩展点都是抽象基类。平台、记忆、上下文引擎、模型供应商、执行环境、定时提供者 —— 全部是「定义契约,实现可替换」。而且区分了「可叠加能力」和「必须单选的策略」。
② 安全是分层的、fail-closed 的。工具收窄 × 审批红线 × 执行隔离 × 注入检测。每一层都不可靠,叠起来才够用。不确定的时候一律选择「不执行」。
③ 上下文是最稀缺的资源,一切设计围绕它。渐进式披露、委派分区、记忆预取、压缩策略 —— 表面上是七八个不同的机制,本质上都在回答同一个问题:「怎么让模型在任意时刻只持有它真正需要的那部分信息」。
13 · The Skill System
81 SKILL.md files, spread across 15 categories. skills_hub.py is 4,956 lines. This chapter covers how to teach an agent, using plain text, to do something it didn't know how to do.
13.1 What a Skill Is
A skill is one Markdown file. No code, no compilation, no registration.
---
name: deploy-to-staging
description: Deploy the current branch to staging and verify the health check
version: 1.2.0
author: platform-team
license: MIT
platforms: [slack, cli]
metadata:
hermes:
tags: [deploy, ci, infra]
related_skills: [rollback-deploy, check-service-health]
---
# Deploy to staging
## Pre-flight checks
1. Confirm CI is all green on the current branch: `gh pr checks`
2. Confirm there are no uncommitted changes: `git status --porcelain`
## Deployment steps
1. Tag: `git tag staging-$(date +%Y%m%d-%H%M%S)`
2. Push: `git push origin --tags`
3. Wait for the deploy pipeline: `gh run watch`
## Verification
- Hit https://staging.example.com/health; it should return 200
- If it hasn't gone green within 5 minutes, run the rollback-deploy skill
Why is this useful?
The model knows git, knows gh, knows how to make an HTTP request. What it doesn't know is “on your team, this is how deployment works” — which command, in what order, verifying what, and who to call when it breaks.
That is exactly the gap skills fill: not teaching the model new abilities, but telling it “in this specific environment, here is the right way to do it.”
13.2 The Front Matter, Field by Field
The part between the --- markers at the top of the file is called “front matter”: structured information in YAML format.
| Field | Role |
|---|---|
name | The skill's unique identifier. Users can invoke it directly (/deploy-to-staging) |
description | The single most important field. It determines when the model will think to use this skill. See the next section |
version | Skills evolve too. When the team's deployment process changes, the skill has to change with it |
author | Who to ask when something goes wrong |
license | Skills can be shared and open-sourced. That needs an explicit license |
platforms | Restricts which platforms it's available on. Some skills only make sense in the CLI (they involve local files); others only in a chat app (they involve sending messages) |
metadata.hermes.tags | Tags, for categorization and retrieval |
related_skills | Relationships between skills. In the example above, the deploy skill points to the rollback skill — so when something goes wrong, the model knows which one to look at next |
13.3 Progressive Disclosure: The Core Mechanism of the Skill System
How much text is it if all 81 skills are expanded? At 3 KB each, that's 243 KB ≈ 60,000 tokens.
The fix: keep only the “catalog” resident, and load contents on demand.
This explains why description is the most important field.
It is the only information the model can see when judging “is this skill relevant to the current task”.
Written well: “Deploy the current branch to staging and verify the health check” → matches when the user says “push to staging.”
Written badly: “Deployment tool” → too vague; the model doesn't know deploy where, or deploy what.
The rule for writing skill descriptions: write “when to use it,” not “what it is.”
13.4 The Infrastructure Around Skills
A skill itself is plain text, but a whole engineering apparatus surrounds it:
skills_hub.py 4,956 lines loading, retrieval, and execution orchestration of skills
skill_ledger.py ★ skill ledger
skill_provenance.py ★ provenance tracking
skill_usage.py ★ usage statistics
skill_linter.py ★ format checking
skills_guard.py ★ security guard
skills_sync.py ★ sync
skill_provenance.py: provenance tracking
“Provenance” (origin, source) is a security concept here.
The agent follows the steps written in a skill file. So: a skill file is a piece of executable instructions — it just happens to be written in natural language.
The attack scenario: someone drops a skill file into your skills directory with a perfectly normal-looking description (“clean up temporary files”), but whose body sends sensitive data to an outside party. The next time the model decides temporary files need cleaning up, it will do exactly that.
Provenance tracking answers: who wrote this skill? Where did it come from? Has it been modified?
skills_guard.py: the security guard
Runs security checks before a skill is loaded or executed. These may include:
- Whether the skill's content contains suspicious instruction patterns (same lineage as chapter 12's injection detection)
- Whether the tools the skill wants to use are allowed in the current context
- Whether the source is trusted (working together with provenance)
skill_linter.py: format checking
A “linter” is the general term for a code-style checker. The skill linter checks:
- Whether any required front-matter fields are missing
- Whether the skills referenced in
related_skillsexist - Whether the
descriptionis too short or too vague - Whether the format follows the spec
Why a linter is needed: skills are written by people, and people make mistakes. Misspell the description field name and that skill will never be matched — and nothing errors out; it just “mysteriously doesn't work.” The linter turns that kind of silent failure into an explicit error.
skill_usage.py: usage statistics
Records which skills were used, how many times, and with what success rate. Uses:
- Find skills that have never been used — either the description is poorly written (never matches), or nobody needs it (delete it)
- Find skills that fail often — the steps are out of date, the environment has changed
- Find high-frequency skills — worth investing effort to optimize, or worth turning into a real tool
skill_ledger.py and skills_sync.py
The ledger records the complete inventory of skills and their state (enabled/disabled, version, origin). Sync keeps skills consistent across multiple locations — for example, pulling the team's skill library from a shared repository.
13.5 Skills vs. Tools vs. Plugins
| Skill | Tool | Plugin | |
|---|---|---|---|
| What it is | Markdown text | A Python function | A Python package |
| What it teaches the model | How to do it (with existing abilities) | What it can do (a new ability) | What it can do + changes to system behavior |
| Who writes it | Anyone, including non-programmers | Programmers | Programmers |
| Consequence of a mistake | The model takes a wrong turn and can usually correct itself | The tool throws an error | May affect the whole system |
| Resident cost | 1 line of description | One JSON schema (a few hundred tokens) | Depends on what it registers |
| Typical example | “Our team's deployment process” | “Read a file,” “run a command” | “Connect to Slack,” “swap the memory backend” |
The key distinction: a skill gives the model no new abilities, only “the right way to do it in this environment.”
Every command in the deploy skill (git tag, gh run watch) is something the model could already run — it has the terminal tool. What the skill supplies is the order, the parameters, the verification method, and the fallback when things fail.
That is why a skill can be plain text: it encodes knowledge, not capability.
13.6 An Implicit Design in the Skill System: Composability
The related_skills field, plus references inside skill bodies like “run the rollback-deploy skill,” form a web of relationships between skills.
This is the same idea as progressive disclosure, extended.
Not “stuff all the related knowledge into the context at once,” but “at the moment it's needed, tell it where to find the next piece.”
Context is finite and expensive. A good way of organizing knowledge should let the agent hold, at any moment, only the part it actually needs right then.
This principle runs through every mechanism covered in this book: the skill catalog, memory prefetch, the context engine's selection, toolset provisioning — all of them are different faces of the same thing.
13.7 The 15 Skill Categories
The 81 skills are spread across 15 categories. The categories themselves reflect the range of work the agent is expected to take on:
This distribution shows what the skill system is really for: specializing a general-purpose agent into “this team's engineering assistant.” The model itself is generic; the skill library is team-specific. The same model + a different skill library = a completely different assistant.
13.8 Looking Back Across the Book: The Overall Shape of Hermes
① Every extension point is an abstract base class. Platforms, memory, context engines, model providers, execution environments, cron providers — all of them are “define the contract, make the implementation replaceable.” And it distinguishes “stackable capabilities” from “strategies that must be single-select.”
② Security is layered and fail-closed. Toolset narrowing × approval red lines × execution isolation × injection detection. No single layer is reliable; only stacked together are they enough. When in doubt, always choose “don't execute.”
③ Context is the scarcest resource, and every design revolves around it. Progressive disclosure, delegation partitioning, memory prefetch, compaction strategy — on the surface, seven or eight different mechanisms; underneath, all answering the same question: “how do we let the model hold, at any moment, only the information it actually needs.”