はじめに
私はエンジニアとして3年目になります。
業務では業務系のWebアプリケーション(Java / Spring Boot)の案件を担当しつつ、個人開発でiOSアプリも作っています。
AIコーディングツールは日常的に使っています。Claudeに課金して、業務でも個人開発でも普通に相棒として動いてもらっている感じです。
そんな中で、最近こんなことをよく考えます。
「AIが書いたコードに、人間のレビューって本当に必要なんだろうか?」
この問い、答えは「そりゃ必要でしょ」で終わりそうに見えます。
でも自分は一度、真剣に「いらないかもしれない」と思いました。そして、その考えを変えるきっかけになった出来事がありました。
この記事は、その一連の考えの整理です。
同じようにAIを使って開発している方に、何か引っかかるものが残せたら嬉しいです。
正直、「レビューいらないかも」と思ったことがある
まずは正直な話から始めます。
AIコーディングツールを使い始めた頃、自分はけっこう舐めていました。「どうせ雑なコードが出てくるんだろう」と。
でも、実際に使ってみると想像以上でした。
- 頼んだ機能が一発で動く
- 自分が書くより綺麗な書き方をしてくる
- 例外処理やnullチェックまで気を利かせて入れてくる
- 「なんでこう書いたのか」を聞けばちゃんと説明してくる
自分が3年かけて身につけてきたことを、数秒でやってのける。
これを目の当たりにすると、「レビューって儀式化してるだけじゃないか?」という気持ちが芽生えてきます。
しかも、レビューって時間がかかるんですよね。
レビュアーの時間を奪うし、指摘の往復で1〜2日溶けることもある。それだけのコストを払う価値が、AIのコードに対して本当にあるのか。
「AIの方が自分より上手いなら、自分がレビューする意味なくない?」
この疑問は、けっこう本気で持っていました。
考えが変わった出来事
その考えが変わったのは、個人開発でのある出来事がきっかけです。
自分は「MyEat」という飲食店記録アプリを個人開発しています。
構成はSwiftUI + Spring Boot + AWS Lightsailで、飲食店データの取得にGoogle Places APIを使っています。ソースコードはAzure Repos(Azure DevOps)のprivateリポジトリで管理しています。
このバックエンド部分を作るとき、AIにフレーム的な部分(概要)を依頼し、ディティールを自分で整える。そんな開発手順で進めていました。
そして出てきたコードは、ちゃんと動きました。APIを叩いて、レスポンスをパースして、アプリに返す。想定通りの挙動でした。
でも、後から見返してみたら、APIキーがソースコードに直書きされていました。
// イメージ(実際のコードとは異なります)
private static final String API_KEY = "AIzaSy...";
環境変数でも、.envでも、設定ファイルでもなく、ソースコードの中にべた書き。
サーバー側のアプリケーションなので、クライアント側に露出するわけではありません。
Azure Reposのprivateリポジトリなので、その瞬間に世界中に公開されたわけでもありません。
それでも、これはやばいと思いました。
「privateだから大丈夫」ではない
正直に言うと、今回助かったのはたまたまprivateリポジトリだったからです。
自分の判断が正しかったからではなく、運用の初期設定に救われただけ。ここを勘違いすると、次に同じことをやったときに終わります。
なぜやばいのか、理由を挙げてみます。
① 公開範囲は永遠に変わらない保証がない
privateだったリポジトリを、後からOSS化したくなるかもしれません。誰かにコードを見せる機会が出てくるかもしれません。CI/CDの設定ミスでログにキーが吐かれるかもしれません。
「今はprivateだから安全」は、未来の自分の選択肢を縛るか、あるいは未来の自分が事故を起こすかのどちらかです。
② Gitの履歴は消えない
これが一番厄介です。
「やばい」と気づいて後からコミットで消しても、履歴を遡れば見えてしまいます。完全に消すにはリポジトリの履歴を書き換える必要があって、これがまた面倒です。
つまり**「後で直せばいい」が通用しない**タイプのミスなんです。
③ 課金APIなので、漏れたら金銭被害に直結する
Google Places APIは従量課金です。
キーが漏れて悪用されたら、身に覚えのない請求が飛んできます。個人開発でこれをやったら、洒落にならない金額になる可能性もあります。
普通に考えてやばいこと
この件で一番「やべー」と感じたのは、金額のことでも公開範囲のことでもありません。
(金額は普通に怖いです)
コードが完璧に動いていたことです。
エラーは出ない。テストも通る。アプリからも問題なく使える。
「動作確認」という観点では、100点満点のコードでした。
もしここで自分がコードを読んでいなかったら、そのまま気づかずにリリースしていたと思います。
前に脆弱性診断の記事でも書いたんですが、「動くこと」と「安全であること」は完全に別の話です。
そしてAIは「動くコード」を書くのはとんでもなく上手いけれど、「安全なコード」を書けているかどうかは、また別の問題なんだと痛感しました。
AIは「間違えている」わけじゃない、というのが厄介
ここで大事なポイントがあります。
AIは、間違ったコードを書いたわけではありません。
「APIキーを使ってGoogle Places APIを叩くコードを書いて」という依頼に対して、過不足なく応えているんです。
自分が「キーは直書きせず.envから読み込むようにして」と言わなかっただけ。
「先に指示すればいい」は正論だけど、現実的じゃない
ここで当然、こういう反論が出ます。
依頼するときに「APIキーは直書きせず環境変数に切り出して」と一言添えれば済む話では?
その通りです。実際、そう指示すれば一発で解決します。
今は自分も、機密情報を扱う実装を頼むときは「環境変数は後で自分が書くから空定義だけしておいて」と依頼します。
でも、これを全部やるのは骨が折れます。
というのも、この方法には前提があるからです。
**「起こり得る問題を、依頼する前にこちらが全部知っている」**という前提です。
- APIキーは環境変数に切り出して
- ユーザー入力はプリペアドステートメントで扱って
- 出力時はエスケープして
- 例外を握りつぶさないで
- ログに個人情報を出さないで
- 外部URLへのリクエストはホワイトリストで制限して
- パスにユーザー入力を直接使わないで
- ……
依頼のたびにこれを全部前置きするのは、正直しんどいです。
しかも、この前置きリストは自分が知っていることしか書けません。
今回のAPIキーの件も、「知っていたけど言い忘れた」なら、まだマシです。
怖いのは、自分が知らない観点は、そもそも前置きリストに入らないということです。
だから結局、こういう構図になります。
AIのコードの穴は「AIのミス」ではなく「依頼した側の視野の穴」として現れる。
AIは、聞かれたことには完璧に答えます。でも、聞かれていないことは教えてくれません。
人間の先輩なら、「これ、キー直書きしてるけど大丈夫?」と一言くれます。AIは、こちらが問題意識を持って聞かない限り、そのまま渡してきます。悪意があるわけでも、能力が低いわけでもなく、単純に「そこは依頼されていないから」です。
事前指示は予防にはなりますが、発見にはなりません。
自分の視野の外にある問題を見つけるには、結局「出てきたコードを読む」というプロセスが要るんです。
人間のレビューでしか拾えないもの
この経験を経て、「じゃあ人間のレビューは何を見るべきなのか」を整理してみました。
自分なりの結論は、AIが得意なことと人間が見るべきことは、そもそも領域が違うということです。
AIが得意なこと(=人間が頑張らなくていい領域)
- 構文の正しさ
- 一般的なコーディングスタイル
- よくあるバグパターン(null チェック漏れ、境界値など)
- 定型的な実装(CRUD、バリデーション、変換処理)
このあたりは、正直AIの方が安定しています。
「セミコロンが抜けてる」「インデントがずれてる」みたいな指摘に人間の時間を使うのは、もう無駄だと思います。
人間が見るべきこと
① 業務的に正しいか
コードとしては正しくても、業務要件と合っているかは別問題です。
AIはプロジェクトの背景も、クライアントとの合意事項も、過去の経緯も知りません。「ステータスが2のときだけこの処理をスキップする」みたいな業務ルールは、コードの外側にあります。
② 既存システムと整合しているか
自分たちのプロジェクトには、独自の共通クラスや命名規約、レイヤー構成のルールがあります。
AIは「一般的にはこう書く」を出してきますが、「このプロジェクトではこう書く」は知りません。既存コードとちぐはぐな実装は、後々の保守で確実に効いてきます。
③ セキュリティ的に問題ないか
今回の自分のケースがまさにこれです。
機密情報の扱い、入力値のバリデーション、認可のチェック。動作確認では絶対に検出されない領域なので、意識的に見にいくしかありません。
④ そのコードが本当に必要か
AIは「書いて」と言えば書いてくれます。
でも、そもそもその実装が必要なのか、もっとシンプルな方法はないのか、既存の共通処理で済むんじゃないか——という判断は人間の仕事です。AIは「いらないですよ」とは言ってくれません。
レビューは「不要」になるんじゃなくて「変わる」
ここまでの話をまとめると、自分の結論はこうです。
人間のレビューは必要。ただし、役割が変わる。
これまでのレビューは、どちらかというと「ミスを見つける作業」でした。
書き方の指摘、バグの発見、規約違反のチェック。全行を目でなぞって、粗を探す感じ。
でもAIがコードを書く時代のレビューは、**「AIが判断できない領域を人間が埋める作業」**になっていくと思います。
| 観点 | これまで | これから |
|---|---|---|
| 構文・スタイル | 人間がチェック | AIに任せる |
| よくあるバグ | 人間が探す | AIがほぼ潰す |
| 業務要件との整合 | 人間がチェック | 人間がチェック(重要度上昇) |
| 既存システムとの整合 | 人間がチェック | 人間がチェック(重要度上昇) |
| セキュリティ | 人間がチェック | 人間がチェック(重要度上昇) |
| 設計の妥当性 | 人間がチェック | 人間がチェック(重要度上昇) |
見るべきポイントが減るんじゃなくて、見るべきポイントの密度が上がるイメージです。
むしろレビューは難しくなるかもしれません。
「未確認のコードをレビュアーに渡す」ということ
最後に、これは技術というより姿勢の話です。
業務でAIを使うこと自体は、今の現場では普通に許可されています。使うなという話ではありません。
ただ、自分が理解していないコードをそのままレビュアーに渡すのは、さすがに失礼だと思っています。
レビュアーは、自分の作業時間を削ってレビューしてくれています。
その人に対して、「AIが書いたので中身は分かりません」というコードを渡すのは、自分が本来やるべき仕事を相手に丸投げしているのと同じです。
しかも厄介なのが、レビュアーは「この人は理解した上で出している」という前提で見ます。
その前提が崩れていると、レビューの精度そのものが落ちます。
なので、自分は最低限このラインを守るようにしています。
- AIが書いたコードは、自分の言葉で説明できる状態にしてから出す
- 「なぜこの実装になっているのか」に答えられない箇所は、理解するか書き直す
- 理解できなかった部分があるなら、それを正直に添えてレビューに出す
最後のやつが地味に大事で、「ここ、AIが提案してきた実装なんですが、なぜこうしているのか自分でも確信が持てていません」と一言添えるだけで、レビュアーはそこを重点的に見てくれます。
分からないことを分からないと言うのは、丸投げとは違います。
まとめ
「AIが書いたコードに人間のレビューは必要か」——自分の答えは**「必要。ただし役割は変わる」**です。
理由を3つにまとめると、こうなります。
① AIは「動くコード」は書けるが、「安全なコード」かは保証されない
自分のAPIキー直書きの件がまさにそれでした。完璧に動くコードが、完璧に危険でした。
② 事前指示は予防にはなるが、発見にはならない
「先に条件を伝えればいい」は正論ですが、それは自分が知っている問題にしか効きません。全部の懸念を毎回前置きするのは現実的じゃないし、自分の視野の外にある問題はリストにすら載りません。だから、出てきたコードを読むプロセスが要ります。
③ レビューで見るべきポイントは減らず、密度が上がる
構文チェックはAIに任せられる分、業務整合性・既存システムとの整合・セキュリティ・設計の妥当性といった「人間にしか見られない領域」に集中することになります。
AIはめちゃくちゃ強力な相棒です。課金してでも使う価値があると思っているし、使わない手はないと思います。
でも、AIに任せられるのは「書くこと」であって、「責任を持つこと」ではないというのが、今の自分の実感です。
出したコードの責任は、最終的に出した人間が持つ。
これはAIがどれだけ賢くなっても、たぶん変わらないんじゃないでしょうか。
実際はAPIキーべた書きの状態でAzure repoにpushしてません。事前に気づきました。
ただpushしていた可能性はあるため、強調の意を込めて本記事ではpushしたような書き方をしています。
この記事は実務3年目のいちエンジニアの経験に基づいています。
「うちの現場ではこうしてる」「自分はこう考える」など、コメントもらえると嬉しいです。