生成AIが大人気です。生成AIを使うと簡単な指示を与えるだけで、プログラムを生成してくれます。とは言え、各AI(大規模言語モデル)ごとに異なる結果を出力します。そこで、今回は、素数生成などのお題を使って、Google BardとOpenAI ChatGPTの生成するプログラムを比較してみましょう。

生成AIのコード生成機能について

『生成AI(Generative AI)』とは、事前に膨大なデータを利用して学習した大規模モデルを利用して、画像、音楽、会話などさまざまな新しいコンテンツを生成できるAIのことです。例えば、OpenAIが開発したChatGPTは、高度な文章生成能力を持っており、自然にAIと会話できるだけでなく、文章の要約から、外国語への翻訳など、さまざまな能力を持っています。また、プログラムを生成する機能も優れており、今後、プログラマーの働き方にも変化がありそうです。

そして、大きな話題になったChatGPTに続き、2023年5月、GoogleもBardと呼ばれる生成AIのベータ版をリリースしました。Bardのプログラム生成機能も優れており、C++、Go、Java、JavaScript、Python、TypeScriptなど20を超えるプログラミング言語に対応しています。

そこで、ChatGPTとBardに対して同じお題を与えてみて、どちらが優れたプログラムコードを生成するのか、プログラマー視点でジャッジしてみます。

一番勝負 - 素数を3000個表示するプログラム

それでは、最初の勝負です。ここでは、次のようなお題を出してみようと思います。AIなんかに負けないという腕をお持ちの皆さんは、答えを見ないで自分で作ってみてください。

【お題】
素数を画面に3000個表示するPythonのプログラムを作成してください。

まずは、素数を求めるだけの簡単なプログラムを作るという単純なお題です。「素数」とは、1と自分自身以外の約数を持たない正の整数です。それで、1とその数自体以外では割り切れない数が素数です。

それで、ChatGPTとBardに対して上記の指示をそのまま入力してみました。すると、次のようなプログラムを生成しました。

次の画面が、ChatGPT(モデルGPT-3.5)が出力したプログラムです。

  • 素数を3000個求めるChatGPTのプログラム

    素数を3000個求めるChatGPTのプログラム

そして、次の画面が、Bardが出力したプログラムです。

  • 素数を3000個求めるBardのプログラム

    素数を3000個求めるBardのプログラム

比べてみましょう。どちらも、似たプログラムを出力しています。どちらにも、is_prime関数があります。そして、ループ変数iを利用して引数nが割り切れるかどうかを「%」演算子で確認しています。

しかし、プログラムを実行してみると異なる結果が出力されます。特に、初見でもBardが出力する素数の個数が間違っていることが分かります。お題では、3000個の素数を出力するようにというお題でしたが、Bardが出力したのは、2から3000までの整数の中から素数のものを出力するものでした。実際に出力されたプログラムから該当する部分を抜粋したのが以下のものです。

# Bardの出力したコード
# 2から3000までの数を走査する
for i in range(2, 3001):
  if is_prime(i):
    print(i)

この点では、ChatGPTの方が優秀でした。下記のように変数countを用いて3000個の値を出力するようにしています。

# ChatGPTが出力したコード
count = 0
number = 2

while count < 3000:
    if is_prime(number):
        print(number, end=' ')
        count += 1
    number += 1

そうです。この勝負、完全にChatGPTの勝利です。

とは言え、素数かどうかを求める関数is_primeをしっかり作っています。筆者の独断と偏見で点数を付けると、ChatGPTが95点としたら、Bardは70点です。

二番勝負 - 素数判定の関数をテストするプログラム

ところで、先ほどの勝負では、お題のポイントとなるのが、素数判定を行うis_prime関数でした。そこで、次の勝負は、これに関連したものにしました。

【お題】
素数判定を行う関数is_primeをPythonで作りました。この関数をテストフレームワークのPyTestでテストするプログラムを作ってください。

