Ralph Loop

2026年9月6日

🐧 要するにどういう話か

「Ralph」は、The Simpsons のキャラクター「Ralph Wiggum」に由来する。Ralph Wiggumは賢くはないが、無邪気で、やるときはやるという感じのキャラクターらしい(知らんけど)。LLMを賢いと思わずに(Ralphだと思って)うまく導いてやると成果を出せるよ、ということらしい。

Ralph Loopとは

Ralph Loopは、LLMにプロンプトを繰り返し与えてソフトウェアを構築する技術である。最も純粋な形は、Bashのループである。

while :; do cat PROMPT.md | claude-code ; done

LLMにゴールを与え、LLMがそれを達成しようとし、ループが再開され、LLMが前回までを踏まえて続ける。内側のループに人間はいない。

重要な洞察は次の通りである。

この技術は、非決定論的な世界の中で決定論的に壊れる。

つまり、個別のループ反復は非決定論的だが、壊れるパターンは予測可能である。壊れ方を観察し、その失敗モードに対するプロンプトを書き、ループが改善する。ギターをチューニングするようなものである。楽器を書き換えるのではなく。

Ralph LoopはGreenfield(ゼロから作る)プロジェクト向けの手法である。作者自身こう言っている: 「既存のコードベースにRalphを使うつもりは毛頭ない」。期待値はおよそ90%まで到達することである。

登場背景

Ralphの作者であるGeoffrey Huntley氏は、3年前と比べてソフトウェアの開発アプローチが根本的に変わったと述べている。標準的なソフトウェア開発は、レンガを1枚ずつ積み上げるように垂直に構築することである(ジェンガのようなもの)。しかし、彼はもはやすべてをループとして捉えている。

Ralphは、前進モード(自律的に構築する)や逆モード(クリーンルーム)だけでなく、これらのコンピュータがプログラミングできるというマインドセットでもある。

この変化は、既存のワークフローをAIで加速することではない。作業の単位が変わったのである。コードを1行ずつ書く代わりに、ループ自体をプログラムする——コンテキストの割り当て、ゴール、反復、である。

Ralphの最初の投稿当時、多くの人がマルチエージェント、エージェント間通信、マルチプレクシングに取り組もうとしていた。彼の主張は、それは不要だということである。マイクロサービスとその複雑さを考えろ。さらに、そのマイクロサービス(エージェント)自体が非決定論的だとどうなるか。マイクロサービスの反対はモノリシックなアプリケーションである。単一プロセスが垂直にスケールする。Ralphはモノリシックである。単一リポジトリで、単一プロセスとして、1ループに1タスクを実行する。

より広い文脈として、作者は従来のソフトウェア開発は終わったと主張している。ソフトウェアはハンバーガー店員の時給より安く開発でき、AFK(Away From Keyboard、席を外している)間に自律的に構築できる。これは誇張ではない。Ralphループだけで、LLMの学習データに存在しない全く新しいプログラミング言語(CURSED)を構築して実証している。

最小構成

必要なものは次の3つだけである。

  • 指示を含む PROMPT.md ファイル
  • ツールコール回数に上限がないLLM CLIツール(例: claude-code)
  • while ループ

これがシステムのすべてである。フレームワーク不要、オーケストレーション層不要、マルチエージェント基盤不要。パワーは反復とプロンプトから生まれる。複雑さからではない。

実践: 実行の流れ

実際にプロジェクトを動かす場合の全体像は以下の通りである。

ファイル構成

project/
├── loop.sh                    # ループスクリプト
├── PROMPT_plan.md             # 計画モード用プロンプト
├── PROMPT_build.md            # 構築モード用プロンプト
├── AGENTS.md                  # 実行方法のガイド(毎回コンテキストに読まれる)
├── IMPLEMENTATION_PLAN.md     # 優先順位付きタスクリスト(Ralphが生成・更新)
├── specs/                     # 仕様(1トピック1ファイル)
│   ├── feature-a.md
│   └── feature-b.md
└── src/                       # ソースコード

