이 글에서는 여러분을 대신해 작업을 수행할 프로그래밍 가능한 에이전트를 직접 만드는 방법을 소개하겠습니다. 매일 아침 컴퓨터를 켜서 반복적으로 명령을 내릴 필요가 없도록 말이죠.
에이전트는 스스로 깨어나고, 스스로 작업을 찾고, 스스로 문제를 식별하며, 결과를 저장해 여러분이 검토할 수 있도록 책상 위에 제시할 것입니다.
서문
Loop 의 아이디어는 갑자기 나온 것이 아닙니다. 2026 년 6 월의 어느 한 주 동안, 세 명의 업계 전문가가 거의 동시에 같은 생각을 표현했습니다. 바로 이 수준의 개발을 시작할 때가 되었다는 것이었죠.
일주일 후, Andrew Ng 는 이 논의를 "제품을 0 에서 1 로 구축하기"라는 더 넓은 맥락 안에 배치하며 더 포괄적인 그림을 제시했습니다.
이 글은 그 이야기에서 시작하여, 처음부터 최소한의 완전한 Loop 를 구축하는 과정을 안내합니다. 5 가지 동작, 6 가지 부품, "아니오"라고 말하는 하나의 문, 그리고 하나의 인간용 문으로 구성되며, 모두 여러분의 컴퓨터에서 실행되고 모든 소프트웨어 프로젝트에 재사용할 수 있습니다.

출처: 화슈 오렌지 북, Loop 엔지니어링: 그것이 무엇인지 더 이상 묻지 마세요 (v260615, 2026 년 6 월)
세 사람이 도화선에 불을 붙인 그 주
2026 년 6 월: 서로 조율하지 않은 세 사람이 며칠 간격으로 거의 같은 말을 했습니다.
Peter Steinberger, OpenClaw 의 창시자는 X 에 두 문장을 게시했고, 이는 890 만 회의 조회수를 기록했습니다.
https://x.com/steipete/status/2063697162748260627
그 게시물이 바로 논의가 실제로 시작된 지점이었습니다. 선언문이나 긴 에세이가 아니라, 사람들이 이미 조용히 하고 있던 일에 이름을 붙인 두 줄에 불과했습니다.
Boris Cherny: 저는 더 이상 Claude 에게 프롬프트를 입력하지 않습니다. 제게는 실행 중인 Loop 들이 있습니다. 그 Loop 들이 Claude 에게 프롬프트를 입력하고 무엇을 해야 할지 파악합니다.
Addy Osmani: Loop 엔지니어링은 에이전트에게 프롬프트를 입력하는 사람으로서의 자신을 대체하는 것입니다. 대신 그렇게 하는 시스템을 설계하는 것이죠.
실제 실행은 이름보다 몇 달 앞서 있었습니다. 모두가 이미 Loop 를 작성하고 있었지만, 아무도 그것에 이름을 붙이지 않았던 것입니다.
따라서 Loop 는 이제 AI 에이전트가 장기적으로 반복적으로 작업하여 소프트웨어를 만들 수 있도록 하는 핵심적인 방법이 되었습니다.

Andrew Ng 는 시간 척도에 따라 세 가지 Loop 를 가장 안쪽부터 가장 바깥쪽까지 배열했습니다. 가장 안쪽 Loop 가 가장 빠르고, 가장 바깥쪽 Loop 가 가장 느립니다. 또한, 가장 바깥쪽 Loop 의 입력은 가장 안쪽 Loop 의 출력에서 비롯됩니다.
Loop
누가 실행하는가
주기 길이
바깥쪽 레이어에 출력하는 것
Agentic coding loop
에이전트 자체
초 ~ 분
실행되는 버전
Developer feedback loop
인간 + 에이전트
수십 분 ~ 시간
더 명확한 제품 비전과 명세
External feedback loop
사용자 + 팀
시간 ~ 주
비전을 발전시키는 실제 데이터
Andrew Ng 는 시간별로 지도를 제공했습니다. 서로 다른 속도로 실행되는 세 개의 Loop 말이죠. Addy Osmani 는 추상화 수준에 따라 두 번째 지도를 그렸습니다. 프롬프트 -> 컨텍스트 -> Harness -> Loop.

Loop 엔지니어링은 최상위에 위치하며 Harness 에는 없는 세 가지 동사를 추가합니다. 타이머로 실행되고, 도우미를 생성하며, 스스로에게 피드를 제공합니다. 오늘의 출력이 내일의 입력이 되는 것이죠. 마지막 특성이 바로 이것을 Loop 로 만드는 것이며, 동일한 작업을 N 번 반복하는 것과는 다릅니다.
가장 중요한 직관: 동일한 버그라도 각 레이어에서 비용이 다릅니다.
레이어
관심사
핵심 질문
Prompt eng.
프롬프트 작성
모델에게 무엇을 말할 것인가
Context eng.
윈도우에 로드된 것
무엇을 가져오고, 요약하고, 지울 것인가
Harness eng.
단일 실행 준비
어떤 도구, 어떤 동작, 무엇을 완료로 간주할 것인가
Loop eng.
Harness 위의 스케줄링
어떻게 하면 라운드마다 스스로 실행되게 할 것인가
Loop 는 설계상 "턴 수"를 크게 만드는 기계입니다. 여기서부터의 모든 결정(평가자, 인간 게이트, 토큰 상한, 상태 파일)은 "실수 발생"과 "누군가가 그것을 봄" 사이의 거리를 줄이기 위해 존재합니다.
하나의 턴 내부에서 일어나는 일:
"Loop"는 "제자리에서 빙글빙글 도는 것"으로 오해받곤 합니다. 하지만 그렇지 않습니다. 모든 턴에는 5 가지 구체적인 동작이 있습니다. 하나라도 빼면 Loop 는 실행되지 않거나, 실행되더라도 아무데도 나아가지 못합니다.

