チームでAIに成果物を作らせて、人がレビューして、直させる、を毎日やっています。その「直させる」が、どこにも残っていないことに気づきました。
うちの流れはこうです。
- 空コミットでPRを作る
- ローカルでAIに成果物を作らせて、人が確認し、問題があればその場で直させる
- 揃ったらpushしてPRを更新する
- モブレビューかPRレビューで指摘をもらい、直して完成させる
2の修正指示は、ローカルのチャットで消えます。4のPRコメントは残っています。過去にPRコメントを元にチェックルールを作ってみたこともありますが、効果があるか分からず、やめてしまいました。同じ指摘を別の人が別のPRでまたしています。普通に勿体無い。
「レビューの指摘をAIのルールに変える」という考え方自体は、もう新しくありません。CursorのBugbotは、この仕組みで11万リポジトリから4.4万本のルールを作っています。この記事は世の中でのベストプラクティスを調べてまとめた記事です。実際に試した結果はまた別の記事で書こうと思います。
世の中はもう、レビューの指摘からルールを作っている
| 出典 | やっていること |
|---|---|
| Cursor Bugbot learned rules(2026-04) | Bugbotのコメントへの反応、返信、人間レビュアーのコメントの3つを入力に、候補ルールを作る。候補は次のPRで評価され続け、有用と分かったら本番に昇格。否定的な反応が続けば無効化。ベータ以来11万リポジトリ・4.4万ルール |
| OpenAI harness engineering(2026-02) | 1枚の巨大なAGENTS.mdは失敗。AGENTS.mdは目次にして詳細はdocs/へ。古い記述や規約違反を見つけて修正PRを出すエージェントを定期的に回す。人の好みは1回だけ取り込み、custom linterで継続的に強制する |
| Claude Code auto memory(公式docs) | 人の修正をClaudeが自分で記録する。起動時に読むのは索引の先頭200行/25KBだけで、詳細は別ファイルにしてオンデマンドで読む。「Shorter files produce better adherence.」(短いファイルほど従いやすい) |
| ACE(ICLR 2026、Stanford/SambaNova/Microsoft) | コンテキストを「進化するplaybook」として扱う。実行役・振り返り役・整理役に分け、全体を書き直さず差分で足す。全体書き換えは伝言ゲームで情報が崩れる |
| LangSmithなどのトレース基盤(2026-03) | 人の修正を実行トレースに紐づけて溜め、評価データセットにする。成果物のない大量の出力(回答、エージェント実行)向き |
やり方は違いますが、共通する設計が4つあります。
- 入力は否定的な合図だけ(反応、返信、指摘)
- 候補と本番を分けて、本番には上限を置く
- 証拠で昇格し、使われないものは機械的に落とす
- 機械で判定できるものはlinterに逃がす
自分のチームで始める前に引っかかった疑問が3つあって、この4つで全部答えが出ました。
OKからは学べない。溜めるのはNGだけ
AIの提案に「それでいいよ」と言ったとき、何を「良い」と判断したのかは、わざわざ言語化しないことが多いです。だからOKを溜めても何も出てきません。OKが持っている情報は「今回は足すことがない」だけです。
世の中も同じ結論で、Bugbotの入力3つは全部NG側です。OpenAIも「人の好みを取り込む」対象は違反のほうです。
なので溜めるのはNGだけです。OKは「その後、同じファイルへの修正が来なかった」という形で暗黙に残るので、記録しなくても後から分かります。
「なぜダメか」は人に書かせず、繰り返しから引く
NGのときも、人は「ここがダメ、こうしてほしい」は言いますが、「なぜ」はあまり言いません。最初は「なぜ」を書いてもらう欄を作ろうかと思いましたが、やめました。毎回書かせると続かないし、1回のNGの「なぜ」は言った本人にも言語化できないことが多いからです。
代わりに、「なぜ」は繰り返しから機械的に出します。「このクラスに足さないで、新しいクラスに切り出して」という指摘が3回来たら、理由を聞かなくても「既存の大きなクラスにロジックを足すのを嫌う」というルールが抽出できます。Bugbotが候補ルールを次のPRで評価し続けるのも、人に理由を聞く代わりに繰り返しで確かめている形です。
人が残すのは「どこ・どうしてほしい」だけ。それは今のレビューコメントで既にやっています。抽象化はLLMの仕事にします。
ルール飽和を防ぐ方法:上限を設け、低利用率は機械的に落とす
一番の心配はここでした。溜めると陳腐化する。量が多すぎるとLLMが拾ってくれなくなる。多すぎると人が管理できない。
答えは「溜めない」でした。正確には、溜める場所と効かせる場所を分けて、効かせる場所に上限を置く、です。
| 層 | 中身 | 上限 | 陳腐化 |
|---|---|---|---|
| 記録 | 修正指示、レビューコメント | なし。溜まる一方でいい | 読むのは抽出するLLMだけなので、腐っても害がない |
| 本番ルール | CLAUDE.mdやrulesファイル | 数十行。1つ足すなら1つ消す | 一定期間発火しなければ落とす |
| 機械の制約 | linter、構造テスト、allowlist | なし | テストで守られるので腐らない |
LLMが拾わなくなるのは、本番の層が肥大化したときだけです。記録がいくら溜まっても、LLMに渡すのは本番の数十行なので、拾う確率は落ちません。Claude Codeのauto memoryが索引の先頭200行しか読まないのも、OpenAIがAGENTS.mdを目次にしたのも、同じ考え方です。
本番の上限を守るには、ルールを上か下に逃がします。
- 下へ:「このディレクトリからあのモジュールをimportしない」のように機械で判定できるものはlinterにする。プロンプトから消えるので、コンテキストを食わず、腐らず、破られない
- 上へ:「Aクラスに追記するな」「Bクラスに追記するな」が5つ並んだら、「既存の大きなクラスにロジックを足さず、新規クラスに切り出す」の1行にまとめる
陳腐化は、人が定期的に見直す設計にはしません。続かないからです。ルールが最後に効いた(違反を止めた、修正指示の根拠になった)日時を持たせて、3ヶ月効いていなければ削除候補にします。Bugbotの自動無効化、OpenAIの定期的な修正PR、ACEのカウンタによる剪定、どれも人の見直しに頼っていません。
記録が増えることは、許容することにしました。増える知識のほうが大きいし、抽出する前の記録なので、将来抽出のやり方が変わっても記録から引き直せます。どんなAIに置き換えることになっても必要になる情報です。
自分の設計:修正指示を、成果物と同じブランチに1行残す
記録を残す仕組みは1つだけです。AIが人から修正を受けたら、成果物と同じブランチのファイルに1行追記する。
date: 2026-09-19
artifact: docs/design/auth.md
instruction: 既存のUserManagerに足さず、新規クラスに切り出して
change: UserStatusCalculatorを新設。UserManagerは呼び出しのみに
置き場は.ai/corrections/<branch>.mdで、1ブランチ1ファイルです。専用のディレクトリにまとめて、対象はartifactのパスで指します。3でpushされるので、修正指示がPRに乗ってチームに見えます。どの成果物のレビューで出た指示かも分かります。人が新しく書くものはありません。
書き込むのはhook。AIの判断は入れない
「今のチャットが指摘かどうか」をAIに判断させるのはやめました。代わりに、Claude CodeのPostToolUse hookで、次の条件が揃ったときだけ書きます。
- AIが既に作ったファイルを、AIが書き換えた
- その直前に、人の発言がある
つまり「AIが作った → 人が何か言った → 同じファイルを書き換えた」の3つが揃ったら記録する。これは修正の定義そのものなので、判断は要りません。hookのスクリプトはtranscriptから直前の発言を取ってきて、そのままinstructionに入れます。要約させないのが要点で、記録は発言のまま残し、一般化は抽出側に任せます。
この境界で拾えないものもあります。
- ファイルが変わらない修正。「いや、そのままでいい」「前提が違う、考え直して」
- 最初の書き込みより前の指示
上2つは、成果物を作るskill側に「却下や方向転換があったらchange: noneで1行」を足せば埋まりますが、そこはAIの判断が入るので、まずhookだけで回してから決めます。
PRコメントは転記しない
PRコメントは、対象ファイル、行、発言者、日時が付いてGitHubに残っています。corrections.mdより情報が多いので、転記すると二重になるだけです。抽出するときに、corrections.mdとPRコメントの両方を読んで、同じ形式に揃えます。
穴はモブレビューでした。口頭で決まったことはどちらにも残りません。Meetなどの議事録を取っておいて、そこから抽出します。
実装でも資料でも同じ
hookが見ているのは「既存ファイルを書き換えたか」だけなので、設計書でもコードでも動きます。「Aを作って → できました → aのここをbにして → 修正しました」なら、artifactがソースファイルのパスになるだけです。
Googleドキュメントのような資料でも、末尾に「AIへの修正履歴」のタブを1つ持たせて、同じ形式で1行追記させれば済みます。
週次で抽出して、候補を差分PRにする
記録が溜まったら、週1回の定期実行でルールを抽出します。
- 候補は本番に入れません。Bugbotと同じで、根拠になった指摘が2〜3件揃ったものだけ人が本番に昇格させます
- 差分で足します。LLMにルールファイル全体を書き直させると、ACEが言う伝言ゲームで既存のルールが崩れます
- 候補には根拠件数を付けます。「この候補の根拠3件、反証0件」と数字で出れば、人の判断は数分で済みます
- 消すのも同じ定期実行がやります。3ヶ月効いていないルールを削除候補のPRにして、人が見て決めます
記録の1行がそのまま本番に入るわけではありません。同じ趣旨の指摘をまとめたものが候補になり、人が通したものだけが本番に入ります。行き先は種類で分けます。
| 種類 | 行き先 |
|---|---|
| 機械で判定できる | linter、hook |
| 判断が要る | CLAUDE.md、rulesファイル、REVIEW.md |
| 決定 | ADR。取り消すときは削除ではなく新しい記録で上書きして、鎖を残す |
| 振る舞いの期待 | テストケース |
おわりに
Microsoftの牛尾剛さんがNewbeeの動画で、LLMがどれだけ進化しても自社のドメインは学べないので、それを言語化したskillやagent definitionがエージェントの資産であり、これだけはエージェントが作り出せない、今のうちに貯めるのが一番のおすすめだ、と話していました。
corrections.mdは、その資産の元になる記録です。ルールの抽出のやり方は変わっても、記録があれば引き直せます。だから、増えることは気にしないことにしました。
まだ何も動いていませんが、以下の順番だけ決めました。
-
corrections.mdを書くhookを置く。これだけで記録は溜まり始める - 2〜3週間で何が溜まったかを見る。何件、どの成果物に多いか、往復が何回のものがあるか
- 溜まり方が見えてから、週次の抽出を足す
結果は別の記事に書こうと思います。
この記事はZennにも投稿しています。