手順

  1. 要件定義(人間 + LLM対話): プロジェクトのアイデアをLLMと対話して整理し、各トピックを1ファイルずつ specs/ に書き出す。この段階でコードは書かない。
  2. 計画モードを実行: PROMPT_plan.md をループに与えて実行する。Ralphが specs/ と既存コードを比較し、優先順位付きの IMPLEMENTATION_PLAN.md を生成する。このモードでは実装しない。
  3. 構築モードを実行: PROMPT_build.md をループに与えて実行する。Ralphがタスクリストから最も重要な項目を選び、実装し、テストし、コミットする。これをループする。
  4. 観察してチューニング: ループの出力を観察し、失敗パターンがあればプロンプトに「看板」を追加する。
  5. 必要に応じてプランを再生成: タスクリストが陳腐化したら手順2に戻る。

3フェーズの構造

  • フェーズ1: 要件定義 — 人間が主体。LLMとの対話で仕様を形成する。
  • フェーズ2: 計画 — Ralphが主体。仕様とコードの差分を分析し、タスクリストを生成する。通常1〜2回で完了する。
  • フェーズ3: 構築 — Ralphが主体。タスクリストから1つずつ実装する。ここが本体である。

各フェーズで使うプロンプトが違うが、実行機構(ループ)は同じである。

ループの運用

ループは自動で回り続ける。PROMPT.md の内容をLLMに与え、LLMが完了したら次の反復が始まる。これを繰り返す。

運用の流れ:

  1. ループを開始する
  2. 数回〜十数回分を観察する
  3. Ctrl+C で停止する
  4. 失敗パターンを確認し、プロンプトに「看板」を追加する
  5. ループを再開する

モードの切り替え(計画 → 構築)も同じく、止めてからプロンプトファイルを差し替えて再開する。

作者の言葉: 「ループを観察することが重要である。そこがあなたの成長と学習の源になる。失敗ドメインを見たら、エンジニアの帽子をかぶり、それが再び起こらないよう問題を解決せよ。」

コア原則

1ループ1タスク

これが最も重要なルールである。各ループ反復でLLMはちょうど1つのことだけを行う。プロンプトには「最も重要なものを選べ」と指示する。何を最も重要と考えるかはLLMが決める。

極端に聞こえるかもしれないが、これは制約から来る。使えるコンテキストウィンドウは約170kである。1つのループでやろうとする量が多いほどコンテキストを消費し、結果が悪くなる。

マルチエージェントではなくモノリシック

Ralphは単一リポジトリ内で単一プロセスとして動作する。エージェント間通信、マルチプレクシング、マイクロサービス風の分解は不要である。LLMの非決定論性を考えると、この段階でのマルチエージェント調整は最悪のカオスである。

LLMに優先順位を委ねる

Ralphが最も重要な実装対象を決定するのを信頼する必要がある。LLMは次のステップを推論することに驚くほど特化している。これは完全なハンズオフのバイブコーディングであり、あなたが「責任あるエンジニアリング」と考える境界を試す。

プロンプトとチューニング

完璧なプロンプトは存在しない

作者は明確に述べている。「プログラミングコミュニティには完璧なプロンプトへの執着がある。そのようなものは存在しない。」

CURSEDのプロンプトは、LLMの行動を観察しながら継続的にチューニングされた結果である。ループが動いている間にストリームを見て、悪い行動のパターンを探す——それがチューニングの機会である。

チューニングのプロセス: 遊具の比喩

Ralphは遊具を作るのがとても上手い。しかし滑り台から転んで痣を作って帰ってくるので、滑り台の横に「滑り台は滑るもの。飛び降りるな。周りをみよう。」という看板を立ててRalphをチューニングする。そうするとRalphは看板を見て気づく可能性が高まる。

各失敗モードが新しい指示(「看板」)になる。最終的にRalphが考えるのはすべて看板であり、もはや欠陥を感じさせない新しいRalphになる。

ループの外に居る

Ralphの効果を最大限に引き出すためには、人間の役割が「ループの中で作業する」から「ループの上から観察する」に変化する。

  • 観察する: 特に初期は座って見る。どのようなパターンが現れるか、どこで間違えるか、どんな「看板」が必要か。
  • 反応して調整する: あれこれ先回りして指示するのではなく、Ralphが特定の失敗をしたらその場で「看板」を追加する。
  • 「看板」はプロンプトだけではない: プロンプトのガードレール、AGENTS.md の運営メモ、コードベース内のユーティリティパターン——Ralphが発見できるものなら何でも「看板」になり得る。

