Yyatmita

Ralph Wiggum Loop でサイトを自動構築する

bash スクリプトと Claude Code で Next.js のサイト構造を自動構築した記録。build/test/lint が通るまでループする仕組み

サイトをつくってみた#ralph-loop#claude-code#automation#next-js
← 前の記事: Claude Code の開発環境をつくる:WSL から Docker へ

claude -p というコマンド

Claude Code には、ターミナルから対話的に使うモード以外に、パイプモードというものがある。claude -p と打つと、テキストを標準入力で渡して、Claude に作業させて、終了させることができる。

対話的に使うときは「これやって」「わかりました」「ここどうする?」「こうします」というやりとりが続く。パイプモードはそれをしない。テキストを渡したら Claude が作業して、黙って終わる。

これが何を意味するかというと、シェルスクリプトの中から AI を呼べるということだ。

echo "〇〇を実装してください" | claude -p --model sonnet

このコマンドを自動化の部品として使えば、人間がターミナルの前に座っていなくても、AI が作業する。

AI に「作って」と言ったら本当に作ってくれた

yatmita.com は Next.js + Tailwind CSS で作っている。最初の頃、私はサイトの設計をドキュメントにまとめて、Claude Code に渡した。

「このルーティング構造で、このコンポーネント構成で、こういうページを作ってほしい」

渡したら、本当に作った。ファイルが増え、コンポーネントができ、ルーティングが繋がっていった。AI に設計を渡すだけでサイトの骨格ができるというのは、最初に体験したとき少し信じられない感覚だった。

ただ、一発では完成しない。

build エラーが出た。型エラーも出た。テストが落ちた。そのたびに「ここがエラーになってます」と貼り付けて、Claude に直してもらう。直ったと思ったら別のエラーが出る。また貼り付ける。

これの繰り返しが、正直面倒だった。

while ループという発想

ある時点で気づいた。

「指示を渡す → AI が作る → チェックする → エラーがあれば戻す」——これを私は手で毎回やっている。でもよく考えたら、このフローは全部コマンドだ。claude -p で AI を呼べる。build も test も lint も、シェルコマンドで実行できる。

じゃあ、これ while ループで回せるじゃないか。

構造はシンプルだった。

繰り返す(エラーがなくなるまで):
    prompt.md の内容を claude -p に渡す
    build を実行する
    test を実行する
    lint を実行する
    全部通ったら終了
    どれかが失敗したら → エラー内容をプロンプトに追加して次の繰り返しへ

これだけだ。本当にこれだけで、AI が自分の出力を自分で修正するループが回る。

このパターンには「Ralph Wiggum Loop」という名前がある。シンプソンズに出てくるラルフ・ウィッガムというキャラクターが由来で、深く考えずひたすら繰り返す——そういうイメージからきている。

bash スクリプトの実装

ralph_wiggum_loop.sh というスクリプトがこのループを担っている。

使い方は簡単だ。prompt.md にやってほしいことを書いて、スクリプトを実行する。

スクリプトが claude -p を呼んで Claude が作業する。終わったら、npm run build で型チェックとビルドを確認し、npm test でテスト、npm run lint でコードの静的解析を走らせる。

3つとも通れば完了。ループを抜けてスクリプトが終わる。

どれかが失敗した場合——ここが肝だ。エラー出力をそのままテキストファイルに保存しておいて、次の繰り返しのとき、プロンプトの末尾にそれを追加する。

【前回のエラー】
Build Failed:
  Type error: Property 'xxx' does not exist on type 'yyy'
   → /src/components/Foo.tsx の35行目

このエラー文をそのまま Claude に渡す。Claude は自分が出したエラーを読んで、自分で直す。

また同じエラーが出たら、また追加される。直るまで繰り返す。progress.md にイテレーションごとの記録が残るので、後から何が起きたかを追える。

最初にこのループを回したとき、少し笑った。AI が自分で直して、また自分でチェックして、また直して——誰も見ていない深夜に、ターミナルの中でそれが黙々と動いていた。

Phase 1〜8:サイトが育っていく

prompt.md の中身を差し替えることで、フェーズごとに別のタスクを渡せる。

Phase 1 でプロジェクトの骨格を作る。Phase 2 でルーティング構造を整える。Phase 3 でコンテンツの読み込みロジックを実装する——という順で積み上げていった。

フェーズを細かく分けるのが重要だった。「全部まとめて作って」と渡すと、タスクが大きすぎてエラーが複雑に絡まる。小さく分けて、それぞれがクリーンに通るまで繰り返す。

「build が通る」「test が通る」「lint が通る」——この3つの基準が明確だから、AI もゴールがわかる。あいまいな指示ではなく、合否が数値で出る採点基準がある。これが、ループが機能する理由だと思う。

Phase 8 まで回し終えた時点で、Next.js のルーティング、コンテンツ読み込み、型定義、テスト——サイトの構造がほぼ揃っていた。

見えてきた限界

このループ、コードの構造を作るのには完璧にフィットした。

build が通るかどうかは機械的に判定できる。型エラー、テストの失敗、lint 違反——どれも「合否」が明確だ。だからループが機能する。

でも、サイトはコードだけじゃない。

Phase 8 が終わった時点で、ページはあるけどコンテンツがなかった。記事を書いて、食材の説明を書いて、レシピを書いて——これはどうやって量産するのか。

「コンテンツの品質が高いかどうか」は、build コマンドで採点できない。

次に考えなければならないのは、そこだった。


手動でやっていた「AI に渡す → チェックする → エラーを戻す」を、スクリプトにしただけだ。発想は単純だ。でも回してみると、確かにサイトの骨格ができあがっていく。手が動いていないのに、進んでいる——その感覚は、なんとも言えなかった。