Chengshu@skadai · 2026.10.20
RSS
2,307 字 · 694 词 · 约 9 分钟

writing-for-agents 精读:写 agent 要读的文档(终章 + 全系列索引)

writing-for-agents 是这季技能的元篇:它不写代码,也不写文章,而是写『给 agent 读的文档该长什么样』。它把写作建议改造成两种预算(上下文负载 / 认知负载)和一条三级的信息阶梯,给出指针、渐进披露、完成条件、leading word、修剪这些可操作的杠杆,并在 SKILL-MECHANICS.md 里分出『技能特有』的那一支。本文走完这套规范,把整季结论回收成一份『写你自己第一个技能』的起点,并在文末给出 27 篇的全系列索引。

本篇属于系列 读懂最优秀的开发技能是怎么写的(Matt Pocock skills 逐技能精读) · 第 27 篇

(本文读的是 mattpocock/skills 快照 5beb35b,2026-10-19。引用原文都能按文中路径回仓库核对。这是「逐个技能精读」系列的第二十七篇,也是最后一篇,聚焦 writing-for-agents。文末附全系列索引。)

它怎么工作:一份通用规范,加一条技能专线

skills/productivity/writing-for-agents/ 有两个文件。主文件 SKILL.md 是一份纯参考(全是一个个定义和规则,没有步骤,和 code-review 同构),开篇就划定它管的东西:

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.

「agent 每次跑的是同一个过程,而不是产出同一份结果」——这句话解释了它为什么把力气放在可复现的过程上,而不是「让文章好看」。它没有 disable-model-invocation,是 model-invoked:任何技能(如 retro)都能在需要判定 agent 文档时把它调起来。

它的杠杆分几组:

一、指针(context pointer)。 一条 AGENTS.md 里的指向、一个技能的 description,都是同一类对象——「一条保存在 agent 上下文里的引用,指向某段上下文外的材料,并编码了去取它的条件」。关键判据是措辞:

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.

因为它每轮都在花钱,所以修剪得比正文还狠:leading word 前置、一个分支只留一个触发器、删掉正文已经承载的身份信息。

二、两种负载。 每加一份文档或一个指针,都在花两种预算之一:上下文负载(常驻 agent 窗口、每轮都烧 token 和注意力)与认知负载(压在人身上——记住有哪些文档、什么时候用)。第二个尤其常被误解:

Cognitive load is the cost on the human … Not a cost to minimise: it is the price of human agency; spend it where human judgement matters, remove it where it does not.

三、信息阶梯。 文档由步骤和参考两种内容构成,核心决定是每块内容坐在阶梯的哪一级:in-file step(主层)→ in-file reference(按需查阅)→ disclosed reference(推出到单独文件、用指针去取)。伴随两个动作:渐进披露(往下推,保住顶层的可读性)与就近安置(co-location,把定义、规则、例外放在同一个标题下)。失败模式是 sprawl——就算每行都有效、都唯一,太长也会让注意力变薄。

四、完成条件。 每个步骤都以一条完成条件收尾,它有两个属性:清晰度(能否分清做完没做完;含糊会招来「过早完工」)与要求度(逼出多少「legwork」,比如「每个被改的 model 都要交代」远强于「产出一张变更清单」)。The strongest criteria are both checkable and exhaustive.

五、什么时候拆。 拆一份文档要花掉前述两种负载之一,所以要拆得值:按序列拆(把「完工后才走」的步骤藏起来,逼 agent 在当前任务上更下功夫)、按调用方式拆(技能专线,见下)。

六、leading word。 一个活在模型预训练里的小概念,被当作 token(不是句子)反复使用,就攒出一层分布式定义,用最少的 token 圈住一大片行为——fog of war、tracer bullets、tight、red。它是这套规范里最省力的杠杆:一个词同时收敛 token,又让 agent 的思考有个挂钩处。

七、修剪。 单一真相来源、警惕重复(重复会把一个含义在阶梯上的重要性抬高到失真)、把环境(package.json、配置、目录结构、--help)当成真相来源(复述它就是一份会过期的 cache)、逐行查相关性(默认命运是 sediment:一层层过期沉淀),以及逐句猎 no-op:

an instruction the model already obeys by default pays load to say nothing.

第二个文件 SKILL-MECHANICS.md 是「技能特有」的那一支:frontmatter、调用方式的选择(model-invoked 换上下文负载、user-invoked 换认知负载)、以及路由技能(router skill)。

它和「一般技能」的差别:它是一张「写文档的决策梯」

一般「写作规范」给的是风格建议——语气、长度、人设。这一篇一律做成预算加阶梯:不说「请简洁」,而是给出两个被命名的负载和一条三级的信息阶梯。命名的意义是让权衡可检查——你能指着某一行说「它该 disclosed 而不是 in-file」。

它也是这季所有技能的元篇:它讲的语言,正是其余 26 个技能被写出来所用的语言。这一篇能立得住,靠的恰恰是前面 26 篇提供的样本。

还有一处结构上的差别:它被 retro 每次运行都加载,而不是「只在要写的时候」加载。.out-of-scope/lazy-load-writing-for-agents.md 给的理由是——它更像一部定义集(什么叫 no-op、什么算好技能),retro 用这些定义去判定它读到的 steering 文件,而判定发生在写之前。所以它不只是风格指南,是一套共享词汇。

它有意识摒弃了什么

一、摒弃了「让产出好看」这个目标。 它优化的是过程可复现,不是结果长得像样。

