AI に同じ失敗を
二度させない
開発体制を「進化」させる仕組み
個人開発のリポジトリで回している「開発体制を進化させる仕組み」についてまとめる。
何を作っているか
- 進化型カード TRPG「カルタグラフ」
- 仕様書サイト(VitePress)+ Web アプリ(React)
- 書いているのは主に AI コーディングエージェント
- 人間は「決める」「確かめる」係
Note:
作っているのは「カルタグラフ」という、遊ぶほどルールが進化していくカード TRPG 。
仕様書サイトと Web アプリのモノレポで。コードはほとんど AI エージェントに移譲。
何を作るか決めることと、出来上がったものを確かめることが人間の仕事。
ルールに書いても反映されないことがある
CLAUDE.md に「heredoc でファイルを書くな」と書いた
↓
次の PR でまた heredoc で書いて壊す
ルールを読ませても、注意力はモデル次第・その日次第
Note:
注意書きは「読んで、覚えていて、守る」という AI の注意力に頼っているので、モデルやその日のコンテキストで簡単に崩れる。
発想:体制そのものを「進化」させる
候補 → 評価 → 採用 / 却下
(誰でも) (人間が裁定) (却下も理由付きで残す)
- 記録先は1ファイル:
docs/process/evolution.md - 採用した変更には きっかけ と 止め方 を必ず書く
Note:
「進化ループ」を開発体制にも入れた。
作業中に「ルールが足りない」「邪魔だった」と気づいたら、人間でも AI でも候補として進化ログに書く。
振り返りで人間が採用か却下を決める。却下したものも消さずに、理由と一緒に残す。
ポイントは、採用した変更には必ず「何がきっかけで」「どうやって止めるか」を書くこと。
1サイクルの流れ
1. プラン作成(AI が質問・人間が答える)
2. プランの AI レビュー
3. テスト網羅レビュー
4. 実装
5. テスト全通過(TDD)
6. 実装の AI レビュー(3観点を並列)
7. 人間レビュー
8. push・振り返り ──▶ 進化ログに候補を出す
振り返りで出た改善が、次のサイクルのルールになる
Note:
1機能をこの8ステップのサイクルで作成。
最後の「振り返り」で出た改善候補が、次のサイクルのルールや仕組みになる。
開発サイクルの外側に、体制を育てるもう1つのループが回っている。
方針:改善は「ルール」より「仕組み」で
止め方を4つに分類している
| 止め方 | 例 |
|---|---|
| 機械 | git フック・CI・lint・ビルド時の検査 |
| レビュー観点 | AI レビューのチェック項目に足す |
| 手順・ルール | 文書に書く |
| 置き場所 | ページ・ファイルを新設・移動する |
まず機械で止められないか考える。
ルールで済ませるなら、その理由を書く
Note:
改善の止め方は4種類に分けて記録。
一番効くのは「機械」で止めること。git フック、CI、lint、ビルド時の検査方針として、改善案を出すときはまず機械で止められないかを考え、文書のルールで済ませるときは「なぜ機械にしないか」を書くことにしている。
人や AI の注意力に頼る形は、モデルや担当が変わると崩れる。
実例①:置換が二重に当たった
失敗:sed -i で用語を置き換えたら
「作者」→「製作者」が2回当たり 「製製作者」 に
テストの期待値も同じ置換で化けて、テストは通った
↓
- Claude Code のフックで
sed -iを止める - 置換は
replace-once.mjsで
「件数」と「二重の当たり」を確かめてから書く
きっかけ:作業中の失敗 / 止め方:機械
Note:
実例をいくつか紹介。
用語をそろえるときに AI が sed -i で置換したら、同じ置換が2回当たって「製製作者」という謎の言葉が生まれた。
しかもテストの期待値も一緒に化けたので、テストは通ってしまった。
注意書きではなく、Claude Code のフックで sed -i 自体を止め、代わりに件数を宣言して二重の当たりも検査する置換スクリプトを使わせるようにした。
実例②:用語の揺れが毎回レビューで出る
失敗:「シナリオ作成者/制作者/作者」…
AI レビューが毎回見つけ、毎回直す
↓
- 旧称の一覧を持つ
check-terms.mjsを作り -
pnpm docs:buildの最後で ビルドを落とす - pre-push・CI でも止まる
きっかけ:AI レビュー / 止め方:機械(ビルド時の検査)
Note:
「作成者」「制作者」「作者」がバラバラに書かれていて、AI レビューが毎回それを見つけて、毎回直していた。
レビューで見つかるのは良いことだが、毎回同じ指摘にトークンを払うのはもったいない。
旧称の一覧を持つ検査スクリプトを作り、ドキュメントのビルドで落とすようにした。
実例③:進化ログ自体の書き漏らし
失敗:体制を変えたのに、進化ログに書き忘れた
↓
.githooks/commit-msg で止める
- ルール・
AGENTS.md・.claude/・CI などを変えたのに
進化ログが変わっていないコミットは 拒否 - 不要なら
進化ログ不要: <理由>を書けば通る
Claude Code のフックではなく git のフック = どのツールでも効く
Note:
3つ目はちょっとメタな話で、進化ログそのものの書き漏らし。
体制を変えたのにログに書き忘れることがあった。
そこで、ルールや CI、.claude 配下などを変えたのに進化ログが変わっていないコミットは、commit-msg フックで止めるようにした。
記録が要らない場合は「進化ログ不要」と理由を書けば通る。なぜ記録しなかったか、も残る。
Claude Code ではなく git のフックにしたのは、どのツールで作業しても効くようにするため。
1か月の結果
採用 44 件(却下 4 件)
| 止め方 | 件数 |
|---|---|
| 機械 | 29 |
| 手順・ルール | 21 |
| 置き場所 | 11 |
| レビュー観点 | 4 |
※1件に複数の止め方あり。
機械で止めた割合:9月 62% → 10月 68%
Note:
1か月で採用したのが 44 件、却下が 4 件。
止め方の内訳は、機械が 29 件で一番多く、44 件のうち 3 分の 2 は機械で止めている。
月別に見ると、機械で止めた割合が少しずつ上がっている。
タイムラインも自動生成
- 進化ログの「きっかけ」「止め方」を
ビルド時に読み取って年表と内訳を描く - 書き写さないので二重管理にならない
- 書式が崩れていたら ビルドが止まる
docs/process/timeline.md ← evolution.md から生成
Note:
この数字も手で数えていない。
進化ログの「きっかけ」「止め方」をビルド時に読み取って、仕様書サイトに年表と内訳を自動で出している。
書き写さないので二重管理にならないし、書式が崩れていればビルドが止まるので、記録の質も機械で守られる。
モデル・ツールが変わっても回るように
- 入口はツール非依存の
AGENTS.md-
CLAUDE.mdはそれを読み込むだけ
-
-
.claude/は 呼び出し口、手順の本文はdocs/process/ - サブエージェントの model は
inherit(固定しない) - 作業ごとに 段(強い/標準/軽い) で割り当てる
Note:
もう1つ意識しているのが、特定のモデルやツールに依存しないこと。
入口はどのエージェントでも読む AGENTS.md にして、CLAUDE.md はそれを読み込むだけ。
.claude の中のスキルやサブエージェントは呼び出し口にして、手順の本文はリポジトリのドキュメントに置いている。
モデルも製品名で固定せず、「強い・標準・軽い」の段で作業ごとに割り当てている。
これも、トークンを使いすぎだという振り返りから入った変更。
人間が決めるところは固定する
- ルールと仕様が矛盾したら → 止めて人間に聞く
- 採用 / 却下の裁定 → 人間
- 人間レビューは AI に判定させない唯一の型
AI が提案し、機械が守り、人間が決める
Note:
全部を AI と機械に任せない。
ルールと仕様が矛盾したら AI は止まって人間に聞く。改善を採用するかどうかは人間が決める。
人間レビューは、AI には説明だけさせて、判定は人間がする。
AI が提案し、機械が守り、人間が決める、という役割分担。
まとめ
- 失敗は 進化ログ に「きっかけ」と「止め方」で残す
- 止め方は ルールより機械(フック・CI・ビルド時の検査)
- 知識は モデルではなくリポジトリ に置く
注意書きを増やすより、
同じ失敗ができない仕組みを増やす