월요일에 잘 돌아가던 기능이 화요일엔 망가져 있다. AI에게 고쳐달라고 했더니 로그인이 터진다. 로그인을 고쳤더니 결제 웹훅이 침묵한다. 10번의 프롬프트 끝에 UI 세 곳이 새로 부서지고, 어느 버전이 제대로 동작했는지조차 기억나지 않는다. 이 패턴에 이름이 있다. 둠 루프(Doom Loop)다.
dev.to에 게재된 분석 아티클 "Why Your Vibe-Coded App Keeps Breaking Every Time You Fix Something"은 이 현상이 운이나 실력 문제가 아님을 명확히 한다. 네 가지 기술적 한계가 동시에 복합 작용한 예측 가능한 결과라는 것이다. Hacker News의 한 개발자는 이를 이렇게 묘사했다. "Bolt로 PoC를 여러 번 시도했는데 매번 둠 루프에 빠진다. 각 '수정'이 이전 '파괴'를 부활시키는 사이클." r/vibecoding의 다른 개발자는 더 직접적이었다. "프로젝트가 커지면 기존 코드를 망가뜨린다."
왜 AI 에이전트는 구조적으로 루프에 빠지는가
첫 번째는 컨텍스트 로트(Context Rot)다. Claude, GPT-4o, Gemini 2.5 Pro 같은 최신 모델들은 200K~1M 토큰의 컨텍스트 윈도우를 자랑하지만, Chroma Research가 18개 프론티어 모델을 대상으로 수행한 연구는 냉혹한 현실을 보여준다. 모델은 컨텍스트를 균일하게 사용하지 않으며, 입력 길이가 길어질수록 성능이 불규칙하게 저하된다. NoLiMa 벤치마크에서는 테스트한 12개 LLM 중 10개가 32K 토큰 시점에서 단문 기준 성능의 50% 아래로 떨어졌다. GPT-4o는 99.3%에서 69.7%로 추락했다. 에러 로그를 붙여넣고 "이것도 건드리지 마세요"를 반복할수록, 두 프롬프트 전에 설명한 불변 조건은 사실상 사라진 것이나 다름없다.
두 번째는 비결정론(Non-determinism)이다. 같은 프롬프트를 다시 보내면 더 나은 버전이 돌아온다고 착각하기 쉽다. 그러나 ACM TOSEM에 게재된 연구에 따르면, ChatGPT에 829개 코딩 문제를 각 5회씩 실행했을 때 CodeContests 기준 75.76%의 태스크에서 단 한 번도 동일한 출력이 나오지 않았다. temperature를 0으로 설정해도 이 효과는 완전히 제거되지 않았으며, 심지어 요청이 떨어지는 GPU 종류와 배치 사이즈까지 결과에 영향을 미친다는 후속 연구도 있다. "다시 시도"는 같은 질문을 두 번 하는 게 아니라, 다른 하드웨어에서 새로운 주사위를 굴리는 행위다.
세 번째는 블래스트 래디어스 미계산이다. 이것이 가장 중요하고, 가장 오해받는 메커니즘이다. 오늘날의 AI 코딩 에이전트들은 코드를 편집하기 전에 언어 인식 기반의 크로스 파일 의존성 그래프를 구축하지 않는다. Anthropic 엔지니어링 팀 스스로가 인정했듯, 에이전트는 glob과 grep 같은 텍스트 검색 기반으로 코드베이스를 탐색한다. 실제 콜 그래프를 순회하는 게 아니라 관련 있어 보이는 텍스트를 찾는 것이다. Microsoft Research의 CodePlan 연구는 그 비용을 정량화했다. GPT-4에 명시적 의존성 그래프를 제공했을 때는 6개 레포지토리 중 5개에서 유효성 검사를 통과했지만, 그래프 없이는 6개 중 0개였다. 에이전트는 인증 헬퍼를 수정하면서 그것이 4개의 컨트롤러, 2개의 커맨드, 1개의 큐 잡에서 호출된다는 사실을 모른다.
네 번째는 얕은 디버깅이다. LLM 코딩 에이전트는 근본 원인 대신 가장 최근에 인용된 에러 라인을 패치하는 경향이 있다. SWE-Bench+ 감사에서 GPT-4의 성공적 패치 251개를 수동 검토한 결과, 31.08%는 약한 테스트 케이스 덕분에 통과한 '그럴듯하지만 의미적으로 잘못된' 패치였다. 테스트 스위트를 강화하자 주요 코딩 에이전트들의 평균 해결률은 51.7%에서 25.9%로 폭락했다. 에러 텍스트를 구체적으로 붙여넣을수록, 에이전트는 그 라인에만 더욱 집중한다. try/except로 감싸거나 특수 케이스를 추가하면 다음 실행은 통과하지만, 콜스택 한 단계 위를 터뜨린다.
루프는 프롬프트 문제가 아니다, 진단 문제다
이 네 가지가 동시에 작동하면 어떤 시스템이 만들어지는가. 대화가 길어질수록 제약 조건을 잊고, 매번 비결정론적으로 다른 시도를 내놓고, 무엇이 무엇에 의존하는지 모른 채 편집하고, 눈에 보이는 에러만 최적화한다. 루프는 이 네 가지의 창발적 결과물이다. 더 좋은 프롬프트로는 탈출할 수 없다.
비용도 현실적이다. Lovable의 Pro 플랜은 월 25달러에 100크레딧을 제공하는데, 한 사용자는 에이전트가 버그를 고치고 새 버그를 만들고 다시 고치는 사이에 12크레딧이 한 루프에서 소진되는 것을 목격했다고 기록했다. 둠 루프는 단순히 시간 낭비가 아니라 비용이 과금되는 퇴행이다.
탈출구는 아키텍처 컴파일러와 계약 설계에 있다
두 가지 접근이 이 문제를 구조적으로 해결한다. 첫 번째는 아키텍처 컴파일러다. dev.to에 소개된 Atomadic Forge는 Python과 JavaScript 레포를 대상으로 모든 심볼·티어·의존성을 매핑하고, 계층 위반을 감지하며, 0~100 점수와 SHA-256 수령증을 발급한다. 핵심 원리는 '5-티어 모나딕 컴포지션 법칙'이다. 상수, 순수 함수, 상태 클래스, 피처, 오케스트레이션—각 파일은 정확히 하나의 티어에 속하고, 티어는 위 방향으로만 합성된다. MCP 서버로 실행되기 때문에 Cursor나 Claude Code에서 certify, enforce 같은 도구를 직접 호출할 수 있다. 47점짜리 레포를 forge enforce --apply로 실행하면 34개 위반 중 31개를 자동 수정해 91점으로 끌어올린다. 에이전트가 편집하기 전에 구조적 피드백이 먼저 존재하는 것, 이게 핵심이다.
두 번째는 계약 우선(Contract-First) 워크플로우다. dev.to의 또 다른 아티클 "Your Coding Agent Doesn't Need Better Prompts. It Needs a Contract."은 가장 위험한 실패 모드가 깨진 코드가 아니라 '그럴듯한 코드'라고 지적한다. 테스트를 통과하고, 요청에 가까운 무언가를 구현하면서, 아무도 승인하지 않은 방향으로 제품 표면을 조용히 확장하는 코드. 이름하여 드리프트(Drift)다.
저자가 AnchorMap 프로젝트에서 구축한 패턴은 단 4개의 파일로 작동한다. AGENTS.md는 진입 지도다. docs/contract.md는 명령, 사전 조건, 출력, 종료 코드, JSON 스키마, 결정론 규칙 같은 관찰 가능한 행동만 명시한다. docs/evals.md는 계약에서 직접 파생된 픽스처와 골든 파일로 검증 게이트를 정의한다. docs/tasks.md는 태스크 ID 없으면 구현 없음이라는 실행 계획을 유지한다.
계약의 핵심은 닫힌 스키마다. scan --json 커맨드의 출력에 세 개의 키만 있어야 한다면, 테스트는 기대하는 키의 존재만 확인하는 것이 아니라 예상 외 키의 부재까지 검증해야 한다. additionalProperties: false가 없는 JSON Schema 테스트는 에이전트가 meta 키를 조용히 추가해도 통과한다. 3주 뒤 다운스트림 소비자가 스키마 불일치로 응답을 거부하거나, 더 나쁘게는 내부 경로 정보가 유출될 수 있다. 계약은 에이전트가 "도움이 될 것 같아서" 추가한 행동을 시스템이 거부하게 만드는 구조다.
설계가 먼저다, 프롬프트는 그다음이다
이 모든 논의가 가리키는 방향은 하나다. AI 코딩 에이전트를 신뢰할 수 있게 만드는 것은 더 정교한 프롬프트가 아니라, 에이전트가 작동하는 구조적 환경이다. 의존성 그래프가 없는 레포에서 에이전트는 맹목적으로 편집한다. 계약이 없는 레포에서 에이전트는 선의로 드리프트한다. 닫힌 테스트가 없는 레포에서 에이전트는 그럴듯한 패치를 축적한다.
빠른 프로토타이핑의 가치는 여전히 유효하다. 다만 프로토타입이 프로덕션으로 전환되는 순간, 아키텍처 레이어와 행동 계약이 동반되지 않으면 속도는 부채 축적 속도로 전환된다. 둠 루프는 AI의 한계가 아니라 구조 없는 워크플로우의 예측 가능한 출력이다. 탈출구는 항상 설계 쪽에 있었다.