観察すべき一般的な失敗モード

  • プレースホルダー実装: LLMはコンパイルは通るが実際には機能しない最小実装を好む傾向がある。
    • 対策: プロンプトで明示的に禁止する。
  • 未実装の誤判定: LLMが ripgrep を実行し、非決定論的な結果を得て、(たまたま見つけられず)実装されていないと結論する。
    • 対策: 推測する前にきちんと検索するよう指示する。
  • 方向性の誤り: LLMが間違った方向に進む。
    • 対策: プロンプトではなく仕様の修正を考える。

コンテキストウィンドウ管理

制約

使えるコンテキストウィンドウは約170kである。すべてのツールコール、評価、結果がこれに加算される。使用量が多いほど結果が悪くなる。

サブエージェントによるコンテキスト拡張

解法は、プライマリコンテキストに割り当てないことである。代わりに、高コストな作業にはサブエージェントを生成する。プライマリコンテキストはスケジューラとして機能し、以下をサブエージェントに委譲する。

  • コードベースの検索
  • ファイルの書き込み
  • テストの成否の要約
  • 仕様の研究

並列度の制御

サブエージェントの並列度は制御できる。検索やファイル書き込みには多数を並列に使えるが、ビルド/テストのような高コストな検証作業には1つのサブエージェントに限定する。同時に大量のビルド/テストを走らせるとリソース競合で結果が信頼できなくなるためである。

「すべての操作に並列サブエージェントを使えるが、ビルド/テストにはサブエージェント1つのみ。」

コード検索の非決定論

コーディングエージェントは ripgrep を通じて動作するが、コードベース検索は非決定論的になり得る。よくある失敗は、LLMが ripgrep を実行して結果を得たが、実装が存在するのに見つからず「未実装」と結論してしまうことである。対策は、並列サブエージェントで複数角度から検索させ、明示的に「未実装と推測するな」と指示することである。

「変更を加える前に、並列サブエージェントを使ってコードベースを検索せよ(実装されていないと推測するな)。よく考えろ。」

生成と検証

Phase 1: 生成

コード生成は安くなった。何が生されるかは2つのメカニズムで制御する。

  • 仕様(specs/): プロジェクトの初期段階でLLMと長く対話し、要件を詳しく理解させた上で、各仕様を1ファイルとして specs/ フォルダにそれぞれ書き出させる。
  • 標準ライブラリ / 技術パターン: LLMが間違ったパターンを生成するなら、標準ライブラリを更新して正しいパターンに誘導する。

LLMが完全に間違ったものを作っている場合、仕様自体が誤っている可能性が高い。作者は、lexerの仕様が1つのキーワードを2つの相反するシナリオに対して重複定義しており、多くの時間を無駄にしたと述べている。

Phase 2: バックプレッシャー

生成は簡単である。正しさを保証することが難しい。無効な出力を却下するメカニズム、すなわちバックプレッシャーが必要である。

バックプレッシャーの選択肢:

  • 型システム(言語に組み込み)
  • テストスイート
  • 静的アナライザ / 型チェッカー
  • セキュリティスキャナ
  • 無効なコードを却下できるものなら何でも

重要な制約: ホイールは速く回らなければならない。反復速度が命である。Rustは優れた型システムを持つがコンパイルが遅い。動的型付け言語は速いが、静的アナライザを組み込む必要がある(例: ErlangならDialyzer、Pythonならpyrefly)。

テストの重要性を記録する

各ループは新しいコンテキストウィンドウから始まるため、LLMはテストがなぜ存在するかを覚えていない。その場でテストの重要性を文書化するよう指示する必要がある。

「ドキュメントを作成する際、テストとその背後の実装がなぜ重要かを記述せよ。」

これは未来のLLM反復に向けたメモを残すようなものである。LLMがテストを削除する、変更する、あるいは失敗を解決するかを決める際に影響する。

プレースホルダー禁止

