AIが書いたコードを取り込む前に確かめること
AIにコードを書かせて、動いた。エラーも出ない。だから取り込む——この判断だけで進めていないでしょうか。
動くことと、正しいことは別です。そして厄介なのは、動くのに間違っているコードが、いちばん見つけにくいということです。エラーが出るコードは、その場で目に付きます。しかし動いてしまうコードは、見た目には何の問題もなく通り過ぎていきます。問題が表に出るのは、想定していなかった値が入ってきたときや、しばらく経ってからデータの扱いに不整合が見つかったときです。そのときにはもう、誰が書いたかも、どういう意図だったかも忘れられていることが少なくありません。
この記事では、AIツールの導入手順や料金、どのツールを選ぶべきかといった話はしません。すでにAIにコードを書かせている人が、出てきたコードをどう確かめてから取り込むか、その一点だけを扱います。
「動いた」で確認は終わっていません
AIに指示を出してコードが返ってくると、まず試してみるはずです。実行してエラーが出なければ、あるいは用意していたテストが通れば、多くの人はそこで安心して次の作業に移ります。ですが、その「通った」が意味しているのは、自分が試した範囲では問題が表面化しなかったという事実だけです。試していない入力、想定していなかった状態、めったに通らない分岐については、何も確かめられていません。
テストが通ることと、コードが正しいことは、重なる部分はあっても同じではありません。テストは書いた人が思いついた条件しか検証できず、AIが書いたコードに対して自分がテストを書く場合も、自分が思いつく範囲でしか穴を塞げません。さらに、AIが提案してきたコード自体に「自分がそもそも想定していなかった前提」が紛れ込んでいることもあります。この前提のずれは、実行してみただけでは絶対に表面化しません。見た目が動いているからこそ、後から気づきにくいのです。
だからこそ、「動いた」を確認の終着点にせず、そこから先に何を見るかを決めておく必要があります。次の節で、その順番を整理します。
確かめる順番を決めておく
AIが返してきたコードを前にすると、つい上から下へざっと目を通して「まあ良さそうだ」で終えてしまいがちです。これでは、自分がもともと何を実現したかったのかという基準が抜け落ちたまま読むことになり、コードの見た目のもっともらしさに引っ張られてしまいます。確かめる順番をあらかじめ決めておくと、この抜け落ちを防げます。
順番の考え方は次のとおりです。
- まず、自分が何をさせたかったのかを言葉にして確認する。指示を出した時点の意図を、コードを読む前にもう一度自分の言葉で書き出しておきます。ここを飛ばすと、後の工程すべてが「なんとなく良さそう」という印象評価になってしまいます
- 次に、そのコードを読んで、意図と合っているかを見る。書いてある処理が、さきほど言葉にした目的をそのまま実現しているかを一行ずつ追います。目的からずれた分岐や、余計な処理が紛れていないかもここで確認します
- 続いて、境界の値や異常系を試す。空の入力、極端に大きい・小さい値、想定外の型や欠けたデータなど、普段の動作確認では通らない条件を意図的に試します
- 最後に、既存のコードとの整合を見る。命名や設計の方針が周囲のコードとかけ離れていないか、同じ処理が別の場所にすでにあって重複していないか、周辺の処理を壊していないかを確認します
このエディタ内での確認は、コードを書いている最中に何度も繰り返す作業になります。エディタの中で候補を提示しながらコードを書き進めるタイプのAIツールを使っている場合は、この順番を一回だけでなく、提案を受け入れるたびに小さく回すことになります。
順番を決めておく利点は、抜け漏れを減らせることだけではありません。どこまで確認したかを自分自身で把握できるようになる、という点も大きいです。「意図の確認はしたが境界値はまだ」という状態が分かっていれば、途中で作業を中断しても再開しやすくなります。
判断基準表 — どこまで自分で確認するか
AIが書いたコードのすべてを同じ密度で確認する必要はありません。定型的な処理まで毎回時間をかけていては、AIに書かせる意味が薄れてしまいます。一方で、確認を省いてよい場所を見誤ると、被害の大きい箇所を素通りしてしまいます。次の表は、その線引きの目安です。
| 種類 | 具体例 | 確認の重さ | 理由 |
|---|---|---|---|
| そのまま取り込みやすいもの | 定型的な変換処理、既存の書き方に合わせただけの記述、テストコードの雛形 | 軽く目を通す程度でよい | 誤りがあっても影響範囲が狭く、動作を見ればすぐ分かることが多い |
| 必ず自分で確認すべきもの | 外部からの入力を扱う箇所 | 意図・境界値・異常系まで確認 | 想定していない値が来ることが前提の場所であり、抜けがそのまま不具合や不正な動作につながる |
| 必ず自分で確認すべきもの | 認証や権限に関わる箇所 | 意図・境界値・異常系まで確認 | 誤りが起きたときに、見えてはいけないものが見えたり、できてはいけない操作ができたりする |
| 必ず自分で確認すべきもの | お金や数量の計算 | 意図・境界値・異常系まで確認 | 端数や上限の扱いを誤ると、金額や在庫の数値がそのまま食い違う |
| 必ず自分で確認すべきもの | データを消す・上書きする処理 | 意図・境界値・異常系まで確認 | 取り消せない操作であり、条件を一つ間違えるだけで対象を広げてしまう |
| 必ず自分で確認すべきもの | 日付や時刻の扱い | 意図・境界値・異常系まで確認 | 期日の前後関係やタイムゾーンの取り違えは、見た目には気づきにくい |
表の右側に並んでいる項目に共通しているのは、間違えたときに気づきにくく、かつ後から直すのが大変という点です。ここに時間をかけ、左側の定型的な処理には時間をかけない、というメリハリをつけることが、確認作業全体を軽くするコツです。
読めないコードは取り込まない
確かめる順番のなかで、いちばん見過ごされやすいのが「そもそも自分が読んで理解できているか」という点です。動いていて、意図とも合っていそうに見えても、自分がそのコードの動きを人に説明できないなら、それはまだ取り込むべきではありません。
理由は単純です。自分が説明できないコードを取り込んでしまうと、後で不具合が起きたときに自分では直せません。書いたのが自分ではなくAIであっても、取り込んだ以上は自分のコードです。動かなくなったときに頼れるのは、そのときの自分の理解だけです。
読んで分からない部分があったら、AIにその部分の説明を求めるのは有効です。ただし、返ってきた説明を鵜呑みにしてはいけません。説明してもらった上で、自分でもう一度コードを読み直し、その説明が実際のコードの動きと一致しているかを確認する、という手順を挟みます。AIの説明ともっともらしさは、コードそのものの正しさとは別の話だからです。説明が分かりやすかったからといって、コードが正しいとは限りません。
この確認を面倒に感じるときほど、その部分は複雑で、しかも重要な処理である可能性が高いです。面倒だからと読み飛ばした部分に限って、後から問題が見つかるということが起こりがちです。
もっともらしいが存在しないものに注意する
AIは、実在しない関数名やオプションを、自信を持った書き方で提案してくることがあります。文脈からすればいかにも存在しそうな名前がついているため、詳しい人でもぱっと見ただけでは気づきにくいのが厄介なところです。
このような提案を見分ける確実な方法は、公式のドキュメントで実在を確認することです。名前の雰囲気や、コメントの説明がもっともらしいかどうかでは判断材料になりません。使ったことのない関数やオプションが出てきたら、実装を進める前に、その存在と使い方を公式の情報で照らし合わせる習慣をつけておくと安心です。
これは特別な処理に限った話ではありません。見慣れた処理の中に、見慣れない引数やオプションが一つだけ紛れ込んでいる、というような小さな形で現れることもあります。全体の見た目に違和感がないぶん、見逃しやすい点に注意が必要です。
見つけたときは、その場で存在を確認する習慣をつけておくと、後からまとめて調べ直す手間が省けます。公式のドキュメントに載っていない名前であれば、似た働きをする別の書き方を探すか、AIに別の案を出し直してもらうか、いずれにしても自分で存在を確かめてから先に進むことが大切です。
出所とライセンスの確認
AIが提案してくるコードの中には、どこかで見たコードによく似たものが混じっていることがあります。学習の過程で似た書き方を数多く扱っているため、特徴的な処理ほど既存のコードと似通った形になりやすいためです。
このこと自体を過度に恐れる必要はありませんが、出所がはっきりしないコードをそのまま取り込むと、後になってライセンスや著作権の面で問題になることがあります。判断は状況によって変わるため、この記事の中で一律の結論を出すことはできません。社内の方針や契約で扱いが決まっている場合は、必ずそちらに従ってください。判断に迷うコードが出てきたときは、取り込む前に、社内の担当部署や責任者に確認する、という一手間を惜しまないことをおすすめします。
とくに、特徴的なアルゴリズムやまとまった処理のかたまりを丸ごと提案されたときは、定型的な処理よりも一段丁寧に扱ったほうが安全です。取り込む前に立ち止まって出所を意識する、という一つの習慣を持っておくだけでも、後になって慌てて調べ直す状況を避けやすくなります。
レビューする人への配慮
AIに書かせた部分を、そのままチームメンバーにレビュー依頼することもあるはずです。ここで気をつけたいのは、自分が理解していない状態でレビューに出すと、負担がレビュアーに寄ってしまうという点です。
本来レビューは、書いた本人がある程度理解した上で「ここの判断に自信がない」「この境界値の扱いを見てほしい」といった具体的な観点を示し、レビュアーがその観点を中心に確認する、という分担で成り立っています。ところが、書いた本人がコードの意図すら説明できない状態で出してしまうと、レビュアーは意図の推測から始めなければならず、確認すべき範囲もどこまでかが分からなくなります。結果として、本来レビュアーがしなくてよいはずの作業まで背負わせることになります。
ここまでに挙げた、意図の確認・読み込み・境界値の確認・判断基準表による選別を自分の手で済ませておくことは、レビュアーへの配慮でもあります。自分がどこまで確認し、どこに自信がないかを一言添えてレビューに出すだけでも、レビュアーの負担はかなり変わります。
まとめ
AIが書いたコードを取り込むかどうかは、動くかどうかだけでは判断できません。動くのに間違っているコードは、見た目には何も問題がないように見えるからこそ見つけにくく、後になって表面化しやすいものです。
自分が何をさせたかったのかを言葉にして確認し、そのうえでコードを読んで意図と合っているかを見て、境界の値や異常系を試し、既存のコードとの整合を確認する。この順番を踏むこと、そして自分が読んで説明できないコードは取り込まないことが、確認の土台になります。判断基準表を目安に、確認の重さにメリハリをつければ、すべてを同じ密度で見る必要もありません。実在しない関数やオプションの提案、出所やライセンスがはっきりしないコードには注意を払い、判断に迷うものは取り込む前に確認する。そして、レビューに出す前に自分の理解を整えておくことが、レビュアーへの配慮にもなります。
最後に、取り込む前の確認として振り返っておきたい項目をまとめます。
- 自分が何をさせたかったのかを、コードを読む前に言葉にできているか
- コードを読んで、その意図と処理の内容が一致しているか
- 境界の値や異常系を、実際に試したか
- 既存のコードとの整合が取れているか、重複や矛盾がないか
- 外部からの入力・認証や権限・お金や数量の計算・データを消す/上書きする処理・日付や時刻の扱いを、とくに重点的に確認したか
- そのコードの動きを、自分の言葉で人に説明できるか
- 実在しない関数名やオプションが紛れていないか、公式のドキュメントで確認したか
- 出所がはっきりしないコードについて、社内の方針や契約に照らして問題がないか確認したか
- レビューに出す前に、自分がどこまで確認し、どこに自信がないかを添えられているか
エディタの中でAIに提案させながら書き進めるスタイルに慣れてきた人は、GitHub Copilotの始め方もあわせて参考にしてみてください。導入や設定そのものより、日々の確認の習慣づけに時間を使うほうが、長い目で見て効いてきます。