[아티클 02] 랄프 루프, , 루프 엔지니어링이 필요할 때
만화 심슨 가족에 나오는 랄프(Ralph)는 똑똑하지는 않지만 엉뚱하고 귀여운 친구입니다. 무엇보다도, 한 가지를 끈질기게 반복하는 캐릭터입니다. 랄프 루프(Ralph loop)라는 이름은 제프리 헌틀리(Geoffrey Huntley)라는 엔지니어가 이 기법을 소개하면서 붙인 이름입니다.
랄프 루프의 아이디어는 이렇습니다. 클로드 코드 같은 CLI를 비대화형 모드로 계속 반복 호출합니다. 심지어 매번 같은 프롬프트를 사용합니다. 매 호출마다 새로운 세션이 시작됩니다. 세션이 종료될 때 작업 상태를 파일에 기록해 다음 세션으로 넘깁니다. 지금까지 무엇을 했고 다음에 무엇을 할지를 파일로 남기는 방식입니다. 이 방법은 세션을 짧게 유지하므로, 모델의 컨텍스트가 커져서 성능이 하락하는 현상을 줄입니다. 세션을 짧게 유지하고, 파일을 메모리처럼 사용합니다. 에이전트 입장에서는 기억상실증에 걸린 직원이 출근할 때마다 인수인계 문서를 읽는 것과 같은 상태이긴 합니다.
루프 자체의 구현은 정말 단순해서 몇 줄로 끝납니다.
위 예시는 루프의 최소 형태를 보여주기 위한 무한 루프입니다. 실제로는 TASKS.md에 완료 표식을 남기게 하고, 셸 스크립트가 그 표식을 검사해 종료하도록 만드는 편이 안전합니다.
--permission-mode acceptEdits는 주로 파일 작성과 수정, 그리고 작업 디렉터리 안의 일반적인 파일 시스템 명령을 자동 승인하는 모드입니다. 테스트 실행이나 uv, git, 서버 기동처럼 셸을 거치는 작업은 Bash 권한과 별도 허가 규칙의 영향을 받습니다. 그래서 비대화형 루프에서는 --allowedTools Bash처럼 넓게 주기보다, 가능하면 Bash(uv run pytest*), Bash(git status*)처럼 필요한 명령만 좁혀 허용하는 편이 안전합니다.
PROMPT.md에는 임무와 작업 절차를 적습니다. 한 세션에 한 항목만 처리할 것, docs/TASKS.md의 체크박스로 진행 상태를 관리할 것, 막히면 해당 항목에 BLOCKED: {이유}를 적고 종료할 것 같은 규칙이 핵심입니다. TASKS.md는 세션 사이를 잇는 연속성이고, JOURNAL.md는 루프가 무슨 작업을 했는지 나중에 확인하기 위한 기록입니다.
예를 들어 uv run pytest가 계속 실패하는데도 클로드가 같은 수정을 반복한다면, TASKS.md에 해당 항목을 BLOCKED로 표시하고 다음 항목으로 넘어가게 합니다. 세 번 이상 같은 실패 로그가 반복되면 루프를 멈추고 사람이 확인합니다. 루프는 반복을 대신할 수 있지만, 막힌 문제를 무한히 해결해 주지는 않습니다.
랄프 루프는 개인 프로젝트 수준에서는 충분히 동작합니다. 다만 한 에이전트가 구현과 검증과 리뷰를 모두 맡으므로, 자신이 작성한 결과를 다른 관점에서 점검할 주체가 없습니다. 체크박스가 모두 채워졌다고 해서 완성도가 보장되지는 않습니다. 또한 BLOCKED 표시가 쌓이면 결국 사람이 개입해야 합니다. 막힌 항목을 풀어줄 판단 주체가 루프 안에 없기 때문입니다.
이 한계를 줄이려면 두 가지가 필요합니다. 반복과 종료를 사람이 셸로 관리하지 않고 도구가 직접 처리하는 것, 그리고 작성하는 모델과 채점하는 모델을 분리하는 것입니다. 이 두 가지를 명령 하나로 제공하는 것이 /goal입니다.

