見出し画像

コード生成技術から考える、人とAIの共生

AIがソースコードを書く時代

プログラミングを始めた頃、ソースコードをAIが書くような世界が訪れるなどとは全く思っていなかった。現在のまるで魔法のように何でも理解するAIと比較すると、かつてのAIはファジーなものを扱うことにはあまり向いておらず、どちらかというと極めて論理的な代物であった。なので、人々の中には、コンピュータというのは処理を忠実に実行する装置であり、コンピュータに何をどう実行するのかを正確に命令するのが人間だという認識があった。コンピュータは融通が聞かない道具で、ソースコードの中に1文字でもミスがあれば呪文のような謎の横文字を羅列し、プログラミングを始めたばかりの人を苦しめてやる気を削ぐ。コンピュータとはそういう存在だった。だから、プログラムが書けるということは、その融通の効かないコンピュータに対して、何をどうするのかを一つ一つ正確に書き記すことができることと同義だと考えていた。

その認識は世の中の全てのプログラマーに共通なもので、未来においてもそうであり続けるのだろうと思っていた。しかし、ニューラルネットワークをベースとしたAI技術の飛躍的な進歩により、昨今その認識が大きく変わりつつある。ChatGPTが世の中に普及し、生成AIを用いたコード自動生成がトレンドとなる中、人間とコンピュータの関係が変わり始めている。コンピュータはもはや命令を忠実に実行するだけの存在ではなく、AIによって何をどのように実行するかを自分で生み出し、人に提案するようなパートナー的存在へとなりつつある。この界隈においては、人とAIが共創するような未来が生まれつつあるのだ。

AIの助けによって、今まで一人では出来なかったことができるようになることは非常に喜ばしい。プログラマであれば誰しも、一番最初に自分が書いたコードが動いた時には感動を覚えたはずだ。それが今、AIの力を借りて、今までは手が届かなかったような様々なことを実現できるようになっている。身の回りでも、今まではプログラミングに興味があったけど敷居が高くて手を出せなかった人が、ChatGPTに教えてもらうことでプログラミングを習得したというケースを見かけたことがあるはずだ。ちょっとしたプログラムを作り、自分の仕事を効率化したなどという良いニュースも耳に入るようになってきている。誰もがこの技術の恩恵を受けることができる素晴らしい時代だ。

図1: GitHub Copilotによるオートコンプリート 

しかし、人とAIが共に何かを作るというこのユートピア的な時代は、実はそう長くは続かないかもしれない。私たちは、チェスや囲碁・将棋のようなゲームの世界で、人間が呆気なくAIに先を越されてしまう光景を目の当たりしにしてきた。プログラミングにおいても、AIは人の能力のはるか先を行き、人とAIは対等に共創できる関係にはなくなるかもしれない。もしかすると、人はAIの生成するものをただ認めることしかできなくなり、「創造する」という有史以来長きにわたって人を人たらしめてきた尊い行いが、AIに完全に取って代わられてしまうかもしれないのだ。

考えてみれば、Computerとは元々「計算作業をする人」を指していた言葉だ。今この言葉をその意味で使う人はいない。それどころか、その語源が人に由来していたことすら知っている人はあまりいない。プログラミングにおいても、「かつて、人がコンピュータに命令していた時代があった」などと歴史の一幕として語られてしまうのだろうか。

人の役割、AIの役割

1997年、IBMが開発したDeep Blueというスーパーコンピュータが、当時のチェス世界チャンピオン、ゲリー・カスパロフに勝利した。それは、知能という分野で人間がコンピュータに敗北する歴史的な瞬間だった。チェスはそこから数年間、最強の人間と最先端のコンピュータの能力が拮抗する時代が続いたが、その後は人間の能力のはるか上をいくようになった。今では手持ちのスマートフォンですら、トップレベルの人間よりも遥かに強い。

カスパロフはDeep Blueとの対局後、コンピュータを利用した新たなチェスのプレイの仕方を切り開こうと、「アドバンスト・チェス」という人間とコンピュータがタッグを組んで他のタッグと対局するというゲームを考案した。人間の創造性とコンピュータの計算能力を組み合わせてハイレベルな対局が生み出せるのではないかというクリエイティブな試みだ。このルールを生み出して以降、カスパロフは強力なコンピュータを用いて、同じくトッププレイヤーとコンピュータのタッグと対局した。しかし、残念ながらその対局のチェスの質はあまり振るわないものとなった。

アドバンスト・チェスのマッチの試みを通じて彼が発見した最も興味深い事実は、最終的に勝ったのはコンピュータ単体ではなく、強いプレイヤーとコンピュータのタッグでもなく、弱いプレイヤーとコンピュータのタッグだったことだ。強いプレイヤーがコンピュータとタッグを組む際、強いプレイヤーはコンピュータに対して主導権を握ろうとしてしまう。プロのプレイヤーであれば、自分の立てた戦略でゲームを進めることは当然だ。そしてコンピュータを計算するための道具として利用する。しかし、チェスをプレイする上で強いプレイヤーが思い通りにプレイをすることが、本来は人間より能力の高いはずのコンピュータのポテンシャルを封じ込め、期待通りのパフォーマンスを発揮できなくしてしまう。結果、コンピュータのやり方を妨げない弱いプレイヤーの方が良いパフォーマンスを発揮したのだ。

この結果を振り返り、彼は「人間と機械の共同作業の中で人間が行うべき唯一のことは、機械が最大限に力を発揮するように導くことだ」と言う。コンピュータと人がタッグを組む中で人の役割はインターフェースであり、チェスに関する深い知識は必要なく、コンピュータのやり方に従いつつも時々それを修正し、正しい方向に導くことだと述べる。これはチェスのエキスパートではない人にとって、新たな可能性を開く考えだ。

