Ralph 루프: 자율 AI 에이전트를 밤새 운영하는 방법
중지 훅을 통해 종료 시도를 가로채고, 파일 시스템 메모리로 컨텍스트 윈도우 간 상태를 유지하며, 스폰 예산으로 무한 재귀를 방지하는 자율 에이전트 시스템을 구축했습니다. 이 시스템은 여러 야간 세션에 걸쳐 9개 PRD로 구성된 숙의(deliberation) 인프라(Python 3,455줄, 테스트 141개)를 출시했습니다.1
TL;DR
Ralph 아키텍처는 세 가지 문제를 동시에 해결하여 장기 실행 자율 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/ |
JSON 파일 14개 | 임계값, 예산, 규칙 인코딩 (하드코딩 아님) |
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"
}
상태가 손상되면 (개발 중 두 번 발생), 복구 패턴은 충돌 대신 안전한 기본값에서 재생성합니다:
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 작업에는 세 가지 요소가 포함됩니다: 목표, 완료 기준, 컨텍스트 포인터:
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 | bash 통합 테스트 48개 (7개 스위트) | 커밋 10df724 |
| PRD 7-8 | 훅 연결 + Python 단위 테스트 81개 | 커밋 fbf1a0d |
| PRD-9 | E2E 파이프라인 시뮬레이션 테스트 12개 | 커밋 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에 스폰 예산 모델을 추가했습니다. 에이전트는 깊이를 증가시키는 대신 부모로부터 예산을 상속받습니다. 예산이 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))을 사용하는 것이었습니다. MEMORY.md에 문서화된 이 bash 함정 지식은 이후 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 디버깅.
set -e에서의((VAR++))종료 코드 동작이 세션 간 학습으로 MEMORY.md에 문서화. ↩