GoogleのAlphaEvolve(アルファエボルブ)とSakanaAIのDarwin Gödel Machine(ダーウィン・ゲーデルマシン)を参考に簡略化した自己改善型AIシステムで遊んだ話

「進化的アルゴリズムAI」や「自己改善型AI」とは

近年、AI研究の世界でじわじわと注目を集めているキーワードがある。それが「進化的アルゴリズムAI」や「自己改善型AI」だ。

要するに、AIが自分自身のコードや構造を見直して、より賢くなる方法を自分で考え、試し、改善していくというコンセプトである。

これが実現すれば、AIは単なるツールから、ある種の“学び続ける存在”へと進化する可能性を秘めている。

この分野で特に話題になった2つの事例がある。ひとつは、Google DeepMindが開発したAlphaEvolve(アルファエボルブ)。

そしてもうひとつが、Sakana AIによるDarwin Gödel Machine(DGM)だ。

進化的アルゴリズムAIとは

進化的アルゴリズムAIとは、生物の進化の仕組みを応用した人工知能だ。

複数のAI(個体)を用意し、性能の良いものを選んで子を作り、少しずつ変化させながら世代交代を繰り返す。

これにより、最適な解や動作を自動的に進化させていく。
ゲームやロボット制御、デザイン生成など幅広く使われている。

AlphaEvolveは、AI自身が自分のニューラルネットワーク構造を進化させるシステムだ。

従来のモデル構築は人間が試行錯誤する必要があったが、AlphaEvolveは複数のモデル構造を遺伝的に生成し、その中で最も優れたものを選抜・交配していくという、いわば“AIの自然選択”のような仕組みを持っている。

自己改善型AIとは何か?

一方、DGMは少し違う。こちらはAIが自分のPythonコードそのものを読み取り、改善案を考え、自ら書き換えていくという、まるでAIがプログラマーのように振る舞うスタイルをとっている。

LLM(大規模言語モデル)を使って改善案を生成し、それを実行して効果があるかをベンチマークで評価。

効果があれば採用、なければ元に戻す。まさに“自己改善ループ”が構築されているのだ。

自分で作ってみた「ミニDGM」

そんな高度な仕組みを見ていると、「自分でもちょっと遊んでみたい」と思った。

そこで今回は、Sakana AIのDGMのアイデアを参考にしつつ、Google Colab上で動く簡易版の自己改善型AIシステムを作ってみた。

テーマはシンプル。

「数字のリストをソートするプログラムを、GPT-4に自動的に改善させる」というものだ。

初期コードと改善戦略

最初に与えるコードは、あえて非効率な「バブルソート」だった。

しかも time.sleep(0.001) をループ内に入れて、わざと遅くしてある。

def sort_numbers(numbers):
    for i in range(len(numbers)):
        for j in range(len(numbers) - i - 1):
            if numbers[j] > numbers[j+1]:
                numbers[j], numbers[j+1] = numbers[j+1], numbers[j]
            time.sleep(0.001)
    return numbers

これを GPT-4 に渡し、「もっと速くなるように改善して」と頼む。

改善案はColab内で保存し、実際に実行してスピードと正確性でスコアを出す。

改善後のスコアが高ければ採用、そうでなければ前のコードに戻す――という流れだ。

以下Pythonコードです。
ご自由に使ってください。

import os
import importlib.util
import shutil
import yaml
from openai import OpenAI

client = OpenAI()  # APIキーは環境変数 OPENAI_API_KEY から取得

# 評価関数読み込み
def load_benchmark(entry_path, eval_fn_name):
    spec = importlib.util.spec_from_file_location("benchmark", entry_path)
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return getattr(mod, eval_fn_name)

# 改善案をGPTから取得(プロンプト強化+バグ回避)
def generate_candidate_code(code, score):
    prompt = f"""You are an AI agent improving the following Python code to increase its performance.
The current code scores {score} points. Suggest a better version of the code.

# CODE START
{code}
# CODE END

Return only the improved code. Do not include explanations or comments. 
Ensure the code is syntactically correct and fully executable.
"""
    response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7
    )
    return response.choices[0].message.content

