mcpField
W
writing-for-agents

writing-for-agents

github.com/leandrocfeAgent 工作流4165 次安装11 周前更新
代码仓库

关于 writing-for-agents

面向 Agent 文档作者的写作参考,涵盖 Skill、AGENTS.md、CLAUDE.md 和链接文档。介绍如何设计上下文指针、信息层级、步骤与完成标准,让 Agent 的执行更可预测。

主要功能

  1. 01上下文指针设计
  2. 02上下文与认知负担指导
  3. 03信息层级与渐进披露
  4. 04步骤完成标准
  5. 05文档拆分与精简

适用场景

  1. 01编写 Agent Skill
  2. 02组织 AGENTS.md 或 CLAUDE.md
  3. 03减少 Agent 的无用上下文
  4. 04提高 Agent 流程的一致性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/leandrocfe/skills --skill writing-for-agents

安装后在 Claude Code 中输入/writing-for-agents确认已加载。

附带文件agents/openai.yamlSKILL-MECHANICS.md

详细介绍

供编写任何 Agent 会读取的文档时参考——无论是 skill、AGENTS.md / CLAUDE.md,还是通过指针引导到的文档。打包方式各不相同;写作方式却相同:同样的杠杆能让每种文档都可预测——让 Agent 每次执行都采用相同的 流程,而不是生成相同的输出。

如果你正在编写的文档是 skill,请阅读 SKILL-MECHANICS.md,了解 frontmatter、调用方式的选择和路由 skill。

上下文指针

上下文指针是在 Agent 的上下文中保留的一种引用,用于指明上下文之外的材料,并编码何时应访问该材料。skill 的描述就是一种;AGENTS.md 中指向某份文档的一行也是同一种东西。决定 Agent 何时访问材料、以及访问得有多可靠的,是指针的_措辞_,而非其目标。措辞不佳的指针指向必需目标,是一个方差问题:先打磨措辞,只有打磨无效时才将材料内联。

指针有两项作用——说明材料是什么,并列出应触发访问它的分支(分支是文档处理的一个独立情形,因此不同执行会沿着不同分支进行)。常驻指针中的每个词都会在每轮消耗成本,因此它比正文更值得严格精简:

  • 将首要词放在前面——指针正是靠它来触发访问。
  • 每个分支只设一个触发词。 为同一分支换个名称的同义词,等于把一个分支写了两遍;将它们合并,只保留真正不同的分支。
  • 删掉正文中已有的身份信息。

两种负担

你添加的每份文档和指针都会消耗以下两种预算之一:

  • 上下文负担——Agent 上下文窗口中常驻材料的成本:AGENTS.md 中的一行、skill 描述,以及每轮都留在上下文中的任何内容;无论是否触发,都会消耗 token 和注意力。
  • 认知负担——人类承担的成本:有哪些文档,以及何时访问每一份。人类就是索引。它不是需要最小化的成本,而是人类能动性的代价;在人类判断至关重要之处投入,在无关之处移除。

只有通过指针访问的材料,能免于上下文负担,但代价是指针所在行本身;完全没有指针的材料,则全部由认知负担承载。

信息层级

文档由两类内容构成——steps(Agent 按顺序执行的操作)和 reference(按需查阅的定义、规则和事实)——两者可以自由组合:只有 steps(一份操作指南)、只有 reference(review 的规则,即本 skill),或两者兼有。核心决策是每项内容在信息层级中的位置;这个层级按 Agent 对材料的紧迫需求程度排列:

  1. 文件内 step — 主要层级:Agent 按顺序执行的操作。
  2. 文件内 reference — 按需查阅。通常可以合理地保持同级平铺(review 的所有规则都处在同一层)——这是良好的安排,并非异味。
  3. 已披露的 reference — 移至单独的文件,通过上下文指针访问,仅在指针触发时加载。范围从同一文件夹中的同级文件,到完全外部、存放在任意位置且任何文档都能指向的 reference。

下沉得不够,顶部就会臃肿;下沉得太多,又会把 Agent 确实需要的材料藏起来。整个决策就在于权衡这种张力。

渐进式披露就是沿层级向下移动——移出主文件,放到指针之后——让顶部保持易读。这主要不是为了优化 token,而是为了维护层级。分支是检验披露方式最直接的方法:将所有分支都需要的内容内联,把只有部分分支会用到的内容放到指针之后。文档包含 steps 时,本应披露的文件内 reference 会将它们淹没,让 Agent 能否注意到这些内容变成抛硬币式的偶然结果——这影响的是结果的方差,而不仅仅是可读性。

就近放置是在文件内部配合层级的做法:层级决定一项内容放得有多深,就近放置则决定它放好后与什么内容相邻。将一个概念的定义、规则和注意事项放在同一个标题下,而不是四处分散,这样读到某一部分时,相关内容也会一并呈现。检验方法:文档读起来应该像是专为 Agent 编写的文档——内容分组时是这样,分散时则不是。(这与重复不同:重复是在两个地方重述同一个含义;分散则是把一个含义拆散到多个地方。)

蔓延是这里的失效模式:文档只是过长,即使每一行都切题且独一无二也是如此。内容过多会分散注意力,而每增加一行,就多一行需要保持相关。解决办法是层级:将 reference 通过指针披露,并按分支或顺序拆分,让每条路径只承载所需内容。

Steps 与完成标准