恐らくプログラミングに関しても同じことが言えるのだろう。恐らく未来のいずれかの段階で、AIのプログラムを書く能力が人間のそれよりも高くなる。そうなった時に、AIを目的に向かってうまく導くことのできるような人が価値を発揮することになる。それは必ずしも現在の基準で能力の高いプログラマである必要はなく、全く別の特性、例えば様々なものを使いこなして目的に向かう力を備えた人が活躍するかもしれない。人とAIの関わり方はさまざまな可能性に満ちているのだ。

AIの計算能力を最大限に活かす

コンピュータチェスが人間のトッププレイヤーを凌駕したのは、コンピュータの計算能力が進歩したためだと言われている。現在、ChatGPTを筆頭とした強力な大規模言語モデル(LLM)の登場で、その流れは様々な分野に訪れている。コード生成に関しても、AIが人の能力に急速にキャッチアップしている分野の一つであるのは前述の通りだ。

ただし、コード生成の問題はコンピュータチェスの問題よりも複雑だ。チェスの場合、次の一手として選択できる候補は有限だ。それも候補手数の平均値は35とかなり少ない。一方コードを生成する言語モデルの場合、選択肢はトークンの数だけあるので、探索しなければならない空間がほぼ無限に広い。そのままナイーブに総当たり式で探索を行えば、すぐに計算能力の限界を迎えてしまう。その広大な探索空間から、学習データ内の言語の使用のパターンに基づいて、あり得る選択肢に絞り込むのがLLMだ。LLMに次のトークンの候補とその尤もらしさを尋ねることで、ほぼ無限個の選択肢全てを考慮に入れなくとも、ある程度確率的に当たりをつけられるのである。

しかし、仮にどんなに事前学習やファインチューニングを行ったとしても、LLMが選択肢を一つに絞り込むことはない。それは、そもそも言語そのものに曖昧性が内在するため、LLMに与える指示を厳密に一意に定めることはできないからだ。つまり、一つの指示に対しては複数通りの解釈が存在し、それらはどれもあり得る解釈である。あり得るのであれば、人間の言葉の使用の仕方をよく学習し、人間に類似する帰納バイアスを有するLLMは、その複数通りの選択肢それぞれに対して低くない確率を割り当てるのである。

コード生成に関して言えば、一つの指示に対する実装は一つだけでなく、往々にして複数通り存在する。例えば、数列をソートするように指示された場合、バブルソート、クイックソート、マージソートなど、様々な実装があり得るようなイメージだ。指示への要求を完全に満たすものであったとしても、解の選択肢は一つに定まらないのだ。

通常LLMでは、尤もらしさが最も高いものを出力させ続けて一つのトークン列を得る(Greedy Decoding)。しかし、それは前述のような言語の内在的な曖昧性を捨象し、どれか一つのみを選択することである。そしてその結果、たまたま誤りだとカテゴライズされるもの生成がされることがある。その事象に対してHallucination(幻覚)という名前が付けられている。

図2: Greedy Decodingによって引き起こされるHallucinationのイメージ

そこでもう一度、LLMが出力する確率分布が織り成す探索空間そのものの考慮に立ち返りたい。原理的に、学習されたモデルの中には様々なソースコードの記述パターンが含まれている。指示に対して答えるようなものの選択肢が山のように存在しているのだ。それらの選択肢の山のうち、本当に指示に対して正しく答えているものはごく一部だ。もしそれを何らかの方法で引き当てることが出来たら、コード生成の問題は解決なのである。

幸運なことに、ソースコードは「検証可能」であるという特徴を持っている。生成されたコードは、それがコンピュータ言語である以上シンタックス的に正しくなければならなく、それはつまりコンパイルできる必要がある。また、そのコードが目的を果たすかどうかは、それを反映したユニットテストに通るかどうかで確認できる。つまり、これらを試金石として、玉石混交の大量のコード候補から、意図した挙動を示さないものをふるいにかけることができる。まさに砂金探しのような方法だ。

このように、コード生成に関しては、LLMによってある程度当たりのついた選択肢に対し、計算資源の許す限り生成し、それらを全て「評価」して、良いもののみを残するという総当たり方式が成立する。ちょうど、チェスや囲碁のAIが、大量に何手も先読みをした結果を評価して、その局面の評価値の最も高いものを選択するのと同じアプローチを取れるのである。

図3: LLMによるガイド付きのサンプリングと評価で出力を決定する

AIの手綱を引いて正しい方向へ導く

結局、人間とAIの役割分担は何だろうか。AIは私たちの到底及ばないような計算能力を持ち、客観性が支配する枠組みの中にある問題を人間よりも圧倒的に早く正確に解決できる。しかし、その枠組み自体を作るのは人間だ。AIは大量に候補を生成し、それを自動的に評価することで正解を得ることができるが、その評価基準を定めるは人間だ。目的に合致するように評価基準を作り、また状況に応じて臨機応変に評価基準を修正し、AIが間違った方向で生成するのを防ぐ、これらは人間の役割だ。

それはまるで、暴れ馬に馬具(harness)を装着して、暴れないようにいなしながら操るのと似ている。玉石混交を生成するAIの手綱を人間が引き、幻覚(Hallucinations)と隣り合わせのAIの創造性を上手にコントロールし、正しいゴールへと導く。私たちの持つ目的へ導く力こそが、人とAIの共生の最大の鍵なのだ。

この記事が気に入ったらサポートをしてみませんか?