# メインループ
def main():
    config = yaml.safe_load(open("configs/sort_experiment.yaml"))
    agent_path = config["agent"]["path"]
    benchmark = config["benchmark"]
    evaluator = load_benchmark(benchmark["entry_point"], benchmark["evaluation_function"])

    os.makedirs("output", exist_ok=True)
    shutil.copy(agent_path, "output/agent_0.py")
    current_score = evaluator("output/agent_0.py")
    print(f"[Turn 0] Score = {current_score}")

    for turn in range(1, config["runtime"]["max_turns"] + 1):
        prev_path = f"output/agent_{turn - 1}.py"
        new_path = f"output/agent_{turn}.py"
        log_path = f"output/log_turn_{turn}.txt"

        old_code = open(prev_path).read()
        new_code = generate_candidate_code(old_code, current_score)

        # 保存:改善コードログ
        with open(log_path, "w") as logf:
            logf.write(new_code)

        # 保存:実行用エージェントコード
        with open(new_path, "w") as f:
            f.write(new_code)

        try:
            new_score = evaluator(new_path)
        except Exception as e:
            print(f"[Turn {turn}] ❌ Evaluation error: {e}")
            new_score = 0

        print(f"[Turn {turn}] Score = {new_score}")

        if new_score > current_score:
            print("✅ Improvement accepted.")
            current_score = new_score
        else:
            print("❌ No improvement. Reverting.")
            shutil.copy(prev_path, new_path)
            current_score = evaluator(prev_path)

if __name__ == "__main__":
    main()



GPT-4は何をしたか?

1ターン目でGPT-4は見事に改善に成功した。

バブルソートを numbers.sort() に置き換え、処理時間が大幅に短縮。

ベンチマークスコアは一気に50点から100点に上昇し、コードは無事採用された。


def sort_numbers(numbers):
    numbers.sort()
    return numbers

だが、その後のターンでは改善の余地がないと判断され、スコアは100点のまま変化せず、コードも元に戻された。

興味深かったのは、GPT-4が「関数の重複定義」や「構造を簡素化しすぎる」など、改善案として微妙な方向に進んだケースがあったことだ。

たとえば、main()の中に sort() を直接書いてしまう案などもあり、構文的には正しくても設計上の意図から外れていたりする。

改善の工夫と学び

今回の実験では以下のような工夫が効果的だった。

意図的にコードを非効率にして、改善余地を作る。

スコアの評価関数を調整して、“改善したと判断できる余地”を作る。

GPTの出力をログに保存し、問題が起きたときに原因をすぐ特定できるようにする。

プロンプトを工夫して「重複コードを出さない」「説明文を返さない」よう指示する。

わずか数十行のコードでも、自己改善の流れを構築することで、AIが「考え、試し、評価し、直す」というプロセスを擬似的に再現できたのはかなり面白い体験だった。

今後に向けて

今回の実験は、言ってしまえば超簡略版の自己改善型AIだが、それでも「AIが自分で進化することを考える」というサイクルが働いていることにワクワクを感じた。

AlphaEvolveやDGMのような本格的な自己進化・自己改善型AIシステムは、まだまだ研究の序章だ。

しかし、こうしてそのエッセンスを切り取って再現してみることで、自分なりにその仕組みを体験できるというのは、大きな学びと楽しさがある。

次は、もっと複雑なタスクに自己改善型AIを応用してみたいと思っている。

「AIが自身を育てる」
そんな未来が、もうすぐそこまで来ていると感じた実験だった。


ただ注意しなければならないのは、人間による要チェックを怠ってはいけないということだ。

これはsakanaAIさんのブログ記事を見てもわかるように、AIが自分勝手に都合のいいように改造していく例があったようだ。

ここの所は十分にチェック機構を持たないといけないだろう。

****************

最近のデジタルアート作品を掲載!

X 旧ツイッターもやってます。
https://x.com/ison1232

インスタグラムはこちら
https://www.instagram.com/nanahati555/

****************

Follow me!

PAGE TOP