为 agent 消费的任何文档——一项 skill、一份 AGENTS.md / CLAUDE.md、一个通过 pointer(指针)触达的文档——提供撰写参考。包装形式不同,写作方法不变:相同的杠杆(levers)让每一份文档都可预测——agent 每次运行都走相同的_过程_,而不是产出相同的输出。
当你撰写的文档是一项 skill 时,请阅读 SKILL-MECHANICS.md,了解 frontmatter、调用方式选择和 router skills(路由类 skills)。
上下文指针(Context pointers)
context pointer(上下文指针) 是保存在 agent 上下文中的一种引用:它指名某些上下文之外的材料,并编码了触达该材料的条件。skill 的 description 就是一个例子;AGENTS.md 中指名某文档的一行也是同一类对象。决定 agent 何时、以及多可靠地触达材料的,是指针的_措辞_,而不是它的目标。一个必须触达的目标藏在措辞软弱的指针后面,就是一次 variance bug(方差性缺陷):先打磨措辞,只有当打磨无效时才把材料内联进来。
指针承担两项工作——说明材料是什么,并列出应触发触达它的 branches(分支)(一个 branch 是文档处理的某个独立情形,不同的运行会走不同的路径)。常驻加载的指针每个词每一轮都在消耗成本,因此它比正文更应被严格修剪:
- 把 leading word 前置——指针正是在这里完成它的触发工作。
- 每个 branch 一个触发词。 为同一个 branch 换名的同义词,等于把同一个 branch 写了两遍;合并它们,只保留真正不同的 branches。
- 删掉正文已承载的身份信息。
两种负载(The two loads)
你添加的每一份文档和指针都会消耗两种预算之一:
- Context load(上下文负载)——常驻材料对 agent 窗口的消耗:一行
AGENTS.md、一条 skill description、任何每一轮都待在上下文里的东西,无论是否触发都在消耗 tokens 和注意力。 - Cognitive load(认知负载)——对人的消耗:存在哪些文档、何时该使用哪一份。人是索引。这不是需要最小化的成本——它是人类能动性的代价;在人类判断重要的地方投入它,在不重要的地方移除它。
只通过指针触达的材料,以指针自身那一行为代价躲开 context load;完全没有指针的材料则完全承载在 cognitive load 上。
信息层级(Information hierarchy)
一份文档由两种内容类型构建——steps(步骤)(agent 执行的有序动作)和 reference(参考)(按需查阅的定义、规则、事实)——它们可以自由混合:全是 steps(一份菜谱)、全是 reference(一次 review 的规则、本 skill),或两者兼有。核心决策是每一块内容在**information hierarchy(信息层级)**上的位置——这是一把按 agent 需要该材料的紧迫程度排序的梯子:
- In-file step(文件内步骤)——最顶层:agent 按顺序做什么。
- In-file reference(文件内参考)——按需查阅。常常是一组合法的扁平同级内容(一次 review 的所有规则在同一级)——这是合理的安排,不是坏味道。
- Disclosed reference(外置参考)——被推送到单独的文件中,通过 context pointer 触达,仅在指针触发时加载。范围从同一文件夹中的同级文件,一直到完全外部的参考——后者可以存在于任何地方,任何文档都可以指向它。
往下推得太少,顶层会臃肿;推得太多,你会藏起 agent 真正需要的材料。这种张力就是整个决策本身。
Progressive disclosure(渐进式披露) 是沿梯子向下的动作——移出主文件、放到指针之后——让顶层保持易读。它首先不是 token 优化:它是保护层级的方式。分支是最干净的披露测试:把每个 branch 都需要的内容内联,把只有部分 branch 会触达的内容放到指针之后。当文档含有 steps 时,本应被披露的 in-file reference 会埋没它们,把对步骤的关注变成一次抛硬币——这是 variance 杠杆,而不仅是可读性杠杆。
Co-location(共置) 是文件内的配套动作:梯子决定一块内容_向下放多深_,co-location 决定它_旁边放什么_。把某个概念的定义、规则和注意事项放在同一个标题下,而不是散落各处,这样阅读其中一部分时会把相邻内容一起带出来。检验标准:文档读起来应当像是专门为 agent 写的文档——分组的内容读起来如此;散落的内容则不然。(这不同于 duplication(重复):重复是在两处重复同一个含义;散落是把一个含义拆散到多处。)
Sprawl(蔓延) 是这里的失败模式:文档就是太长,即使每一行都是有效且独一无二的。注意力在过量内容上被稀释,每多一行就多一行需要保持相关。解药就是那把梯子:把 reference 披露到指针之后,并按 branch 或 sequence 拆分,让每条路径只承载它需要的内容。
步骤与完成标准(Steps and completion criteria)
每个步骤都以一个 completion criterion(完成标准) 收尾——告诉 agent 工作已完成的条件。两个属性使它成为杠杆:
Clarity(清晰度)——agent 能区分完成与未完成吗?模糊的边界("已达成共识")会招致 premature completion(过早完成):在步骤真正完成之前就结束它,注意力转向"显得完成"的状态。仍然可见的前方步骤——post-completion steps(完成后的步骤)——提供拉力;标准的清晰度则是阻力。按顺序防守:先打磨边界(局部且廉价);只有当边界无法再收紧_并且_你观察到了匆忙收尾时,才通过拆分序列把后续步骤隐藏起来——而且隐藏只有在跨越真正的上下文边界时才有效(一次 hand-off 或一次 subagent 派遣;内联调用会让后续步骤仍然留在上下文里,什么也清不掉)。
Demand(要求强度)——它要求做到什么程度。"每个被修改的模型都交代清楚"会迫使彻底的工作,而"产出一份变更清单"则不会。Demand 驱动 legwork(苦功)——agent 在工作中自行挖掘的深度,它潜藏在措辞里,而不是写成独立的一步——而且它不受步骤限制:"每条规则都应用到位"约束的是一大块扁平 reference,正如"每一步都完成"约束的是一段序列——这正是纯 reference 文档仍然带有穷尽性门槛的方式。
最强的标准既可核查又穷尽。
何时拆分(When to split)
把一份文档拆成两份会消耗两种负载之一,所以只有在拆分的收益配得上成本时才拆:
- 按 sequence(序列)拆分——当 post-completion steps 诱使 agent 匆忙完成当前步骤时,拆分这段步骤序列。让它们保持在视线之外,会在当前任务上驱动更多 legwork。当心反向情况:合并序列会让每一步的后续步骤暴露在接下来的内容面前,招致 premature completion。
- 按 invocation(调用方式)拆分——skill 特有:参见
SKILL-MECHANICS.md。
Leading words(领航词)
leading word(领航词) 是已经存在于模型预训练中的紧凑概念,agent 在执行文档时会用它来思考(lesson、fog of war、tracer bullets)。以 token 而非句子的形式反复出现,它积累起一个分布式定义,并通过征用模型已有的先验,用最少的 token 锚定一整片行为区域。自己造词也行,只要定义清楚——但一个生造的词征用不到任何先验:你要为定义付出 token,而一个预训练过的词是免费赠送的;先找现成的词。
它锚定两次。在正文中,锚定 execution(执行):每次这个词出现,agent 都会走向相同的行为;在扁平 reference 内部,它把注意力聚焦到要寻找的一类东西上。在指针中,锚定 invocation(调用):当同一个词同时出现在你的 prompts、你的文档和你的代码库中时,agent 会把这种共享语言与材料关联起来,从而更可靠地触达它。
主动寻找用 leading words 重构的机会。一个在三处展开的三元组、一句指向某个概念的指针——每一处都是渴望坍缩成单个 token 的段落:
- "fast, deterministic, low-overhead" → tight (a tight loop).
- "a loop you believe in" → red — a fuzzy gate becomes a binary observable state (the loop goes red on the bug, or it doesn't).
你赢两次:更少的 token,以及一个更锐利的钩子让 agent 挂起它的思考。假定每份文档都携带着可以被 leading words 退役的重述——去找出它们。
Negation(否定式表述) 是这个杠杆旁边的失败模式:通过禁止来引导,会把被禁止的行为拖进上下文,让它变得_更容易_被激活,而不是更难。"别想大象",结果满脑子都是大象;否定是一个弱修饰语,会被强烈激活的概念压过,于是禁令有一半会被读成"去做这件事"的指令。改用正向提示——陈述目标行为("写一行式注释"),让被禁止的行为永远不被提及。禁令只有在作为无法用正向方式表述的硬护栏时才有立足之地;即使如此,也要把它与正向目标配对,让注意力落在"该做什么"上。
修剪(Pruning)
把每个含义保持在**单一事实来源(single source of truth)**中:一个权威的位置,这样改变行为就是一次单点编辑。Duplication(重复)——同一个含义出现在不止一处——要付出维护成本和 token,还会把某个含义在梯子上的显要程度抬高到超出它的真实位次。(这是 leading word 的意外镜像:leading word 是有意重复 token,从不重复含义。)
环境也是一个事实来源——
package.json里的 scripts、配置文件、目录结构、--help的输出——而一份重述它的文档就是一个 cache(缓存):一份查找结果的副本,只有当查找本身昂贵时才配得上它的负载。缓存 agent 靠查看无法找到的东西:未写下来的约定、某个选择背后的原因、任何配置都不会承认的坑。把"一个文件、一条命令"就能查到的内容留给环境,在那里它们不会过时。逐行检查相关性(relevance):它还与这份文档所做的事相关吗?一行内容要么因为从未作用于任务(纯叙述,或一个本应被披露的 branch)而失去相关性,要么因为它所描述的行为或世界发生变化而过时。更短的文档更容易保持相关。没有修剪纪律,默认的命运是 sediment(沉积):一层层过时的内容沉淀下来,因为添加让人感觉安全、删除让人感觉有风险,直到你不得不穿透它们才能找到仍然有效的内容。
逐句搜寻 no-ops(空操作):一条模型默认就会遵守的指令,付出了负载却什么也没说。检验标准——它是否改变了相对默认行为的行为?——是相对于模型而言的,不是相对于读者:两个人对一条 no-op 意见不一,其实是对默认行为意见不一,解决方式是运行这份文档,而不是辩论。当一句话检验不通过时,删除整句话,而不是从它里面删几个词。这个检验同样给 leading words 打分:一个弱到无法胜过默认行为的词(agent 已经相当 thorough 时还说_be thorough_)就是 no-op,解决办法是换一个更强的词(relentless),而不是换一种技巧。