生成AIの書いたコードを読むべきか
最近、生成AIの書いたコードを読むべきか、読むべきだとしたら、どのくらいちゃんと読むべきか、といった議論が増えてきました。実際にAnthropicも、社内でコードレビューをどのように回しているか、といった紹介をする記事を出していました。
これに対して、私個人の見解としては、「読みたいなら読めばいいし、読みたくないなら読まなければいい」と思います。何かを言っているようで何も言っていませんが、そういうことにしか結論はならないのだと思います。本記事では、そこに至るまでの思考を整理してみます。
なお、本記事の内容はどこかの組織を代表する内容ではなく、私個人の意見・感想です。また本記事は思考整理を目的に書き始めたため、章構成など分かりづらい箇所、矛盾点なども多数存在する可能性があります。ご容赦ください。
コードを全て読む場合と読まない場合
まず、プログラミング言語によって書かれたソースコードを1行ずつ見るといったことを考えてみましょう。この場合、たしかにプログラミング言語によって表現しうる可能な限りの情報を得ることができます。1行ずつ、丁寧に読んでいるのですから、当然です。
では、ソースコードを大雑把に読むといったことを考えてみましょう。この場合、大雑把に読んでいるので、プログラミング言語によって表現しうる詳細を理解しきれていない可能性がありえます。
次に、ソースコードを全く読まないといったことを考えてみましょう。この場合は大雑把に読んでいる場合と同様に、プログラミング言語によって表現しうる詳細を理解しきれていない可能性がありえます。
今回は3パターンとして具体例を取り上げてみましたが、実際のところは大枠としての分類としては2パターンしか存在しません。プログラミング言語によるソースコードを全て読むのか、読まないのか。
プログラミング言語によって書かれたソースコードを全て読んだ場合、プログラミング言語を処理するシステムが仕様通り正しく処理するという前提において、100%自分の読んだ通りに動くということになります。逆に、全てを読んでいない場合は、プログラミング言語を処理するシステムが仕様通り正しく処理するという前提を置いたとしても、100%自分の想定した通りに動くとは言えないということになります。
「全て読めば100%」の前提
先ほど置いた前提はとても重要です。プログラミング言語を処理するシステムが仕様通り正しく処理するという前提が崩れた場合、ソースコードをすべて読んだとしても、自分の読んだ通りに動かない可能性が出てくるということになります。つまり、前提が崩れると、ソースコードを読むべきか読まないべきかという議論の意味が小さくなってきます。
実際のところ、この前提は概ね成立すると言って良いでしょう。著名なプログラミング言語がそうそう仕様通りに動かないということはありません。無名なプログラミング言語、いわゆる遊び道具であれば、仕様通り動かないということも頻繁に起こりうるかもしれませんが、著名なものはよくできているということです。
ただし、「概ね成立する」というのは、当然ながら、成立しない場合も稀にあるということです。プログラミング言語自体のバグです。プログラミング言語のルールに則って記述をしているのに、その通りに動いてくれない。
何が言いたいかというと、ソースコードをすべて読んだとしても、必ずしもその仕様に沿って動くとは限らないということです。本当にそのプログラミング言語の仕様が正しいのかどうかは、プログラミング言語自体の実装を見に行く必要が出てきます。プログラミング言語の実装はまたプログラミング言語であったりしますし、機械語と呼ばれるものであったりするでしょう。100%を追求するなら、結局これらをすべて見る必要があります。そして、もっといえば機械語は機械語でしかありませんから、それらを最終的に動かすハードウェアの内部まで見にいく必要があるでしょう。こうなると、世界中を旅して各家庭のパソコンを覗き込む必要が出てきてしまいますね。
ここまでの話は、「ソースコードをすべて読む必要はない」と結論づけたいわけではありません。言いたいのは、ソースコードをすべて読んでいる人であっても、その下にあるプログラミング言語の実装やハードウェアについては、読まずに信頼して使っているということです。誰しもどこかで「ここから先は信頼する」という線を引いています。そして、生成AIの書いたコードをどこまで読むかも、同じく「どこに線を引くか」という問いとして捉えられるのではないかと思っています。ただし後で述べるように、プログラミング言語と生成AIとでは、その線を引く根拠となる信頼の性質が大きく異なります。
抽象化としてのプログラミング言語と生成AI
我々は、具体化と抽象化を利用して、脳で考えられるひとつのことに集中してきました。プログラミング言語というのは、ある意味で抽象化の方法です。機械語を都度書くなんてとてつもなく大変なので、抽象的にしたプログラミング言語が生まれました。これによって、具体的すぎる機械語を意識することなく、我々はプログラムを作り上げることができています。
抽象化された仕組みを使うにあたって、インターフェースが重要になってきます。インターフェースには、契約とも言える約束が伴います。この操作をしたら、これが起こる、ということを約束するものです。
プログラミング言語は、約束を概ね守りますが、バグといった形で例外的に約束を破る場面もありえます。
プログラミング言語にバグが見つかった場合、そのプログラミング言語の利用者達は、約束を破られたことになります。プログラミング言語を作っている人たちは、多くの場合約束は守りたいと思っているでしょうから、破ってしまった約束を再発させないために、修正を施していきます。そうして、利用者達は修正を見て、そのプログラミング言語に信頼を取り戻すかもしれないし、そのプログラミング言語から離れるかもしれません。
ちなみに、多くの方がそうであると認識しているだろう通り、生成AIもまた、ある意味で抽象化の方法だと捉えることができます。プログラミング言語が機械語を抽象化したように、生成AIはプログラミング言語を抽象化し、我々は自然言語で指示を出すだけでプログラムを作り上げることができるようになりました。
個人としての信頼と責任
先ほど述べたように、抽象と具体の間には、インターフェースを通じた契約があります。その契約がどのくらい守れるか、また破られた場合にその契約通りの状態に戻すためにどのくらいの行動ができるのか。これはまさに信頼です。
核心に近づいてきました。改めて本題に戻ると、「生成AIの書いたコードを読むべきか、読むべきだとしたら、どのくらいちゃんと読むべきか」については、どのくらい生成AIを信頼するかといったことに他なりません。
私個人としてはとても驚きなのですが、生成AIのプロバイダーは、生成AIが作った成果物(ソースコード)に対して責任を負いません。成果物によって利用者が万が一傷ついたり、重大な損失を被ったとしても、基本的には利用者側の責任であるということになります。生成AIのプロバイダーは、あくまで生成AIが動き続けることに対して責任を負うのであって、生成AIが生み出すコンテンツには責任を負いません。
たとえばAWSも、インフラを抽象化して提供するサービスですが、SLAとして可用性などを定めており、それを下回った場合の補償も含めた契約があります。プログラミング言語には仕様という約束があり、AWSにはSLAという法的な契約があります。一方で、生成AIの成果物には、そのどちらもありません。
では、生成AIの書いたコードがバグを生み出した場合、そのバグは誰が責任を取るのでしょうか。生成AIプロバイダーは責任をとりませんから、生成AIを利用した人が責任を取るのか、それとも「生成AIがやったことだから」として、生成AIという存在概念に責任をなすりつけるのか、といったところになってきます。生成AIは、幸いにも生成AIプロバイダーの責任によって動き続けはしますから、生成AIという存在に責任をなすりつけるという考え方も、今後は増えていくのかもしれません。
そもそも、自分に目指したい世界があって、それを実現するためにソースコードを書いているのであれば、責任はすべて自分にあると考えることもできます。自分の人生に起こるすべてのことは自分の責任だという理論です。
ここまでをまとめると、「生成AIの書いたコードを読むべきか、読むべきだとしたら、どのくらいちゃんと読むべきか」については、結局のところ、その結果に対して自分が責任を持って対処できるかどうか、といったところに帰結するでしょう。そして、その主観的な判断基準としては、どれだけ生成AIという存在を信頼するか、といったところになります。生成AIがバグを生み出したとしても、生成AIが直してくれる、と信じている人にとって、生成AIは信頼できる存在でしょうし、生成AIがバグを生み出した後に解決してくれないと感じた人にとって、生成AIは信頼できない存在でしょう。また、生成AIの設計には信頼をしていないが、設計に基づく実装であれば信頼できる、といった中間的な信頼などもあるでしょう。
社会としての信頼
個人としての信頼だけでなく、生成AIが世の中一般としてどれだけ信頼されているかといったことも重要になってくるでしょう。「生成AIが書いたコードのせいで障害が起きました」と言った時に、極端に例えれば、「ちゃんとレビューをしなかったお前が悪いんだろう!」と考えることが一般的なのか、それとも「それなら仕方ないな」となるのか。
ここ数年における一例としては「AWS障害」は良い例だと思います。AWSに障害が起こっているなら、(もちろんサービスの性質や規模にもよりますが)サービスが落ちていてもある程度仕方ないね、と一定考える人は多い状況だと思います。それはやはりAWSという存在に対してとても大きな信頼があるのだと思います。仮に無名クラウドサービスを使っていて、その無名クラウドサービスに障害が起きた際、そのサービスは「そんな無名クラウドサービスを使うのが悪いんだ!」と言われるかもしれません。
生成AIが流行り始めたばかりの頃は、世の中として信頼が得られていないので、信頼をしない前提でフローを回す必要があり、また信頼が得られてからは、信頼をする前提でフローを回すこともできるようになってきます。つまり、生成AIの書いたコードをどこまで読むべきかは、生成AIの出す成果の品質だけで決まるのではなく、社会が生成AIをどれだけ信頼しているかにも左右されるのだと思います。
分からないことだらけ
具体・抽象・契約・責任・信頼・・・。本題について、私はこれらの言葉が何であるかをまず議論することが先決であると思っています。これらの言葉が何であるか、といったことを、まじめに考えて突き詰めるのでなければ、そもそも「生成AIの書いたコードを読むべきか、読むべきだとしたら、どのくらいちゃんと読むべきか」といったことに回答することはできないと思っています。
社会としての信頼やルールに従うだけで良いのか
先ほど挙げた中の「責任」への理解を深めるために、私は先日ハンナ・アーレントの『責任と判断』という書籍を読み始めました。
まだ最初の方しか読んでいませんが、ナチス政権下で上からの命令に従い、ユダヤ人の強制収容所への移送を指揮したアイヒマンが、戦後に裁かれ死刑となった裁判を題材に、個人の責任や道徳性について論じた書籍のようです。
「当時その国においては合法的に命令に従って行ったはずの行為が、後に罪として裁かれる」というのは、その文面だけを見ればとても異質なものであると感じました。法律・ルールに基づいた行動をするだけではダメであり、個人個人の判断や道徳性が重要になってくる、ということです。
最近であれば、生成AIによるサイバー攻撃も増えているように思いますが、これも一種の道徳性の問題と捉えられるかもしれません。「単にAGENTS.mdの内容に従って動いた」だけの生成AIがサイバー攻撃を行っていた場合、生成AIはルールに従って単に行動したといえますが、これは許容されるべき問題なのかどうか。もちろん許容されるわけはありませんが、現代においては少なくとも生成AIを利用した人だけが悪いのであって、(よほど悪質な生成AIでない限りは)生成AI自体および生成AIプロバイダーが悪いとは基本的にみなされないでしょう。
これを本題に引き戻してみます。生成AIの書いたコードが原因で障害が起きたときに、「生成AIが書いたコードなので」「チームで決めたレビューのフローには従ったので」と説明する場面を想像します。これらの説明も、ルールに従っただけという説明に近い構図なのかもしれません。生成AIの書いたコードをどこまで読むかという問いは、そのコードがもたらす結果について、自分がどこまで責任を引き受けるのか、そしてその判断は道徳的に正しいのか、という問いでもある。先ほど、社会として生成AIが信頼されるようになれば、信頼する前提でフローを回せるようになると述べました。しかし、社会に許容されていることと、個人として正しい判断であることは、必ずしも同じではないのかもしれません。