name: writing-for-agents description: "为 Agent 编写文档。创建或编辑 skill,或修改 AGENTS.md、CLAUDE.md 时使用。"
怎样写出 Agent 真能执行的说明
这篇是驾驭 AI 的核心教材:完成标准、上下文指针、信息层次和删减,比“请认真工作”更能指导行为。
还不清楚 Skill、Agent、安装和调用?先读 从零开始的6节入门课。
在关系图中查看 writing-for-agents 与其他技能的关联 →
先把必要的概念讲清楚
这课讨论如何写让 Agent 更稳定执行的文档。重点不是写得越长或越短,而是把任务、触发条件、信息位置和完成标准安排清楚。它直接帮助你理解 AGENTS.md 与 skill 的关系。
下面是老师补充的入门说明;原作者的要求保留在中英对照正文中。所有例子均为帮助理解而构造的教学情境。
context pointer|上下文资料指引
告诉 Agent 在什么条件下去读哪份材料的短指引。例如“新增或修改数据写入时,先读权限规则文档”。它同时承担地址与触发条件两项作用。只有“见文档”太模糊,可能找不到或不知道何时需要;一股脑放入所有内容又会占用上下文。
context|Agent 当前可用的上下文
模型这一轮实际能使用的请求、对话、指令和已读文件内容。它不是电脑上所有资料,也不是永久记忆。文件存在但没被读到,就不一定参与推理。交接文档应指明当前目标、进度、关键证据位置和下一步,让新会话能够恢复必要背景。
context load / cognitive load|上下文负担与人的认知负担
前者是材料占用模型当前可处理的容量与注意力;后者是人需要记住有哪些工具、何时该用的负担。把所有指令都常驻会增加前者;把所有技能都藏起来靠人记忆会增加后者。目标是合理分配,而非单纯追求文档最短。
frontmatter|Markdown 文件头元数据
文档最前面两条 --- 之间的键值信息,如 name、description。正文讲怎样做事,文件头帮助宿主识别名称、用途和调用方式。保留字段名称是为了维持技术含义,不是要求你熟悉英文;具体支持哪些字段取决于客户端。
acceptance criteria|验收条件
明确规定结果满足什么才算完成,应尽量可观察、可检验。例如“收藏后刷新页面仍可见,重复点击只保留一条”。“体验很好”“代码完善”没有明确边界,难以判断。验收条件关注结果,不是把实现步骤换个标题列出来。
读原文,理解每一步为什么这样做
左右内容按小节对应;窄屏先中文、后英文。两种语言均完整展示,对应讲解紧接在小节之后。译文传达原文要求;老师讲解补充概念、原因、例子与适用边界。
name: writing-for-agents description: Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.
这是一份给 Agent 阅读的文档写作参考,适用于技能、AGENTS.md、CLAUDE.md,以及通过引用找到的其他资料。包装形式不同,写作原则相通:让 Agent 每次遵循稳定的过程,而不是要求每次生成一模一样的结果。
编写技能时,还要阅读 SKILL-MECHANICS.md,了解文件头、调用方式选择和路由技能。
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 for frontmatter, invocation choice, and router skills.
指向其他背景资料的引用
context pointer 是已经进入 Agent 上下文的一段引用。它说明外部还有什么材料,并说明什么情况下应该去读取。技能 description 是一种,AGENTS.md 中指向某份文档的一行说明也是一种。
决定 Agent 何时找到资料、能否稳定找到的,是引用怎样措辞,不只是目标文件写得好不好。重要资料藏在含糊引用之后,会导致有时读、有时不读。先改进引用;仍不奏效时,再考虑把必要内容直接放进入口。
一条引用应说明材料是什么,以及哪些不同情形需要它。始终加载的引用每轮都占用上下文,因此比正文更需要节制:
- 先写最能概括和触发该能力的核心词。
- 每种实际分支只写一种触发说明。多个同义词描述同一分支,只是在重复。
- 删除正文已经承担的身份介绍,保留真正有助于找到材料的内容。
Context pointers
A context pointer 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 variance bug: 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:
- Front-load the leading word: 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.
指引要同时告诉 Agent:读什么,以及什么时候读
假设项目有一份重要权限规则,但 AGENTS.md 只写“可参考其他文档”。Agent 可能不知道何时必须访问它,规则虽然存在,却没有进入实际推理。
可以改为“新增或修改数据写入时,先阅读权限规则文档”。这给出触发条件与目标材料。指针措辞弱时,先改清楚,不必立刻把整份文档复制进全局指令。
分支指文档处理的不同情况。例如新增功能与排查权限错误可能都需要该资料,但“写新功能”和“开发新功能”只是同一触发的换词,不必反复列出。
两种负担
增加文档与引用会使用两种不同资源:
- 上下文负担:AGENTS.md 入口、技能描述等始终可见的材料,每轮都消耗 token 和注意力,无论实际是否使用。
- 人的认知负担:人需要记住有哪些文档、什么时候选哪一个。这里人承担索引作用。作者认为它不应被一概最小化;需要人作判断的地方,这种投入有价值,不需要人判断的地方则应减少。
通过引用按需读取的材料,本身不一直占上下文,但引用仍有成本。完全没有引用的材料,则依靠人记得并主动找到。
The two loads
Every document and pointer you add spends one of two budgets:
- Context load is the cost of always-loaded material on the agent's window: an
AGENTS.mdline, a skill description, anything sitting in context every turn, spending tokens and attention whether or not it fires. - Cognitive load 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 context load at the price of the pointer's own line; material with no pointer at all rides entirely on cognitive load.
省下模型上下文,可能增加人的记忆负担
每轮都加载的规则会占用上下文,即使当前任务完全无关。如果把所有规则拆成隐藏文件,却没有触发指引,人又得记住每份文件在哪里、何时用。
例如常驻只保留项目导航、关键边界和明确触发,具体发布步骤在发布时再读,可以减少无关信息。但某项必须由你决定的选择,不能为了自动化而悄悄消除。
这是一项分配问题:哪些判断交给模型,哪些规则用工具执行,哪些资料按需读,哪些决定需要人。把全局文件删得很短本身并不证明设计更好。
信息放在哪一层
文档包含两类内容:按顺序执行的步骤,以及按需查阅的定义、规则和事实。可以全是步骤、全是参考,也可以混合。关键是按使用的紧迫程度安排位置:
- 主文件里的步骤:直接说明 Agent 按什么顺序做事,是最主要的一层。
- 主文件里的参考:需要时查阅。有些规则天然并列,例如审查清单全部同级,并不构成问题。
- 独立参考文件:由引用引导,只有触发相关条件才读取。可以是同目录文件,也可以是其他位置的资料。
放出去太少,入口会臃肿;放出去太多,Agent 又可能找不到当前必需内容。需要权衡。
逐步披露,就是把并非每次都需要的参考内容移到链接文件,让主流程容易辨认。目的不仅是节省 token,更是保护信息层次。判断办法是看分支:所有分支都需要的留在主文件,只有部分分支需要的放到引用后。否则详细参考可能淹没步骤,使执行变得不稳定。
就近组织则解决同一层内部怎样摆放。一个概念的定义、规则和注意事项应放在同一标题下,让读到一部分时也能看到相邻条件。它与重复不同:重复是在多处说同一个意思,散落是把同一个意思拆到多处。
内容蔓延是另一种问题:即使每行都有效且不重复,文档仍可能太长,导致注意力分散、维护困难。用层次安排解决,按分支或顺序拆开,使每次只携带相关材料。
Information hierarchy
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 information hierarchy, a ladder ranked by how immediately the agent needs the material:
- In-file step is the primary tier: what the agent does, in order.
- 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.
- Disclosed reference is pushed out into a separate file, reached by a context pointer, 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.
Progressive disclosure 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.
Co-location is the within-file companion: where the ladder decides how far down a piece sits, co-location 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.
步骤、就近参考与外置参考,为什么要分层
步骤说明依次做什么;参考说明需要时查的定义、规则和例外。将每一步都塞进大段背景,Agent 可能看不清现在应做的动作。
渐进披露可理解为“需要时再展开资料”。所有分支都需要的内容放正文,只有某一分支需要的详细说明放链接文件。比如所有评审都需要比较范围,只有数据库变更评审才需读迁移细则。
就近组织则解决文件内部的问题:一个概念的定义、限制和例子放一起。你指出旧教材术语难懂,正说明只把定义放远处不够;读到概念时应得到必要解释。
步骤与完成条件
每一步都应以一个能判断是否完成的条件结束。它有两个关键方面。
清晰度:Agent 能否区分完成与未完成?“已经充分理解”这样模糊的标准,容易导致提前宣布结束。后面还有可见任务,会吸引它赶往下一步。先把当前标准说准确,这是较小、较便宜的修正。只有标准确实无法更清楚,而且观察到了抢跑,才拆开顺序,隐藏后续步骤。
隐藏必须发生在真实的上下文切换中,例如交接或独立子 Agent。只在当前会话调用另一个技能,并不会自动清掉仍在上下文里的后续内容。
要求程度:标准要求完成多少工作。“每个修改过的模型都已说明”比“生成改动清单”要求更充分。这样的措辞会推动 Agent 深入查找和核对,不一定要另写一个调查步骤。纯参考文档也可以要求“每条规则都已应用”,因此完整性要求不只适用于步骤列表。
最有力的标准同时可检查,并覆盖所有必要事项。
Steps and completion criteria
Every step ends on a completion criterion, 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 premature completion: 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.
完成标准要能挡住“差不多了就往下走”
“充分理解项目”没有清楚边界,Agent 可能读两份文件就跳到实现。“列出本次涉及的公开接口,并为每个找到现有调用和测试依据”则更可检查。
清晰度回答能否区分做完与没做完;要求强度回答覆盖多少。只说“生成清单”可能漏项,要求“每个修改过的数据结构均已交代影响”会促使主动查探。
但标准越多也可能增加无用流程。应让要求对应真实风险,而不是逐层堆审批。只有实际观察到后续步骤诱使当前工作草率完成,且标准难再明确时,作者才建议通过真实交接边界拆流程。
怎样让“做完了”变成可以核对的结论?
这节与你驾驭 Agent 的目标直接相关。 “认真检查并完成”很难判断;“53 篇正文均有对应译文,原文条件未遗漏,讲解与对应段落匹配,网站可以直接阅读”则可以逐项核对。
假设 AI 只翻了前两段,却生成了漂亮页面。若完成标准只是“做好学习网站”,它可能过早结束。明确每篇范围和可读性要求,才能让界面完成与内容完成分开验证。
context pointer 也可以写得具体:“修改测试时,先读测试入口约定”,比“其他文档见这里”更能说明读取条件。资料放到别处并不自动保证会被读到。
给 Agent 写说明,与给初学者写教材,受众不同。 本篇追求减少重复的运行指令;你的教材需要补足人尚未掌握的背景。不能借“节省上下文”来删掉教学解释。
作者关于某个词、否定表达如何影响模型的说法,是设计经验,不能当成对所有模型都保证成立的定律。应以实际任务行为检验,也不能为避免否定句而删掉必要边界。
什么时候拆文件
拆分会增加前面某一种负担,只有收益值得时才拆。
- 按顺序拆:后续步骤诱使 Agent 草率结束当前步骤时,让后面内容暂时不可见,帮助它集中把当前事情做足。反过来,把原本分开的顺序合并,也可能增加提前结束的倾向。
- 按调用方式拆:这是技能特有的问题,参见 SKILL-MECHANICS.md。
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 premature completion.
- By invocation, skill-specific: see
SKILL-MECHANICS.md.
用核心词组织行为
leading word 是一个紧凑概念,模型可能已在预训练中接触过,例如 lesson、fog of war、tracer bullets。文中重复这个词,而不是每次重复整段解释,可以让它成为一组相关行为的共同提示。
也可以创造新词,但必须定义清楚;新词没有已有知识可借用,需要更多解释,因此优先考虑合适的现有概念。
它作用于两处:正文里帮助执行时想到同一类行为;引用里帮助把用户请求、项目文档和代码中的同一语言关联起来,找到相应材料。
寻找可以改善的重复表达。例如“快速、结果稳定、开销低”多次出现,可以在已明确定义后用 tight 表示;“一个你相信的验证流程”过于主观,可以改为 red,即这个流程确实能在 bug 出现时失败。
作者认为这样既减少文字,又让行为提示更明确。需要实际寻找文档中可以由清楚核心概念承担的重复说明。
旁边也有一个失败风险:否定式提示。作者用“不要想大象”说明,反复提禁止行为可能反而增加它的显著性。因此优先描述要做什么,例如“注释写成一行”。确实无法正面表达的硬限制仍保留,同时配上应采用的行动方向。
Leading words
A leading word 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 leading words. 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 leading words 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.
引导词借助已有概念,但不能把术语当魔法
模型在训练中接触过“课程”“反馈循环”“曳光弹”等概念,一个准确词可能带出比长段重复描述更一致的行为。作者把这样的词称为 leading word。
例如用“遇到目标 bug 必须报红”比“建立一个你觉得可靠的循环”更可观察。tight 则把快、确定、低负担聚为一个品质。但对初学者教学,必须先解释含义,不能为了省 token 牺牲理解。
否定指令可能让被禁止行为更显眼,是作者对提示设计的观察,不是所有否定都必然失效。明确的安全边界仍可用禁令,同时说明应采取什么替代行动。
删减与维护
- 每个含义只有一个权威位置,修改时只需改一处。重复不仅增加维护和 token,还会让该内容显得比实际更重要。核心词的有意重复不同,它重复的是已定义名称,而非整套含义。
- 运行环境也是依据,例如 package.json 脚本、配置、目录和 help 输出。文档复述这些内容相当于缓存,只有原查询成本较高时才值得。重点记录无法直接查到的约定、选择理由和隐藏陷阱;一条命令或一个文件就能查到的事实,尽量让 Agent 查询当前环境,减少过时副本。
- 逐行检查相关性:是否仍服务于此文目的?从来无关、应放分支参考、或已过时的内容,都可能不再有用。不持续维护,旧说明会像沉积层一样越积越厚,因为增加感觉安全,删除感觉有风险。
- 逐句寻找不起作用的指令。模型默认已经会做的事,重复要求可能只增加负担。判断取决于模型实际默认行为,应通过运行比较,而不是争论。没有作用时删除整句,不只是缩短几个字。核心词也要接受同样检验:模糊的“全面一点”若不改变行为,就需要更明确有力的要求。
Pruning
- Keep each meaning in a single source of truth: 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 leading word, which repeats a token on purpose, never the meaning.)
- The environment is a source of truth too (
package.jsonscripts, config files, the directory layout,--helpoutput), 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 no-ops 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 leading words: 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.
删除什么,比把每句话缩短更重要
重复同一规则会增加维护成本:改了一处,另一处仍旧。环境可直接查询的事实,例如 package.json 脚本名,也不一定值得复制进长期文档,否则变动后容易过期。
应保存不容易自行查到的原因、例外和隐含约定。例如为什么必须先检查某服务兼容性,通常比重复列出每个目录更有价值。
no-op 是不改变模型默认行为的指令;是否无效应通过实际执行比较,而非凭作者或老师感觉。删除过时和无效要求,是让剩余规则更突出,不是单纯追求字数最少。
配套参考资料(英文)
先作答,再看参考思路
用自己的话说明:它解决什么问题,完成后会留下什么?
请各用一句话回答。若它只做规划或解释,不要把“已开发”“已部署”写成产物。
“见 docs/”与“修改任务状态前,读取 docs/state-rules.md”有什么差别?
我已思考,查看参考思路
后者给出触发条件和准确目标,能减少何时读、读哪份的歧义;前者只是目录位置,未形成可靠的上下文指针。
原文中哪条要求在你的环境下可能不成立?
说出具体一句及其前提,例如工具不可用、资料缺失、已有项目约定冲突,或它只是作者偏好。把你的答案带回课堂,我们据此继续讨论。
把方法放进一个具体情境
教学案例:把“认真检查全部资料”改成“列出输入清单;逐份读取;记录无法读取的文件;所有条目都有阅读状态后才进入总结”。后一句能被检查,同时暴露漏读,不保证读后理解一定正确。
边界与容易误读的地方
文档不是越短越好,也不是越长越严谨。关键要求藏到没有触发指针的附件里,Agent 可能根本不会读。宿主对触发字段的支持也需实际核验。
讨论后再实践:先判断上述情境是否适用,再选择真实任务。现在无需安装、运行命令或修改现有项目。