Skill Learning

writing-for-agents

1. Bilingual SKILL.md

左右滑动可直接切换英文版与中文版;两种语言按段落自动对齐。英文中的蓝色虚线词语可点击查看解释。共标记 25 处。

入口 skill:writing-for-agents左右滑动切换语言 · 段落位置自动对齐
Reference for writing any document an agent consumes: a skill, an `AGENTS.md` / `CLAUDE.md`, a doc reached by a pointer. The packaging differs; the writing does not: the same levers make each one predictable, since the agent takes the same _process_ every run rather than producing the same output.
When the document you're writing is a skill, read [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md) for frontmatter, invocation choice, and router skills.
## s
A **** is a reference held in the agent's context that names some out-of-context material and encodes the condition for reaching it. A skill's description is one; a line in `AGENTS.md` naming a doc is the same object. The pointer's _wording_, not its target, decides when the agent reaches the material, and how reliably. A must-have target behind a weakly worded pointer is a : sharpen the wording first, and inline the material only if sharpening fails.
A pointer does two jobs: state what the material is, and list the **branches** that should trigger reaching it (a branch is a distinct case the document handles, so different runs take different paths through it). Every word of an always-loaded pointer costs on every turn, so it earns even harder pruning than the body:
- ****: the pointer is where it does its triggering work. - **One trigger per branch.** Synonyms that rename a single branch are one branch written twice; collapse them and keep only genuinely distinct branches. - **Cut identity the body already carries.**
## The two loads
Every document and pointer you add spends one of two budgets:
- **** is the cost of always-loaded material on the agent's window: an `AGENTS.md` line, a skill description, anything sitting in context every turn, spending tokens and attention whether or not it fires. - **** is the cost on the human: which documents exist and when to reach for each. The human is the index. Not a cost to minimise: it is the price of human agency; spend it where human judgement matters, remove it where it does not.
Material reached only through a pointer escapes at the price of the pointer's own line; material with no pointer at all rides entirely on .
##
A document is built from two content types: **steps** (the ordered actions the agent performs) and **reference** (definitions, rules, facts consulted on demand). The two mix freely: all steps (a recipe), all reference (a review's rules, this skill), or both. The core decision is where each piece sits on the ****, a ladder ranked by how immediately the agent needs the material:
1. **In-file step** is the primary tier: what the agent does, in order. 2. **In-file reference** is consulted on demand. Often a legitimately flat peer-set (every rule of a review on one rung), which is a fine arrangement, not a smell. 3. **Disclosed reference** is pushed out into a separate file, reached by a , loaded only when the pointer fires. Spans a sibling file in the same folder through fully external reference that lives anywhere and any document can point at.
Push too little down and the top bloats; push too much and you hide material the agent actually needs. That tension is the whole decision.
**** is the move down the ladder (out of the main file and behind a pointer) so the top stays legible. Not primarily a token optimisation: it is how the hierarchy is protected. Branching is the cleanest disclosure test: inline what every branch needs, and push behind a pointer what only some branches reach. When a document has steps, in-file reference that should be disclosed buries them and turns attending to them into a coin-flip: a variance lever, not just a legibility one.
**** is the within-file companion: where the ladder decides _how far down_ a piece sits, decides _what sits beside it_ once there. Keep a concept's definition, rules, and caveats under one heading rather than scattered, so reading one part brings its neighbours with it. The test: the document should read like documentation written for the agent. Grouped material reads that way; scattered material does not. (Distinct from duplication: that repeats one meaning in two places; scattering fragments one meaning across many.)
**Sprawl** is the failure mode here: a document simply too long, even when every line is live and unique. Attention thins across the excess, and every extra line is one more to keep relevant. The cure is the ladder: disclose reference behind pointers, and split by branch or sequence so each path carries only what it needs.
## Steps and completion criteria
Every step ends on a ****, the condition that tells the agent the work is done. Two properties make it a lever:
- **Clarity**: can the agent tell done from not-done? A vague bound ("understanding reached") invites ****: ending the step before it is genuinely done, attention slipping to _being done_. The visible steps still ahead (the **post-completion steps**) supply the pull; the criterion's clarity is the resistance. Defend in order: **sharpen the bound first** (local and cheap); only if it is irreducibly fuzzy _and_ you observe the rush, hide the later steps by splitting the sequence. Hiding only works across a real context boundary (a hand-off or a subagent dispatch; an inline call leaves the later steps in context and clears nothing). - **Demand**: how much it requires. "Every modified model accounted for" forces thorough work where "produce a change list" does not. Demand drives **legwork** (the digging the agent does within the work, latent in the wording rather than written as its own step), and it is not step-bound: "every rule applied" binds a body of flat reference just as "every step done" binds a sequence, which is how an all-reference document still carries an exhaustiveness bar.
The strongest criteria are both checkable and exhaustive.
## When to split
Splitting one document into two spends one of the two loads, so split only when the cut earns it:
- **By sequence**: split a run of steps where the post-completion steps tempt the agent to rush the one in front of it. Keeping them out of view drives more legwork on the current task. Beware the reverse: merging sequences exposes each step's later steps to what follows, inviting . - **By invocation**, skill-specific: see [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md).
## s
A **** is a compact concept already living in the model's pretraining that the agent thinks with while running the document (_lesson_, _fog of war_, _tracer bullets_). Repeated as a token, never as a sentence, it accumulates a distributed definition and anchors a whole region of behaviour in the fewest tokens, by recruiting priors the model already holds. Coining your own works if you define it clearly, but a made-up word recruits no priors: you pay in definition tokens what a pretrained word gives free; reach for an existing word first.
It anchors twice. In the body, _execution_: the agent reaches for the same behaviour every time the word appears, and inside flat reference it focuses attention on a class of thing to look for. In a pointer, _invocation_: when the same word lives in your prompts, your docs, and your codebase, the agent links that shared language to the material and reaches it more reliably.
Hunt for opportunities to refactor with s. A triad spelled out at three sites, a pointer spending a sentence to gesture at one idea. Each is a passage begging to collapse into a single token:
- "fast, deterministic, low-overhead" → _tight_ (a _tight_ loop). - "a loop you believe in" → _red_, turning a fuzzy gate into a binary observable state (the loop goes _red_ on the bug, or it doesn't).
You win twice: fewer tokens, and a sharper hook for the agent to hang its thinking on. Assume every document is carrying restatements that s retire. Go find them.
**Negation** is the failure mode beside this lever: steering by prohibition drags the forbidden behaviour into context and makes it _more_ available, not less. _Don't think of an elephant_, and the elephant is all there is; the negation is a weak modifier the strongly-activated concept overruns, so the ban half-reads as an instruction to do the thing. Prompt the **positive**: state the target behaviour ("write one-line comments") so the banned one is never spoken. A prohibition earns its place only as a hard guardrail you cannot phrase positively; even then, pair it with the positive target so attention lands on what to do.
## Pruning
- Keep each meaning in a ****: one authoritative place, so changing the behaviour is a one-place edit. **Duplication** (the same meaning in more than one place) costs maintenance and tokens, and inflates a meaning's prominence on the ladder past its real rank. (The accidental inverse of a , which repeats a token on purpose, never the meaning.) - The **environment** is a source of truth too (`package.json` scripts, config files, the directory layout, `--help` output), and a document that restates it is a **cache**: a copy of a lookup, earning its load only when the lookup is expensive. Cache what the agent cannot find by looking: the unwritten convention, the reason behind a choice, the gotcha no config confesses. Leave the one-file, one-command lookups to the environment, where they cannot go stale. - Check every line for **relevance**: does it still bear on what the document does? A line loses relevance by never bearing on the task (mere exposition, or a branch that should be disclosed) or by going stale as the behaviour or world it describes changes. Shorter documents are easier to keep relevant. Without a pruning discipline the default fate is **sediment**: stale layers that settle because adding feels safe and removing feels risky, until you must core down through them to find what is still live. - Hunt **** sentence by sentence: an instruction the model already obeys by default pays load to say nothing. The test (does it change behaviour versus the default?) is model-relative, not reader-relative: two people disagreeing about a no-op disagree about the default, and settle it by running the document, not by debate. When a sentence fails, delete the whole sentence rather than trim words from it. The test also grades s: a word too weak to beat the default (_be thorough_ when the agent is already thorough-ish) is a no-op, and the fix is a stronger word (_relentless_), not a different technique.
这是一份关于如何编写智能体所消费的任何文档的参考:skill、`AGENTS.md` / `CLAUDE.md`,以及通过指针抵达的文档。它们的封装方式不同,写法却相同:同一组杠杆让每一种文档都可预测,因为智能体每次运行时采用相同的_过程_,而不是产出相同的结果。
当你正在编写的文档是 skill 时,请阅读 [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md),了解 frontmatter、调用方式选择和路由 skill。
## 上下文指针
**上下文指针(context pointer)**是智能体上下文中保存的一条引用:它指出某份位于上下文之外的材料,并编码抵达该材料的条件。skill 的 description 就是一种;`AGENTS.md` 里点名某份文档的一行也是同一种对象。决定智能体何时抵达材料以及抵达得多可靠的,是指针的_措辞_,而不是它的目标。必需材料若藏在措辞薄弱的指针后面,就是一个方差缺陷:先让措辞更精准,只有精准化仍无效时才把材料内联。
一个指针做两件事:说明材料是什么,并列出应该触发读取它的**分支**(分支是文档所处理的一种独立情形,因此不同运行会沿着不同路径经过它)。常驻加载的指针中,每个词都会在每一轮付出成本,所以它比正文更值得严厉删减:
- **把引导词放在最前面**:指针正是在这里完成触发工作。 - **每个分支只留一个触发条件。** 只是给同一分支换名的同义词,相当于把一个分支写了两遍;将其合并,只保留真正不同的分支。 - **删掉正文已经携带的身份信息。**
## 两种负载
你添加的每一份文档和每一个指针,都会花费以下两种预算之一:
- **上下文负载(Context load)**是常驻材料占用智能体上下文窗口的成本:`AGENTS.md` 中的一行、skill 的 description,以及每轮都位于上下文里的任何内容;无论是否触发,它都消耗 token 和注意力。 - **认知负载(Cognitive load)**是人类承担的成本:要记住有哪些文档,以及何时该找到每一份。人类就是索引。它不是需要最小化的成本,而是人类自主性的代价;在人类判断重要之处投入它,在不重要之处移除它。
仅通过指针抵达的材料,以指针自身一行的代价避开上下文负载;完全没有指针的材料,则完全依赖认知负载。
## 信息层级
一份文档由两类内容组成:**步骤**(智能体按顺序执行的动作)与**参考资料**(按需查阅的定义、规则和事实)。两者可以自由组合:全是步骤(配方)、全是参考资料(评审规则、本 skill),或二者兼有。核心决策在于每一项内容处于**信息层级(information hierarchy)**的哪一层;这是一架按照智能体需要材料的即时程度排序的梯子:
1. **文件内步骤**是首要层:智能体按顺序做什么。 2. **文件内参考资料**按需查阅。它常常可以是一组合理扁平的同级内容(例如某项评审的所有规则都在同一层),这种安排完全正常,并非坏味道。 3. **披露式参考资料**被推到单独文件中,通过上下文指针抵达,且只在指针触发时加载。它既可以是同一目录中的兄弟文件,也可以是位于任何地方、供任何文档指向的完全外部参考资料。
向下推得太少,顶部就会膨胀;推得太多,又会把智能体真正需要的材料藏起来。整个决策就在这股张力之中。
**渐进披露(Progressive disclosure)**是沿梯子向下移动内容(移出主文件并放到指针后面),让顶层保持清晰。它首先不是 token 优化,而是保护信息层级的方法。分支是最干净的披露测试:每个分支都需要的内容内联,只有部分分支才会抵达的内容放到指针后。当文档包含步骤时,本应披露出去的文件内参考资料会掩埋步骤,让是否注意到步骤变成抛硬币:这不仅影响可读性,更是控制方差的杠杆。
**共置(Co-location)**是文件内部的配套原则:信息梯子决定一项内容要放到_多靠下_的位置,而共置决定它到了那里以后_旁边放什么_。把一个概念的定义、规则和注意事项放在同一个标题下,不要四处分散;这样读到其中一部分时,也会一并带出相邻部分。检验方法是:文档读起来应该像专门为智能体写的文档。成组材料有这种感觉,散落材料则没有。(这不同于重复:重复是在两处复述同一个含义;散落则把同一个含义拆碎到多处。)
**蔓延(Sprawl)**是这里的失败模式:即使每一行都仍然有效且独一无二,文档本身还是过长。注意力会在过量内容中变稀,每增加一行,就多一行需要持续保持相关。解决办法仍是这架梯子:把参考资料披露到指针后,并按分支或顺序拆分,使每条路径只携带它需要的内容。
## 步骤与完成标准
每个步骤都以一项**完成标准(completion criterion)**结束,它是告诉智能体工作已经完成的条件。两项性质让它成为杠杆:
- **清晰度**:智能体能否区分完成与未完成?模糊边界(“已经理解”)会诱发**过早完成(premature completion)**:步骤尚未真正完成便结束,注意力滑向_赶紧完成_。前方仍然可见的步骤(**完成后的步骤**)提供拉力,而标准的清晰度提供阻力。防守顺序是:**先收紧边界**(局部且成本低);只有当边界确实无法消除模糊,_并且_你观察到赶工时,才通过拆分序列来隐藏后续步骤。隐藏只有跨越真实上下文边界才有效(交接或子智能体派发;内联调用仍把后续步骤留在上下文中,什么也没有清掉)。 - **要求强度**:它要求做到什么程度。“每个修改过的模型都已交代清楚”会迫使工作更彻底,而“生成变更列表”不会。要求强度驱动**跑腿深挖(legwork)**,即智能体在工作内部进行的挖掘;它潜藏在措辞里,而不是单独写成一个步骤。它也不受步骤限制:“每条规则都已应用”可以约束一组扁平参考资料,就像“每个步骤都已完成”约束一个序列;因此,全参考型文档仍然可以携带穷尽性门槛。
最强的标准既可检查,又穷尽完整。
## 何时拆分
把一份文档拆成两份会花费两种负载之一,因此只有当切分值得时才拆:
- **按顺序拆分**:当完成后的步骤诱使智能体赶着做完眼前步骤时,就拆开这一串步骤。让后续步骤离开视野,会促使智能体在当前任务上做更多深挖。也要警惕反面:合并序列会让每个步骤都看见接下来发生什么,从而诱发过早完成。 - **按调用方式拆分**(skill 专属):见 [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md)。
## 引导词
**引导词(leading word)**是一个已经存在于模型预训练中的紧凑概念,智能体运行文档时会用它思考(如 _lesson_、_fog of war_、_tracer bullets_)。把它作为一个 token 反复使用,而不是反复写整句,它就会积累出分布式定义,并借助模型已有先验,用最少 token 锚定整片行为。你也可以自造词,但必须清楚定义;自造词无法调动先验,你需要用定义 token 支付预训练词免费提供的东西。因此先寻找现有词。
它会锚定两次。在正文中锚定_执行_:每当该词出现,智能体都会调用同一种行为;在扁平参考资料中,它会把注意力聚焦到一类要寻找的对象。在指针中锚定_调用_:当同一个词出现在提示词、文档和代码库里时,智能体会把这套共享语言与材料连接起来,从而更可靠地抵达材料。
主动寻找用引导词重构的机会:在三个位置反复拼写的三元组,或用一整句话含糊指向一个想法的指针。每一处都是在请求压缩成一个 token:
- “快速、确定、低开销” → _tight_(一个 _tight_ 循环)。 - “一个你信得过的循环” → _red_,把模糊门槛变成二元可观察状态(循环能因该 bug 变成 _red_,否则不能)。
你会赢两次:token 更少,智能体挂接思考的钩子更锋利。假设每份文档里都有可以被引导词淘汰的重复表述。去把它们找出来。
**否定式表达(Negation)**是这个杠杆旁边的失败模式:用禁令引导会把被禁止的行为拖进上下文,使它变得_更_容易出现,而不是更少。_不要想一头大象_,结果脑中只剩大象;否定只是一个弱修饰语,会被强烈激活的概念压过去,于是禁令有一半读起来像是在要求执行那件事。要提示**正向目标**:直接说明目标行为(“写单行注释”),让被禁止的做法根本不被说出口。只有无法改写为正向形式的硬性护栏才值得保留禁令;即便如此,也要搭配正向目标,让注意力落在应该做什么上。
## 修剪
- 让每个含义都保存在一个**单一事实来源(single source of truth)**中:一个权威位置,使行为变更只需改一处。**重复(Duplication)**把同一个含义放在多处,会增加维护成本和 token,并把该含义在信息梯子上的显著程度抬高到超过真实级别。(它恰好是引导词的意外反面:引导词有意重复一个 token,而从不重复含义。) - **环境**也是事实来源(`package.json` 脚本、配置文件、目录布局、`--help` 输出);重复环境内容的文档就是一份**缓存**:它复制了一次查询,只有查询代价很高时才值得承担负载。应当缓存智能体无法通过查看找到的东西:未成文的约定、某项选择背后的原因、任何配置都不会坦白的坑。单文件、单命令即可查到的内容留在环境中,那里不会过时。 - 检查每一行的**相关性**:它是否仍然关系到文档所做的事情?一行内容可能因为从未关系到任务(只是阐述,或本应披露出去的分支)而失去相关性,也可能因其描述的行为或世界已经变化而过时。较短文档更容易保持相关。没有修剪纪律时,默认结局就是**沉积物(sediment)**:陈旧层不断沉降,因为添加让人安心,删除让人不安,最终你必须像取岩芯一样一路钻下去,才能找到仍然有效的东西。 - 逐句寻找**无效指令(no-ops)**:如果模型默认已经会遵守某条指令,写下它只会付出负载却什么都没改变。检验问题是“相比默认行为,它是否改变了行为?”;这取决于模型,而不是读者。两个人对一条指令是否无效有分歧,本质是在争论默认行为,应通过运行文档来解决,而不是辩论。当一句话检验失败时,删除整句,不要只是修短。这个检验也能评估引导词:如果一个词弱到无法胜过默认行为(智能体本来就还算仔细,却只说 _be thorough_),它就是无效指令;修复方法是换成更强的词(_relentless_),而不是换一种技巧。

Entry SHA-256: 551adca942227b44192edba88acd4e8db911f0121ce58ad16944ccf6a896a74a

2. Why This Skill Is Clever

一句话核心机制

把“为智能体写文档”建模为一组可调杠杆:用指针控制加载,用信息层级保护注意力,用可检查的完成标准控制工作深度,再持续删除重复、陈旧内容和无效指令。

触发与边界

直接来源。 frontmatter 把触发边界写得很宽但很具体:Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md. 它适用于任何被智能体消费的文档,而不只是 SKILL.md。

直接来源。 当任务确实是写 skill 时,入口文件只把 skill 特有机制指向 SKILL-MECHANICS.md,没有把 invocation 与 router 细节复制进正文。因此本报告的原文只展示当前 SKILL.md;兄弟文件仅作支持性背景,不冒充所选原文。

解释。 这个 skill 是“参考型规范”,不是自动执行某个固定流程的 recipe。它提供判断框架,最终切分位置、措辞强度和负载交换仍需要作者判断。

信息架构 / 执行顺序

  1. 先识别入口。 通过 context pointer 明确“材料是什么、哪些分支应加载它”。
  2. 再算两种成本。 在 Context load 与 Cognitive load 之间做显式交换。
  3. 把内容放上梯子。 区分 in-file step、in-file reference 与 disclosed reference。
  4. 为动作设终点。 用清晰度与要求强度构造 completion criterion。
  5. 决定是否拆分。 只有按顺序或按调用切开能真正赚回负载时才拆。
  6. 压缩行为语言。 用已有先验的 leading word 替代重复解释,并优先写正向目标。
  7. 最后修剪。 保持 single source of truth,信任可直接查询的环境,并删除 sediment 与 no-ops。

最巧妙的设计点

1. 指针的措辞就是可靠性接口

The pointer's wording, not its target, decides when the agent reaches the material

直接来源。 作者把“链接到了正确文件”与“智能体会在正确时机读取它”分开。指针必须同时声明对象和触发分支;弱措辞会成为 variance bug。

解释。 这把常被当作文案问题的 description 提升为控制流接口:链接正确只是静态正确性,触发措辞才决定运行时可靠性。

2. 两种负载让“该不该内联”不再凭感觉

Every document and pointer you add spends one of two budgets

直接来源。 常驻材料花 context load;没有自动入口的材料花 cognitive load。作者甚至明确说人的认知负载“不应一味最小化”,因为它是人类自主判断的价格。

解释。 这个双预算模型避免一种常见优化偏见:只盯 token,就会把材料拆得人类无法发现;只求方便,又会让每轮上下文膨胀。

3. 渐进披露首先是注意力工程

Not primarily a token optimisation: it is how the hierarchy is protected.

直接来源。 分支测试决定哪些内容内联:所有分支都要用的留在主文件,只有部分分支需要的放到指针后面。

解释。 这比“长了就拆文件”更强。拆分依据不是长度,而是执行路径;其目标是防止参考资料把步骤埋住,降低同一提示在不同运行间的方差。

4. 完成标准同时控制可检查性与深挖强度

The strongest criteria are both checkable and exhaustive.

直接来源。 Clarity 防止智能体无法区分 done / not-done,Demand 则决定它要做多少 legwork。模糊标准先局部收紧,只有观察到真实赶工且边界无法澄清时,才用上下文切分隐藏后续步骤。

解释。 这里没有把“更认真”写成空泛要求,而是把认真程度编码进结果边界,例如 Every modified model accounted for。这是可复用的质量控制方法。

5. 引导词是一种调用模型先验的压缩算法

Repeated as a token, never as a sentence

直接来源。 leading word 既在正文中锚定执行,又在指针中锚定调用;优先选择预训练中已有的概念,因为自造词需要额外定义成本。

解释。 精妙之处不在“少写几个词”,而在少量 token 同时提高一致性与检索率。它刻意区别于 duplication:重复的是词形钩子,而不是整段含义。

6. 环境也被纳入单一事实来源

a document that restates it is a cache

直接来源。 package.json、配置、目录和 --help 都是可查询的权威事实。文档只有在查询昂贵时才值得缓存它们;真正应该记录的是无法直接查到的约定、原因和坑。

解释。 这条规则主动切断文档漂移来源:不要维护一份迟早过时的命令副本,让智能体去读不会撒谎的运行环境。

防失败机制与 trade-off

可迁移原则

  1. 把 description 和 AGENTS.md 中的引用当作控制流接口来测试,而不是普通说明文字。
  2. 拆文件前先标出分支:全路径共用的内联,局部分支需要的披露到指针后。
  3. 每个步骤都写一个既可检查又穷尽的完成标准,用结果边界驱动深挖。
  4. 让配置、目录和 --help 承担可直接查询的事实,文档只解释原因、约定和隐藏陷阱。
  5. 用目标模型做 A/B 运行来识别 no-op;不要靠作者之间争论“这句话看起来有没有用”。

今日实践题

选你现在一份 AGENTS.md:找出一条指向外部文档的句子。它是否同时说清了“材料是什么”和“哪几个不同分支必须读取它”?如果没有,请用一个前置的 leading word 重写它,并删掉同一分支的同义触发词。

Evidence note

Source & provenance
Repository path
skills/productivity/writing-for-agents/SKILL.md
Generated
2026-08-28 11:28 Asia/Shanghai
Upstream commit
6654f6b60cd9d5be8b54c6fafe44346dabeb3b76
Source
View on GitHub