writing-for-agents について
skill、AGENTS.md、CLAUDE.mdや参照先の文書など、エージェント向けドキュメントの執筆ガイドです。ポインター、情報階層、完了条件を通じて、実行プロセスの予測可能性を高める方法を説明します。
主な機能
- 01トリガーを備えたコンテキストポインターの設計
- 02コンテキスト負荷と認知負荷の区別
- 03階層に沿った手順と参照情報の整理
- 04確認可能な完了条件の定義
- 05順序や呼び出し方式に基づく文書分割
- 06重複、古い内容、ノーオペレーションの削除
活用シーン
- 01エージェント向けプロジェクト文書の執筆
- 02後から読み込む参照情報の選定
- 03エージェント手順の完了条件の改善
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vinvcn/ mattpocock-skills-zh-cn --skill writing-for-agentsインストール後、Claude Code で/writing-for-agentsを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlSKILL-MECHANICS.md
詳細
エージェントが消費するあらゆるドキュメントへの参考資料:スキル、AGENTS.md / CLAUDE.md、ポインター経由で到達するドキュメント。包み方は異なりますが、書き方そのものに違いはありません。同じレバーがどれも予測可能にします。つまり、エージェントが毎回の実行で同じ プロセス を取ることであり、同じ output を生み出すことではありません。
書いているドキュメントがスキルである場合は、SKILL-MECHANICS.md を読んで frontmatter、invocation の選択、router skills について理解してください。
Context pointers
context pointer とは、エージェントの context 内に保持される reference であり、ある context の外にある材料を名指しし、それに到達する条件をエンコードしたものです。ある skill の description はその一つです。AGENTS.md の中であるドキュメントを名指しする一行も同じオブジェクトです。エージェントがいつ、どれだけ確実に材料へ到達するかを決めるのは、ポインターの 文言 であり、その対象ではありません。対象でなければならないのに、弱い文言の pointer が担っている内容は variance bug です。まず文言を磨き、磨いてもうまくいかないときだけその材料をインライン化してください。
ポインターは二つのことを行います。材料が何であるかを示し、それを到達させるべき branches を列挙します(branch とはドキュメントが扱う独立した状況であり、それによって異なる runs が異なる経路を通ります)。常にロードされるポインターは、その一語一語が毎ターンコストを支払うため、本文以上に大胆に削るべきです。
- leading word を先頭に置く:ポインターはそこでトリガーの仕事をします。
- branch ごとに trigger を一つ。 同義語が単一の branch に別名を付けているだけなら、それは同じ branch を二度書いたことになります。それらを統合し、本当に異なる branches だけを残してください。
- 本文がすでに担っている identity を削除する。
二つの load
あなたが追加するすべてのドキュメントと pointer は、二つの予算のどちらかを消費します。
- Context load:常にロードされる材料がエージェントの window に課すコスト。
AGENTS.mdの一行、ある skill description、毎ターン context 内に横たわるあらゆるものは、トリガーされるかどうかに関わらず tokens と注意力を消費します。 - Cognitive load:人間に対するコスト。どのドキュメントが存在し、それぞれをいつ手に取るか。人間が index そのものです。これは最小化すべきコストではなく、human agency の代価です。人の判断が効くところに使い、効かないところからは取り除いてください。
pointer 経由でしか到達できない材料は、その pointer 自身の一行を代価に context load を逃れます。pointer がまったくない材料は、完全に cognitive load が担います。
情報階層
一つのドキュメントは二種類の内容から成ります。steps(エージェントが実行する順序立った動作)と reference(必要に応じて参照する定義、ルール、事実)で、これらは自由に混ざります。すべてが steps(レシピ)、すべてが reference(ある review のルール、この skill)、あるいは両方です。核心となる判断は、各内容の塊を information hierarchy のどこに置くかです。これはエージェントが材料をどれだけ即座に必要とするかで並べた ladder です。
- In-file step(primary tier):エージェントが順番に行うこと。
- In-file reference:必要に応じて参照する。多くの場合、正当な flat peer-set(ある review のすべてのルールが一つの rung にある)であり、これは妥当な配置であって、悪い匂いではありません。
- Disclosed reference:独立したファイルに押し出し、context pointer 経由で到達し、pointer がトリガーされたときだけロードされる。同じフォルダー内の sibling ファイルも、どこにでも存在しどのドキュメントからも指せる完全に external な reference も含みます。
下放する内容が少なすぎると最上位が膨張します。下放する内容が多すぎると、エージェントが実際に必要とする材料が隠れます。その緊張こそが判断のすべてです。
Progressive disclosure は ladder を下る動作です(メインファイルから出し、pointer の後ろに置く)。これにより最上位が明瞭に保たれます。これは主に token 最適化ではありません。hierarchy が守られる方法なのです。Branching が最も明快な disclosure のテストです。各 branch が必要とする内容はインライン化し、一部の branches だけが到達する内容は pointer の後ろに置いてください。ドキュメントに steps があるとき、本来 disclose されるべき in-file reference はそれらを埋もれさせ、それらに注意を払うことをコイン投げに変えます。これは可読性のレバーだけでなく、variance のレバーです。
Co-location はファイル内の付随動作です。ladder が内容を どれだけ下へ移すか を決め、co-location はそこに着いたら その隣に何があるか を決めます。ある概念の定義、ルール、caveats を同じ heading の下に置き、あちこちに散らさないでください。そうすれば一部分を読むときその隣人もついてきます。検証基準:ドキュメントはエージェント専用に書かれた documentation のように読めるべきです。グループ化された材料はそう読めますし、散らばった材料はそう読めません。(これは duplication とは異なります。duplication は同じ意味を二か所で繰り返すことです。散らばりは一つの意味を多くの場所に断片化することです。)
Sprawl はここでの失敗モードです。たとえ一行一行が live で unique であっても、ドキュメントが長すぎる状態です。注意力は余分な内容の上で薄まり、余分な一行ごとに保守すべきものが一つ増えます。治療法は ladder です。reference を pointers の後ろに disclose し、branch または sequence ごとに分割し、各経路がそれに必要なものだけを運ぶようにしてください。
Steps と completion criteria
すべての step は completion criterion で終わります。これはエージェントに仕事が完了した条件を伝えます。二つの属性がこれをレバーにします。
- Clarity:エージェントは done と not-done を区別できるか? 曖昧な境界("understanding reached")は premature completion を誘発します。つまり step が本当に完了する前に終わらせ、注意力が being done へ滑ります。まだ見えている後続の steps(post-completion steps)は引っ張る力を与えます。criterion の明瞭さは抵抗力です。順を追って防御してください。まず境界を sharp にする(局所的で安価)。それが不可避的に曖昧 かつ あなたが rush を観察したときにのみ、sequence を分割して後続の steps を隠してください。しかも隠すのは本当の context boundary(hand-off または subagent dispatch。inline 呼び出しは後続の steps を context に残し、何も消しません)を越えるときにだけ効きます。
- Demand:それがどれだけを要求するか。"Every modified model accounted for" は徹底的な仕事を強いますが、"produce a change list" はそうしません。Demand は legwork(エージェントが仕事の内部で行う掘り下げであり、独自の step として書かれるのではなく文言に潜むもの)を駆動し、それは step に縛られません。"every rule applied" が一整套の flat reference を縛るのは、"every step done" が一つの sequence を縛るのと同じであり、それこそが全 reference のドキュメントがなお網羅性の敷居を帯びる理由です。
最強の criteria は検証可能でありかつ網羅的です。
いつ分割するか
ドキュメントを二つに分割すると二つの load のどちらかを消費するため、その一太刀がコストを取り戻すときにだけ分割してください。
- By sequence:post-completion steps がエージェントを目の前のその step を早く終わらせようと誘うとき、一連の steps を分割します。それらを視界の外に遮ることで、現在のタスク上でより多くの legwork が駆動されます。逆の面に注意してください。sequences を統合すると、各 step の後続 steps がその先にあるものへ露出し、premature completion を誘発します。
- By invocation、skill 専用:
SKILL-MECHANICS.mdを参照してください。
先導語
先導語とは、モデルの事前学習にすでに存在する、コンパクトな概念です。エージェントはドキュメントを実行する際に、それを使って考えます(lesson、fog of war、tracer bullets)。先導語は文としてではなく、トークンとして繰り返し現れ、分散した定義を積み重ねながら、モデルがすでに持つ事前知識を呼び起こし、最小限のトークンで一連の行動を固定します。自分で言葉を作ってもかまいません。ただし、明確に定義してください。造語では事前知識を呼び起こせないため、定義において、事前学習済みの語なら無料で提供してくれるものを補う必要があります。まずは既存の言葉を使いましょう。
先導語は2つの方法で固定します。本文では execution を固定します。この語が現れるたびに、エージェントは同じ行動に手を伸ばし、フラットなリファレンスの中で、探すべき種類のものに注意を向けます。ポインターでは invocation を固定します。同じ語がプロンプト、ドキュメント、コードベースに存在すれば、エージェントはその共通言語を資料につなげ、より確実にたどり着けます。
先導語を使って、文章を再構成できる箇所を探しましょう。3か所にまたがって説明された三つ組や、概念を指すのに一文を費やしているポインターなど、あらゆる段落が、1つのトークンへと集約されることを求めています。
- 「速く、決定的で、オーバーヘッドが小さい」→ tight(tight なループ)。
- 「信頼できるループ」→ red:曖昧なゲートが、二値で観察可能な状態になります(ループのバグが red になるか、そうならないか)。
2つの利点があります。トークンが減り、エージェントが思考を結び付ける、より明確なフックが得られます。各ドキュメントには、先導語で置き換えられる言い換えが含まれていると考え、それを探しましょう。
否定表現は、この手法に隣接する失敗パターンです。禁止による誘導は、禁止した行動をコンテキストに引き込み、浮かび上がりにくくするどころか、かえって 浮かび上がりやすく します。ゾウを想像しないでください と言われれば、頭の中はゾウでいっぱいになります。否定表現は、強く活性化された概念に押し負ける弱い修飾語であり、禁止文は半分、その行動を促しているように読めます。プロンプトでは 肯定形を使い、目標とする行動を直接示しましょう(「1行のコメントを書く」)。そうすれば、禁止したいことを一切口にせずに済みます。禁止表現を使うのは、厳格なガードレールを肯定形で表現できない場合に限ります。その場合でも、何をすべきかに注意を向けるため、肯定的な目標を添えましょう。
削減
- それぞれの意味を 単一の信頼できる情報源に保ちましょう。つまり、行動を変えるときに1か所だけ編集すればよい、唯一の権威ある場所です。重複(同じ意味が複数の場所に現れること)は、メンテナンスコストとトークンを増やし、ラダー上でのその意味の目立ちやすさを、本来の位置よりも高めてしまいます。(これは先導語の意図しない反例です。先導語では、1つのトークンを意図的に繰り返しますが、意味は決して重複させません。)
- 環境もまた、信頼できる情報源です(
package.jsonの scripts、config files、ディレクトリ構成、--helpの出力)。環境を言い換えたドキュメントは キャッシュです。参照結果の複製であり、参照コストが高い場合にのみ、その読み込みに見合います。エージェントが環境を調べても見つけられないものをキャッシュしましょう。書かれていない慣習、ある選択の理由、設定ファイルからは分からない落とし穴などです。1ファイル、1コマンドで確認できる情報は環境に任せましょう。そうすれば古くなりません。 - 関連性を1行ずつ確認しましょう。その行は、ドキュメントが果たす役割を今も支えていますか?ある行は、タスクを支えることがない(説明にとどまる、あるいは明示すべき分岐を扱う)ために関連性を失うこともあれば、説明対象の行動や状況が変わって古くなることもあります。短いドキュメントほど、関連性を保ちやすくなります。削減の規律がなければ、たどり着く先は 堆積です。追加は安全に見え、削除は危険に見えるため、古くなった層が積み重なり、今も有効な情報を探すのに掘り進めなければならなくなります。
- すべての文を見直し、無効な記述を探しましょう。モデルが既定で従う指示は、読み込みコストだけを発生させ、何も伝えません。判定基準(既定の動作と比べて行動が変わるか?)は、読者ではなくモデルを基準にします。無効な記述について2人の意見が分かれるなら、実際には既定の動作について意見が食い違っています。議論ではなく、実行用ドキュメントで決着させましょう。文が基準を満たさない場合は、単語を削るのではなく、文全体を削除します。この基準は先導語の評価にも使えます。既定の動作に勝てない弱い語(エージェントがすでにおおむね徹底しているときの be thorough)は無効です。修正するには、より強い語(relentless)に置き換えましょう。手法を変えるのではありません。