それでは、上記のお題をChatGPTとBardに入力してプログラムを出力させてみました。なお、生成AIを使う場合、いつも同じ結果を返す訳ではありません。気に入らない時は、同じ入力から異なる出力を再生成させることができます。そこで、今回は、いくつかプログラムを生成させてみて、最も優秀なものを採用することにしました。

次の画面がChatGPTで素数判定is_primeをテストするプログラムです。

  • ChatGPTで素数判定関数をテストするプログラム

    ChatGPTで素数判定関数をテストするプログラム

ちょっとプログラムが長いので、画面に入りきらないため、ポイントを抜粋して以下に記述します。素数の場合、素数ではない場合、大きな素数で素数のもの、素数でないもの、負の数の場合など、コメントで場合分けを付けてテストを記述しています。

def test_is_prime():
    # 素数の場合
    assert is_prime(2) == True
    assert is_prime(3) == True
    assert is_prime(5) == True
    assert is_prime(7) == True
    assert is_prime(11) == True
    # 素数ではない場合
    assert is_prime(1) == False
    assert is_prime(4) == False
    assert is_prime(6) == False
    assert is_prime(8) == False
    assert is_prime(9) == False
    # 大きな素数
    assert is_prime(997) == True
    assert is_prime(7919) == True
    assert is_prime(104729) == True
    # 大きな素数ではない場合
    assert is_prime(1000) == False
    assert is_prime(12345) == False
    assert is_prime(99999999) == False
    # 負の数
    assert is_prime(-2) == False
    assert is_prime(-7) == False
    assert is_prime(-11) == False

次に、Bardが出力したプログラムを確認してみましょう。

  • Bardで素数判定関数をテストするプログラム

    Bardで素数判定関数をテストするプログラム

こちらも、プログラムを抜粋したものを紹介します。Bardが出力したプログラムを確認してみましょう。こちらも、素数の場合、素数でない場合、値の境界となる値に分けてテストを出力しています。

def test_is_prime_positive():
    assert is_prime(2) == True
    assert is_prime(3) == True
    assert is_prime(5) == True

def test_is_prime_negative():
    assert is_prime(1) == False
    assert is_prime(4) == False
    assert is_prime(6) == False

def test_is_prime_edge_case():
    assert is_prime(0) == False
    assert is_prime(1) == False

初見では、今回のプログラムはどちらも悪くありません。そもそも、プログラムのテストを記述する場合、期待する値を網羅して記述する必要があります。双方、期待する値を網羅している点で、良い勝負と言えます。

それでは、両者のプログラムを判定してみましょう。ChatGPTは90点、Bardは85点です。どちらのプログラムも良いのですが、ChatGPTは大きな素数や負数と、より多くのケースをテストするようになっていたので、少し点を高くしました。二番勝負も、僅差でChatGPTの勝利です。

なお、ChatGPTとBardの両者が出力したテスト関数を使って、先ほどのis_prime関数をテストしてみました。すると、両者ともテストは成功していました。

三番勝負 - Luaを使ったコイン枚数を調べるプログラム

それでは、次の試合を楽しみましょう。これまでは、Pythonのプログラムでしたが、少しマイナーなプログラミング言語のLuaを使ったプログラムを指定して、以下のようなお題を試してみました。

【お題】
次のようなプログラムをLuaで作ってください。

財布の中に硬貨があります。
1640円を支払いたいのですが、最も少ない枚数で支払える組合せを求めたいです。
なお、財布の中には次の枚数の硬貨があるものとし、値をテーブルで指定してください。
・500円硬貨が5枚
・100円硬貨が20枚
・50円硬貨が8枚
・10円硬貨が30枚

すると、それぞれの生成AIが次のようなLuaのプログラムを生成しました。

この記事は
Members+会員の方のみ御覧いただけます

ログイン/無料会員登録

会員サービスの詳細はこちら