二、摒弃了禁止式写法。 Negation is the failure mode beside this lever——用禁令来引导,反而把被禁的行为拉进上下文、变得更可得(Don't think of an elephant)。办法是正面说出目标行为:

Prompt the positive: state the target behaviour … so the banned one is never spoken.

三、摒弃了重复。 同一个含义只留一处(single source of truth),重复会抬高它在阶梯上的虚假重要性。

四、摒弃了「把环境写进文档」。 环境本身就是真相来源;复述它是会过期的 cache。

五、摒弃了「默认常驻」。 model-invoked 每轮都付上下文负载,所以 description 修剪得比正文还狠;能只靠人手打的技能就该做成 user-invoked,零上下文负载、改付认知负载。判据很清楚:Pick model-invocation only when the agent must reach the skill on its own, or another skill must.

六、摒弃了「一份文档包打天下」。 该拆就拆——按序列(藏起后续步骤)或按调用方式(拆出能被独立触发的触发器)。

七、摒弃了自造术语。 优先用预训练里已有的词;自造词拿不到任何先验,定义成本得自己掏。

原文证据

过程而非结果:

… the agent takes the same process every run rather than producing the same output.

指针措辞决定可靠性:

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.

两种负载:

Context load is the cost of always-loaded material on the agent’s window … Cognitive load is the cost on the human … the price of human agency.

正面措辞与 no-op 的判据:

Prompt the positive: state the target behaviour … so the banned one is never spoken.

an instruction the model already obeys by default pays load to say nothing.

调用方式二选一:

Pick model-invocation only when the agent must reach the skill on its own, or another skill must.

可迁移结论:写你自己第一个技能的起点

把整季回收成一份清单,每条都能指回前面某篇:

  1. 先决定它是薄指针还是厚文档。 grill-me 正文只有 7 行,research 正文只有 12 行,writing-for-agents 自己是一篇厚参考——薄厚取决于「决定权放在谁手里」。
  2. 再决定它由人打还是由模型自动触发。 ask-matt、setup-matt-pocock-skills、teach、to-questionnaire 都是 user-invoked;research、writing-for-agents 是 model-invoked。取舍见 SKILL-MECHANICS.md 的两种负载。
  3. 每条只承诺一件可验证的事。 research 的三条职责、wizard 的「先读仓库再问人」,都是这个形状。
  4. 把状态写进文件,正文写薄,格式分出去。 teach 的七个文件与各自的 *-FORMAT.md、handoff 的临时目录取舍。
  5. 用「原语 + 调用」而不是「大流程」。 grilling 是复用最多的原语,grill-me / grill-with-docs / triage / wayfinder 都调它。
  6. 给完成条件一条可检查、穷尽的界。 用于步骤,也用于一堆平铺规则(「每条规则都用上了」)。
  7. 把该问的人找对。 事实自己查(派子代理)、决定留给人(grilling);你答不出的那部分,转手问那个知道的人(to-questionnaire)。
  8. 承认技能不解决什么,并写进文档。 research 的那几个坑、question-limits.md 的「不设上限」、native-question-tool.md 的「拒绝 UI」。
  9. 别为某个 harness 加分支。 技能是 harness 中立文本;把宿主偏好留在用户自己的 CLAUDE.md / AGENTS.md 里。
  10. 定期修剪你的技能和环境。 retro 就在做这件事;writing-for-agents 提供了那把尺子(no-op、重复、sediment)。

全系列索引

整个系列到此收束:27 篇,一篇一个技能,读的都是 mattpocock/skills 快照 5beb35b。按主题分组如下。

起步与路由(3)

  • ask-matt——一张会撒谎的地图;宁可手写也不去扫描你已经装了什么
  • setup-matt-pocock-skills——每仓库跑一次的配置,为什么不把 issue tracker 写死在技能里
  • grilling——复用最多的原语:design tree、frontier、事实给子代理、决定留给人

追问与澄清(3)

  • grill-me——一个只有 7 行的技能,为什么反而是设计
  • grill-with-docs——同一个访谈,为什么它敢往你的仓库里写文件
  • wait-what——事后纠偏:为什么「简洁一点」永远失败,而「等一下」能成功

把想法变成工单(3)

  • to-spec——明令「不许提问」,却把唯一一次打断留给接缝
  • to-tickets——竖着切、给每张票画上依赖的边
  • wayfinder——只肯产出「决定」的技能,怎么处理一次会话装不下的规划

实现(2)

  • implement——17 行,用三条契约驱动整次实现
  • implement-spec——把工单读成 task graph,终点是集成分支而不是 PR

质量与验收(3)

  • code-review——两条轴各开一个子代理,最后谁也不许评总冠军
  • pr——用最小的那个视图说清改动,再交出一个门和一片爆炸半径
  • triage——只碰别人建的 issue,把标签当状态机,每个决定先交回给人

设计与调试(5)

  • codebase-design——一份词汇表,用「删掉它」判定一个模块该不该存在
  • domain-modeling——术语是契约,值得在会话中途打断你
  • prototype——先有问题才有形状,一次原型只回答一个问题
  • tdd——没商定接缝就不写测试,重构不在这条循环里
  • diagnosing-bugs——没有红得起来的反馈回路,不许进入假设

调研与演进(3)

  • research——12 行定住一个后台代理,产物是一个带引用的 Markdown 文件
  • improve-codebase-architecture——先决定扫哪里,把候选画成一份 HTML 报告,然后才开始问
  • retro——它改的不是代码,是 agent 的环境

传递与元技能(4)

  • handoff——让工作「旅行」,而不是把对话再讲一遍
  • teach——把当前目录当成有状态的教学工作区(本批)
  • to-questionnaire——把答不上来的决定变成给别人的问卷(本批)
  • writing-for-agents——本篇:写 agent 要读的文档

自动化(1)

  • wizard——把「只有人能做的事」做成一台脚本

讨论

用 GitHub 账号留言;评论保存在公开仓库chengshu-blog-discussions的 Discussions 里。也可通过 RSS 订阅后续文章。