Writing Skills — TDD 驱动的技能工程
吸收自: obra/superpowers v6.1.1,Jesse Vincent / Prime Radiant
核心洞察: 写技能 = 对过程文档执行 TDD。压力测试驱动 → 基线失败 → 写技能 → 验证合规 → 封堵漏洞。
Overview
Writing skills IS Test-Driven Development applied to process documentation.
你写测试用例(带子代理的压力场景),看它们失败(基线行为),写技能(文档),看测试通过(Agent 遵守),然后重构(封堵漏洞)。
Core principle: If you didn't watch an agent fail without the skill, you don't know if the skill teaches the right thing.
REQUIRED BACKGROUND: 必须先理解 test-driven-development 技能的 RED-GREEN-REFACTOR 循环。本技能将 TDD 适配到文档领域。
What is a Skill?
A skill 是可复用技术、模式、工具的参考指南。技能帮助未来的 Agent 找到并应用有效方法。
Skills are: 可复用技术、模式、工具、参考指南
Skills are NOT: 关于"你怎么解决过一次问题"的叙事
TDD Mapping for Skills
| TDD Concept | Skill Creation |
|---|---|
| Test case | 带子代理的压力场景 |
| Production code | 技能文档 (SKILL.md) |
| Test fails (RED) | Agent 在没有技能时违反规则(基线) |
| Test passes (GREEN) | Agent 在有技能时遵守规则 |
| Refactor | 封堵漏洞,保持合规 |
| Write test first | 写技能前先跑基线场景 |
| Watch it fail | 记录 Agent 使用的确切合理化借口 |
| Minimal code | 写技能针对那些具体的违规 |
| Watch it pass | 验证 Agent 现在遵守 |
| Refactor cycle | 发现新合理化 → 封堵 → 重新验证 |
When to Create a Skill
Create when:
- 技术/方法对你来说不是直觉性的
- 你会跨项目再次引用
- 模式广泛适用(非项目特定)
- 其他人会受益
- 你发现自己反复纠正 Agent 同一个错误
Don't create for:
- 一次性解决方案
- 已被广泛文档化的标准实践
- 项目特定约定(放入项目 instructions 文件)
- 机械性约束(如果可用 regex/validation 自动化,自动化它——文档留给判断类决策)
Skill Types
Technique(技法)
有步骤的具体方法(condition-based-waiting、root-cause-tracing)
Pattern(模式)
思考问题的方式(flatten-with-flags、test-invariants)
Reference(参考)
API 文档、语法指南、工具文档
Directory Structure
skills/
skill-name/
SKILL.md # 主参考文件(必需)
references/ # 参考文件(方法论、模板、案例)
scripts/ # 可执行脚本
templates/ # 输出模板
Hermes 技能结构(比 superpowers 更丰富):
references/放重参考(100+ 行)、方法论框架scripts/放可执行工具templates/放输出模板- 原则、概念、短代码模式保持内联
SKILL.md Structure
Frontmatter (YAML):
- 必需字段:
name,description name: 仅用字母、数字、连字符description: 第三人称,描述何时使用(非技能做什么)- 以 "Use when..." 或 "当...时使用" 开头
- 包含具体触发条件、症状、场景
- 绝不总结技能的工作流(见 SDO 章节说明)
---
name: skill-name-with-hyphens
description: 当 [具体触发条件和症状] 时使用
version: 1.0.0
metadata:
hermes:
tags: [tag1, tag2]
related_skills: [skill-a, skill-b]
---
# Skill Name
## Overview
这是什么?1-2 句核心原则。
## When to Use
[仅在决策不明显时使用小型内联流程图]
触发条件列表
何时不使用
## Core Pattern (for techniques/patterns)
Before/after 代码对比
## Quick Reference
常见操作的速查表
## Implementation
简单模式内联代码;重参考或可复用工具外链文件
## Common Mistakes
什么会出错 + 修复方法
## Real-World Impact (optional)
具体结果
Skill Discovery Optimization (SDO)
Critical for discovery: 未来的 Agent 需要找到你的技能。
1. Rich Description Field
Purpose: Agent 读 description 来决定是否为当前任务加载此技能。
Format: 以触发条件开头,不总结工作流。
CRITICAL: Description = When to Use, NOT What the Skill Does
description 应该只描述触发条件。绝不在 description 中总结技能的工作流。
Why: 测试发现,当 description 总结了工作流时,Agent 可能照着 description 做而不读完整技能内容。一个 description 写"在任务间做代码审查"导致 Agent 只做一次审查,而技能流程图明确写了两次审查。
# ❌ BAD: 总结了工作流 - Agent 可能照此执行而不读技能
description: 执行计划时分派子代理,在任务间做代码审查
# ❌ BAD: 过程细节太多
description: TDD 时用 - 先写测试,看它失败,写最少代码,重构
# ✅ GOOD: 只有触发条件,无工作流摘要
description: 当执行含独立任务的实现计划时使用,在当前会话中
# ✅ GOOD: 仅触发条件
description: 当实现任何功能或 bugfix 时,在写实现代码之前使用
2. Keyword Coverage
使用 Agent 会搜索的词:
- 错误消息: "Hook timed out", "ENOTEMPTY", "race condition"
- 症状: "flaky", "hanging", "zombie", "污染"
- 同义词: "timeout/hang/freeze", "cleanup/teardown"
- 工具: 实际命令、库名、文件类型
- 中文触发词: 必须包含 ≥3 个中文触发场景
3. Descriptive Naming
动词优先,主动语态:
- ✅
creating-skills不是skill-creation - ✅
condition-based-waiting不是async-test-helpers
以你做的动作或核心洞察命名:
- ✅
condition-based-waiting>async-test-helpers - ✅
root-cause-tracing>debugging-techniques
-ing 形式适合流程:
creating-skills,testing-skills,debugging-with-logs
4. Token Efficiency
Problem: 频繁加载的技能进入每次对话。每个 token 都算数。
Move details to tool help:
# ❌ BAD: 在 SKILL.md 中记录所有 flags
search-conversations 支持 --text, --both, --after DATE, --before DATE, --limit N
# ✅ GOOD: 引用 --help
search-conversations 支持多种模式和过滤。运行 --help 查看详情。
Use cross-references:
# ❌ BAD: 重复工作流细节
搜索时,分派子代理使用模板...
[20 行重复指令]
# ✅ GOOD: 引用其他技能
始终使用子代理(节省 50-100x 上下文)。REQUIRED: 使用 [other-skill-name] 获取工作流。
Eliminate redundancy:
- 不重复交叉引用的技能内容
- 不解释命令本身就清楚的
- 不包含同一模式的多个示例
5. Cross-Referencing Other Skills
使用技能名,加显式要求标记:
- ✅ Good:
**REQUIRED SUB-SKILL:** 使用 test-driven-development - ✅ Good:
**REQUIRED BACKGROUND:** 必须理解 systematic-debugging - ❌ Bad:
参见 skills/testing/test-driven-development(不清楚是否必需) - ❌ Bad:
@skills/testing/test-driven-development/SKILL.md(强制加载、燃烧上下文)
Flowchart Usage
仅在以下情况使用流程图:
- 非显而易见的决策点
- 可能过早停止的流程循环
- "何时用 A vs B"决策
绝不使用流程图:
- 参考材料 → 表格、列表
- 代码示例 → Markdown 块
- 线性指令 → 编号列表
- 无语义含义的标签 (step1, helper2)
Code Examples
一个优秀的示例胜过许多平庸的示例
选择最相关的语言:
- 测试技术 → TypeScript/JavaScript
- 系统调试 → Shell/Python
- 数据处理 → Python
Good example:
- 完整且可运行
- 良好注释解释 WHY
- 来自真实场景
- 清晰展示模式
- 可直接适配
Don't:
- 实现 5+ 种语言
- 创建填空模板
- 写人为构建的示例
The Iron Law
NO SKILL WITHOUT A FAILING TEST FIRST
这适用于新技能和对已有技能的编辑。
写技能之前没有测试?删除。重新开始。 编辑技能没有测试?同样的违规。
No exceptions:
- 不是对"简单添加"
- 不是对"只是加一节"
- 不是对"文档更新"
- 不保留未测试的修改作为"参考"
- 不在跑测试时"适配"
- 删除就是删除
REQUIRED BACKGROUND: test-driven-development 技能解释了为什么这很重要。
Match the Form to the Failure
写指导前,分类基线失败。一种失败类型有效的形式可能在另一种上适得其反。
| 基线失败 | 正确形式 | 错误形式 |
|---|---|---|
| 压力下跳过/违反规则(知道更好,还是做了) | 禁令 + 合理化表格 + Red Flags | 软指导 ("prefer...", "consider...") |
| 合规但输出形状不对(臃肿 prompt、埋没结论、重述 spec) | 正面配方或合约:陈述输出 IS——组成部分、顺序 | 禁令列表 ("don't restate", "never narrate") |
| 从已产出内容中遗漏必需元素 | 结构性:他们填的模板中的 REQUIRED 字段 | 模板附近的散文提醒 |
| 行为应依条件而定 | 基于可观察谓词的条件 ("if the brief exists, reference it") | 无条件规则 + 豁免条款 |
Bulletproofing Skills Against Rationalization
执行纪律的技能需要抵抗合理化。Agent 在压力下很聪明,会找漏洞。
Close Every Loophole Explicitly
不只声明规则——禁止具体的变通方法:
No exceptions:
- 不作为"参考"保留
- 不在写测试时"适配"
- 不看它
- 删除就是删除
</Good>
### Address "Spirit vs Letter" Arguments
早期添加基本原则:
```markdown
**Violating the letter of the rules is violating the spirit of the rules.**
这切断了整类"我遵循精神"的合理化。
Build Rationalization Table
从基线测试中捕获合理化。Agent 制造的每个借口都进表格:
| Excuse | Reality |
|--------|---------|
| "太简单不需要测试" | 简单代码也会坏。测试只要 30 秒。 |
| "我之后会测" | 之后通过的测试什么也证明不了。 |
| "之后的测试达到同样目标" | 之后测 = "这个做什么?" 先测 = "这个应该做什么?" |
Create Red Flags List
让 Agent 在合理化时自我检查:
## Red Flags - STOP and Start Over
- 代码在测试之前
- "我已经手动测过了"
- "之后的测试达到同样目的"
- "这是关于精神不是仪式"
- "这不一样因为..."
**所有这些都意味着:删除代码。用 TDD 重新开始。**
RED-GREEN-REFACTOR for Skills
RED: Write Failing Test (Baseline)
在没有技能的情况下跑压力场景。记录确切行为:
- Agent 做了什么选择?
- 使用了什么合理化(逐字)?
- 哪些压力触发了违规?
这是"看测试失败"——必须看到 Agent 在没有技能时自然做什么。
GREEN: Write Minimal Skill
写针对那些具体合理化的技能。不为假设情况添加额外内容。
用同样的场景带技能跑。Agent 现在应该合规。
REFACTOR: Close Loopholes
Agent 找到了新合理化?添加显式反击。重新测试直到无懈可击。
Micro-Test Wording Before Full Scenarios
完整的压力场景跑是最终门禁,但每次迭代慢且贵。先用微测试验证措辞:
- 每次调用一个全新上下文样本——原始 API 调用,或单次子代理。System prompt = 指导将存在的真实上下文;User message = 诱惑失败的任务。
- 始终包含无指导对照组。 如果对照组不展现失败,就没有什么要修复的——停止。
- 每个变体 5+ 次重复。 单样本会说谎。
- 手动读取每个标记匹配。 模板回显和被引用的反例会伪装成命中;自动化计数会高估失败和成功。
- 方差是度量。 指导落地后,重复应收敛到同一形状。五次重复五种不同解释 = 措辞不具备约束力——在加词之前收紧形式。
Hermes 环境的测试方法
在 Hermes 中测试技能的特殊考量:
- 多模型测试: 同一技能在 DeepSeek/Claude/GPT 下表现不同。至少测试 2 个模型。
- Cron 触发测试: 如果技能有自动触发逻辑,验证 cron 调度下的行为。
- 跨 Profile 测试: 如果技能引用其他技能,验证依赖链在干净 profile 中可用。
- Token 约束测试: 验证技能在上下文窗口压力下仍然完整触发。
Skill Creation Checklist (TDD Adapted)
IMPORTANT: 为以下每一项创建 todo。
RED Phase - Write Failing Test:
- 创建压力场景(纪律技能 3+ 组合压力)
- 不带技能跑场景 - 逐字记录基线行为
- 识别失败/合理化模式
GREEN Phase - Write Minimal Skill:
- 名称仅用字母、数字、连字符
- YAML frontmatter 含必需
name和description(≤1024 字符) - Description 以触发条件开头,含具体触发/症状
- Description 用第三人称
- 全文分布关键词(错误、症状、工具)
- 含核心原则的清晰 overview
- 针对 RED 阶段发现的具体基线失败
- 指导形式匹配失败类型(见 Match the Form to the Failure)
- 代码内联或链接到单独文件
- 一个优秀示例(不多语言)
- 带技能跑场景 - 验证 Agent 现在合规
REFACTOR Phase - Close Loopholes:
- 从测试中识别新合理化
- 添加显式反击(如纪律技能)
- 从所有测试迭代构建合理化表格
- 创建 Red Flags 列表
- 重新测试直到无懈可击
Quality Checks:
- 仅在决策不明显时使用小流程图
- 速查表
- 常见错误章节
- 无叙事性讲故事
- 支持文件仅用于工具或重参考
Deployment (Hermes):
- 通过
skill_manage(action='create')注册技能 - 更新 related_skills 引用网络
- 同步到 GitHub awesome-skills 仓库
- 如适用,更新 README 索引
Anti-Patterns
❌ Narrative Example
"在 2025-10-03 的会话中,我们发现空 projectDir 导致..." Why bad: 太具体,不可复用
❌ Multi-Language Dilution
example-js.js, example-py.py, example-go.go Why bad: 平庸质量,维护负担
❌ Code in Flowcharts
step1 [label="import fs"];
step2 [label="read file"];
Why bad: 无法复制粘贴,难读
❌ Generic Labels
helper1, helper2, step3, pattern4 Why bad: 标签应有语义含义
❌ 跳过基线测试
"我知道 Agent 会做什么" Why bad: 你其实不知道。Agent 在不同模型下表现不同。
❌ Hermes 特有反模式
- 用
skill_manage(action='edit')做小修改(应该用patch) - 不更新 metadata.related_skills 就创建技能(孤立技能 = 死技能)
- 不测试跨模型行为就部署(DeepSeek vs Claude 触发逻辑差异显著)
The Bottom Line
Creating skills IS TDD for process documentation.
Same Iron Law: No skill without failing test first. Same cycle: RED (baseline) → GREEN (write skill) → REFACTOR (close loopholes). Same benefits: Better quality, fewer surprises, bulletproof results.
如果你对代码遵循 TDD,对技能也遵循它。这是同一套纪律应用于文档。
与 Hermes 原生技能的关系
| 技能 | 关系 | 使用方式 |
|---|---|---|
test-driven-development |
upstream | RED-GREEN-REFACTOR 基础方法论 |
skill-evaluator |
downstream | 创建后的三维评测 |
benchmark-generator |
downstream | 自动生成技能的 routing 测试集 |
darwin-skill |
downstream | 创建后的 L1 静态检查 |
hermes-agent-skill-authoring |
sibling | Hermes 特定语法和规范 |
吸收自: https://github.com/obra/superpowers (v6.1.1)
技能吸收标准流程(必须动作)
铁律:技能创建/吸收后必须完成以下5步,缺一不可。
Step 1: 技能引用网络
为新技能建立完整的 related_skills 引用:
- 新技能 → 相关技能:新技能的
related_skills包含所有相关技能 - 相关技能 → 新技能:更新所有相关技能的
related_skills添加新技能 - 验证双向引用:确保引用关系一致(除非明确是单向)
# 检查引用完整性
grep -l "new-skill" ~/.hermes/skills/*/SKILL.md
Step 2: 技能执行测试
验证技能可以正常加载和触发:
# 1. 文件可读性
skill_view(name="new-skill")
# 2. 元数据完整性
- name, description, version, triggers 存在
- related_skills 引用的技能都存在
- references 目录下的文件可读
# 3. 触发词验证
- triggers 不与现有技能冲突
- 触发词准确描述使用场景
Step 3: 审计产出结果
检查技能质量和规范:
| 检查项 | 标准 |
|---|---|
| 来源标记 | 吸收技能必须有 吸收自 xxx 或 adapted from xxx |
| upstream | metadata 中必须有 upstream 字段 |
| 版本号 | 首次创建为 1.0.0 |
| 格式 | 遵循 SKILL.md 规范(frontmatter + markdown) |
| 内容 | 无敏感信息、无硬编码路径、无过时内容 |
Step 4: 上传到 GitHub
使用 github-release-readme 技能执行同步:
# 1. 双源扫描
python3 scripts/scan_inventory.py
# 2. 复制技能(穿透 symlink)
cp -rL ~/.hermes/skills/category/new-skill /tmp/awesome-skills/
# 3. 更新 README
- Badge 计数 +1
- 分类表添加条目
- 版本历史添加新行
# 4. 提交推送
git add -A && git commit -m "v{x.y.z}: +1 新增(new-skill)"
git push origin main # WSL 必须后台模式
# 5. 创建 Release
gh release create "v{x.y.z}" --notes-file release_notes.md
Step 5: 记录变更
更新 MEMORY 中的技能计数和版本信息。
检查清单
每次技能吸收前确认:
- 引用网络已建立(双向验证)
- 执行测试通过(文件可读、元数据完整)
- 审计通过(来源标记、upstream、版本号、格式)
- GitHub 同步完成(README 更新、Release 创建)
- MEMORY 已更新
执行顺序(铁律)
先做完全部 Step 1-3,再做 Step 4。 不要创建完技能就停下。 用户纠正过:"以后技能吸收以上这几个步骤为技能创建后必须动作"—— 创建只是第一步,引用网络/测试/审计/上传是必须动作,不是可选。
🚨 Pitfall: GitHub push 代理超时
git push 通过 HTTP 代理经常超时(尤其 WSL/Windows 环境),原因是
credential manager 交互式认证卡住。解法:用 gh auth token 嵌入 URL。
cd /tmp/awesome-skills
TOKEN=$(gh auth token)
git remote set-url origin "https://用户名:${TOKEN}@github.com/用户名/仓库.git"
git push origin main
此方式绕过 credential manager,推送立即成功。推送后记得清理 URL 避免 token 残留。