
ClaudeとGPT-5に何度もキャッチボールでコードレビューさせたのに、なぜ抜けは残ったのか
こんにちは。非エンジニアのHaradaです。
はじめに
先月、GASで社内ツールを作成しました。
その際のコードレビューで生成AIを通し経験したこと記したいと思います。
作成したツールは「スプレッドシートの情報からPDFを作成するツール」です。
扱う情報には漏洩しない方が良いものも含まれるため、セキュリティ面を意識する必要がありました。
片方の見落としをもう片方が補えるはず、という考えをもとに
GASコードを生成後、ClaudeとGPT-5をキャッチボール形式で相互レビューさせました。

レビューさせた観点は以下のとおりです。
- GASのベストプラクティス
- セキュリティ
- 一時ファイル削除
- XSS
- HTMLテンプレート
- Drive API
- エラーハンドリング
- 実行時間やAPI制限
- マジックナンバー
- バッチ処理効率
結構細かい観点でレビュー・修正をさせると
これでかなり堅いです
実運用レベルです
最終版として扱ってよいです
という評価が出るにも関わらず、ClaudeとGPT5でキャッチボール・レビューをさせたり
他者(エンジニア=人間)にレビューをしてもらうと
重要な指摘が出てきて、修正を繰り返す……という無限ループにハマってしまったのです。
AIレビューで見つかったもの
まず前提として、非エンジニアでGASコードの知識が0の私にとって、AIレビューはかなり役に立ちました。
たとえば、以下のような点はAIレビューで簡単に改善できました。
- クライアントから渡された行番号をサーバー側でも再検証する
- パスワードを HTML の
type="password"で受け取る ui.prompt()ではなく HTML ダイアログにする.gsと.htmlを分離する<?= ?>による HTML エスケープを使うtextContentを使い、innerHTMLを避ける- 一時 Google ドキュメントを
Drive.Files.removeで完全削除する - 削除失敗時にユーザーへ警告を返す
- 保存先フォルダの共有状態をチェックする
- 同名フォルダが複数ある場合に中断する
getValue()ではなくgetValues()/getDisplayValues()を使う- ID系の値が数値化・指数表記にならないようにする
- エラーIDを付与し、ユーザー向けメッセージと開発者向けログを分ける
これらは人間は見落としやすいものだと思います。
AIレビューの効果はかなり大きく、特に「セキュリティ観点を広げる」「GAS特有の落とし穴を洗い出す」「コードを読みやすく整理する」という点においては、とても強力でした。
それでも抜けたもの
一方で、改めて指摘された点もありました。特に大きかったのは以下のようなものです。
1. replaceText の置換値エスケープによる値破損リスク
AIレビューの中で、DocumentApp.replaceText() に渡す置換値に $ や \ が含まれると危ないのでは、という指摘がありました。そこで一度、置換値をエスケープする関数を追加しました。
しかし、その後の人間(エンジニア)によるレビューで、
replaceText(searchPattern, replacement)の replacement はリテラル扱いなので、逆にエスケープすると値が壊れる可能性がある
と指摘されました。
「”リテラル扱い”って何?おいしいの?」状態でしたが、「リテラル=書いてある通りにそのまま読む」という意味だそうで
エスケープ($ → \$ に変換する処理)を追加してしまうと、本来の情報が勝手に変わってしまうことになります!
もし「123$」のような文字列が「123\$」のように変換され出力されると、誤った情報をPDFに記載することになります。
セキュリティ対策のつもりで入れたコードが、実データを壊す可能性がありました。
最終的には実機検証を行い、エスケープせずそのまま渡す実装に戻しました。
2. appsscript.jsonに追加したと言ったが、実際にはコミットされていなかった
Advanced Drive Serviceを使うために、Drive API v3を有効化する必要がありました。
この点はAIレビューでも指摘されていて、appsscript.jsonにenabledAdvancedServicesを追加する案も出ていました。
しかし、実際にAIで変更されたコードにはappsscript.jsonが含まれていませんでした。
コードのヘッダーコメントには「appsscript.jsonでDrive API v3を固定する」と書いてあるのに、リポジトリにはそのファイルがない、というコメントと実体がズレが生じていました。
コードの一部だけを見ていると「コメント上は対応済み」に見えますが、今回の変更内容全体や、実際に変更されたファイルまで見ないと判断できません。
今回のケースでは、まさにそこが落とし穴でした。
3. コミットメッセージの表現が実装とズレていた
コミットメッセージ(変更内容の説明)に「リビジョン完全削除」という表現がありました。
しかし実際のコードでは、Drive.Revisions APIを使ってリビジョン単位の削除をしていたわけではありません。
やっていたのは、テンプレートから作成した一時GoogleドキュメントをDrive.Files.removeでファイルごと完全削除する処理でした。
実装としては問題ありませんでしたが
「リビジョン完全削除」という表現は、読む人に誤解を与える可能性がありました。
これも、コードそのものの動作だけではなく、PR説明・コミットメッセージ・実装意図の整合性を見るレビューです。
AIにコードだけを渡してレビューしていると、どうしても抜けやすい部分だと実感しました。
なぜAIレビューでは抜けたのか
今回の経験から、AIレビューの弱点がいくつか見えました。特に「キャッチボール形式でも抜けた」という点が、自分にとって一番印象的でした。
1. AIは「もっと安全そうな一般論」に寄せがち
$ や \ を含む文字列を置換する、という話をすると、多くのエンジニアは反射的に「エスケープが必要では?」と考えるらしいです。
AIも同じように、一般的な正規表現置換の文脈で「置換文字列をエスケープした方が安全」と提案してしまい、非エンジニアの私にはそれに気付けないというザル状態でした。
しかし、今回のAPIではreplacementがリテラル扱い(=画面に書いてある文字をそのまま)でした。
つまり、一般論としてはごもっともな指摘も、ツールや機能によって逆効果になりえるということが分かりました!
どうやら、AIレビューは「それっぽい安全策」を提案することがあるようです。
でも、それが本当に必要かどうかは、それぞれの仕様や実機検証で確認する必要があるのだと感じました。
2. AIは提示された範囲の外を見られない
appsscript.json がコミットされていない問題は、まさにこれです。
AIに .gs と .html のコードだけを渡していた場合、リポジトリ全体のファイル構成はわかりません。
コメントに「appsscript.jsonで固定」と書かれていれば、AIはそれを前提にしてしまうことがあるようです。
人間レビュワーはPR(プルリクエスト=コードの変更内容をレビューしてもらう申請)全体を見て
ファイルが実際に追加されているか、コミットに含まれているか、PR説明と差分が一致しているかをチェックします。
こうした「コード外の整合性」は、AIには見えないことが分かりました。
3. キャッチボールで増幅されるのは「共通して気づいていること」だけ
2つのAI(ClaudeとGPT5)が互いにレビューし合うと、
片方の指摘をもう片方が補足したり、説明をわかりやすくしたりしてくれるので、「気づいていること」については精度が上がります。
しかし、AI同士で何度やり取りさせても、出てこないものは出てこないということが分かりました。
両方のAIが最初から気づいていない点は、何往復させてもそのまま残ってしまいました。
たとえば、必要な appsscript.json が実際の変更内容に入っていなかったこと。
それから、replaceText の仕様について思い違いがあったこと。
このあたりは、AI同士のレビューでは拾いきれませんでした。
理由は、おそらく「コードの外側を見ること」や「実際のAPIの動きを確かめること」が、どちらのAIにとっても苦手だったからでは?と考えています。
4. 「最終版」という言葉が危険
今回、AIから何度も「最終版として良い」という評価をもらいました。
ただ振り返ると、これは少し危険な言葉でした。
- コード単体として動くか
- セキュリティ上明らかな穴がないか
- 実機で動作確認したか
- リポジトリ上のファイル構成と一致しているか
- コメントと実装が一致しているか
- PR説明とコミットメッセージが正確か
- 運用ルールと実装が一致しているか
「最終版」の定義の範囲を広げれば、指摘はまだ出たと思います。
AIが「最終版」と言っても、それは多くの場合「今のコードと観点の範囲では大きな問題は見当たらない」という意味でしかありません。
本当の最終判断は、人間がレビュー・基準を決める必要があるのだと実感しました。
AIレビューは無意味だったのか
では、AIレビューは無意味だったのか?というと、まったくそんなことはありません。
むしろ、特に非エンジニアの私にとっては、かなり有効でした。
今回のコードは、以下の点でAIレビューを重ねる前と後では、明らかに品質が上がりました。
- 入力検証が強くなった
- 一時ファイル削除が堅くなった
- エラー処理が整理された
- HTMLとロジックが分離された
- XSS対策が明確になった
- Drive共有設定への意識が入った
- 実行時間やAPI呼び出しの無駄も減った
一人で見ていたら気づきにくい観点を、短時間で大量に出してくれました。
ただし、AIレビューは「人間レビューの代替」ではなく、あくまで「人間レビューの前処理」として使うのが正しいと感じました。
今回学んだこと
AIの指摘も実装前に仕様確認する
「AIが言っていたから」ではなく、公式仕様(Googleが出している「この関数の使い方・ルール」のドキュメント)や実機検証で確かめる。
特に今回引っかかった正規表現・エスケープ・認証・ファイル削除・外部APIあたりは要注意です。
実機検証はレビューの一部
特に、GASやGoogle Workspace系のAPIはドキュメントだけではわかりにくい挙動もあります。
「コードレビュー」と「実機検証」は別物ですが、実際には両方必要です。
コードだけでなくプルリクエスト全体を見る
追加すべきファイルがコミットされているか、コメントと実装が一致しているか、コミットメッセージが誤解を招かないか。
これらはAIにコードを渡すだけでは見えません。
AIレビュー結果は「採用」ではなく「レビュー対象」にする
その指摘は本当に正しいか、仕様上必要か、逆にデメリットや副作用はないか、実機で確認したか。
ここまで見て初めて採用すべきだと思いました。
まとめ
ClaudeとGPT-5にキャッチボール形式で何度もレビューさせても、抜けは残りました。
でも、それはAIレビューが使えないというわけではありません。
AIレビューは、レビューを楽にする。でも、レビューを終わらせるものではない。
AIで取れるものを取り切ってから人間に渡しますが、最後に品質を保証するのは、やはり人間のレビューと実機検証でした。
今後も AI レビューは使っていこうと思いますが、「AIがOKと言ったからOK」ではなく、AIの指摘も含めて人間が判断するという前提で使っていきたいと思います。
また、非エンジニアなりにより精度の高いレビューのプロンプト等も考えていきたいと思っています。





