このシリーズでは、AIエージェントを「コードを書かせる道具」ではなく、開発工程に入る作業者として扱います。
第0回では、全体を Plan、Work、Review、Compound に分けました。
第1回では、エージェントに渡す仕様書の書き方を扱いました。
第2回では、エージェントの仕事をどう検品するかを扱いました。
今回は、最後の Compound です。
Compound は、少し抽象的に聞こえます。けれど実務ではかなり具体的です。
同じ指摘を、次のPRでもまた書いていないか。
同じ調査を、別のセッションでまたゼロからやっていないか。
同じ失敗を、別のagentがまた踏んでいないか。
これを減らすのが Compound です。
言い換えると、AIエージェントとの開発で一番もったいないのは、失敗そのものではありません。
失敗から得た判断基準が、次の作業に戻らないことです。
Memoryは「覚える」ではなく「戻す」
AIエージェントの話になると、すぐ memory という言葉が出てきます。
ただ、ここで大事なのは「AIに何でも覚えさせる」ことではありません。
記憶が増えても、次の作業の入口で使われなければ意味がありません。古い判断、曖昧な好み、期限切れの仕様が混ざると、むしろ邪魔になります。
開発で必要な memory は、保管庫ではなく、戻り道です。
Review で見つかった問題を、次の Plan に戻す。
テストで落ちた条件を、次の仕様書に戻す。
人間が毎回説明している好みを、次の作業開始時に戻す。
調査で見つけた設計判断を、次の実装時に戻す。
この「戻す」仕組みを作ると、エージェントとの仕事は少しずつ楽になります。
毎回うまくプロンプトを書く人が強いのではありません。
毎回の作業結果が、次の作業の文脈になるチームが強い。
記憶には寿命がある
memory を考えるときは、保存先より先に流れを見ます。
- 何を残すか
- どう要約するか
- いつ取り出すか
- どこに注入するか
- いつ消すか
この5つです。
多くの失敗は、1番目だけを見て起きます。
「全部残す」だけでは、次回の作業は良くなりません。
古い判断が残る。
今回だけの事情が残る。
似たメモが増える。
重要なルールが埋もれる。
agent が毎回関係ない文脈を読む。
こうなると、memory は助けではなく負荷になります。
だから、memory には寿命を持たせます。
短期:
- 今回の調査ログ
- 一時的な仮説
- 作業中のメモ
中期:
- 何度か使う checklist
- 最近の失敗パターン
- 今月だけ有効な移行ルール
長期:
- repo-wide rule
- test command
- 触ってはいけない領域
- 繰り返す設計判断
短期のものを AGENTS.md に入れない。
長期のものをチャットの流れにだけ置かない。
この分け方が大事です。
memory は、保存、検索、注入、削除まで含めて設計します。
まず、残すものを3種類に分ける
何でも AGENTS.md に書けばいい、という話ではありません。
何でも CLAUDE.md に書けばいい、という話でもありません。
何でも memory tool に保存すればいい、という話でもありません。
残すものは、まず3種類に分けた方が扱いやすいです。
1つ目は、事実と入口です。
どのファイルから読むか。
どのコマンドでテストするか。
どの設計ドキュメントが今も有効か。
どの画面がどのコンポーネントに対応しているか。
これは README.md、docs/、INDEX.md、runbook に置きます。
2つ目は、作業ルールです。
このリポジトリでは何をしてはいけないか。
変更前に何を読ませるか。
テストが失敗したとき、どこまで直してよいか。
大きな変更をするとき、どこで止まるべきか。
これは AGENTS.md や project-scoped memory に置きます。
3つ目は、手順です。
バグ再現の手順。
PR review の手順。
DB migration の確認手順。
障害調査の切り分け手順。
仕様書を作る手順。
これは checklist、template、skill、custom command にします。
この3つを混ぜると、すぐ読みにくくなります。
AGENTS.md に全部入れると、agent は毎回長い注意書きを読むことになります。CLAUDE.md に全部入れると、個人の好みとリポジトリのルールが混ざります。memory tool に全部入れると、どれが今も有効な判断なのか分からなくなります。
最初に置き場所を分けるだけで、かなり事故が減ります。
AGENTS.mdに書くもの
AGENTS.md は、エージェント向けのリポジトリ説明書です。
人間向けの README.md が「このプロジェクトは何か」を説明するものだとしたら、AGENTS.md は「このプロジェクトで作業するとき、どう振る舞うべきか」を説明するものです。
書くべきなのは、毎回効いてほしいルールです。
たとえば、こういうものです。
# AGENTS.md
## Before Editing
- 変更前に関連する router、service、test を読む。
- UIだけを見て API 契約を推測しない。
- 既存の helper がある場合、新しい wrapper を作る前に使えるか確認する。
## Commands
- Unit test: `pnpm test`
- Type check: `pnpm typecheck`
- Lint: `pnpm lint`
## Boundaries
- 認証まわりの仕様変更は、このタスクの範囲外なら触らない。
- migration を追加した場合は rollback 手順も書く。
- flaky test を消す場合は、理由をPR本文に残す。
## Stop Conditions
- 仕様と実装が矛盾している場合、勝手に片方へ寄せずに止まる。
- テスト失敗の原因が今回の変更範囲外なら、修正候補をまとめて止まる。
- public API の戻り値を変える必要が出たら、実装前に確認する。
ここで大事なのは、AGENTS.md を願望リストにしないことです。
悪い例です。
- きれいなコードを書く。
- 最高の実装にする。
- バグを出さない。
- 丁寧に作業する。
これはほとんど効きません。
「きれい」とは何か。
「最高」とは何か。
「丁寧」とは何をすることか。
agent が実行可能な形になっていないからです。
良い AGENTS.md は、行動に落ちています。
- `services/search.ts` を変更した場合、`tests/search/*.test.ts` を実行する。
- 新しい検索条件を追加した場合、既存条件との組み合わせテストを1つ以上追加する。
- SQL を変更した場合、空結果、複数件、権限なしの3ケースを確認する。
このくらい具体的なら、次の Plan と Review に戻ってきます。
AGENTS.mdは「受け入れる成果物」も決める
SQLite の AGENTS.md は、この点でかなり面白いです。
SQLite は、agent が生成したコードをそのまま受け入れるわけではありません。一方で、agent が作った bug report、再現手順、test case は受け入れやすい。
これは重要です。
AIエージェントとの開発では、「何を作らせるか」だけでなく、「何なら受け入れるか」を決める必要があります。
たとえば、リポジトリによってはこう書けます。
## Accepted Agent Outputs
- 小さなテスト追加
- bug reproduction
- 失敗ログの整理
- 既存実装の調査メモ
- doc の更新案
## Outputs Requiring Human Review
- 認証、課金、権限、データ削除に関わる変更
- DB schema migration
- public API contract の変更
- 大きな依存ライブラリの追加
これは過剰に慎重な話ではありません。
むしろ、エージェントを実務に入れるための現実的な線引きです。
全部任せない。
けれど、全部禁止もしない。
どの成果物なら速く受け取れるかを決める。
ここが決まると、Codex や Claude Code に渡す仕事の粒度がかなり安定します。
CLAUDE.mdに書くもの
CLAUDE.md は、Claude Code でよく使われる作業文脈のファイルです。
AGENTS.md と似ていますが、完全に同じものとして扱わない方がいいです。
AGENTS.md は、リポジトリに入る agent 全体への作業ルール。
CLAUDE.md は、Claude Code で作業するときの文脈、好み、ワークフロー。
たとえば CLAUDE.md には、こういうものが向いています。
# CLAUDE.md
## Working Style
- 最初に関連ファイルを読み、すぐ実装に入らない。
- 変更案が複数ある場合、既存パターンに近い案を優先する。
- 大きい変更は Plan を出してから進める。
## Review Preference
- review では、style より behavior regression を優先して見る。
- 問題がない場合も、残るリスクとテスト不足を書く。
## Project Notes
- 管理画面は密度を優先する。marketing page のような大きな hero は使わない。
- API 層では既存の serializer を通す。
ただし、CLAUDE.md は長くしすぎない方がいいです。
長すぎる CLAUDE.md は、それ自体が負荷になります。毎回すべてを読ませると、そのセッションに関係ない情報まで文脈を圧迫します。
長くなったら、分けます。
CLAUDE.md
docs/agent-guides/
review.md
migration.md
frontend.md
incident-debugging.md
skills/
write-pr-review/
reproduce-bug/
draft-spec/
常に読むものは短く。
必要なときだけ読むものは guide や skill へ。
この分け方ができると、memory はかなり軽くなります。
INDEX.mdは地味だが効く
大きいリポジトリでは、agent はまず迷います。
どこから読めばいいのか。
何が古い設計で、何が今の設計なのか。
似た名前のファイルのうち、どれが入口なのか。
ここで INDEX.md が効きます。
INDEX.md は、長い説明書ではありません。入口の地図です。
# Project Index
## Product List
- `app/products/page.tsx`
- 商品一覧画面の入口。
- `components/products/ProductTable.tsx`
- 一覧表示とページング。
- `services/product-search.ts`
- 検索条件を組み立てる service。
- `tests/product-search.test.ts`
- 商品検索の主要ケース。
## Auth
- `middleware.ts`
- route guard。
- `services/session.ts`
- session 読み取り。
- `tests/session.test.ts`
- 権限まわりの回帰テスト。
## Do Not Start Here
- `legacy/products-old.tsx`
- 旧画面。参照だけ。新規変更はしない。
これだけで、最初の調査コストがかなり下がります。
agent は全部読めるように見えますが、実際には入口が悪いと時間を無駄にします。関係ないファイルを読み、古い実装を参考にし、似ているが違うテストを修正します。
INDEX.md は、その無駄を減らすための小さな地図です。
Skillにするもの
何度も繰り返す作業は、skill にします。
ここでいう skill は、特定のagentが必要なときに読む手順書です。Claude Code の skill でも、Codex の project guide でも、独自の skills/ ディレクトリでも構いません。
目安は単純です。
週に一度やるなら、skill にする候補です。
たとえば、こういうものです。
- 仕様書を作る
- PRをreviewする
- バグを再現する
- flaky test を切り分ける
- migration を確認する
- release note を書く
- 障害調査メモを作る
- セキュリティ影響を確認する
skill にするときは、抽象的な説明より、入力と出力をはっきりさせます。
# Skill: Bug Reproduction
Use this when a user reports a bug but the root cause is unknown.
## Inputs
- User report
- Relevant logs
- Suspected route or component
## Steps
1. Rephrase the symptom in one sentence.
2. Identify the smallest path that can reproduce it.
3. Search for tests covering the same path.
4. Add or update one failing test before changing implementation.
5. If reproduction is impossible, write what evidence is missing.
## Output
- Reproduction steps
- Failing test or reason why no test was added
- Suspected cause
- Next action
これくらいなら、次に同じ種類のバグが来たときに使えます。
「バグを調べて」と頼むより、かなり強いです。
Compound noteを書く
Review の最後に、毎回少しだけ Compound note を書きます。
これは長い日報ではありません。
次の作業に返すためのメモです。
たとえば、検索機能のPRをreviewしたとします。
問題はこうでした。
- 商品名検索は追加された
- category filter と同時に使うと壊れる
- テストは商品名だけを見ていて、既存filterとの組み合わせを見ていない
その場でコードを直すだけなら、次回また同じことが起きます。
Compound note にすると、こうなります。
## Compound Note
### What failed
商品名検索の実装で、既存の category filter との組み合わせが漏れた。
### Pattern
新しい検索条件を追加するとき、単体条件だけをテストしてしまい、既存条件との組み合わせを見落としやすい。
### Add to AGENTS.md
- 検索条件を追加・変更した場合、既存条件との組み合わせテストを1つ以上追加する。
### Add to Review Checklist
- 新しい filter は、既存 filter と同時に指定したケースを確認したか。
### Add to Spec Template
- 既存条件との組み合わせで期待結果を書く。
この note の価値は、「今回の失敗」を「次回の入口」に変えることです。
ここまでやって初めて、Review が Compound になります。
悪いCompound note、良いCompound note
悪い note は、反省文になります。
次からはもっと注意する。
検索まわりは気をつける。
テストをちゃんと書く。
これはほとんど効きません。
良い note は、次の作業に入ります。
検索条件を追加した場合、単体条件だけでなく既存条件との組み合わせテストを追加する。
対象: `services/product-search.ts`
確認先: `tests/product-search.test.ts`
Review checklist: filter composition を確認する。
「気をつける」ではなく、次の Plan、Review、Test に入る形にします。
どこに戻すかを決める
Compound note を書いたら、置き場所を決めます。
この表でだいたい判断できます。
| 戻したい内容 | 置き場所 |
|---|---|
| リポジトリ全体の作業ルール | AGENTS.md |
| Claude Code での作業方針 | CLAUDE.md |
| 入口ファイルの地図 | INDEX.md |
| 何度も使う手順 | skill / custom command |
| 毎回確認する条件 | checklist / eval |
| 仕様書に入れるべき項目 | spec template |
| 判断理由の記録 | ADR / docs |
| その場限りの調査ログ | PR comment / issue comment |
全部を永続化しないことも大事です。
一回だけの調査ログを AGENTS.md に入れると、すぐ汚れます。
逆に、毎回同じreview指摘をPRコメントだけに書いているなら、それは永続化すべきです。
判断基準はこうです。
次の3回の作業でも効くなら、残す。
今回だけなら、残さない。
迷うなら、まず checklist に置く。
Memory layerが出てくる場所
ここで、GPS、Walrus Memory、Minimi のような memory layer が自然に出てきます。
ただし、これらを「記憶ツール」とだけ見ると弱いです。
開発での役割は、次の作業開始時に必要な文脈を戻すことです。
たとえば、こういう問題があるとします。
- agent が毎回同じrepo ruleを忘れる
- 過去の設計判断を毎回説明している
- 別のアプリや別のセッションで決めたことが戻ってこない
- 「前回なぜその実装にしなかったか」が消える
この段階で、memory layer が候補になります。
GPS は、repo rules と past lessons を保存する memory layer として紹介されています。
Walrus Memory は、apps と sessions をまたいで agent が context を持つための道具です。
Minimi は、Claude 向けの ambient memory という位置づけです。
どれを使うかより先に、何を戻したいかを決めます。
悪い使い方です。
全部覚えておいて。
良い使い方です。
このrepoでは、検索条件を追加したら既存filterとの組み合わせテストを必ず追加する。
次回 product search に触るとき、このルールを Plan に戻す。
memory は、量より呼び戻し方です。
Recursiのような道具はどこに入るか
Recursi のような道具も、単に「AIが自分で改善する」と見るより、作業ループのどこに入るかで考えた方がいいです。
Plan、Work、Review、Compound の中では、主に Compound 側です。
作業中に出た修正パターンを、次の作業に戻す。
失敗した流れを、次の実行手順に反映する。
同じ種類の作業を、前回より少ない説明で始められるようにする。
これができるなら、「自分たちの作業に合わせて育つ」という言葉に実体が出ます。
逆に、ただ毎回長いコンテキストを持たせるだけなら、改善ではありません。
学びが戻る場所が必要です。
手順を分ける意味
ここで面白いのは、実装そのものよりも、工程を分けることです。
多くの人は、AIエージェントにこう頼みます。
この機能を作って。
でも、工程として見るなら、こう分けます。
まず plan して。
次に小さく work して。
その結果を review して。
最後に今回の学びを compound して。
これは形式的な違いではありません。
最後に compound を明示すると、agent は「次回に残すべきもの」を探し始めます。
人間も同じです。
作業を終えた瞬間に、すぐ次のタスクへ行くと、学びは消えます。
5分だけでも、次に戻すものを決める。
この5分が、長期的にはかなり効きます。
実例:検索機能PRをCompoundする
もう少し実務に寄せます。
商品一覧に検索を追加するタスクがありました。
仕様はこうです。
商品一覧に商品名検索を追加する。
既存の category filter、status filter、pagination は維持する。
agent は実装しました。
Review で、category filter と検索語を同時に指定したときに壊れることが分かりました。
その場で修正するだけなら、ここで終わりです。
Compound までやるなら、4か所に戻します。
1. AGENTS.mdに戻す
## Search Changes
- 検索条件を追加・変更した場合、既存条件との組み合わせテストを追加する。
- filter、sort、pagination のどれかに触った場合、同時指定ケースを確認する。
これは repo 全体で繰り返し効くルールです。
2. 仕様書テンプレートに戻す
## Existing Behavior To Preserve
- category filter:
- status filter:
- sort:
- pagination:
- empty state:
## Combination Cases
- new condition + category:
- new condition + status:
- new condition + pagination:
次の仕様書を書くとき、最初から既存挙動を確認できます。
3. Review checklistに戻す
## Search Review Checklist
- 新しい条件は単体で動くか。
- 既存条件と同時に指定しても動くか。
- pagination の total count は正しいか。
- empty result の表示は壊れていないか。
- URL query と内部 state は同期しているか。
次のPR reviewで、人間が同じことを思い出さなくて済みます。
4. Test/Evalに戻す
it("combines keyword search with category filter", async () => {
const result = await searchProducts({
keyword: "desk",
category: "furniture",
});
expect(result.items).toEqual([
expect.objectContaining({
name: expect.stringContaining("desk"),
category: "furniture",
}),
]);
});
毎回人間が読むより、テストにした方が強いものはテストにします。
ここまでやると、次の agent は最初から違う地図で作業できます。
これが Compound です。
Compoundは「ドキュメントを増やすこと」ではない
ここで注意があります。
Compound を始めると、ファイルが増えます。
AGENTS.md が増える。
CLAUDE.md が増える。
docs/agent-guides/ が増える。
skill が増える。
checklist が増える。
増やすこと自体が目的になると、すぐ破綻します。
古い memory は、古い依存ライブラリと同じです。
存在しているだけで、次の作業に影響します。
だから、定期的に見直します。
## Memory Review
- このルールは今も有効か。
- すでにテストで保証できているなら、文書から消せないか。
- 特定機能だけの話を repo-wide rule にしていないか。
- 古い設計判断が残っていないか。
- agent が読んでも実行できる表現になっているか。
memory は、足すだけではなく、削る必要があります。
小さく始めるなら、この4つだけでいい
最初から完璧な memory system を作る必要はありません。
まずは4つで十分です。
1つ目。AGENTS.md に、テストコマンド、禁止事項、停止条件を書く。
2つ目。INDEX.md に、主要機能の入口ファイルを書く。
3つ目。PR review の最後に、Compound note を3行だけ書く。
4つ目。同じ指摘が2回出たら、AGENTS.md、template、test、skill のどこかに戻す。
このくらいなら、すぐ始められます。
## Compound Note
- What failed:
- Pattern:
- Where to return it:
最初はこれだけでいいです。
大事なのは、作業の最後に「次回へ戻すものは何か」と聞くことです。
Codex App / Claude Codeではどう使うか
Codex App や Claude Code を使う場合も、考え方は同じです。
最初に agent に渡すのは、巨大な指示文ではありません。
まず AGENTS.md と INDEX.md を読んでください。
今回のタスクに関係するファイルだけを追加で読んでください。
実装前に Plan を出してください。
作業中は、Work を小さく切ります。
まず検索条件の組み立て部分だけ変更してください。
UIはまだ触らないでください。
Review では、検品する観点を渡します。
差分を review してください。
特に既存filter、pagination、empty state の regression を見てください。
最後に Compound します。
今回の作業から、次回に戻すべきルール、checklist、test、skill 候補を挙げてください。
AGENTS.md に入れるべきものと、今回だけのメモを分けてください。
これで、agent は単発の実装者ではなく、工程の中で学習を返す作業者になります。
まとめ
AIエージェントを使うと、一回の作業は速くなります。
でも、それだけではチームの開発速度は安定しません。
安定させるには、Review で見つかったことを次の Plan に戻す必要があります。
AGENTS.md は、repo-wide な作業ルール。
CLAUDE.md は、Claude Code 向けの作業文脈や好み。
INDEX.md は、リポジトリの入口地図。
skill は、繰り返す手順。
memory layer は、過去の判断を次の作業開始時に戻すための部品。
どれも、ただ増やせばいいものではありません。
目的は、AIにたくさん覚えさせることではない。
次の作業を、前回より少し良い状態から始めることです。
次回は、AIエージェントに実行させる前の話をします。
sandbox、権限、ファイル境界、secret、ネットワークアクセス。
エージェントを強くするほど、実行環境の設計が重要になります。