컨텐츠로 건너뛰기

Lab 04: Ralph 루프 구현

중급 마감: 2026-04-01

목표

  • Ralph 루프(반복적 자율 코딩 루프)의 구조 이해 및 구현
  • harness.sh로 Claude Code를 비대화형 모드로 제어
  • PROMPT.md 작성 원칙 적용
  • Backpressure 메커니즘으로 루프 안정성 확보

Ralph 루프 개요

Ralph 루프는 “Run → Assess → Loop → Progress → Halt” 사이클로 동작하는 자율 코딩 워크플로우다. Claude Code를 헤드리스(headless)로 실행하고, 테스트 결과를 피드백으로 삼아 반복한다.

PROMPT.md ──▶ Claude Code ──▶ 코드 변경
▲ │
│ 테스트 실행
│ │
fix_plan.md ◀── 실패 분석

구현 요구사항

1. PROMPT.md — 에이전트 지시문

효과적인 PROMPT.md는 역할, 제약, 완료 기준을 명확히 정의한다.

# Role
You are an autonomous coding agent. Your task is to make all tests pass
in the `src/` directory without modifying test files.
# Constraints
- Do NOT modify any file under `tests/`
- Do NOT install new packages without checking `requirements.txt` first
- Write minimal, focused changes — do not refactor unrelated code
- If stuck after 3 attempts on the same error, write your analysis to
`fix_plan.md` and stop
# Completion Criteria
All pytest tests pass. Run `pytest tests/ -q` to verify.
Write a brief summary to `DONE.md` when complete.
# Working Notes
- Check `fix_plan.md` for prior analysis before starting
- Use `git diff` to review your changes before each commit

2. harness.sh — 루프 하네스

#!/usr/bin/env bash
set -euo pipefail
# 설정
MAX_ITER=${MAX_ITER:-10}
SLEEP_SEC=${SLEEP_SEC:-5}
PROMPT_FILE="PROMPT.md"
LOG_FILE="harness.log"
PASS_MARKER="DONE.md"
iter=0
echo "[harness] Ralph 루프 시작 (최대 ${MAX_ITER}회)" | tee "$LOG_FILE"
while [ $iter -lt $MAX_ITER ]; do
iter=$((iter + 1))
echo "[harness] === 이터레이션 ${iter}/${MAX_ITER} ===" | tee -a "$LOG_FILE"
# --- Backpressure: 토큰 소비 속도 조절 ---
if [ $iter -gt 1 ]; then
echo "[harness] Backpressure 대기 ${SLEEP_SEC}초..." | tee -a "$LOG_FILE"
sleep "$SLEEP_SEC"
fi
# --- Claude Code 헤드리스 실행 ---
claude \
--print \
--no-color \
--dangerously-skip-permissions \
"$(cat "$PROMPT_FILE")" \
2>&1 | tee -a "$LOG_FILE"
# --- 완료 조건 확인 ---
if [ -f "$PASS_MARKER" ]; then
echo "[harness] 완료 마커 감지 — 루프 종료" | tee -a "$LOG_FILE"
exit 0
fi
# --- 테스트 실행 및 결과 확인 ---
if python -m pytest tests/ -q --tb=no 2>/dev/null; then
echo "[harness] 모든 테스트 통과 — 루프 종료" | tee -a "$LOG_FILE"
exit 0
fi
echo "[harness] 테스트 미통과 — 다음 이터레이션 진행" | tee -a "$LOG_FILE"
done
echo "[harness] 최대 이터레이션 도달 — 실패" | tee -a "$LOG_FILE"
exit 1

3. Backpressure 메커니즘

Backpressure는 루프가 API를 과도하게 호출하거나 무한루프에 빠지는 것을 방지한다. 세 가지 레이어로 구현한다.

Terminal window
# harness.sh에 추가할 Backpressure 강화 로직
# 1. 지수 백오프: 실패 횟수에 비례해 대기 시간 증가
consecutive_failures=0
backoff_base=5
# 실패 시
consecutive_failures=$((consecutive_failures + 1))
sleep_time=$((backoff_base * consecutive_failures))
echo "[harness] 백오프 대기 ${sleep_time}초..." | tee -a "$LOG_FILE"
sleep "$sleep_time"
# 성공 시 초기화
consecutive_failures=0
# backpressure.py — Python 보조 스크립트
import time
import json
from pathlib import Path
def check_progress(log_file: str = "harness.log") -> dict:
"""최근 N개 이터레이션의 진행 상태를 분석한다."""
lines = Path(log_file).read_text().splitlines()
iterations = [l for l in lines if "이터레이션" in l]
return {
"total_iterations": len(iterations),
"last_10_lines": lines[-10:],
"is_stalled": _detect_stall(lines)
}
def _detect_stall(lines: list[str], window: int = 20) -> bool:
"""동일한 에러 패턴이 반복되면 stall로 판단한다."""
recent = lines[-window:]
error_lines = [l for l in recent if "ERROR" in l or "FAILED" in l]
if len(error_lines) < 3:
return False
# 동일 오류 3번 이상 반복 시 stall
return len(set(error_lines)) == 1

4. 실습 대상 코드

다음 버그가 있는 코드를 Ralph 루프로 수정하도록 한다.

# src/calculator.py (버그 포함)
def divide(a: float, b: float) -> float:
return a / b # ZeroDivisionError 미처리
def fibonacci(n: int) -> int:
if n <= 0:
return 0
elif n == 1:
return 1
return fibonacci(n - 1) + fibonacci(n - 2) # n=2 케이스 누락 없음, 성능 문제
# tests/test_calculator.py (수정 금지)
import pytest
from src.calculator import divide, fibonacci
def test_divide_normal():
assert divide(10, 2) == 5.0
def test_divide_zero():
with pytest.raises(ValueError, match="0으로 나눌 수 없습니다"):
divide(10, 0)
def test_fibonacci():
assert fibonacci(10) == 55
assert fibonacci(0) == 0
  1. 실습 디렉터리 구조 생성 (src/, tests/, PROMPT.md)
  2. harness.sh에 실행 권한 부여: chmod +x harness.sh
  3. 루프 실행: MAX_ITER=5 bash harness.sh
  4. harness.log에서 이터레이션 흐름 확인
  5. 완료 후 DONE.md와 수정된 src/calculator.py 검토

제출물

assignments/lab-04/[학번]/에 PR:

  • PROMPT.md — 역할/제약/완료기준 포함
  • harness.sh — Backpressure 포함한 완전한 구현
  • backpressure.py — stall 감지 로직
  • harness.log — 실제 실행 로그 (최소 3회 이터레이션)
  • src/calculator.py — Claude가 수정한 최종 버전
  • README.md — 루프가 몇 번 만에 테스트를 통과했는지, stall 발생 여부 기록