关于 writing-skills
writing-skills 是用于编写和修改 Agent 技能的技能,采用测试驱动的流程文档方法。它帮助作者依据实际失败制定规则,并设计清晰、精简且易于发现的技能说明。
主要功能
- 01先测试再编写技能
- 02依据失败设计规则
- 03技能描述编写指引
- 04术语与重复内容检查
- 05拆分技能的判断标准
适用场景
- 01创建新的 Agent 技能
- 02根据观察到的失败修改技能
- 03检查技能的描述与结构
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jayden-dang/ skills --skill writing-skills安装后在 Claude Code 中输入/writing-skills确认已加载。
附带文件influence-principles.mdpressure-testing.md
详细介绍
编写技能
技能为何存在
技能旨在从随机系统中梳理出确定性。最根本的优点是可预测性:Agent 每次运行都采用相同的过程,而不是生成完全相同的输出。头脑风暴技能应当稳定地产生不同结果;其 token 会变化,行为不会变化。本文档中的每条规则都是提升可预测性的杠杆。
铁律
NO NEW SKILL AND NO EDIT TO A SKILL SHIPS WITHOUT A FAILING TEST FIRST
编写技能就是将测试驱动开发应用于流程文档。其循环如下:
- RED — 观察失败。 在不使用技能的情况下运行场景(编辑时:使用当前版本)。逐字记录确切的失败和自我开脱——它们定义了文本必须防止什么。如果基线 Agent 没有失败,就停下来:没有需要修复的问题,而没有失败依据的文本毫无作用。
- GREEN — 编写最少文本。 编写能够解决已记录失败的最少技能文本——不要处理假设性问题。使用技能重新运行同一场景。若未遵循要求,说明文本不清楚:修改后重新运行。
- REFACTOR — 堵住漏洞。 面临压力时,Agent 会编造新的自我开脱。逐字记录每条说辞,添加明确的反制规则,并重新测试。不断重复,直到技能在最大压力下仍然有效。
如果你在运行基线之前就写好了文本,那记录的只是你猜测 Agent 会犯的错,而不是它们实际犯的错。现在就运行基线,在此之前不要保留任何文字。
测试方法——场景构建、压力类型、微测试、描述触发、非门槛(技巧/参考)测试和元测试——见本文件旁的 pressure-testing.md。促使 Agent 遵循要求的措辞技巧见 influence-principles.md。
根据失败类型选择形式
写作前先对基线失败分类;能有效修复一种失败类型的形式,可能会明显加剧另一种问题。
| 基线失败 | 应编写 | 不应编写 |
|---|---|---|
| 知道规则,却在压力下违反规则 | 硬性禁令 + 自我开脱对照表(想法 → 现实)+ 危险信号列表 | 语气委婉的“最好/考虑”类指导 |
| 遵循了要求,但输出形式不正确 | 正向范例或契约:明确说明输出是什么——包含哪些部分,以及顺序如何 | 禁令。面对相互竞争的激励,Agent 会用“不要做 X”讨价还价;在措辞对照测试中,禁令组生成的不需要内容甚至比完全没有指导时更多。范例不留讨价还价的余地 |
| 漏掉了原本会生成的某个要素 | 在其填写的模板中加入一个必填项 | 在模板附近用行文提醒 |
| 行为应取决于某个条件 | 由可观察谓词触发的条件规则(“如果存在 design.md,就引用其中的接口缝隙”) | 无条件规则加豁免条款 |
| 绝不能跳过或误判的检查 | 提供一套确定性基础操作,让技能引导 Agent 执行并读取结果——固定的 grep/git/schema 检查流程,以及对其输出的固定规则(参见 trace) | 抽象地描述检查的行文——“确认覆盖范围”会引发自行解释;对指定输入执行指定检查并规定结果的处理方式,则不会 |
不要添加细微差别条款。“除非确有必要,否则不要做 X”会重新开启规则刚刚结束的协商——在奏效的范例后追加一条细微差别条款,会让它从稳定有效退化为嘈杂不定。真正的例外应当作为独立条件,以可观察谓词为依据。豁免条款同样无法限定范围:“代码块不受此限制”仍会抑制代码块;应调整结构,让规则无法触及豁免部分。
Frontmatter 和命名
description说明触发条件 + 结果,绝不描述工作流。 指明该技能产出的交付物(结果名词——“tasks.md实施计划”“双轴评审结论”),以及它何时触发;绝不要概述步骤。流程摘要会让 Agent 走捷径,只遵循摘要而不阅读正文:“在设计获批且需要编写tasks.md计划时使用”会促使 Agent 阅读正文;“在规划时使用——在各任务之间派遣评审者”则会让 Agent 只遵循摘要、忽略正文。这就调和了外部规则的两部分(说明它做什么和何时使用)与跳过正文的问题——结果名词可在众多技能中区分该技能,而步骤列表才是隐患。要描述作为结果的“做什么”;不要描述作为工作流的“做什么”。- 动词优先的名称:
writing-skills、receive-review、debug——命名动作,而不是主题。 - 覆盖关键词:在描述中加入 Agent 或用户实际会搜索或想到的词——症状、具体错误文本(
error、exception、e2e、tech debt)、工具和文件名(tasks.md),以及同义词(spike、mock up)。发现依赖关键词匹配;找不到的技能就等于不存在。结果名词在此也能一举两得。 - 两个失败方向,都要经过测试,而不是靠猜测。 过度概述会导致上述失败;更常见的是规格不足——技能根本不会触发。关键词覆盖和结果名词可以避免后一种问题;省略工作流步骤则可以避免前一种问题。描述是技能中杠杆作用最高的一行,也是唯一不能凭直觉判断的字段——按照
pressure-testing.md对它进行触发测试。 - 项目约定——有意偏离通用指南,以支持自调用。 描述以第二人称开头(“Use when…”),因为这句话是直接写给作出判断的 Agent 的指令;不可跳过的内容使用
## Red Flags、## The Iron Law或<NON-NEGOTIABLE>区块,这是项目约定中与通用## Critical标题等效的写法。整个技能集应保持一致——混用风格的异类是偏差,不是多样性。 - 用户调用的技能设置
disable-model-invocation: true——因此它们不能自动调用,而且任何技能正文都不得告诉 Agent 去调用此类技能。只有把技能名称告知用户让其运行(/handoff、/release),才能将任务移交给用户调用的技能;REQUIRED SUB-SKILL: use \x`仅适用于模型可调用的目标。指示 Agent 调用设置了disable-model-invocation` 的技能会导致移交无路可走——这是实际的错误,而不只是风格问题。 - 两类描述受众,以上规则全都针对面向模型的描述。 模型可调用技能的描述负责路由:应包含关键词覆盖、症状词和结果名词。
disable-model-invocation描述不负责路由——Agent 根本看不到它,用户通过输入技能名称来找到技能。此类描述应写成一句面向用户的简单说明,指出交付物。在用户调用的技能描述中堆砌关键词,只会写出没人会读的文字;“发现仍取决于用户输入的词”并不成立——用户输入的是名称。
词汇表
编写技能时使用这些术语;审核技能时也要对照这些术语。
- 引导词 — 模型从预训练中已掌握的简洁概念(“seam”“tracer bullet”“red”),能用几个 token 为整片行为区域定下基调。作为 token 重复出现时,它会在技能中逐步累积出分布式定义;三个句子的重述往往可浓缩为这样一个词。新造的词没有可借用的先验知识——优先选用预训练中已有的词。
- 完成标准 — 每个步骤都以 Agent 能检查的条件结束(“测试套件通过,输出无瑕”,而不是“测试看起来不错”)。这是防止过早完成的保障:界限模糊,会让注意力从工作本身滑向“赶紧做完”。
- 无操作测试 — 这句话相较于完全没有技能时,能改变行为吗?一句话可以正确、相关,却仍然毫无作用(“要小心”)。默认行为究竟是什么,不能靠争论决定,而要通过运行场景来确定。无法通过测试的句子,应整句删除,而不是删减。
- 重复表述 — 同一个意思在多个地方出现。它与引导词有意为之的做法恰好相反:引导词重复的是 token,以集中注意力;重复表述重复的是 含义,因此改变行为时就得在多个地方修改,而且重述的规则读起来会比其实际级别更重要。无操作排查发现不了它——每个副本都有效,单独看也能通过——所以要单独排查:为每条规则指定唯一归属处,并删除或替换其他所有表述,改为指向该处。规定的门槛形式不在此列:
## Red Flags项目符号或合理化理由表中的行会有意回响其规则,作为失败表所要求的反例——它是该规则的症状,而非规则的第二个归属处。只有当两处都是普通正文时,重述才算重复表述。 - 否定陷阱 — 禁令会把被禁止的行为带入上下文,让它读起来有几分像指令。应改用正向提示(“写一行注释”),这样就不会提到被禁止的模式。唯一例外是压力门槛技能,此时严格禁令加明确反例正是恰当的工具——见上方失败表。
- 信息层级 — 技能内的步骤,其次是技能内的参考资料,再其次是通过上下文指针披露的参考资料。每次运行都需要的内容应内嵌;只有某些分支会用到的内容,则放在指针后面。指针的 措辞 而非目标,决定了材料是否会被加载——必读文件若藏在含糊的指针后面,就是一个变化性缺陷:先强化指针,再内嵌内容。参考文件应与 SKILL.md 最多相隔一层(只能通过另一个文件访问的文件会被略读,而不是阅读);任何超过约 100 行的参考文件,都应在顶部添加目录。
- Token 预算 — 注入会话的技能应保持精简:每个 token 都会在每轮付出成本。三个加载层级决定预算:元数据(名称 + 描述,约 100 个 token)在每个会话的每一轮都会付出成本;正文在技能触发后,会在每一轮付出成本;参考文件则只有在其指针被跟随时才产生成本。规范类技能的核心正文应控制在约 500 词以内(表格和代码块除外);任何 SKILL.md 正文的硬上限为 约 500 行 / 5k 词——超过后,应将细节拆出并放到指针后面。篇幅本身就是一种失败模式,即使每一行都有用也不例外。
什么时候完全不该写
机械可检查的规则并不意味着可以跳过技能,而是意味着应该让技能执行检查,而不是描述检查。当仓库已有常驻检查器(预先配置的 linter、CI schema 检查、git hook)时,技能只需指出它并读取结果。如果没有——这是常见情况,因为这套工具不会向使用它的仓库安装任何东西——技能就应附上确定的操作步骤:Agent 要运行的精确 grep/git/schema 检查,以及针对其输出的精确规则。技能绝不能只是冗长地重述那些检查已编码的规则。文档应把上下文预算用于检查无法做出的判断;确定性的部分应写成精确的检查步骤,而非散文。
何时拆分
只在以下两种情况下拆分技能:
- 触发条件确实不同。 独立的条件或开头词应能单独触发它,或者另一个技能必须能独立调用它。
- 隐藏后续步骤。 后续步骤明显会诱使 Agent 仓促完成当前步骤,而拆分能把它们放到真正的上下文边界之后——子技能交接或子 Agent 调度。行内提及仍会让它们留在上下文中,什么也隐藏不了。
除此之外的拆分都是为了拆分而拆分,只会增加上下文负担或占用用户的记忆。
示例
一个出色的完整示例胜过许多平庸示例:示例应完整、可运行、注释说明 WHY,取自真实场景,并使用最相关的一种语言。不要将它移植到五种语言,也不要把它掏空,改成填空模板。
交叉引用
将这套工具中的其他技能作为散文引用——REQUIRED SUB-SKILL: use \verify``——绝不要链接到其他技能文件夹中的文件。链接会强制加载内容,并使文件夹相互耦合。与自己的 SKILL.md 同目录的文件应使用相对文件名引用,并说明何时加载。
自我安慰
| 想法 | 事实 |
|---|---|
| “这项技能显然很清楚” | 作者的视角永远不能算数。运行它 |
| “这只是个小改动” | 技能和代码一样会因编辑而退化。先与旧版本对比 |
| “测试文档太小题大做了” | 未经测试的技能会在生产环境中失效,每次失效都会耗费整个会话 |
| “通读一遍基本就等于测试了” | 阅读衡量的是流畅度,不是行为。只有实际运行才能回答无操作测试的问题 |
| “出了问题我再修” | Agent 会悄悄忽略技能,于是问题就出现了。你永远看不到这种失效 |
| “批量处理多个技能效率更高” | 一批未经测试的技能,就是一批未经测试的代码 |
部署检查清单
为每个项目创建一个待办事项。
RED
- 根据
pressure-testing.md编写压力场景(门控技能需包含 3 种以上组合压力) - 列出模型清单;在技能将部署到的每个模型上运行基线测试,并为每份对话记录标注其模型
- 在不使用该技能(或使用旧版本)的情况下运行基线测试;逐字记录失败情况和合理化说辞
- 基线测试确实失败了——否则请停止,没有内容需要编写
GREEN
- 对失败进行分类;采用与之匹配的形式(禁止事项集合/操作指南/REQUIRED 槽位/可观察条件)
- 描述 = 触发条件 + 结果名词,不包含工作流步骤;名称以动词开头;包含用户会输入的字面关键词
- 对描述进行触发测试:运行应触发/不应触发的查询,并检查两个方向(根据
pressure-testing.md) - 仅编写解决已记录失败所需的最少文本;最多提供一个完整示例
- 对清单中的每个模型重新运行测试并启用该技能:最弱的模型也能遵守要求
REFACTOR
- 明确应对新的合理化说辞;构建合理化说辞表和危险信号清单(用于门控技能)
- 对塑造行为的措辞进行微测试:设置无技能对照组、每个样本使用全新上下文、至少进行 5 次重复测试,并手动阅读每份标记出的对话记录
- 完成元测试:经测试的 Agent 确认文本清晰,并指出没有任何内容能让遵守要求变得更容易
- 反复重新测试,直到不再出现新的合理化说辞
交付
- 进行无效内容清查:每句话都通过无效性测试,否则整句删除
- 进行重复内容清查(单独执行此步骤——无效内容清查无法发现重复内容):每条规则只有一个指定位置;删除重复表述,或将其替换为指向指定位置的引用
- 每条
disable-model-invocation描述都应是一行简洁、面向用户的文字——不含触发关键词或症状词 - 核心正文控制在令牌预算内(≤~500 行 / 5k 个单词);通过措辞清晰的引用,以不超过一层的深度指向已披露的参考资料;任何超过 100 行的参考资料都应包含目录
- 交叉引用应使用 REQUIRED SUB-SKILL 正文;通过相对名称引用支持文件
- 每次移交都只能调用可由模型调用的技能;任何
disable-model-invocation目标都应指定由用户运行,绝不能调用 - 结构和路由检查(由 Agent 运行):前置元数据有效(包含 name 和 description;用户调用的技能需设置
disable-model-invocation: true)、名称以动词开头、正文不超过行数限制;并手动对描述进行触发测试——根据pressure-testing.md运行其应触发和不应触发的查询,并确认每个查询都按预期路由
不要批量创建技能。 完整完成、测试并验证一项技能后,再开始下一项。