LLMにはコンパイラを満足させるだけの最小実装へ向かう内在的なバイアスがある。これを明示的に打ち破る必要がある。

「プレースホルまたは単純な実装をしてはならない。完全な実装が欲しい。」

初期のループでこれが無視されても動揺するな。モデルは報酬関数(コンパイル成功)を追うように訓練されている。より多くのループを実行してプレースホルダーを特定・置換する。

TODOリスト

TODOリスト(実践では fix_plan.md)はRalph Loopの骨格である。計画と構築を分離する。

計画モード

専用Ralphループがコードベースと仕様を研究し、未実装項目の優先順位付きリストを生成または更新する。

  • specs/* を研究して要件を理解する
  • 既存ソースコードを仕様と照合する
  • TODO、最小実装、プレースホルダーを探す
  • 優先順位付きの箇条書きリストを作成する

構築モード

別のRalphループがTODOリストを読み、最も重要な項目を選び、実装する。実装後、TODOリストを更新する。

TODOリストの再生成

TODOリストは聖なるものではない。作者はCURSEDの構築中に複数回削除した。これは異常ではなく通常運転である。

再生成のタイミングの目安:

  • Ralphが軌道から外れている(間違ったものを実装している、同じ作業を繰り返している)
  • リストが現状と合っていない(陳腐化している)
  • 完了項目の残骸が多すぎてノイズになっている
  • 仕様に大きな変更を加えた
  • 何が実際に完了しているか自分でも把握できなくなった

再生成のコストは計画モードを1回回すだけである。Ralphが同じところで回り続けるコストよりもはるかに安い。

自己改善

Ralphは自身の動作環境を改善できる。

  • AGENT.md: ループの心臓部。プロジェクトのコンパイルと実行方法を文書化する。新しいことを学習したら(例: 正しいビルドコマンド)更新するよう指示する。
  • fix_plan.md: 現在のタスクと無関係でも、発見したバグを文書化するよう指示する。
  • ループバック: Ralphが自身の出力を評価できる機会を常に探す。コンパイラなら、コンパイルしてLLVM IRを調べる。一般的には、デバッグ用のログ追加。

原則: 「RalphがLLMに戻って自己評価できる形でプログラムする。」

運用上の注意点

壊れたコードベースに気づく

これは避けられない。ある時点でコードベースはコンパイルできなくなり、Ralph自身が直せない。選択肢は2つある。

  • git reset --hard で戻してループを再開する
  • レスキュープロンプトを仕込んでRalphを導く

これは判断の問題である。作者は両方実践してきた。

最終整合性を信じる

Ralphで構築するには信念が必要である。個別のステップが間違えていても、系全体が収束すると信じる。ギターのチューニングに似ている——1回の調整で音取りが完璧になるわけではないが、毎回近づいていく。

出力の3つの状態

「Ralphには3つの状態がある。生(未熟)、焼き上がり、焼き上がり+不明確な潜在挙動(時々これはかなり良い!)」

保守性

「保守性という論を聞くと、『誰にとって?』と問う。人間にとってか? なぜ人間が保守性の基準なのか? もはやループを回して必要に応じて解決・適応できるポストAI時代にいるのでは?」

エンジニアは依然として必要

「シニアの専門知識によってRalphを導かずにこれが可能だというわけがない。エンジニアが不要でツールが100%やると言う者は嘘つきである。」

スキルは移った。コードを書くことではなく、ループをプログラムすること——コンテキストエンジニアリング、仕様作成、チューニング。

Ralph Loopの向かう先

Ralph Loopは単なる技術ではなく、マインドセットである。作者の進化:

  • 現在: ループをプログラムし、職務機能自体を自動化し、実装のために人間を雇う必要をなくす。
  • 次(Loom): 進化的ソフトウェア——自律的なループが製品を進化させ、自動的に最適化する。「ソフトウェアファクトリ」。
  • 未解決の問い: 「もしモデルがさらに良くなることが止まらなければ?」

作者の提唱: 自分自身のコーディングエージェントを作れ(LLMトークンをループに投げる300行のコード)。それによって新しいコンピュータをプログラムする方法を学べ。LLMは新しい形態のプログラマブルコンピュータである。

📚 参考文献