- 검증(Verification)은 "아니오"라고 말하는 동작입니다.
- 스케줄링(Scheduling)은 이번 턴을 다음 턴으로 연결하는 동작입니다.
바로 이것이 Loop 를 Loop 로 만드는 부분입니다.
우리가 곧 구축할 프로젝트에 매핑: 소규모 팀을 위한 아침 업무 분류(Triage) Loop 입니다.
동작
하는 일
TRIAGE LOOP 에서
Discovery
이번 턴이 무엇을 해야 할지 파악
스킬이 CI / 이슈 / 최근 커밋을 읽음
Handoff
작업을 할당하고 격리
각 발견 사항은 자체 작업 트리(worktree)를 얻음
Verification
다른 에이전트를 투입하여 "아니오"라고 말하게 함
두 번째 하위 에이전트가 리뷰어 역할을 하며 테스트와 스킬을 점검
Persistence
대화 외부에 상태 기록
PR + Linear 티켓 + ./state/triage.md
Scheduling
턴마다 계속 실행되도록 함
GitHub Actions cron 이 06:00 에 트리거
아래 5 가지 레슨은 각각 정확히 하나의 동작을 발전시킵니다.
다섯 개의 레슨 = 완전한 Loop 입니다.
그리고 첫 번째 레슨인 Discovery 부터 시작합니다. Loop 가 오늘 무엇을 할 가치가 있는지 결정할 수 없다면, 그 이후의 어떤 것도 중요하지 않기 때문입니다.
레슨 1 Discovery: 아침 업무 분류(morning-triage) SKILL.md 작성하기
스킬(Skills)이지, 프롬프트의 장벽이 아닙니다.
상상해보세요. 월요일 아침 6 시입니다. 노트북은 닫혀 있고 GitHub Action 이 깨어나서 claude --skill morning-triage 를 실행합니다. 무엇을 읽을지, 무엇을 실행 가능하다고 판단할지, 결과를 어디에 쓸지 등 모든 내용은 여러분이 곧 작성할 SKILL.md 안에 있습니다.
Osmani 의 핵심 문장: 자동화는 스킬을 트리거해야 합니다. 기록되고 업데이트 가능한 프로젝트 지식이어야 하지, cron 작업에 붙여넣은 프롬프트의 장벽이 아니어야 합니다. 붙여넣은 프롬프트는 그냥 거기서 썩어갑니다. 아무도 일정 안에 묻힌 내용을 다시 업데이트하러 돌아가지 않기 때문이죠.
이번 레슨의 과제: .claude/skills/morning-triage/SKILL.md 에 스킬을 작성하세요. 이 스킬은 세 가지 소스(CI / 이슈 / 커밋)를 스스로 읽고, 무엇을 할 가치가 있는지 스스로 결정하며, 결과를 ./state/triage.md 에 기록합니다. 그리고 Loop 가 수행해서는 안 되는 작업을 명시하는 명시적인 중지(Stop) 섹션을 포함해야 합니다.
다음은 시작 템플릿입니다. 세 가지만 변경하면 여러분의 것이 됩니다:
1# .claude/skills/morning-triage/SKILL.md2---3name: morning-triage4trigger: 일일 자동화에 의해 호출됨5---67## Read (발견 입력 — 여러분의 저장소에 실제로 있는 소스로 교체하세요)8- 마지막 실행 이후 실패한 CI 실행 # gh run list --status failure9- 지난 24 시간 동안 열린 이슈 # gh issue list --search "created:>=…"10- 어제 이후 병합된 커밋 # git log --since=yesterday11- 이전 ./state/triage.md # "어제 → 오늘" 인계1213## Judge (상한선 — Loop 가 선택하도록 하고, 목록을 건네주지 마세요)14각 후보에 대해 다음을 결정하세요:15- 지금 실행 가능한가요, 아니면 노이즈인가요?16- 릴리스를 차단하나요? → 우선순위 = P017- 이미 추적 중인가요? → 건너뛰기18오늘 작업 트리(worktree)를 만들 가치가 있는 것만 유지하세요.1920## Write (지속성 — 채팅이 아닌 마크다운에 기록)21./state/triage.md 에 추가:22| 발견 사항 | 소스 | 우선순위 | 상태 |23내일 읽을 수 있도록 파일을 커밋하세요.2425## Handoff (레슨 2 준비)26유지된 각 발견 사항에 대해 작업 라인을 출력:27 worktree=fix/<slug>28 goal=<중지-조건>2930## Stop (유일하게 상용구가 아닌 섹션 — 여기서 깊이 생각하세요)31절대 병합하지 마세요. 절대 삭제하지 마세요.32확신이 덜 드는 것은 무엇이든 → 인간을 위해 ./inbox/ 로 보내세요.33PR 이 아닙니다.
여기서 실제 작업을 수행하는 세 가지 섹션:
Read: 이것은 Discovery 의 입력입니다. 실제 명령어 수준까지 구체적인 소스를 나열하세요. 기억하세요, "컨텍스트를 읽어라"는 소스가 아니지만, gh run list --status failure 는 소스입니다.
Judge: 이것은 전체 Loop 의 상한선입니다. Loop 가 "실행 가능 vs 노이즈"를 스스로 결정합니다. 여러분으로부터 목록을 받지 않습니다. 매일 아침 여전히 목록을 건네주고 있다면, 실행은 자동화했지만 선택은 자동화하지 않은 것입니다. 그리고 선택은 일반적으로 더 비용이 많이 드는 단계입니다. 아무리 소스가 좋아도 이 섹션이 쓰레기를 선택한다면, 다른 네 가지 동작은 가치 없는 작업에 시간을 낭비하게 됩니다.
Stop: 이 파일에서 유일하게 상용구가 아닌 부분입니다. Loop 는 스킬이 말하는 모든 것을 수행하며, 스킬이 말하는 것만 수행합니다. "절대 병합하지 마세요"라고 쓰지 않으면, 언젠가 여러분을 대신해 병합할 것입니다.
레드라인을 명확히 하세요: 절대 병합하지 않음, 절대 삭제하지 않음, 절대 메인 브랜치에 푸시하지 않음, 불확실한 것은 PR 이 아닌 ./inbox/ 로 보냄.
알아두면 좋은 한 가지 더: 이 동일한 스킬 구조는 아침 업무 분류 외에도 작동합니다. Read 섹션을 "어제의 액세스 로그 + 새로운 이슈 + 현재 배포 버전"으로 바꾸면 저녁 사이트 상태 점검 Loop 가 됩니다. Judge 에 "어제보다 회귀(regression)인가?"라는 한 줄을 추가하면 일간 비교 기능이 생깁니다.
이 레슨이 예방하는 문제 - 블라인드 Loop (Blind Loop):
가장 흔한 "Loop 처럼 보이지만 실제로는 아닌 것": Loop 는 실행되지만, 여러분이 여전히 매일 아침 작업을 할당하고 있습니다("이봐, 이 세 가지 버그 좀 봐"). 이것은 실행의 자동화일 뿐, 발견(Discovery)의 자동화가 아닙니다.
증상: Loop 가 여러분을 절대 놀라게 하지 않습니다. 이미 해야 한다고 알고 있던 일만 수행하기 때문입니다.
해결책: Judge 를 스킬 안에 넣고 오늘의 작업을 스스로 선택하게 하세요.
다음으로 넘어가기 전에, 다음 세 가지 질문에 답하세요:
1/ Stop 섹션은 몇 줄인가요?
"절대 병합하지 마세요"가 전부라면, 한 줄을 더 추가하세요. 이 Loop 가 여러분을 대신해 절대 해서는 안 될 다른 일은 무엇인가요? (이슈를 절대 닫지 않음 / 메인에 절대 푸시하지 않음 / 한 번에 3 개 이상의 발견 사항을 절대 처리하지 않음 등)
2/ Read 의 첫 번째 줄을 여러분의 프로젝트에서 실제로 실행되는 명령어로 다시 작성하세요.
3/ 이 스킬이 1 년 동안 변경되지 않는다면 어떤 일이 발생하나요?
이제 비교해보세요: cron 작업에 붙여넣은 프롬프트의 장벽이 1 년 동안 방치되면 어떤 일이 발생하나요?
레슨 2 Handoff: 작업을 나눠주고 격리하기
레슨 1 의 스킬이 막 실행을 마쳤습니다. ./state/triage.md 에는 이제 5 개의 실행 가능한 발견 사항이 있습니다. 가장 자연스러운 다음 생각은 5 개의 에이전트를 한 번에 실행하여 빠르게 진행하는 것입니다. 바로 그 단계가 얽힌 Loop (Tangled Loop) 를 키우는 방법입니다. 여러 에이전트가 같은 디렉토리에서 같은 파일을 편집하고, 병합하는 날은 고고학 발굴이 되어버리죠.
해결책은 한 줄입니다: 모든 발견 사항은 자체 작업 트리(worktree)를 얻습니다.
git worktree 는 내장된 git 메커니즘입니다. 하나의 저장소, 여러 개의 독립적인 작업 디렉토리, 각각 자체 브랜치로 체크아웃됩니다. git worktree add ../fix-auth fix/auth 는 ../fix-auth 에 완전히 격리된 작업 공간을 엽니다. 빌드, 편집, 테스트 등 어떤 것도 다른 작업에 영향을 주지 않습니다. 발견 사항당 하나의 작업 트리 = 물리적으로 분리된 에이전트.
이번 레슨의 과제: ./state/triage.md 에서 각 발견 사항을 읽고, 발견 사항당 하나의 격리된 작업 트리(fix/<slug> 이름)를 열고, 그 안에서 수정 초안을 작성하도록 에이전트를 보내는 스크립트를 작성하세요. 그리고 무한 생성되지 않도록 병렬 처리 상한선을 설정하세요.
1# state/triage.md 읽기, 발견 사항당 하나의 작업 트리2# 변경: MAX_PARALLEL 을 여러분의 머신/비용이 감당할 수 있는 값으로 설정3MAX_PARALLEL=345# 변경: 실제 triage.md 열에 맞게 파싱 조정6findings=$(awk -F'|' 'NR>2 && $5 ~ /open/ {print $2}' \7 state/triage.md | head -n $MAX_PARALLEL)89for finding in $findings; do10 slug=$(echo "$finding" | tr ' ' '-' | tr -cd '[:alnum:]-')1112 # 핵심 라인: 에이전트당 물리적 격리13 git worktree add ../wt-$slug -b fix/$slug1415 # 변경: goal 은 레슨 3 의 평가자가 읽을 중지 조건입니다16 claude --worktree ../wt-$slug \17 --goal "tests/$slug 의 테스트가 통과하고 lint 가 깨끗함" \18 "다음에 대한 수정 초안 작성: $finding" &19done2021wait # 모든 병렬 에이전트가 끝날 때까지 대기2223# 마감 규칙: 에이전트는 절대 자동 병합하지 않음 — 작업 트리는24# 레슨 5의 인간 게이트를 기다림25echo "모든 작업 트리 검토 준비 완료:"26git worktree list
여기서 중요한 규칙: 메인(main) 브랜치에서 절대 작업하지 마세요.
메인은 인간 검토를 위한 착륙장이지, 에이전트의 책상이 아닙니다. 모든 에이전트는 fix/* 작업 트리에서 작업합니다.
병렬 처리에 상한선을 두세요: 무제한 생성은 토큰 폭발의 지름길입니다(레슨 5 에서 다시 다룹니다). 솔직한 질문에 기반하여 MAX_PARALLEL 을 선택하세요. "내 머신이 몇 개를 실행할 수 있는가"가 아니라 "내가 실제로 검토할 수 있는 PR 은 몇 개인가"입니다.
병합은 인간의 결정입니다: Stripe 는 이와 같은 Loop 를 통해 매주 1,000 개 이상의 PR 을 실행하며, 인간이 여전히 모든 PR 을 검토합니다. 인간은 프로세스에서 떠난 것이 아니라 책상을 바꾼 것입니다. 코드를 작성하는 것에서 코드를 검토하는 것으로 말이죠.
그리고 Stripe 사례에서 가져올 만한 한 가지 세부 사항이 있습니다. 그들은 직관과 달리 가장 큰 모델 대신 엄격한 결정론적 게이트를 가진 더 작은 모델을 사용했습니다.
교훈: Loop 작업에서는 순수 모델 성능보다 엄격한 검증 게이트가 더 중요합니다.
이 레슨이 예방하는 문제 - 얽힌 Loop (Tangled Loop):
단일 에이전트 Loop 는 완벽하게 건강해 보입니다. 문제는 병렬로 실행하는 날에만 나타납니다. 다섯 개의 에이전트가 실행되고, 다섯 개의 diff 가 같은 파일에서 충돌하며, 병합은 혼란 그 자체입니다.
해결책: 모든 작업은 자체 작업 트리를 얻습니다. 에이전트 간에 작업 디렉토리를 절대 공유하지 마세요.
다음으로 넘어가기 전에, 다음 세 가지 질문에 답하세요:
1/ MAX_PARALLEL 을 어떤 숫자로 설정했으며, 그 이유는 무엇인가요?
(비용? 머신 성능? 아니면 "내가 솔직히 검토할 수 있는 PR 수"?)
2/ 작업 트리가 충돌하여 에이전트가 아무것도 건드리지 않고 종료된다면,
내일의 상태 파일은 이에 대해 무엇을 기록해야 할까요?
3/ Stripe 는 가장 큰 모델 대신 더 작은 모델 + 엄격한 결정론적 게이트를 사용했습니다.
이 선택이 여러분의 Loop 에 대해 의미하는 바는 무엇인가요?
레슨 3 Verification: "아니오"라고 말하는 문 설치하기 (가장 중요한 레슨)
이것은 Loop 엔지니어링에서 가장 어려운 동작이며, 다른 어떤 레슨보다 더 많은 노력을 기울일 가치가 있습니다.
Anthropic 의 엔지니어 Prithvi Rajasekaran 은 장기 실행 에이전트 앱을 작업하면서 한 가지를 발견했습니다. 방금 작성한 코드를 평가하도록 에이전트에게 요청하면, 거의 항상 스스로를 칭찬할 것입니다. 인간이 한눈에 평범하다는 것을 알 수 있는 경우에도 말이죠.
이것은 모델이 멍청해서가 아닙니다. 자신의 숙제를 채점하는 것은 구조적으로 잘못되었습니다. 코드가 완성될 때쯤이면 에이전트의 컨텍스트는 왜 이런 방식으로 코드를 작성했는지에 대한 자기 정당화 체인으로 가득 차 있습니다. 자신의 출력물을 볼 때, 결과를 보는 것이 아니라 결과에 대한 주장을 보는 것입니다.
이것을 Loop 안에 넣으면 재앙으로 증폭됩니다. 모든 턴의 "'이것이 충분히 좋은가?'"라는 질문은 방금 그것을 작성한 에이전트에 의해 답변됩니다. 모든 턴이 스스로에게 고개를 끄덕입니다. 오래 실행될수록 실제 품질에서 더 멀어집니다. 이것이 바로 고개 끄덕임 Loop (Nodding Loop) 이며, 목록에서 가장 비용이 많이 드는 문제입니다.
Rajasekaran 의 해결책, 그의 말로:
"회의적인 독립 평가자를 조정하는 것은 생성기가 자신의 작업에 대해 비판적으로 만들려고 하는 것보다 훨씬 다루기 쉽습니다."
이것은 구조적인 문제이지, 표현의 문제가 아닙니다. 저자에게 자신의 머리 밖으로 나오라고 요청할 수는 없지만, 완전히 다른 지침을 가진, 자기 정당화 체인이 전혀 없는 상태에서 코드를 처음부터 바라보는 다른 에이전트를 도입할 수는 있습니다.
비유는 GAN 에서 비롯됩니다. 하나의 네트워크가 구축하고, 다른 하나가 공격합니다. 제작자와 검사자입니다. 오래된 은행 규칙과 같습니다. 송금하는 사람과 승인하는 사람은 달라야 합니다.
이번 레슨의 과제 - 두 가지를 작성하세요:
1) .claude/agents/reviewer.md 에 다섯 개의 섹션(ROLE + ASSUME + CHECK + USE + VERDICT)으로 구성된 평가자 시스템 프롬프트.
2) 생성기가 아닌 별도의 새로운 모델에 의해 판단되는 이 Loop 의 중지 조건을 선언하는 /goal 명령어.
1# .claude/agents/reviewer.md (3 가지 변경)2ROLE: 적대적 코드 리뷰어.3ASSUME: 이 코드는 반대가 입증될 때까지 BROKEN 입니다.4칭찬하지 마세요. 실패하는 부분을 찾으세요.56# 변경: CHECK 를 여러분 프로젝트의 실제 실패 모드 순서로 정렬하세요,7# 실행 가능한 검사부터 먼저8CHECK, 순서대로:9 1. 실행됩니까? (읽지 말고 실행하세요)10 2. 테스트: 실행하고 실제 출력을 붙여넣으세요.11 3. 작성자가 놓친 엣지 케이스.12 4. 동작이 티켓과 일치합니까?1314# 변경: 어떤 MCP 를 사용할지는 테스트 대상에 따라 다릅니다 —15# 프론트엔드 → Playwright, API → curl/httpie16USE Playwright MCP: 페이지를 열고, 클릭하고,17스크린샷을 찍고, DOM 을 검사하세요.18의도가 아닌 동작을 판단하세요.1920VERDICT: 모든 검사가 유지될 때만 PASS.21 그렇지 않으면 REJECT + 각 이유를 나열하세요.
1# 중지 조건 — 생성기가 아닌 새로운 작은 모델에 의해 판단됨2# 변경: 발견 사항의 실제 검증 가능한 조건으로 교체3/goal test/auth 의 모든 테스트가 통과하고 lint 단계가 깨끗함45# 주의: /goal 과 /loop 는 동일한 것이 아닙니다6# /loop = 간격으로 재실행 (중지 판단 없음 — 위험함)7# /goal = 새로운 모델이 조건이 참이라고 판단할 때까지 실행
두 에이전트, 이상적으로는 두 모델: "동일한 모델, 다른 프롬프트"는 종종 동일한 사각지대를 유지합니다. 가능하다면 모델도 바꾸세요.
기본 회의주의: 평가자의 기준선은 ASSUME BROKEN 입니다. 신뢰는 검사를 통과함으로써 얻어져야 하며, 기본적으로 부여되어서는 안 됩니다.
의도가 아닌 동작을 판단하세요: "이 JSX 는 괜찮아 보인다"와 "버튼을 클릭했더니 페이지가 이동했고, 여기 스크린샷이 있습니다"는 완전히 다른 차원의 이야기입니다. 평가자는 행동해야 합니다. 테스트를 실행하고, 페이지를 클릭해야 하지, 코드를 읽고 느낌으로 판단해서는 안 됩니다.
이유와 함께 거부하세요: 이유가 나열되지 않은 REJECT 는 거부가 아닙니다. 생성기는 무엇을 수정해야 할지 전혀 알 수 없습니다.
그리고 결정적인 테스트: 여러분의 평가자가 지난 5+ 턴 동안 실제로 무언가를 거부한 적이 있나요? 수백 번의 턴 동안 단 한 번도 "아니오"라고 말한 적이 없는 Loop 는 실제 작업 부하에서는 통계적으로 불가능합니다. 따라서 평가자가 제대로 작동하지 않고 있다는 증거입니다.
이 레슨이 예방하는 문제 - 고개 끄덕임 Loop (Nodding Loop):
Loop 가 실행되고, 에이전트가 코드를 작성하고, 같은 에이전트가 "괜찮아 보인다"고 말합니다. 모든 턴이 스스로 승인하며, 그럴듯해 보이는 실수를 기계 속도로 쌓아 올립니다. 해결책: 이 전체 레슨입니다. 구조적 분리 + 기본 회의주의 + 행동에 의한 판단 + 제3자 중지 조건.
다음으로 넘어가기 전에, 다음 세 가지 질문에 답하세요:
1/ 평가자가 동일한 모델에 다른 프롬프트를 사용한 것인가요, 아니면 다른 모델인가요? 그 이유는 무엇인가요?
2/ "의도가 아닌 동작을 판단하라"를 여러분 프로젝트의
구체적인 문장으로 번역하세요: "내 평가자는 코드를 읽지 않습니다. ____을(를) 실행하고, ____을(를) 볼 때만 PASS 합니다."
3/ "거의 충분한" 새로운 모델이 여러분의 /goal 조건을 거짓으로 PASS 할 가능성은 얼마나 되나요?
만약 가장 무서운 실패 모드가 X 라면, 지금 당장 중지 조건에 X 에 대한 검사를 추가하세요.
레슨 4 Persistence: 오늘의 작업이 내일까지 살아남게 하기
레슨 3 이 끝났습니다. 평가자가 세 가지 발견 사항을 판단했습니다. 두 개는 PASS, 하나는 REJECT 입니다. 질문: 이 세 가지 평결은 지금 어디에 살아있나요?
만약 답이 "컨텍스트 윈도우 안에"라면, 내일 아침 6 시에 Loop 는 비워진 컨텍스트로 깨어나 아무것도 기억하지 못합니다. 처음부터 다시 업무를 분류하고, 어제 수정되지 않은 REJECT 를 우연히 발견하고, 아마도 다른 에이전트를 할당하여 다시 수정하게 하거나, 완전히 놓치거나, 같은 구멍에 빠질 수도 있습니다.
이것이 바로 기억상실 Loop (Amnesiac Loop) 입니다. 매일 같은 지점에서 시작합니다.
한 줄로 된 해결책: 메모리는 컨텍스트가 아니라 디스크에 기록된 상태입니다. 마크다운 파일, Linear 보드, 데이터베이스 등 한 번 기록되면 에이전트가 아무리 철저히 잊어버려도 상관없습니다.
이 둘은 끊임없이 혼동되므로 차이점을 확실히 하세요:
컨텍스트 = 에이전트가 이번 턴에 보는 윈도우 -> 매 새로고침마다 지워짐.
메모리 = 턴과 날짜를 넘어 살아있는 상태 -> 디스크에 기록됨 (마크다운 / DB / 보드).
Loop 는 오늘 -> 내일을 메모리를 통해서만 연결합니다.
이번 레슨의 과제:
- 최소 4 개의 열(발견 사항 / 소스 / 우선순위 / 상태)이 있는 ./state/triage.md 를 생성하세요. 레슨 1 의 스킬이 이것을 작성하고, 레슨 2 의 작업 트리가 이것을 읽습니다.
- 커넥터(MCP)를 연결하세요. PASS 평결은 자동으로 PR 을 열고, REJECT 는 자동으로 티켓을 업데이트합니다.
- 내일의 Loop 가 오늘의 상태를 실제로 다시 읽을 수 있는지 확인하세요.
1# ./state/triage.md (Loop 의 메모리 — 필요에 따라 변경)23| 발견 사항 | 소스 | 우선순위 | 상태 |4|-----------------|--------------|----------|------------|5| auth 테스트 불안정 | CI #4821 | P0 | 수정 중 |6| null 역참조 | 이슈 92 | P1 | PR 열림 |7| 오래된 의존성 | 커밋 a3f9c | P2 | inbox |89# 필요에 따라 열 확장: last_seen, retry_count, assigned_to10# 이 파일은 저장소에 커밋되어야 합니다.11# 그렇지 않으면 내일의 클라우드 러너가 볼 수 없습니다.
1// .mcp/connectors.json — Loop 를 외부 세계에 연결2{3 "github_pr": {4 "type": "mcp",5 "on_event": "evaluator.verdict.PASS",6 "action": "open_pr",7 "branch": "fix/${slug}",8 "auto_merge": false // ← 반드시 false 여야 함. 인간 게이트 = 레슨 59 },10 "linear": {11 "type": "mcp",12 "on_event": "evaluator.verdict.REJECT",13 "action": "update_ticket",14 "fields": { "status": "차단됨", "reason": "${verdict.reasons}" }15 }16}
각 열이 중요한 이유: 소스가 없으면 발견 사항이 어디서 왔는지 감사할 수 없습니다. 우선순위가 없으면 작업 순서를 정할 수 없습니다. 상태가 없으면 내일이 배턴을 이어받을 수 없습니다.
그리고 이 레슨에 대한 검증은 속일 수 없는 유일한 것입니다. 내일까지 기다리세요. 일어나서 확인하세요. inbox 가 여전히 있나요? 완료되지 않은 발견 사항은 여전히 상태를 유지하고 있나요? 오전 6 시 실행이 어제 멈춘 지점에서 이어서 시작했는가, 아니면 다시 처음부터 시작했는가? 이것은 추론으로 알아내는 것이 아니라 실제로 실행해봄으로써 알게 됩니다.
지속성과 함께 오는 조용한 규율 - 항상 샘플 하나를 읽으세요.
일단 지속성이 작동하면 함정이 열립니다. Loop 가 빠른 속도로 PR 을 발행하고, 여러분은 생산적이라고 느끼지만, 코드베이스에 대한 여러분의 정신적 지도는 조용히 시대에 뒤처집니다. 규칙: 모든 것을 읽지 마세요 (그러면 Loop 의 의미가 사라집니다). 하지만 하루에 하나의 샘플 PR 을 읽고, Loop 가 무엇을 변경했는지 그리고 그 이유를 설명하도록 스스로에게 강요하세요.
설명할 수 없는 순간, 여러분의 지도가 뒤처진 것입니다. 평온한 아침에 이를 고치는 데는 10 분이 걸립니다. 프로덕션 장애 중에 고치는 데는 훨씬 더 많은 비용이 듭니다.
이 레슨이 예방하는 문제 - 기억상실 Loop (Amnesiac Loop):
Loop 가 좋은 작업을 찾아서 수행하지만, 결과가 비워진 컨텍스트에만 살아있었기 때문에 수행했다는 사실을 잊어버립니다. 다음 턴에 동일한 작업을 다시 발견하거나, 더 나쁘게는 다시 수행하여 첫 번째 시도를 덮어씁니다.
증상: 축적된 진행 상황이 없으며, 매일 같은 곳에서 시작합니다. 해결책: 디스크의 상태 파일.
다음으로 넘어가기 전에, 다음 세 가지 질문에 답하세요:
1/ "메모리 ≠ 컨텍스트"를 여러분 프로젝트의 구체적인 문장 하나로 번역하세요.
"내 _____은(는) 메모리이고, 내 _____은(는) 컨텍스트입니다."
2/ 내일의 Loop 가 깨어납니다. state.md 의 어떤 열(COLUMN)을
가장 먼저 읽어서 첫 번째 동작을 결정할까요? 그 열의 이름을 올바르게 지었나요, 아니면 단지 함정을 묻어둔 것인가요?
3/ 규율: 하루에 하나의 샘플 PR 을 읽는 시간은 언제인가요?
지금 캘린더 알림을 설정하세요. 이것은 자신과의 약속입니다.
레슨 5 Scheduling: 현실로 만들고, 안전하게 만들고, 하나의 문을 열어두기
레슨 1-4 가 설치되었지만, 여러분이 버튼을 누르는 것을 멈추는 순간 Loop 도 멈춥니다. 마지막 동작은 하나의 동사입니다. 트리거에 걸어두세요.
하지만 이 레슨에서 가장 위험한 부분은 cron 을 잘못 설정하는 것이 아닙니다. cron 을 올바르게 설정하는 것입니다. 그러면 Loop 가 진정으로 혼자 실행되고, 하나의 버그가 밤새도록 회전하게 만들 수 있으며, 도우미가 도우미를 생성하여 여러분이 알아보지 못하는 청구서를 보고 깨어날 때까지 계속될 수 있습니다.
따라서 이 레슨은 실제로 세 가지를 수행합니다. 트리거를 걸고, 상한선을 설정하고, 인간용 문을 유지하세요.
첫째 - 스케줄러를 선택하세요:
1클라우드 (GH Actions) 데스크탑 예약 /loop (CC 에서)2실행 위치 클라우드 여러분의 머신 여러분의 머신3머신 켜짐? 필요 없음 필요함 필요함4세션 열림? 필요 없음 필요 없음 필요함5최소 간격 1 시간 1 분 1 분6로컬 파일 봄? 아니오 예 예
결정적인 질문: 이 작업이 노트북을 떠날 수 있습니까?
1"1 분마다 내 로컬 개발 서버 확인"2 → 로컬 + /loop 여야 함 (클라우드의 1 시간 간격은 도달할 수 없음)34"오전 3 시에 GitHub 이슈를 스캔하고 PR 열기"5 → 클라우드여야 함 (노트북이 닫혀 있음 — Loop 가6 그것을 기다릴 수 없음)
그리고 전체 실천에서 가장 교활한 자기기만은 로컬 타이머를 "자는 동안 실행 중"으로 취급하는 것입니다. 그렇지 않습니다. "내가 아직 주변에 있는 동안 몇 턴 더 실행하는 것"일 뿐입니다.
이번 레슨의 과제:
- cron 트리거로 아침 트리아지(morning-triage) 스킬을 실행하는
.github/workflows/triage.yml파일을 작성합니다. - 실행당 예산, 일일 예산, 최대 재시도 횟수라는 세 가지 상한선을 설정합니다.
- 워크플로우의 마지막 규칙: PR은 절대 자동 병합되지 않으며, 확실하지 않은 모든 것은
./inbox/로 이동합니다.
1# .github/workflows/triage.yml (3가지를 변경하세요)2name: morning-triage34on:5 schedule:6 - cron: '0 6 * * *' # 변경: UTC 기준으로 해당 시간대의 06:0078jobs:9 triage:10 runs-on: ubuntu-latest11 timeout-minutes: 45 # ← 실행당 상한 · 변경12 permissions:13 contents: write14 pull-requests: write15 steps:16 - uses: actions/checkout@v41718 - name: morning triage19 env:20 ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}21 DAILY_BUDGET_USD: '20' # ← 일일 상한 · 변경22 MAX_RETRIES: '3' # ← 재시도 상한 · 변경23 run: |24 claude --skill morning-triage \25 --max-retries "$MAX_RETRIES" \26 --daily-budget-usd "$DAILY_BUDGET_USD"2728 - name: PR 열기 (절대 자동 병합 금지)29 run: |30 # PR은 자동으로 열립니다. 병합은 사람이 결정합니다.31 gh pr create --draft --base main \32 --title "[loop] $(date +%F) triage" \33 --body-file ./state/triage.md34 # 여기에는 `gh pr merge`가 없습니다 — 의도적입니다3536 - name: 불확실한 항목을 인박스로 라우팅37 run: |38 ls ./inbox/ && echo "인간의 검토를 기다리는 항목이 있습니다"
6개월 후에도 루프가 살아있게 만드는 세 가지 규칙:
배포 전에 상한선을 설정하라: 실행당 타임아웃, 일일 예산, 최대 재시도 횟수라는 세 가지 수준의 상한선을 첫 번째 자율 실행 전에, 무서운 청구서가 도착한 후가 아니라 설정하세요. 토큰 상한선은 비용 절감을 위한 것이 아닙니다. 무제한 위험을 제한된 위험으로 바꿔주는 회로 차단기입니다. 상한선이 없는 루프는 지출 권한을 자체 버그에 위임한 것입니다.
규모로 보자면: Uber는 AI 예산을 4개월 만에 소진한 후 엔지니어당 월 $1,500의 도구 사용 상한선을 설정했습니다. 루프당 상한선은 그 교훈을 세분화한 버전입니다.
하나의 문은 열어두라: PR은 자동 병합되지 않습니다. 불확실한 항목은 인박스에 도착합니다. 당신은 하루에 한 개의 샘플을 읽습니다. 이 문이 존재하는 이유는 인간이 항상 그 문을 통과할 것이기 때문이 아니라, 문이 존재함으로써 당신이 통과할 수 있는 위치에 있기 때문입니다. 모든 문을 완전히 닫아버리면, 막상 들어가야 할 날이 왔을 때 열쇠를 잃어버린 꼴이 됩니다.
실제로 깨어나는지 확인하라. 최소 3회전 이상 실행하세요 (드라이 런도 포함). 가장 흔한 실패 패턴: 데모 데이에는 화려했지만, 목요일이면 죽어있는 경우입니다. "마지막 실행이 데모를 한 날이다"라는 것은 수동 루프(Manual Loop)의 진단 신호입니다.
Claude Code 외부에서도 동일하게 작동합니다 - 기능은 특정 벤더에 종속되지 않으며, 이름만 다릅니다:
1기능 Claude Code Codex2스케줄링 /loop · worker Automations 탭3조건부 실행 /goal automation rerun + judge4병렬 격리 --worktree background worktree5하위 에이전트 .claude/agents/ .codex/agents/6외부 연결 MCP + plugins MCP connector7명시적 스킬 SKILL.md $skill-name8오프라인 실행 Cloud Routines cloud (계획 중)
질문은 결코 "어떤 벤더를 쓸까"가 아니었습니다. "여섯 가지 기능이 모두 설치되어 있는가"입니다.
이 레슨이 예방하는 질병 - 수동 루프(Manual Loop):
네 가지 동작을 아름답게 구축했지만, cron이 없습니다. 그것은 루프가 아니라, 한 번 실행하고 잊어버린 스크립트입니다.
해결책: 당신이 기억하는 것에 의존하지 않는 트리거를 연결하세요.
배포 전에 다음 세 가지 질문에 답하세요:
1/ 세 가지 상한선의 정확한 숫자는 무엇입니까?
버그가 밤새 실행된다면, 어떤 상한선이 가장 먼저 추락을 막아줍니까? 만약 그중 어느 것도 막지 못한다면... 그것이 당신에게 무엇을 말해줍니까?
2/ 당신의 인간용 문은 어떤 모습입니까?
(PR 검토 / 인박스 / 일일 샘플 / 주간 정산?) 그것을 기록하는 것 = 자신과의 계약에 서명하는 것입니다.
3/ 마무리 질문: 6개월 후, 이 루프가 당신을 더 강하게 만들었을까요 (이해력, 판단력, 시스템에 대한 감각 향상) - 아니면 당신이 읽을 수도 없는 기계의 관리인으로 전락시켰을까요? 두 번째 상황을 피하기 위한 당신의 계획은 무엇입니까?
4가지 부채와 엔지니어로 남는 법
당신의 루프는 구축되었습니다: 깨어나고, 작업을 찾고, 스스로를 비판하고, 기억하고, 내일의 일정을 스스로 계획합니다.
루프가 실행되는 동안, 네 가지가 조용히 쌓입니다 - 그리고 그들의 공통점은 그 어느 것도 경보를 울리지 않는다는 것입니다.
1검증 부채(VERIFICATION DEBT) 거부되지 않은 출력물이 쌓여감2이해 부식(COMPREHENSION ROT) 코드베이스는 커지는데, 당신의 멘탈 맵은 그대로임3인지 항복(COGNITIVE SURRENDER) "더 이상 꼼꼼히 살피고 싶지 않아"4토큰 폭발(TOKEN BLOWOUT) 버그가 밤새 실행됨 → 청구서로 확인함
그들은 서로를 먹여살립니다: 검증되지 않은 출력물은 당신의 이해를 침식합니다 -> 침식된 이해는 항복을 초래합니다 -> 항복은 루프를 더 오래 실행하고 더 많은 비용을 쓰게 만듭니다 -> 이는 더 많은 검증되지 않은 출력물을 만들어냅니다.
첫 번째 단독 실행 전에, 새 루프를 네 가지 모두에 대해 감사하세요:
- 내 평가자는 실제로 거부한다 - 장식용이 아니다.
- 나는 하루에 하나의 샘플 PR을 읽고 무엇이 변경되었는지 설명할 수 있다.
- 나는 "이건 틀렸다"고 말하는 습관을 유지했다.
- 내 상한선은 첫 번째 실행 전에, 첫 번째 청구서 후가 아니라 설정되었다.
그리고 모든 것을 결정짓는 부분은 다음과 같습니다:
똑같은 루프라도, 두 사람이 구축하면 정반대의 결과에 도달할 수 있습니다. 한 사람은 코드를 계속 읽고 방향을 유지하면서 더 빠르게 움직이기 위해 사용합니다 - 루프는 그들이 이미 가지고 있는 판단력을 증폭시킵니다.
다른 사람은 똑같은 루프를, 특히 다시는 아무것도 이해하지 않기 위해 사용합니다 - 6개월 후, 첫 번째 사람은 더 예리해져 있고, 두 번째 사람은 자신이 읽을 수 없는 기계의 관리인이 되어 있습니다.
Addy Osmani: "루프를 구축하되, 단순히 '시작' 버튼을 누르는 사람이 아니라, 계속해서 엔지니어로 남을 사람처럼 구축하라."
루프는 생성을 거의 공짜로 만들지만, 여전히 희소한 것은 판단력입니다: 어떤 계획이 옳은지, 어느 지점에서 멈춰야 하는지, 어떤 것은 실행되지만 근본적으로 잘못되었는지. 루프는 판단력을 평가절하하지 않습니다 - 판단력이 아닌 모든 것을 벗겨내고, 오직 판단력만 남깁니다.
루프는 충실한 증폭기입니다:
이해를 가져오면 - 이해를 증폭시킵니다.
게으름을 가져오면 - 게으름을 증폭시킵니다.
무엇을 증폭시킬지 결정하세요 - 구축하기 전에.
계속 지켜봐 주세요!
행운을 빕니다 :)





