这是给代理读的任何文档的写作参考:一份技能、一个 AGENTS.md / CLAUDE.md,或者顺着指针够到的一份文档。它们的打包方式各不相同,写法却是一样的:同样这组杠杆让每一份都变得可预测,因为代理每次运行走的是同一个_过程_,而不是产出同样的结果。
当你写的文档是一份技能时,读 SKILL-MECHANICS.md,了解 frontmatter、调用方式的选择,以及路由技能。
上下文指针
上下文指针是留在代理上下文里的一条引用,它点出某份不在上下文里的材料,并写清了够到它的条件。技能的描述就是一条;AGENTS.md 里点出某份文档的一行也是同一种东西。决定代理什么时候够到这份材料、够得有多可靠的,是指针的_措辞_,而不是它的目标。一个必备的目标如果藏在措辞薄弱的指针后面,就是一个会造成运行波动的缺陷:先把措辞磨利,只有磨不利时才把材料内联进来。
一个指针干两件事:说明这份材料是什么,并列出应当触发去够它的分支(一个分支就是文档要处理的一种独立情况,所以不同的运行会走过不同的路径)。一条常驻加载的指针,每个字都在每一轮里花成本,所以它比正文更该下狠手修剪:
- 把引导词前置:指针正是引导词做触发工作的地方。
- 一个分支一个触发点。 给同一个分支换个名字的同义词,是同一个分支写了两遍;把它们合并掉,只留真正不同的分支。
- 删掉正文已经承载的身份信息。
两种负载
你添加的每一份文档和每一个指针,都要花掉两种预算之一:
- 上下文负载是常驻材料压在代理上下文窗口上的成本:
AGENTS.md里的一行、一条技能描述、任何每一轮都待在上下文里的东西,无论触发与否都在花词元和注意力。 - 认知负载是压在人身上的成本:有哪些文档存在、什么时候该去够哪一份。人就是索引。它不是要尽量压小的成本:它是人保有主导权要付的代价;在人的判断真正重要的地方花它,在不重要的地方去掉它。
只能顺着指针够到的材料,用指针自己那一行的代价换来了免于上下文负载;完全没有指针的材料,则完全由认知负载驮着。
信息层级
一份文档由两类内容组成:步骤(代理按顺序执行的动作)和参考资料(按需查阅的定义、规则、事实)。两者可以自由混合:全是步骤(一份菜谱)、全是参考资料(一次评审的规则、本技能),或者两者都有。核心决策是每一块内容放在信息层级的哪一级;这个层级是一架梯子,按代理多快需要这份材料来排序:
- 文件内步骤是主层级:代理按顺序做的事。
- 文件内参考资料按需查阅。它常常是一组合理地摊平的同类条目(一次评审的每一条规则都在同一级台阶上),这是一种合理的安排,不是缺陷。
- 披露出去的参考资料被推到单独的文件里,靠一个上下文指针够到,只有指针触发时才加载。它从同一目录下的兄弟文件,一直延伸到完全外部的参考资料——放在任何地方、任何文档都可以指过去的参考资料。
往下推得太少,顶层就会膨胀;推得太多,又会把代理真正需要的材料藏起来。这个张力就是全部决策。
渐进式披露是沿梯子往下走(走出主文件、躲到指针后面),让顶层保持易读。它首先不是一种词元优化:它是信息层级得以被保护的方式。分支是检验该披露什么的最干净判据:每个分支都需要的内容就内联,只有部分分支会够到的内容就推到指针后面。当一份文档有步骤时,本该被披露出去的文件内参考资料会把步骤埋起来,让照看步骤变成抛硬币:这就不只是可读性的杠杆,而是运行波动的杠杆了。
就近放置是文件内的搭档:梯子决定一块内容坐在_多深_的位置,就近放置决定它到了那里之后_旁边坐着谁_。把一个概念的定义、规则和注意事项放在同一个标题下面,而不是散落各处,这样读其中一部分就会把它的邻居一起带过来。判据是:这份文档读起来应该像专门为代理写的文档。内容成组地放,读起来就是这样;散着放就不是。(它与重复不同:重复是把同一个意思在两个地方各写一遍;散落是把一个意思打碎撒到很多地方。)
篇幅蔓延是这里的失效模式:一份文档就是太长了,哪怕每一行都还有效、都不重复。注意力会在多出来的部分上变稀,而且每多一行,就多一行要维持相关性。解药就是那架梯子:把参考资料披露到指针后面,并按分支或按顺序拆分,让每条路径只携带它需要的东西。
步骤与完成判据
每个步骤都结束在一个完成判据上,也就是告诉代理活干完了的那个条件。两个性质让它成为一个杠杆:
- 清晰度:代理能分清做完和没做完吗?含糊的界限(「理解已经达成」)会招来提前收尾:在真正做完之前就结束这一步,注意力滑向_已经做完_。还看得见的后续步骤(完成后步骤)提供拉力;判据的清晰度提供阻力。按顺序防守:先把界限磨锋利(就地、便宜);只有当它确实无法再清晰_而且_你观察到了这种抢跑,才用拆分序列的办法把后面的步骤藏起来。藏起来只有在真实的上下文边界两侧才管用(一次交接或一次子代理派发;内联调用会把后面的步骤留在上下文里,什么都清不掉)。
- 要求强度:它要求做多少。「每一处改动过的模型都已交代」会逼出扎实的工作,而「产出一份改动清单」不会。要求强度驱动跑腿活(代理在这件工作之内真去挖的功夫,它潜藏在措辞里,而不是被写成单独的一步),而且它不限于步骤:「每一条规则都已应用」约束的是一整块平铺的参考资料,就像「每一步都已完成」约束的是一个序列;全参考资料型文档仍然带着一条穷尽性标准,靠的就是这一点。
最强的判据,既可检验,又穷尽。
什么时候该拆
把一份文档拆成两份要花掉两种负载之一,所以只有这个切法值回票价时才拆:
- 按序列拆:当完成后步骤会引诱代理对它面前那一步抢跑时,就把这一段步骤拆开。让它们看不见,能逼出更多用在本职工作上的跑腿活。也要提防反过来:把序列合起来,会让每一步后面的步骤暴露给接下来要做的事,从而招来提前收尾。
- 按调用方式拆,这是技能特有的:见
SKILL-MECHANICS.md。
引导词
引导词是一个紧凑的概念,它已经待在模型的预训练里,代理在跑这份文档时用它来思考(lesson、fog of war、tracer bullets)。它以一个词元的形式反复出现,从不以句子的形式出现,于是积累出一个分布式的定义,用最少的词元锚住一整片行为,靠的是调动模型本来就有的先验。自己造词也行,只要你能把它定义清楚,但造出来的词调动不了任何先验:预训练的词白送你的东西,你得用定义词元去付账;所以先去够一个已有的词。
它锚定两次。在正文里锚的是_执行_:每次这个词出现,代理都会去够同一种行为;在平铺的参考资料里,它把注意力聚到某一类要找的东西上。在指针里锚的是_调用_:当同一个词同时活在你的提示词、你的文档和你的代码库里时,代理会把这种共享语言与那份材料连起来,更可靠地够到它。
去寻找用引导词做重构的机会。一个在三个地方展开写的三元组,一个花整整一句话去指一个想法的指针。这些段落都在等着被收拢成一个词元:
- "fast, deterministic, low-overhead" → tight(一个 tight 循环)。
- "a loop you believe in" → red,把一个模糊的关卡变成二值的可观察状态(循环对那个 bug 变_红_,或者不变)。
你会赢两次:词元更少,而且给代理一个更锋利的挂钩来挂它的思考。假设每一份文档里都带着一些可以被引导词退役的重复表述。去找出来。
否定式是这根杠杆旁边的失效模式:用禁止来操纵方向,会把被禁的行为拖进上下文,让它变得_更_可得,而不是更不可得。别去想大象,结果满脑子都是大象;否定是一个弱修饰,会被强烈激活的概念碾过去,于是这条禁令有一半读起来像是在指示你去做那件事。要提示正面:说出目标行为(「写一行的注释」),让被禁的那种从不被说出口。只有当一条禁令是你没法用正面措辞表达的硬护栏时,它才配占一个位置;即便那时,也要把它和正面目标配在一起,让注意力落在该做的事上。
修剪
- 让每个意思待在单一事实来源里:只有一个权威的地方,改行为就是改一个地方。重复(同一个意思出现在不止一个地方)要花维护成本和词元,还会把一个意思在梯子上的显著度抬到超过它真实的等级。(它是引导词意外反过来的那种情况——引导词是有意重复一个词元,从不重复那个意思。)
- 环境也是一处事实来源(
package.json里的脚本、配置文件、目录结构、--help的输出),而一份复述环境的文档是一份缓存:一次查找的副本,只有那次查找很昂贵时才值回它的负载。要缓存的是代理自己看也找不到的东西:没写下来的约定、某个选择背后的理由、没有任何配置会承认的坑。一个文件、一条命令就能查到的,留给环境——在那里它们不会过时。 - 逐行检查相关性:这一行还与这份文档所做的事有关吗?一行会失去相关性,要么是因为它从来就与任务无关(纯粹的阐述,或者一个本该被披露出去的分支),要么是因为它描述的行为或世界变了,它过时了。更短的文档更容易保持相关。没有修剪纪律,默认的结局是沉积:一层层过时的东西落下来,因为加东西感觉安全、删东西感觉有风险,直到你不得不一层层钻下去,去找还活着的那部分。
- 逐句寻找空操作:一条模型本来就会默认遵守的指示,白白花掉负载却什么也没说。判据(它相对默认行为改变了什么吗?)是相对于模型的,不是相对于读者的:两个人对某条算不算空操作有分歧,其实是对默认行为有分歧,解决办法是拿这份文档跑一遍,而不是辩论。当一句话不合格时,删掉整句,而不是从里面抠掉几个词。这条判据也用来给引导词打分:一个弱到打不过默认行为的词(在代理本来就挺彻底的时候说_要彻底_)就是空操作,修法是换一个更强的词(不留情面),而不是换一种技巧。


