AIに任せっきりは怖い。でもCodexは「柵」を立てるとかなり頼れた
はじめに
私は現在、本業でトラックドライバーとして働きながら、PythonやFlaskを使ったWebアプリケーション開発を独学しています。
最近はVS CodeのCodexを使いながら、個人開発中のアプリで、
- セキュリティ対策
- pytestの強化
- DBまわりの検証
- マイグレーションの確認
- 不正入力への対策
などを進めています。
AIコーディングについて調べていると、
AIに任せっきりにすると大変なことになる
という話をよく見かけます。
実際、それはその通りだと思います。
ただ、Codexを使い続けているうちに、
「AIを放し飼いにする」のと、「作業範囲を決めて任せる」のは全然違う
と感じるようになりました。
この記事でいう「柵」とは、Codexに何をさせるかだけではなく、
何をさせないか・どこで止まらせるか
まで先に決めておくことです。
今回は、プログラミング初心者の私がCodexを使うときに決めている「6つの柵」を整理してみます。
1. 今回触っていい範囲を決める
まず最初に、
「今回はどこを直すのか」
を限定しています。
たとえば、
- 売上POSTの入力検証だけ
- DB保存失敗時のrollbackだけ
- 商品マスタPOSTの検証だけ
というように、一度に扱うテーマを小さくしています。
さらにCodexには、
問題を見つけても、今回の範囲外なら勝手に修正せず報告してください。
と伝えています。
Codexが調査中に別の問題を見つけること自体は悪いことではありません。
ただ、その場で次々と修正を広げると、
「結局どこまで変更したのか分からない」
という状態になりかねません。
そのため、
発見することと、修正することを分ける
ようにしています。
2. 先に「赤いテスト」を作る
最近は、修正する前にpytestを書いてもらうことが増えました。
基本的な流れは、
- 危険な状態をテストで再現
- 修正前にテストを実行
- テストが失敗することを確認
- コードを最小修正
- 対象テストが成功することを確認
- pytest全体を再実行
です。
たとえば商品マスタの入力検証では、不正入力17ケースを追加しました。
修正前は、
17 failed
修正後は、
17 passed
となりました。
先に赤になることを確認しておくと、
「なんとなく安全そう」ではなく、実際に存在した穴をテストで再現し、その穴を塞げた
と確認できます。
最近はpytestを単なる動作確認ではなく、
「一度見つけた事故を再発させないための台帳」
のように考えるようになりました。
3. 通常DBや本番環境には直接触らせない
テスト中は基本的に、
- 通常運用しているPostgreSQL
- 通常のDocker DB
- 実Gemini API
- 本番環境
には直接接続させません。
pytestでは通常DBとは接続先を分け、
sqlite:///:memory:
の使い捨てDBを使用しています。
PostgreSQLそのものの挙動やマイグレーションを確認する必要がある場合は、
通常環境とは別に、
- コンテナ
- ネットワーク
- DB
- ボリューム
を分離した隔離環境を作って検証しています。
「テストだから大丈夫」ではなく、
失敗しても被害が通常環境へ広がらない場所でテストする
ことを意識しています。
つまり、
本番や通常DBを使わないこと自体が目的ではなく、失敗時の影響範囲を小さくしておくこと
が目的です。
4. 想定外の問題を見つけても勝手に広げない
Codexが調査していると、今回とは別の問題を見つけることがあります。
以前なら、
「それも直しておいて」
と言いたくなるところですが、最近は止めています。
Codexには、
想定外の問題を発見しても、今回の修正範囲を広げず停止して報告してください。
と伝えることが増えました。
たとえば、
今回は売上POSTの検証だけ
↓
別のDB問題を発見
↓
その場では修正しない
↓
未対応問題として報告
↓
次の作業として改めて切り出す
という流れです。
これなら、一つの変更が必要以上に大きくなりません。
問題を全部その場で直すことより、何を変更したのか追える状態を維持すること
を優先しています。
5. commit・pushは最後のゲートにする
コード修正とテストが終わっても、すぐにはcommit・pushさせません。
まずCodexに、
pytest -v
git diff --check
git status --short
git diff --stat
git diff
などを確認してもらいます。
その結果を見て、
- 指定したファイルだけが変更されているか
- pytestが全部成功しているか
- 無関係な修正が混ざっていないか
- 想定外のファイルが追加されていないか
を確認します。
そのあとで初めて、
「ここまでならcommitしてOK」
と指示します。
Codexにはコードを書いてもらいますが、
Gitの最終ゲートまで自動で通過させない
ようにしています。
commit後も、
- commit hash
- commit message
- push先
- push結果
- 最終的な
git status
まで報告してもらっています。
また、最近は、
「pushするな」と毎回文章で指示するだけに頼るのも弱い
と感じるようになりました。
もし1回でも指示を書き忘れれば、AI側が許可されていると解釈する可能性があります。
そのため理想としては、
プロンプトで禁止する
+
実行権限そのものも必要最小限にする
という二重の柵にしたいと考えています。
人間側の指示忘れまで考えるなら、
「やるな」と伝えるだけではなく、そもそも簡単にはできない状態にしておく
方が安全です。
6. 最後はpytestとCIにも点検してもらう
ローカルでpytestが通ったあと、GitHubへpushするとGitHub Actionsでもpytestが実行されます。
現在の設定では、
-
mainへのpush -
main向けPull Request
をきっかけにGitHub Actionsが動きます。
以前の記事では、これをトラックの点検に例えました。
- pytest:点検するための道具
- pytestのテスト:点検項目
- ローカルpytest:出庫前点検
- GitHub Actions:出荷ゲートでの自動点検
Codexが、
修正できました!
と言ったから終わりではありません。
Codex
↓
pytest
↓
git diff
↓
commit
↓
push
↓
GitHub Actions
と、複数の確認を通すようにしています。
AIの回答そのものを最終判断にするのではなく、
AIが行った作業を別の仕組みでも確認する
という考え方です。
Codexを「放し飼い」にすると何が怖いのか
たとえばCodexに、
このアプリをいい感じに安全にしておいて
とだけ依頼したとします。
するとAI側は、
- どこまで変更していいのか
- DBを触っていいのか
- 本番環境へ接続していいのか
- 追加で見つけた問題も直すのか
- commitしていいのか
- pushしていいのか
- 仕様を変更していいのか
など、多くのことを自分で推測しなければなりません。
私が怖いのは、Codexそのものというより、
人間側が何も決めていない状態で、AIに判断まで全部渡してしまうこと
です。
「AIに任せる」と「AIに丸投げする」は、似ているようでかなり違うと感じています。
トラックの仕事と似ていた
考えてみると、これは本業のトラックの仕事にも似ています。
新人ドライバーに、
適当にこの荷物を配達してきて
とは普通言いません。
- どこへ行くのか
- どのルートを通るのか
- 納品時間はいつか
- どこに注意するのか
- やってはいけないことは何か
- 異常が起きたらどうするのか
などを確認します。
そして、想定外のことが起きたら勝手に判断して進まず、
いったん止まって確認する
という場面もあります。
Codexを使っていて、
「これ、現場で人に仕事を任せるときと似ているな」
と思うようになりました。
AIに任せるのではなく、AIが働ける範囲を作る
私はまだプログラミングを学び始めたばかりなので、Codexの出力を100%判断できるわけではありません。
だからこそ、
AIを完全に信用して自由に動かすのではなく、失敗しても被害が広がりにくい環境を先に作る
ことを意識しています。
最近進めているpytest強化でも、
「注意して同じバグを起こさない」
ではなく、
「同じ危険な状態に戻ったらpytestが止める」
ことを目標にしています。
Codexも同じです。
Codexは放し飼いにしない。
- 作業範囲を決める
- 赤テストを先に作る
- 通常DBや本番環境へ直接触らせない
- 想定外では停止させる
- commit・pushの前に確認する
- pytestとCIでもう一度点検する
この「柵」を作ってから仕事を任せる。
さらに、
プロンプト上のルールだけに頼らず、可能なら権限側でも柵を作る。
これも今後意識したい点です。
今のところ、これが私なりのAIコーディングとの付き合い方です。
放し飼いは怖い。
でも、ちゃんと柵を立てればCodexはかなり頼れる。
そんなことを、最近の個人開発を通して感じています。