每个 step 都以一个完成标准结束——它告诉 Agent 工作何时完成的条件。两个属性让它成为一个杠杆:

  • 明确性——Agent 能区分已完成和未完成吗?模糊的界限(“已达成理解”)会诱发过早完成:在工作真正完成之前就结束 step,注意力滑向_看起来已经完成_。前方仍然可见的 steps——即完成后的 steps——会形成牵引力;标准的明确性则是阻力。按以下顺序处理:先明确界限(局部且成本低);只有当界限确实无法明确_并且_你观察到 Agent 急于完成时,才通过拆分序列来隐藏后续 steps——而隐藏只有通过真正的上下文边界才有效(例如交接或调度子 Agent;内联调用会让后续 steps 仍留在上下文中,无法清除任何内容)。
  • 要求度——标准要求多少。“核对每个已修改的模型”会迫使 Agent 细致工作,而“列出变更”则不会。要求度驱动细致工作——Agent 在工作过程中进行的挖掘,这种要求隐含在措辞中,而不是被写成单独的 step——且不局限于 step:“应用每条规则”对扁平的参考资料正文提出要求,就像“完成每个 step”对序列提出要求一样;因此,只有参考资料的文档也能带有穷尽性要求。

最有力的标准既可核查,又要求穷尽。

何时拆分

将一个文档拆成两个会消耗两种负担之一,因此只有拆分的收益超过成本时才拆分:

  • 按序列拆分——拆分一连串 steps,避免完成后的 steps 诱使 Agent 仓促完成当前工作。让它们不可见,会促使 Agent 在当前任务中做更多细致工作。也要注意相反的情况:合并序列会让每个 step 的后续 steps 暴露给它接下来要做的工作,从而诱发过早完成。
  • 按调用拆分——仅适用于 skill:参见 SKILL-MECHANICS.md。

引导词

引导词是一个紧凑的概念,已经存在于模型的预训练中,供 Agent 在运行文档(lesson、fog of war、tracer bullets)时用于思考。将它作为 token 重复使用,而不是重复一整句话,它就会积累分布式定义,并用最少的 token 锚定一整片行为区域,调动模型已有的先验。自己创造一个词也行,只要定义清楚,但新造的词无法调动任何先验——预训练词可以免费提供的东西,你得用定义 token 来买单;优先使用现有词。

它能双重锚定。在正文中,它锚定_执行_:每次出现这个词,Agent 都会调用同一种行为;在扁平引用中,它会将注意力聚焦于要寻找的一类事物。在指针中,它锚定_调用_:当同一个词出现在你的提示词、文档和代码库中时,Agent 就会把这套共享语言与相关材料关联起来,并更可靠地找到它们。

寻找用引导词重构的机会。一个三元组在三个地方分别写出,一个指针花上一句话来比划某个想法——每一处都是在请求压缩成一个 token:

  • “快速、确定性、低开销” → tight(一个 tight 循环)。
  • “一个你信得过的循环” → red——模糊的门槛变成可观测的二元状态(遇到 bug 时循环会变成 red,否则不会)。

你能获得双重收益:token 更少,Agent 也有一个更锐利的钩子来挂靠思路。假设每份文档都包含一些可以由引导词取代的重复表述——去把它们找出来。

否定是与这一杠杆相伴的失效模式:通过禁止来引导,会把被禁止的行为拖进上下文,使它变得_更容易_被触发,而不是更难。不要想大象,结果大象就占据了全部思绪;否定是一个弱修饰语,会被强烈激活的概念压过,因此禁令看起来有点像是在指示你做那件事。提示正向行为——明确说出目标行为(“写单行注释”),这样就不必提及被禁止的行为。只有当某项禁令无法用正向表述时,它才值得作为硬性护栏保留;即便如此,也要配上正向目标,让注意力落在该做什么上。

削减

  • 让每种含义都保持单一事实来源:一个权威位置,这样要改变行为时只需编辑一处。重复——同一种含义出现在多个位置——会增加维护成本和 token 消耗,还会让某种含义在层级中的显著性高于其实际排名。(意外的 leading word 反转会故意重复一个 token,但绝不重复含义。)
  • 环境也是一个事实来源——package.json 脚本、配置文件、目录布局、--help 输出——而重述这些内容的文档就是一个缓存:查找内容的副本,只有在查找成本高时才值得付出维护代价。缓存 Agent 无法通过查看找到的内容:未写明的约定、某项选择背后的原因、任何配置都不会说明的陷阱。让只需查一个文件、运行一条命令的查找留在环境中,这样它们就不会过时。
  • 逐行检查相关性:这一行仍会影响文档所做的事吗?一行内容可能因为从未影响任务(只是提供背景,或是本应明确披露的分支)而失去相关性,也可能因为它所描述的行为或世界发生变化而过时。文档越短,越容易保持相关。若没有削减的纪律,默认的结局就是沉积物:过时的层层内容不断堆积,因为添加看起来安全,删除却显得有风险,直到你不得不层层挖掘,才能找到仍然有效的内容。
  • 逐句查找无操作指令:模型默认就会遵守的指令,付出了上下文成本却什么也没说。检验标准是——它是否会改变相对于默认行为的表现?——这取决于模型,而非读者:两个人若对某条指令是否无操作有分歧,他们对默认行为的看法就不同,应通过运行文档而非争论来解决。若某句话未通过检验,就删除整句话,而不是删减其中几个词。这个检验也适用于 leading word 的强度:一个弱到无法改变默认行为的词(当 Agent 已经有些细致时说“要细致”)就是无操作指令,正确的做法是换成更强的词(“毫不留情”),而不是改用另一种技巧。

评论

支持 Markdown