# Writing For Agents

> 为智能体编写文档。当你正在创建或编辑技能，或者修改 AGENTS.md / CLAUDE.md 时使用。

- Skill: `devcxl/writing-for-agents` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add devcxl/writing-for-agents`
- Raw SKILL.md: https://api.skillmd.com/api/skills/devcxl/writing-for-agents/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: devcxl (https://skillmd.com/u/devcxl)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/devcxl/writing-for-agents

---


一份用于编写智能体所阅读的任何文档的参考：一个技能、一份 `AGENTS.md` / `CLAUDE.md`、一份通过指针触达的文档。包装方式各异，但写作规则是一致的：同样的杠杆让每份文档都变得可预测，因为智能体每次运行采取的是同一个*流程*，而不是产出同一个输出。

当你正在编写的文档是一个技能时，请阅读 [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md)，了解前置元数据、调用方式的选择，以及路由技能。

## 上下文指针

**上下文指针（context pointer）** 是智能体上下文中持有的一条引用，它指向一份"上下文之外"的资料，并编码了触达该资料的条件。技能的 `description` 就是一条；`AGENTS.md` 中指向某份文档的一行也是同一回事。决定智能体何时、以多高的可靠性触达这份资料的，是这条指针的*措辞*，不是它的指向。一个本应被触达的指向目标，却藏在一段措辞含糊的指针背后：这是一个方差 bug：先打磨措辞；只有当打磨失败时，才把资料直接内联进去。

一条指针承担两件事：说明这份资料是什么，以及列出应当触发触达它的**分支**（branch 是这份文档所处理的一种独立情形，所以不同次运行会走不同的路径）。每一条始终加载的指针里的每一个词，在每一次轮次中都在付代价，所以它需要比正文更严格的精简：

- **把"引导词"前移**：指针是触发工作真正发生的地方。
- **一个分支对应一个触发词。** 同义词把同一个分支换了个说法写两遍，本质上是一个分支；把它们合并，只保留真正不同的分支。
- **去掉正文已经承载的身份信息。**

## 两种负载

你新增的每一份文档与每一条指针，都在花两种预算之一：

- **上下文负载（Context load）**：始终加载的资料占据智能体窗口的代价：一行 `AGENTS.md`、一条技能描述，任何始终留在上下文里、无论是否触发都在消耗 token 与注意力的东西。
- **认知负载（Cognitive load）**：消耗在人类身上的代价：有哪些文档存在、各自在什么时候用。人类就是这个索引。它不是要被最小化的代价：它是人类能动性的价格；把它花在需要人类判断的地方，在不需要的地方去除。

只通过指针触达的资料，逃脱了上下文负载，代价是这条指针自身那一行；完全没有指针的资料，则完全依靠认知负载。

## 信息层次

一份文档由两种内容类型组成：**步骤（steps）**（智能体按顺序执行的动作）和**参考资料（reference）**（按需查阅的定义、规则、事实）。两者可以自由混合：全是步骤（一份操作指南）、全是参考资料（一份审查规则，就像本技能）、或者两者兼具。核心决策是：每块内容应该放在**信息层次**的哪一级：这是一架按"智能体对资料的即时需要程度"排序的梯子：

1. **文件内步骤（In-file step）** 是主要层级：智能体按顺序做的事情。
2. **文件内参考资料（In-file reference）** 按需查阅。常常是合理的扁平同级集合（一条审查规则就是一个层级），这是妥当的安排，不算坏味道。
3. **披露型参考资料（Disclosed reference）** 被推到一份独立的文件中，通过一条上下文指针触达，仅在该指针触发时才加载。跨度可以是从同一文件夹里的相邻文件，到放在任何地方的完全外部参考资料：任何文档都可以指向它。

向下推得不够，顶层就会臃肿；向下推得太多，就会把智能体真正需要的资料藏起来。这种张力就是整个决策。

**渐进披露（Progressive disclosure）** 是沿着这架梯子向下移动（移出主文件、藏到指针背后）的过程，目的是让顶层保持清晰可读。它主要不是为了优化 token：它是保护这架层次结构的手段。分支是最干脆的披露测试：每个分支都需要的内容内联，只有部分分支才会触达的内容推到指针背后。当一份文档有步骤时，本应被披露的文件内参考资料会把它们埋掉，让关注它们变成一件靠运气的事：这是一个方差杠杆，不只是一个可读性杠杆。

**共置（Co-location）** 是文件内的同伴概念：层次结构决定一块内容要放得*多深*，共置决定一旦放到那里，*什么内容与它并排*。把一个概念的定义、规则、注意事项放在同一个标题下，而不是散布在各处，这样读到一处时，它旁边的内容也会跟着进入视野。检验标准是：这份文档读起来，应该像为智能体写的文档。归在一处的资料读起来是这样；分散的资料则不是。（这与"重复"是不同的概念：重复是把同一个意思说两遍；分散是把一个意思碎成多块。）

**蔓延（Sprawl）** 是这里的失败模式：一份文档即使每行都是活的、独特的，也只是单纯地太长。注意力会在冗余中变薄，每多出一行就多一分维护相关性的负担。治疗手段就是这架梯子：通过指针披露参考资料，并按分支或顺序拆分，让每条路径只携带它需要的内容。

## 步骤与完成标准

每一步都以一个**完成标准**收尾：告诉智能体"工作完成"的那个条件。两个性质让它成为一个杠杆：

- **清晰度（Clarity）**：智能体能区分完成与未完成吗？一个含糊的边界（比如"达成理解"）会招致**提前完成**：在这一步真正完成之前就结束，注意力滑向了"完成的状态"。前面仍然可见的步骤（**后续步骤**）提供了拉力；完成标准的清晰度则是阻力。依序防守：**先打磨边界**（局部且廉价）；只有在它本质上就是模糊的、*并且*你观察到了急赶现象时，才通过拆分顺序把后续步骤藏起来。隐藏只有在跨越真正的上下文边界（一次交接或一次子代理分派；一次内联调用会把后续步骤留在上下文里，什么也清不掉）时才有效。
- **要求度（Demand）**：它要求多少。"每一个被修改的模型都被记录"比"产出一个变更清单"逼出了更彻底的工作。要求度驱动**跑腿工作（legwork）**：智能体在工作内部完成的挖掘，潜伏在措辞里而不是被写成单独的步骤：而它不是步骤绑定的："每一条规则都应用"约束的是一整块扁平参考资料，正如"每一步都完成"约束的是一段顺序，这也是为什么一份全参考资料的文档依然承载着"穷尽性"的标准。

最强的完成标准，既是可检验的，也是穷尽性的。

## 何时拆分

把一份文档拆成两份，是在花两种负载中的一种，所以只有在切分"赚得到"时才拆：

- **按顺序拆分**：当一段步骤中，后面的完成步骤会引诱智能体赶在它前面那一步之前匆匆收尾时，就把它拆开。把后续步骤挡在视野之外，会逼着智能体在当前任务上做更多跑腿工作。要小心反向操作：合并顺序会让每一步的"后续步骤"暴露在接下来发生的事情之前，引诱提前完成。
- **按调用方式拆分**：技能特有的切法，参见 [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md)。

## 引导词

**引导词（leading word）** 是一个已经存在于模型预训练中的紧凑概念，智能体在执行这份文档时就是用这个词来思考的（_lesson_、_fog of war_、_tracer bullets_）。它作为一个 token：而不是一句句子：被反复使用，能在最少 token 数下累积一个分布式的定义，并通过调用模型已经持有的先验知识，锚定一整片行为。造一个新词也行，前提是你把它定义清楚；但生造的词招不来任何先验：你得用定义 token 来支付一个预训练词免费给你的东西；先去找一个已有的词。

它锚定两次。在正文中，_执行_：每次这个词出现，智能体都会唤起同样的行为；在扁平参考资料内部，它把注意力集中在一类该去找的东西上。在一条指针里，_调用_：当同一个词同时出现在你的 prompt、文档与代码库中时，智能体会把这种共享语言与那份资料关联起来，更可靠地触达它。

去主动寻找可以用引导词重构的机会。一个被展开在三处的三元组，一条用一句话去暗示某个想法的指针。每一处都在哀求被压缩成一个 token：

- "fast, deterministic, low-overhead" → _tight_（一个 _tight_ 的循环）。
- "a loop you believe in" → _red_，把一个模糊的门控变成一个二元可观察状态（循环在 bug 上变 _red_，或不 _red_）。

你赢两次：token 更少，并且给智能体提供了一个更锐利的"挂钩"来挂住它的思考。假设每一份文档都带着一些引导词可以替换掉的复述。去找它们。

**否定（Negation）** 是这条杠杆旁边的失败模式：用禁止来引导，会把被禁止的行为拽进上下文，让它变得*更*可触达，而不是更少。"不要想一头大象"，于是大象就出现了；否定是一个弱修饰，被强烈激活的概念压过，于是禁止被半读成"去做这件事"。请**正面**提示：陈述目标行为（比如"写单行注释"），这样被禁止的那个就根本不会被说出来。只有当一个禁令无法正面措辞时，它才有立足之地；即便如此，也要把它和正面的目标搭配起来，让注意力落在"该做什么"上。

## 修剪

- 让每一种含义只放在**单一权威来源**：一个权威之处，所以修改行为只改一处。**重复（Duplication）**（同一含义出现在不止一个地方）既消耗维护成本也消耗 token，并且把一个含义在层次结构上的显著度抬高，超过它真实的位次。（这是"引导词"的意外反面：引导词是有意重复一个 token、绝不重复含义。）
- **环境**也是一种权威来源（`package.json` 脚本、配置文件、目录布局、`--help` 输出），而把环境复述一遍的文档就是一份**缓存（cache）**：一份"查找"的副本，只有当这次查找代价高昂时才赚得回来。缓存那些智能体通过查找得不到的东西：未被写下的惯例、选择背后的原因、配置不会坦白的小坑。把那些"一个文件、一条命令"就能查到的查找，交给环境本身，它永远不会过时。
- 逐行检查**相关性**：这一行还在支撑这份文档要做的事吗？一行会失去相关性，要么因为它从未真正承担过这个任务（只是说明、或者本应被披露的分支），要么因为它所描述的行为或世界已经变化，沦为陈旧。更短的文档更容易保持相关。没有修剪纪律，默认命运就是**沉积（sediment）**：陈旧的一层层积淀，因为"添加"感觉安全、"删除"感觉冒险，直到你不得不打穿它们去寻找还活着的东西。
- 逐句猎杀**无操作（no-ops）**：一条模型本来就默认遵守的指令，用负载只说了一句空话。检验标准（"这条指令相对默认行为是否改变了行为？"）是相对于模型的，而不是相对于读者的：两个关于 no-op 的人如果意见相左，他们其实是在对默认行为有分歧，而应当通过运行这份文档来解决，而不是靠争论。当一个句子失败时，删除整句，而不是从它里面挑几个词来削。检验标准同样用来评级引导词：一个弱到打不过默认行为的词（"要彻底"，而智能体本来就差不多彻底）就是一个 no-op，修正方法是换一个更强的词（_relentless_），而不是换一种技巧。

