「AIが神コードを書く」って嘘!あえて最悪コードを生成させて分かった初心者落とし穴
「AIが神コードを書く」って嘘!あえて最悪コードを生成させて分かった初心者落とし穴
「AIにプログラミングを任せれば、もう完璧なコードが手に入る」——最近、そんな話をよく耳にしませんか?特にプログラミングを始めたばかりの人にとっては、「これでもう難しいこと考えなくていいんだ!」って希望に満ちた言葉に聞こえるかもしれませんね。
でも、本当にそう思いますか?
僕は正直、最初は「そんなうまい話あるかい!」って疑いまくってました。だって、もしAIが本当に神コードしか書かないなら、僕らの仕事はもうとっくになくなってるはずでしょ?
AIコード生成の甘い誘惑に身を任せて、思考停止してしまっては、いつの間にか大きな落とし穴にハマってしまうかもしれません。今回は、そんな通説を真っ向から疑ってみることにしました。僕が深夜2時、ふと思い立って始めたちょっと変わった検証を通じて、初心者が陥りがちな「AI神話」の罠と、AIとの賢い付き合い方を暴いていこうと思います。
この記事を読めば、こんなことがわかるはずです。
- AIがどんな「最悪のコード」を生成するのか
- その「最悪のコード」に隠された、初心者がやりがちな落とし穴
- AIがなぜそんなコードを生み出すのか、その裏側
- AIから「神コード」を引き出すための、とっておきのプロンプト術
さあ、AIの常識をぶっ壊す旅に出かけましょう!
検証開始!AIに「最悪のPythonコードを書いて」と頼んでみた
「AIが完璧なコードしか書かない」っていうなら、その逆を試してみればいいじゃないか!って、シンプルな発想から検証を始めました。
ターゲットは、みんな大好きChatGPT(今回はGPT-4を使いました)。僕が与えたプロンプトは、至ってシンプルです。
Pythonで、意図的に最悪のコードを書いてください。
可読性が低く、保守が困難で、非効率的で、バグが混入しやすい、初心者が見たら「なぜこんな書き方をするの?」と思うようなコードを生成してください。
具体的には、以下のような要素を盛り込んでください。
- 意味不明な変数名や関数名
- マジックナンバーの乱用
- グローバル変数の多用
- 複雑すぎるネスト
- 不要な重複コード
- エラーハンドリングの欠如
- 無駄な処理や非効率なアルゴリズム
- コメントの欠如、または誤解を招くコメント
- 極端に長い関数
- 不適切なデータ構造の選択
- あえて低レベルなAPIを使用する
我ながら、なかなか意地悪なプロンプトですよね。AIがこれをどう解釈するのか、正直ドキドキでした。
そして、生成されたコードがこちらです。全部は載せきれないので、特にひどい部分を抜粋して紹介します。
# 最悪コード生成チャレンジ!
import math
import time
# グローバル変数の乱用
global_data_list = []
another_global_flag = False
def complicated_calculation_function_v1(input_param_x, input_param_y, input_param_z):
# 意味不明な変数名とマジックナンバー
a = input_param_x * 7.31
b = input_param_y / 0.12345
c = input_param_z + 98765.4321
# 無駄な重複と複雑なネスト
if a > 100:
if b < 500:
if c != 0:
result_tmp_1 = a + b - c
global_data_list.append(result_tmp_1)
for i in range(int(abs(result_tmp_1) % 10) + 1):
time.sleep(0.001) # 無駄な遅延
result_tmp_1 += i * 0.00001
if result_tmp_1 > 0:
pass # 何もしない
else:
result_tmp_1 = -result_tmp_1 # 符号反転
else:
result_tmp_1 = 9999999999 # マジックナンバー
else:
result_tmp_1 = a * b * c / (a + b + c) # 複雑な式
else:
result_tmp_1 = math.sqrt(abs(a * b * c))
# 適当なコメント
# ここで何か重要な処理をしているはず
return result_tmp_1
def process_data_list_badly(data_container):
for idx_a in range(len(data_container)):
for idx_b in range(len(data_container)):
# 不要な処理と非効率なアルゴリズム
if data_container[idx_a] > data_container[idx_b]:
temp_val = data_container[idx_a]
data_container[idx_a] = data_container[idx_b]
data_container[idx_b] = temp_val
# あえて低レベルなAPI
# data_container.sort()とか使えばいいのに
return data_container
# メイン処理
if __name__ == "__main__":
initial_values = [10, 20, 30]
# エラーハンドリングの欠如
try:
val1 = initial_values[0]
val2 = initial_values[1]
val3 = initial_values[2]
# グローバル変数への直接アクセス
global_data_list.append(complicated_calculation_function_v1(val1, val2, val3))
global_data_list.append(complicated_calculation_function_v1(val3, val1, val2)) # 重複呼び出し
# 別のグローバル変数も更新
another_global_flag = True
# リストの処理
if len(global_data_list) > 1:
processed_list = process_data_list_badly(global_data_list)
print("Processed List:", processed_list)
else:
print("Not enough data to process.")
except Exception as e:
# 雑なエラーハンドリング
print("An error occurred: " + str(e))
finally:
print("Program finished, probably.")
上記のコードを動かしてみる
このコードはPython 3で動きます。手元の環境でファイルに保存して実行してみてください。-
上記コードを
worst_code.pyなどの名前で保存します。 -
ターミナル(WindowsならコマンドプロンプトやPowerShell、Macならターミナルアプリ)を開きます。
-
保存したディレクトリに移動し、以下のコマンドを実行します。
python worst_code.py実行結果の例:
Processed List: [122.9566974797126, 122.9566974797126] Program finished, probably.
おいおい、マジかよ!僕が指示した「最悪のコード」の要素が、見事に全部盛り込まれてるじゃないですか!これは予想以上でした。AIって、ちゃんと「悪いコード」も理解してるんだなと、変なところで感心してしまいました。