Ralphループ:自律型AIエージェントを一晩中稼働させる方法
ストップフックによる終了試行のインターセプト、コンテキストウィンドウをまたぐ状態保持のためのファイルシステムメモリ、暴走的な再帰を防ぐスポーンバジェットを組み合わせた自律エージェントシステムを構築しました。このシステムは、複数のオーバーナイトセッションを通じて、9つのPRDからなる審議インフラ(Python 3,455行、テスト141件)をシップしました。1
TL;DR
Ralphアーキテクチャは、3つの問題を同時に解決することで、長時間稼働する自律型AI開発を実現します。コンテキストウィンドウの枯渇(イテレーションごとにフレッシュなコンテキストで解決)、状態の永続化(ファイルシステムをメモリとして活用して解決)、タスクの継続性(完了前にエージェントが終了するのを防ぐストップフックループで解決)です。このパターンをClaude Codeフックシステムに実装し、マルチエージェント審議インフラの構築に使用しました。システムは機能しますが、スポーンバジェット、基準の品質、ファイルシステム汚染について厳しい教訓を学びました。
コンテキストウィンドウの問題
すべてのAI会話はコンテキストウィンドウ内で動作します。これは、会話履歴、システムプロンプト、ツール出力、ワーキングメモリを保持する固定サイズのバッファです。Claudeのコンテキストウィンドウは約200,000トークンを保持できます。複雑な開発セッションでは、集中的な作業で30〜60分以内にこれを使い果たすことがあります。2
これは審議システムの構築中に直接計測しました。8つのPythonモジュールにまたがる正確なマルチファイル編集から始まったセッションが、90分を過ぎる頃には単一ファイルのトンネルビジョンに劣化しました。エージェントは以前読んだアーキテクチャを参照しなくなりました。そのコンテキストが圧縮されて失われていたためです。3
劣化は予測可能なカーブをたどります:
Iteration 1: [200K tokens] → writes code, creates files
Iteration 2: [200K tokens] → reads files from disk, continues
Iteration 3: [200K tokens] → reads updated files, continues
...
Iteration N: [200K tokens] → reads final state, verifies criteria
単一の長時間セッションと比較してみましょう:
Minute 0: [200K tokens available] → productive
Minute 30: [150K tokens available] → somewhat productive
Minute 60: [100K tokens available] → degraded
Minute 90: [50K tokens available] → significantly degraded
Minute 120: [compressed, lossy] → errors accumulate
イテレーションごとにフレッシュなコンテキストを使用するエージェントは、継続的なエージェントを上回ります。各イテレーションが、過去の推論の重みを引きずるのではなく、現在の状態に対して認知リソースをフルに割り当てるためです。
実装の詳細
ストップフック
再帰ガードシステムは、エージェントの停止試行をインターセプトし、完了基準をチェックします:
#!/bin/bash
# From recursion-guard.sh - simplified
CONFIG_FILE="${HOME}/.claude/configs/recursion-limits.json"
STATE_FILE="${HOME}/.claude/state/recursion-depth.json"
# Safe defaults with config override
MAX_DEPTH=2
MAX_CHILDREN=5
DELIB_SPAWN_BUDGET=2
DELIB_MAX_AGENTS=12
# Load config with validation
load_config() {
if [[ -f "$CONFIG_FILE" ]] && command -v jq &>/dev/null; then
config_depth=$(jq -r '.max_depth // 2' "$CONFIG_FILE")
if [[ "$config_depth" =~ ^[0-9]+$ ]] && [[ "$config_depth" -gt 0 ]]; then
MAX_DEPTH="$config_depth"
fi
fi
}
フックは成功条件を定義する基準ファイルを読み取ります。条件は機械的に検証可能でなければなりません:テストの合否、リンターの出力、HTTPステータスコード、ファイルの存在チェックなどです。4
永続メモリとしてのファイルシステム
重要な洞察:ファイルはコンテキストウィンドウをまたいで永続化されます。.claude/ディレクトリがエージェントの永続メモリとして機能します:
| ディレクトリ | 内容 | Ralphループでの役割 |
|---|---|---|
state/ |
recursion-depth.json、agent-lineage.json |
イテレーション回数、親子関係の追跡 |
configs/ |
14のJSONファイル | 閾値、バジェット、ルールのエンコード(ハードコードではない) |
handoffs/ |
49のコンテキストドキュメント | マルチセッションにわたるアーキテクチャ上の意思決定の保持 |
hooks/ |
95のライフサイクルハンドラー | イテレーション間の品質ゲートの強制 |
各新しいイテレーションはディスクから現在の状態を読み取り、前のイテレーションが中断したところから続行します。セッション開始フックがクリーンな状態を初期化します:
# From session-start.sh - recursion state initialization
RECURSION_STATE_FILE="$RECURSION_STATE_DIR/recursion-depth.json"
# Initialize with safe defaults
{
"depth": 0,
"agent_id": "root",
"parent_id": null,
"initialized_by": "session-start"
}
状態が破損した場合(開発中に2回発生しました)、リカバリパターンはクラッシュするのではなく、安全なデフォルト値から再作成します:
if ! jq -e '.depth' "$RECURSION_STATE_FILE" &>/dev/null; then
# Corrupted state file, recreate with safe defaults
echo "- Recursion state recovered (was corrupted)"
fi
タスク仕様のフォーマット
効果的なRalphタスクには、目的、完了基準、コンテキストポインタの3つの要素が含まれます:
OBJECTIVE: Implement multi-agent deliberation with consensus validation.
COMPLETION CRITERIA:
- All tests in tests/test_deliberation_lib.py pass (81 tests)
- post-deliberation.sh validates consensus above 70% threshold
- recursion-guard.sh enforces spawn budget (max 12 agents)
- deliberation-pride-check.sh passes 5 quality checks
- No Python type errors (mypy clean)
CONTEXT:
- Follow patterns in lib/deliberation/state_machine.py
- Consensus thresholds in configs/deliberation-config.json
- Spawn budget model: agents inherit budget, not increment depth
このパターンで構築したもの
審議インフラ(9つのPRD)
最大規模のRalphループプロジェクト:複数のセッションにわたって実装された9つのプロダクト要件定義書です。
| PRD | 成果物 | テスト |
|---|---|---|
| PRD 1-4 | フック、設定、再帰ガード拡張 | コミット 3cad08c |
| PRD-5 | 48のbash統合テスト(7スイート) | コミット 10df724 |
| PRD 7-8 | フック接続 + 81のPythonユニットテスト | コミット fbf1a0d |
| PRD-9 | 12のE2Eパイプラインシミュレーションテスト | コミット 32bd711 |
総出力: 8モジュールにわたるPython 3,455行、テスト141件、コミット4件。各セッションは前のセッションのファイルシステム状態を引き継いで開始しました。フレッシュなコンテキストにより、各PRDは以前のPRDの会話履歴を引きずることなく、エージェントのフルアテンションを得ることができました。5
ブログ品質システム(12モジュール)
ブログリンターは3モジュールのスクリプトとして始まり、反復的なRalphループを通じて12モジュールに成長しました。各イテレーションでモジュールを追加し、完全なテストスイートを実行し、リグレッションがゼロであることを確認しました。完了基準は次のように進化しました:
- イテレーション1: 「77件すべてのテストが合格」
- イテレーション5: 「77件すべてのテストが合格 AND 33件すべての投稿でリンターのエラーが0」
- イテレーション8: 「すべてのテストが合格 AND エラー0 AND 警告0 AND すべての投稿で深度スコア≥2」
失敗と教訓
失敗1:スポーンバジェットの大惨事
審議システム構築の初期段階で、スポーンバジェット制限なしでセッションを実行しました。エージェントは3つの探索サブエージェントを生成しました。各サブエージェントがさらに独自のサブエージェントを生成しました。数分以内に、再帰ガードフックが数十のスポーン試行をインターセプトしていました。手動で停止するまで、セッションは通常の10倍の速度でAPIトークンを消費しました。6
修正: recursion-limits.jsonにスポーンバジェットモデルを追加しました。エージェントは深度を増分するのではなく、親からバジェットを継承します。budget=12のルートエージェントは、すべての再帰レベルにわたって合計12エージェントまで生成できます。これは重要なアーキテクチャ上の洞察でした:バジェットの継承により、深いエージェントチェーンを許可しながらも指数関数的な増殖を防止できます。
失敗2:自明に合格する基準
初期のタスクでエージェントに「合格するテストを書け」と指示しました。エージェントは最小限のテストを書きました:assert True、assert 1 == 1。技術的には基準は満たされていました。出力は無価値でした。
修正: 基準は量と質の両方を指定する必要があります:
| 基準の品質 | 例 | 結果 |
|---|---|---|
| 曖昧 | 「テストが合格」 | エージェントが自明なテストを書く |
| 計測可能だが不完全 | 「テストが合格 AND カバレッジ >80%」 | エージェントが行をカバーするが意味のあるテストをしない |
| 包括的 | 「すべてのテストが合格 AND カバレッジ >80% AND 型エラーなし AND リンタークリーン AND 各テストクラスが個別のモジュールをテスト」 | プロダクション品質の出力 |
失敗3:ファイルシステム汚染
行き止まりのアプローチを探索したイテレーションがアーティファクトを残しました:部分的に実装された機能、非推奨のファイル、矛盾する設定などです。イテレーション5が、イテレーション4で放棄されたイテレーション3の半完成アプローチの上に構築してしまうことがありました。
修正: ストップフックの基準にクリーンアップステップを追加しました:「インポートまたはテストから参照されていないファイルが存在しないこと」。これにより、イテレーションが完了する前にエージェントが行き止まりの成果物をクリーンアップすることが強制されます。
失敗4:((VAR++)) インシデント
bash統合テスト中、再帰ガードフックが最初のイテレーションでサイレントにクラッシュしました。原因:((VAR++)) はVARが0の場合、終了コード1を返します(0++は0に評価され、bashはこれをfalseとして扱うためです)。set -eが有効な状態では、これがスクリプトを強制終了させました。
修正は ((VAR++)) の代わりに VAR=$((VAR + 1)) を使用することでした。このbashの落とし穴はMEMORY.mdに文書化されており、その後の6つのフックスクリプトで同じバグの発生を防いでいます。7
Ralphが有効な場面と有効でない場面
適している場面
- 明確な仕様があるグリーンフィールド実装(新しいAPI、新しいモジュール、新しいテストスイート)
- 自動検証が存在する場合(テスト、型チェッカー、リンター、コンパイル)
- 単一のタスクファイルで記述できるスコープが限定された作業
適していない場面
- 主観的な品質(「UIを見栄えよくして」)には機械的に検証可能な基準がない
- 方向性が中間的な発見に依存する探索的な作業
- 数十のファイルにまたがるグローバルなコード関係の理解を必要とする大規模リファクタリング
主要なポイント
自律エージェントシステムを構築する開発者へ: - 自律ループを開始する前に、機械的に検証可能な完了基準に投資してください。審議システムが成功したのは、各PRDにテスト可能な成功基準(合計141件のテスト)があったからです - 初日からスポーンバジェットを実装してください。バジェット継承モデル(深度の増分ではなく)は、深いチェーンを許可しながら指数関数的なエージェント生成を防止します - 完了基準にファイルシステムのクリーンアップを追加してください。放棄されたイテレーションからの行き止まりアーティファクトが後続のイテレーションを汚染します
自律型AI開発を評価するエンジニアリングチームへ: - Ralphアーキテクチャは、人間の実装時間を人間の仕様策定時間にトレードオフします。ROIは、ボトルネックが実装能力にあるのか仕様の明確さにあるのかによって決まります - 自律的な出力を、外部コントラクターからのコードと同じ厳密さで監査してください。141件のテストが存在するのは、完了基準を満たすことがプロダクション準備完了を保証するわけではないと学んだからです
参考文献
-
著者によるClaude Codeフックを使用したRalphループパターンの実装。審議インフラ:Python 3,455行、8モジュール、141テスト、4コミット(2025-2026年)。 ↩
-
Anthropic, “Claude Models,” 2025. ↩
-
Liu, Nelson F. et al., “Lost in the Middle: How Language Models Use Long Contexts,” TACL, 2024. ↩
-
Anthropic, “Claude Code Documentation,” 2025. フックライフサイクルイベント。 ↩
-
著者のgitログ。コミット
3cad08c、10df724、fbf1a0d、32bd711は審議インフラ構築全体にわたります。 ↩ -
バジェット制限なしのエージェント生成に関する著者の経験。
~/.claude/projects/*/memory/MEMORY.mdのエラーエントリに記録。 ↩ -
著者のbashデバッグ。
((VAR++))のset -eでの終了コード動作はMEMORY.mdにセッション横断的な学習として記録。 ↩