Lab 04: Ralph 루프 구현
중급
마감: 2026-03-31
1.
섹션 제목: “1. PROMPT.md — 에이전트 지시문”
2.
섹션 제목: “2. AGENTS.md — 누적 학습 기록”
AGENTS.md
3.
섹션 제목: “3. harness.sh — 루프 하네스”
Terminal window
- Ralph 루프(반복적 자율 코딩 루프)의 구조 이해 및 구현
harness.sh로 AI 코딩 CLI를 비대화형 모드로 제어PROMPT.md+AGENTS.md작성 원칙 적용- Garbage Collection과 Backpressure로 루프 안정성 확보
Ralph 루프 개요
섹션 제목: “Ralph 루프 개요”Ralph 루프는 “Run → Assess → Loop → Progress → Halt” 사이클로 동작하는 자율 코딩 워크플로우다. AI 코딩 CLI를 헤드리스(headless)로 실행하고, 테스트 결과를 피드백으로 삼아 반복한다.
PROMPT.md + AGENTS.md
↓
Claude Code코드 변경
↓
테스트 실행
✓성공완료
✗실패GC → AGENTS.md 갱신 → 재시도
구현 요구사항
섹션 제목: “구현 요구사항”1. PROMPT.md — 에이전트 지시문
섹션 제목: “1. PROMPT.md — 에이전트 지시문”효과적인 PROMPT.md는 역할, 제약, 완료 기준을 명확히 정의한다.
# RoleYou are an autonomous coding agent. Your task is to make all tests passin the `src/` directory without modifying test files.
**IMPORTANT: Read `AGENTS.md` first** — it contains learned patternsfrom previous iterations and known failure modes.
# 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 CriteriaAll pytest tests pass. Run `pytest tests/ -q` to verify.Write a brief summary to `DONE.md` when complete.
# Working Notes- Check `AGENTS.md` for learned patterns and anti-patterns- Check `fix_plan.md` for prior analysis before starting- Use `git diff` to review your changes before each commit- Update `AGENTS.md` with new learnings after each attempt2. AGENTS.md — 누적 학습 기록
섹션 제목: “2. AGENTS.md — 누적 학습 기록”루프가 반복되면서 학습한 패턴과 실패 원인을 기록하는 파일이다. 에이전트는 매 이터레이션 시작 시 이 파일을 읽고, 동일한 실수를 반복하지 않는다.
## 학습한 패턴 (Learned Patterns)- (루프 실행 후 에이전트가 추가)
## 금지 패턴 (Anti-Patterns)- tests/ 디렉터리의 파일을 수정하지 말 것- 새 패키지 설치 전 requirements.txt 확인할 것
## 진행 상태 (Progress)- [ ] test_divide_normal — ?- [ ] test_divide_zero — ?- [ ] test_fibonacci — ?3. harness.sh — 루프 하네스
섹션 제목: “3. harness.sh — 루프 하네스”#!/usr/bin/env bashset -euo pipefail
# 설정MAX_ITER=${MAX_ITER:-10}SLEEP_SEC=${SLEEP_SEC:-5}PROMPT_FILE="PROMPT.md"LOG_FILE="harness.log"PASS_MARKER="DONE.md"AI_CLI="${AI_CLI:-claude}" # 도구 선택: claude, gemini, codex
# --- Git 초기화 (Garbage Collection 전제조건) ---if [ ! -d .git ]; then git init git add -A git commit -m "initial: harness 시작점" echo "[harness] Git 저장소 초기화 완료"fi
iter=0echo "[harness] Ralph 루프 시작 (최대 ${MAX_ITER}회, 도구: ${AI_CLI})" | 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
# --- AI 코딩 CLI 헤드리스 실행 --- case "$AI_CLI" in claude) claude --print --no-color --dangerously-skip-permissions \ "$(cat "$PROMPT_FILE")" 2>&1 | tee -a "$LOG_FILE" ;; gemini) cat "$PROMPT_FILE" | gemini 2>&1 | tee -a "$LOG_FILE" ;; codex) codex --approval-mode full-auto \ "$(cat "$PROMPT_FILE")" 2>&1 | tee -a "$LOG_FILE" ;; *) echo "[harness] 지원하지 않는 도구: $AI_CLI" | tee -a "$LOG_FILE" exit 1 ;; esac
# --- 완료 조건 확인 --- 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
# --- Garbage Collection: 실패한 코드 변경 롤백 --- # AGENTS.md의 학습 내용은 보존 if [ -f AGENTS.md ]; then cp AGENTS.md /tmp/AGENTS.md.bak fi echo "[harness] GC: 실패한 변경 롤백 (git checkout .)" | tee -a "$LOG_FILE" git checkout . if [ -f /tmp/AGENTS.md.bak ]; then cp /tmp/AGENTS.md.bak AGENTS.md fi
echo "[harness] 테스트 미통과 — 다음 이터레이션 진행" | tee -a "$LOG_FILE"done
echo "[harness] 최대 이터레이션 도달 — 실패" | tee -a "$LOG_FILE"exit 14. Backpressure 메커니즘
섹션 제목: “4. Backpressure 메커니즘”Backpressure는 루프가 API를 과도하게 호출하거나 무한루프에 빠지는 것을 방지한다. 세 가지 레이어로 구현한다.
# harness.sh에 추가할 Backpressure 강화 로직
# 1. 지수 백오프: 실패 횟수에 비례해 대기 시간 증가consecutive_failures=0backoff_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 timeimport jsonfrom 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)) == 15. 실습 대상 코드
섹션 제목: “5. 실습 대상 코드”다음 버그가 있는 코드를 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 pytestfrom 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- 실습 디렉터리 구조 생성 (
src/,tests/,PROMPT.md,AGENTS.md) harness.sh에 실행 권한 부여:chmod +x harness.sh- 루프 실행:
MAX_ITER=5 bash harness.sh harness.log에서 이터레이션 흐름 확인- GC 동작 확인:
git log --oneline으로 롤백 여부 확인 AGENTS.md에 학습 내용이 누적되었는지 확인- 완료 후
DONE.md와 수정된src/calculator.py검토
제출물
섹션 제목: “제출물”assignments/lab-04/[학번]/에 PR:
-
PROMPT.md— 역할/제약/완료기준 포함,AGENTS.md참조 지시 -
AGENTS.md— 루프 실행 후 누적된 학습 기록 (최소 2회 실패 후 성공 과정이 보일 것) -
harness.sh— Backpressure + Garbage Collection 포함한 완전한 구현 -
backpressure.py— stall 감지 로직 -
harness.log— 실제 실행 로그 (최소 3회 이터레이션) -
src/calculator.py— Claude가 수정한 최종 버전 -
README.md— 루프가 몇 번 만에 테스트를 통과했는지, GC 동작 확인, stall 발생 여부 기록