目次
背景
- 最近めっきり自分の手でコードを書かなくなった
- AIに書いてもらったほうが速くて正確だから
- でもAIで書いてもらっても課題はやっぱりある
- そこでその解決策を考えた
AI駆動開発の課題
- AI駆動で開発する一番の問題は変更がシーソー化する件
- AI駆動でコードを書くと機能を追加するのが速いし、レビューが追いつかない
- そのため、AIを信じて機能をガンガン追加してもらう
- そうすると気が付かないうちにエンバグやデグレを起こしている事が多い
- Aを解決するためにBを足した結果、CとDの問題が新たに発生したみたいな現象
- それをさらにアドホックに直すと課題が発散して、まるでハウルの動く城のようになってしまう
- 特に安い簡便な解決策ほど副作用があったりする(例えば正規表現で安易に回避など)
解決策はHypothesis-Driven Development
- そのシーソーの解決策は、Hypothesis-Driven Development
- Hypothesis-Driven Developmentは課題解決に飛びつかない実装方法
- 以下HDDと略す
HDD
- HDDでは以下のワークフローを通す
- 6段階のフローを通して課題の発見と解決をする
| |
それぞれの意味は以下になる:
- runs: 動かした時に出たすべての実行ログ、実行日時ごとにフォルダ分けされる
- issues: 課題をフォルダにまとめて再現コードも含めたもの、課題を見つけてもすぐ直さず温めておく場所
- eval: 課題を解決する方法を検証するために、A vs Bなどの検証を行う場所
- src: 実際のコード置き場、課題解決方法で検証が終わったあとにここに変更を加える
- tests: 課題解決方法で検証が終わったものに対して再発しないようにCheckを入れる場所
- docs: 諸々のドキュメントをまとめる。意思決定のログなども
つまり、観測 → 再現 → 仮説 → 比較検証 → 本番昇格 → 再発防止という流れ。
HDDのエッセンス
- runs
- runsは実行時のログは実行時の画像や動画、音声も含めてjsonlなどで全ての実行ログを保存しておく
- 例えば、
runs/2024-1010-1012/{001_face.jpg, 001_out.txt, 002_voice.wav, logs.jsonl}みたいな感じ - runsの狙いは、問題の原因を一発で探せるようになり、AIがguessで解答させなくする目的
- issues
- issuesは問題が起きてもすぐ直さず、runsのデータから再現をさせて一旦放置する場所
- そこでまずは問題をrunsのログをベースに再現できる形にする
- その上で原因の特定や解決方法の仮説を出す
- その理由はその課題を解決することによるside effectもあるし、実はedge caseだったりすることもあるから
- つまり、課題->解決とは安易に進まないための場所
- tests
- 課題に対して再発しないように回帰テストを入れる
- なお、失敗に対してもxfail(期待通り失敗)も入れる
- 全体
- 一番大切なのはdon’t guess, measure
- また、solutionに安易に飛びつかないこと
まとめ
- AIによるシーソーゲームの解決方法はHDD
- HDDはラチェットを締めるように開発する手法
- つまり「一方向には進むが、逆戻りしない歯車」みたいに開発を進めるべき
- 言い換えると、探索と本番コードを分離し、検証済みの知識だけを一方向に昇格させる仕組み
- 奇しくも、ローカルでgithubのissueやPRを再現している事に近い
