はじめに
お疲れ様です。
タイトル通りですが、最近claude codeを用いてAI駆動開発をしている同期から、ハーネス設計という言葉を知りました。
調べた感じかなり大事な考えというか設計だったので、今回はハーネス設計についてまとめてみようと思います。
ハーネス設計 とは
ざっくり言うと、以下の考え方です。
AI が壊した時に検知できる仕組みを先に作る
AIに自由にコードを書かせる
↓
壊れたら検知する
↓
安全に戻せる
を先に作っておくこと。です。
なぜハーネス設計が必要なのか
ここ最近の AI はスラスラとスピーディーにコードを書いてくれます。
ただ、その反面一見すると自然で正しそうなコードを書くことが多々あります。
簡単な例で言うと
- null チェック漏れ
- edge case 未考慮
- 型崩れ
- 既存仕様の破壊
などを平気でやってきます。
さらに最近はコード生成だけでなく、
- API 実行
- コマンド実行
- DB 操作
まで AI に任せるケースも増えてきていると思います。
実際、知り合いのエンジニアが Claude に API の仕様調査をやらせていた際も、本番 API に対して、
偽装トークン付きの curl を実行しようとしていたらしく、普通に任せきるのは危険だなと感じました。
もちろん悪意がないのはわかるし、目的達成のために最短手段を選んだだけだと思います。
ですが、人間側からすると危険でしかありません。
そのため、
AIに自由に実装させる
↓
人間が頑張ってレビューする
ではなく、
壊れたことを検知する仕組みを先に作る
という考え方が重要になります。
これが、ハーネス設計の必要性なんだなと思っています。
ハーネス設計の例
ケース①: 本番 API を実行しようとしてしまう
例えば、AI に API の仕様調査を任せたとする。
その際 AI が、以下のようなコマンドを生成し、そのまま実行しようとするケースがあります。
curl https://api.example.com/users \
-H "Authorization: Bearer xxx"
上記は「API の動作確認をしたい」と言う目的を達成するために、最短で実行できそうな方法を選ばれたとします。
ただし人間側からすれば、危険行為でしかないので、このような事故を防ぐために以下のような制約を先に用意しておく必要があります。
- 本番環境への通信を禁止する
- sandbox 環境しか触れないようにする
- read only 権限に制限する
- curl 実行前に確認を挟む
ケース②: 作業ブランチのつもりが develop に push されてしまう
例えば、AI に develop から作業ブランチを切って push してと命令したとする。
この時、AI が作業ブランチを作成したものの、upstream が develop のままになっており、push 時に意図せず develop へ反映されてしまうケースがあります。
人間が気づければ防げますが、AI 駆動開発ではコマンド実行の速度が速いため、毎回目視で止めるのは現実的ではありません。
そのため、以下のような制約を先に用意しておく必要があります。
- develop / main への直接 push を禁止する
- push 前に現在のブランチと upstream を確認する
- 保護ブランチへの push コマンドをブロックする
- Bash ツール実行前に機械的なチェックを挟む
ケース③: AI が不要なリファクタを始める
例えば、AI にこのバグだけ直してと命令したとする。
ですがこのバグだけと言う依頼に対して、以下のような関係ない修正まで始めるケースがあります。
- 関数名変更
- ディレクトリ構成変更
- 共通化
- import 整理
- formatter 適用 etc...
AI としては、「コードを綺麗にしたほうが良い」という判断で自然にやってきますが、
結果として、1行の修正のはずが、大量 diff になってレビュー不能になるみたいなことが結果的に起こりえるのです。
そのため、このような事故を防ぐには、以下のような制約がやはり必要になってきます。
- diff サイズ制限を設ける
- 指定ファイル以外の変更を禁止する
- formatter-only 変更を弾く
- AI 用レビュー gate を挟む
- 不要な rename を検知する
要するに
変更行数が一定以上なら停止や、指定外ファイルを変更したらエラー、ファイル削除や本番環境に干渉するコマンド、などを機械的に判定することで、
AI が余計な事を始める
↓
ハーネスが検知する
↓
実行前に止める
という形にできます。
おわりに
まだ自分も理解・設計途中ではありますが、AI 駆動開発では、**「AI に正しく書かせる」より、「壊れた時に止められる」**ことのほうが重要なんだと感じました。
AI は確かに便利なものですが、その便利さを安全に使うために、人間側の制約設計がかなり大事になります。
これから AI を開発フローに組み込む上で、ハーネス設計は避けて通れない考え方なんだなと思いました。