はじめに
AI Agentに比較的大きな実装を任せるときに、いきなり実装させるより、先に TODO を作らせたほうがうまくいく という小ネタの紹介です。
AI Agent に比較的大きな実装を任せるとき、みなさんはどうしていますか?
- 頭の中のイメージを言語化して、詳細に伝える
- やりとりしながら修正していく
LLM の良いところは、こういった多様なやり方に柔軟に対応してくれるところです。
ただ、ある程度の規模の修正や新機能追加になると、途中で迷子になることがあります。
最初から完璧に伝えるのは難しいし、かといって行き当たりばったりで修正を重ねると、
- チャットが際限なく伸びていく
- 「そうじゃない」「違う、そこじゃない」の繰り返し
- 思った通りの修正がされず、面倒になってくる
こういう経験、ありませんか?
AI Agent の実装でよく聞く困りごとが、アプリ固有の仕様や実装方針を知らないため想定と異なる実装を進めようとする、というものです。「RuleやMCPなどの整備をしなきゃ使えないのかな、、、」となりますよね。
これをちょっとし工夫で改善できるよーという小ネタです。
1. まずは Plan を TODO.md に
コードは書かせず、まず「実装計画」を TODO として出力させます。
「〇〇を実装したい。どんな感じになる?」
こんな感じで聞いてみると、AI は大体こういう情報を返してくれます。
- 修正内容の一覧
- 修正時のポイント・注意点
- 影響を受けそうな既存クラス
- 新しく追加しそうなクラスや責務
- 必要なテスト
- 設定などのコード以外の変更
「そうじゃない」と言う前に、まずは TODO として Markdown などで出力 させましょう。
TODO.md のサンプル
AI に作らせた TODO.md の例です。内容はでたらめですが、粒度として感を。
このような出力をさせろというわけではなく、ドライブする人側のイメージとずれないものであれば。
# TODO: 注文完了時のメール通知の重複制御
## 修正・追加内容一覧
- `IdempotencyRepository` の作成 `新規`
- `NotificationService` に重複処理を追加 `修正`
- `application.yml` に設定を追加
---
## 実装例
### 1. NotificationService(重複チェック部分)
``java
// 重複チェック
if (idempotencyRepository.existsByEventId(eventId)) {
log.info("Duplicate notification event: {}", eventId);
return;
}
``
---
## 影響を受ける既存クラス
- `OrderService`: イベント発行処理は既存のまま
- `NotificationService`: 非同期送信メソッドを使用
- `EmailNotificationProvider`: メール送信ロジックを使用
---
## 設定ファイル変更
### application.yml
設定の追加
``yaml
spring:
mail:
host: smtp.example.com
``
---
## テストケース
### NotificationServiceTest
- [ ] 通知送信成功
- [ ] 重複イベントIDで送信スキップ
- [ ] メール送信失敗時に例外スロー
### OrderEventHandlerTest
- [ ] 注文完了イベント受信時に通知サービス呼び出し
- [ ] 非同期処理で実行される
2. TODO を見ながらピンポンする
TODO が出力されたら、それを見ながら認識合わせをしていきます。
この「出力する」という行為にメリットが結構あります。
- 内容が補足しやすい -> AIに伝えづらいドメイン知識や実装方針をここで補足できる
- 指摘がピンポイントになる -> 「この部分が違う」と具体的に言える
- 指示側も抜け漏れに気づきやすい -> 全体を俯瞰できるので、見落としを防げる
- 後戻りが楽 -> どこまで合意したかが明確なので、修正の起点が分かる
TODO に出力させると、この段階で前提条件や要求を追加できます。
「この仕様って、実は実装されてないんだけど、あるふりしてるんだ。」などなどドメイン固有の事情も補足できます。
さらに TODO が「合意のチェックポイント」になってくれるため、
「エイヤ! → もうぐちゃぐちゃ → 全部元に戻す」といった虚無が防げます。
よくある虚無
人「じゃあ、前の〇〇はいらないから、△△をやって」
AI「了解です。〇〇をやめて△△で実装しますね」
人「じゃあやってみて」
AI「……」
〜 実装後 〜
人「思いっきり〇〇やってるやないかい!やらないで」
AI「申し訳ございません、修正します」
〜 再実装 〜
人「なんか壊れてきた。なんでそうなってるの?」
AI「〇〇がなくなったので、代わりに□□で代替実装しました」
(善意の配慮が裏目に出るパターン)
人「(あ、〇〇って必要だったのか……気づかなかった)」
人「.....全部元に戻して」
この虚無に陥る前に気づけるのが最大のメリットです。
3. 固まったら実装させる
TODO.md の内容で合意できたら、実装に移ります。
ここでおすすめなのが、新しいチャットを開いて実装させる ことです。
長いやりとりでコンテキストが膨らむと、AI の判断精度が落ちることがあります。
TODO で合意した内容を新しいチャットで参照させることで、フレッシュな状態で実装させると成功率が上がりやすい気がします。
また、実装段階でトラブルが起きても、実装部分の齟齬であることが多く問題の切り分けがしやすくなります。AI も迷いにくくなる印象です。
それでも、仕様そのものの方向性を変えて暴走しかけることもありますが「TODO から外れていなで」という指摘がしやすいです。
必要であれば TODO 自体を更新するのも有効です。
補足: Spec Driven Development じゃん?
と思った方もいるかもしれませんが、その通りです。
軽量な実装の仕様合意を挟む
というものです。
- ちゃんとした仕様書を書くほどではない
- でも、いきなりコードは書かせたくない
Spec Driven Development はフレームワーク的な要素もあり、チーム開発では導入のハードルが少し高いこともあります。その前段として TODO という軽い形で整理する、という位置づけが良いかもですね。
追記 Research → Plan → Implement(RPI)
Research → Plan → Implement(RPI)でやるといいよーという話もあるようです。
この記事も仕様(Spec)よりはプロセスの話なので、府落ちしやすいかもですね
TODO.md は残す? 捨てる?
ここは正直、悩みどころです。
TODO に書かれている内容は、
- これまで PR やレビューコメントに残っていた情報でもある
- コードと一緒にリポジトリで管理するべきかは微妙なライン
今のところは、次の感じで運用しています。
- TODO は一時的なメモ (gitにコミットつむ)
- 残件や重要な注意点はコードコメントに落とす
- TODO 自体は破棄する (gitから削除)
人がこのレベルの内容を出力していた頃は、
「もったいないお化け」が出てきて残したくなってきましたが贅沢な時代になりました。
ただ今後、AI にさらに主導権を持たせて自律的に開発させるようになると、検討記録は照査ログとして残すことが大切になるかと思います。そのあたりで Spec Driven Development の出番が来るのかな、とも思っています。
まとめ
正直、Plan モードが自動でファイル保存されるようになる日もすぐでは?
なんて思ったりもしますが、
- AI Agent にいきなり実装させない
- まず TODO を作らせる
- 認識合わせをしてから実行する
これだけで、結構うまくいくかもという、使い方を少し工夫する話として、参考になれば幸いです。