Logo ari Space

오래 혼자 돌아가는 코딩 에이전트는 어떻게 만들까 — Anthropic 하네스 설계 글 쉽게 읽기

AI
갱신일 May 27, 2026
20 min read
Table of Contents

이 글은 Anthropic Engineering의 Harness design for long-running application development (Prithvi Rajasekaran, 2026-03-24)를 제가 이해한 대로 쉽게 풀어 정리한 글입니다. 수치나 사례는 원문을 따랐고, 어려운 용어는 본문 안에서 그때그때 풀어 설명했습니다.


들어가며: 무엇을 풀려고 했나

요즘 AI 코딩 도구의 화두는 “모델이 얼마나 똑똑한가”만이 아닙니다. 그 모델을 어떻게 감싸서 일을 시키느냐, 즉 하네스(harness) 설계가 성능을 크게 좌우합니다.

Definition (하네스 설계란)

하네스(harness)는 원래 “말이나 장비를 붙들어 제어하는 마구·고정 장치”를 뜻합니다. AI에서는 모델 자체가 아니라, 그 모델을 감싸서 일을 시키는 바깥 구조 전체를 가리킵니다. 어떤 지시문(프롬프트)을 줄지, 여러 에이전트에게 역할을 어떻게 나눠 맡길지, 긴 작업에서 기억(컨텍스트)을 어떻게 관리할지, 어떤 도구를 연결해 줄지 같은 것들이죠.

그래서 하네스 설계란 “같은 모델로 더 나은 결과를 내기 위해 그 바깥 구조를 어떻게 짤지 고민하는 일”입니다. 똑같은 Claude를 쓰더라도, 혼자 알아서 하게 두느냐 / 기획·구현·검증 역할을 나눠 협업시키느냐에 따라 결과물 품질이 크게 달라지는데, 이 글이 바로 그 차이를 다룹니다.

원문 저자는 성격이 꽤 다른 두 문제를 동시에 다뤘습니다.

  • 프론트엔드 디자인: “이 디자인 예쁘냐?”처럼 주관적인 취향의 영역
  • 장기 자율 코딩: 앱 하나를 사람 개입 없이 끝까지 만들어내는, 정답이 검증 가능한 영역

이 둘은 정반대처럼 보이지만, 저자는 양쪽에 통하는 한 가지 아이디어를 찾아냈습니다. 바로 GAN(생성적 적대 신경망) 에서 가져온 구조입니다. 무언가를 만드는 에이전트(generator, 생성자) 와 그것을 채점하는 에이전트(evaluator, 평가자) 를 따로 두고, 서로 주고받으며 품질을 끌어올리는 방식이죠.

Definition (GAN이란)

GAN(Generative Adversarial Network, 생성적 적대 신경망) 은 원래 머신러닝 기법입니다. 만드는 쪽(생성자) 과 그것이 진짜 같은지 판별하는 쪽(판별자) 을 서로 경쟁시키는데, 생성자는 판별자를 속이려고, 판별자는 가짜를 더 잘 잡아내려고 겨루면서 양쪽이 함께 실력을 끌어올립니다. 위조지폐범과 감별사가 서로 수법을 발전시키는 것에 비유되곤 하죠.

이 글에서는 신경망을 실제로 학습시키는 게 아니라, 그 “만드는 쪽과 채점하는 쪽을 분리해 서로 주고받게 한다”는 아이디어만 차용했습니다. 생성자 에이전트가 결과물을 만들고, 평가자 에이전트가 채점·비평하면, 그 피드백으로 생성자가 다음 결과물을 더 낫게 만드는 식입니다.

여기에 예전 장기 코딩 실험에서 얻은 두 가지 교훈 — ① 작업을 다룰 만한 크기로 쪼개기, ② 세션이 바뀔 때 맥락을 넘겨주는 “인수인계 문서” 쓰기 — 를 더해, 최종적으로 Planner(기획) → Generator(구현) → Evaluator(검증) 의 3-에이전트 구조에 도달합니다. 이 구조로 여러 시간짜리 자율 코딩 세션을 돌려 제법 완성도 있는 풀스택 앱을 만들어냈습니다.


왜 그냥 “알아서 해줘”라고 시키면 안 되나

긴 작업을 에이전트에게 통째로 맡기면 시간이 지날수록 점점 길을 잃습니다. 저자는 그 원인을 두 가지로 봤습니다.

1. 컨텍스트가 차오르면 흐트러진다

모델은 지금까지 오간 대화를 컨텍스트 창이라는 한정된 작업 기억 공간에 담아두고 일합니다. 그런데 작업이 길어지면 이 공간이 점점 차오르고, 가득 찰수록 모델은 앞에서 정한 규칙이나 맥락을 놓치며 일관성을 잃기 시작합니다. 사람으로 치면, 회의가 너무 길어져 처음에 합의한 내용을 까먹고 엉뚱한 소리를 하는 것과 비슷합니다.

게다가 일부 모델은 여기에 더해 “컨텍스트 불안(context anxiety)” 이라는 버릇을 보입니다. 작업 기억이 한계에 가까워졌다고 스스로 느끼면, 아직 할 일이 잔뜩 남았는데도 서둘러 일을 끝내버리려 드는 현상입니다.

예를 들어 화면을 10개 만들어야 하는데, 7개쯤 만든 시점에 “곧 공간이 부족하겠다” 싶으면 나머지 3개를 제대로 만들지 않고 “나머지는 비슷한 방식으로 구현하면 됩니다” 같은 말로 마무리 짓거나, 기능을 대충 빈 껍데기(stub)로 때우고 “완료했습니다”라고 선언해 버리는 식이죠. 마감이 코앞이라고 느낀 사람이 남은 일을 대충 뭉개고 손 떼는 것과 똑같습니다.

이걸 푸는 방법이 컨텍스트 리셋(context reset) 입니다. 컨텍스트를 통째로 비우고 새 에이전트를 띄우되, 직전 에이전트의 상태와 다음 할 일을 담은 인수인계 문서를 같이 넘겨줍니다.

여기서 말하는 컨텍스트 리셋은 흔히 쓰는 컴팩션(compaction) 과 다릅니다. 둘 다 “컨텍스트가 차오르는 문제”를 다루지만 방식이 정반대입니다.

컴팩션(compaction)컨텍스트 리셋(context reset)
하는 일앞 대화를 요약해 압축컨텍스트를 통째로 비움
어떻게 하나① 그동안 오간 대화를 요약하고 → ② 원본을 그 요약본으로 교체해 기록을 짧게 만든 뒤 → ③ 같은 에이전트가 그 짧아진 기록 위에서 계속 일함① 직전 에이전트가 상태·다음 할 일을 담은 인수인계 문서를 남기고 → ② 컨텍스트 창을 완전히 비운 새 에이전트를 띄운 뒤 → ③ 그 인수인계 문서만 넘겨주고 이어서 작업하게 함
누가 이어서?같은 에이전트가 짧아진 기록으로 계속새 에이전트가 인수인계 문서를 받아 시작
장점연속성이 좋음”깨끗한 새 출발”이라 컨텍스트 불안이 사라짐
약점새 출발이 아니어서 컨텍스트 불안이 남을 수 있음인수인계 문서에 충분한 상태가 담겨 있어야 함

즉 핵심 차이는 “기억을 압축해 같은 에이전트가 계속 가느냐(컴팩션)” vs “기억을 비우고 새 에이전트가 인수인계받아 다시 시작하느냐(리셋)” 입니다.

실제로 Claude Sonnet 4.5는 컨텍스트 불안이 강해서 컴팩션만으로는 부족했고, 그래서 리셋이 필수였다고 합니다. 다만 리셋은 오케스트레이션 복잡도·토큰 비용·지연시간을 늘립니다.

2. 스스로는 자기 일을 후하게 채점한다

더 근본적인 문제는 자기 평가(self-evaluation) 입니다. 에이전트에게 “네가 만든 것 평가해봐”라고 하면, 사람 눈에 명백히 별로인 결과물도 자신만만하게 칭찬하는 경향이 있습니다. 특히 디자인처럼 정답이 없는 주관적 작업에서 심합니다.

해결의 핵심 지렛대는 일하는 에이전트와 채점하는 에이전트를 분리하는 것입니다. 분리만으로 후한 평가가 사라지진 않습니다(평가자도 결국 LLM이라 LLM 결과물에 관대하죠). 하지만 독립된 평가자를 “깐깐하게” 튜닝하는 일이, 생성자가 자기 작업을 스스로 비판하게 만드는 것보다 훨씬 다루기 쉽습니다. 그리고 외부 피드백이 생기는 순간, 생성자에게는 고쳐나갈 구체적 기준이 생깁니다.


프론트엔드 디자인: 주관적 품질을 채점 가능하게

저자는 자기 평가 문제가 가장 두드러지는 프론트엔드 디자인부터 손댔습니다. 별다른 개입이 없으면 Claude는 안전하고 뻔한, 기능은 하지만 밋밋한 레이아웃으로 수렴하는 경향이 있었거든요.

두 가지 통찰이 바탕이 됐습니다.

  • 아름다움을 점수 하나로 환원할 순 없어도, 디자인 원칙을 담은 채점 기준으로 개선할 수는 있다. “이 디자인 아름답냐?”는 답하기 어렵지만, “우리가 정한 좋은 디자인 원칙을 따르냐?”는 채점할 거리가 생긴다.
  • 생성과 채점을 분리하면, 생성자를 더 나은 결과로 밀어붙이는 피드백 루프가 만들어진다.

그래서 양쪽 프롬프트(생성자와 평가자에게 주는 지시문)에 네 가지 채점 기준을 넣었습니다.

기준내용
디자인 품질색·타이포·레이아웃·이미지가 따로 노는 부품이 아니라, 하나의 무드와 정체성으로 어우러지는가
독창성의도적인 창작 선택이 보이는가, 아니면 템플릿·라이브러리 기본값·“AI 티 나는 패턴”(예: 흰 카드 위 보라색 그라데이션)인가
완성도(craft)타이포 위계, 간격 일관성, 색 조화, 대비비 같은 기술적 실행력. 창의성이 아니라 기본기 점검
기능성미적인 것과 별개로, 사용자가 무엇을 하는 화면인지 알고 주요 동작을 찾아 헤매지 않고 끝낼 수 있는가

핵심은 디자인 품질·독창성에 가중치를 더 줬다는 점입니다. 완성도와 기능성은 Claude가 이미 기본적으로 잘했지만, 디자인과 독창성에서는 결과물이 밋밋했기 때문입니다. 기준에서 “AI 슬롭”(AI가 찍어낸 티 나는 뻔한 디자인 — 흰 카드 위 보라색 그라데이션, 템플릿 기본값 같은 것들) 패턴에는 점수를 깎고, 디자인·독창성에 높은 점수를 주도록 기준을 짰습니다. 그러자 모델의 행동이 달라졌습니다. 점수를 더 받으려면 안전하고 뻔한 디자인으로는 안 되고, 평소라면 시도하지 않았을 과감한 색·레이아웃·구성을 꺼내야 했기 때문입니다. 점수가 일종의 보상 역할을 해서, 모델이 익숙한 안전지대를 벗어나 더 모험적인 디자인을 시도하도록 떠밀린 셈입니다.

Explanation (가중치를 어떻게 더 줬을까)

원문은 “design·originality를 더 무겁게 뒀다”고만 하고 몇 점 대 몇 점 같은 배점표는 밝히지 않습니다. 대신 가중치는 평가자에게 주는 채점 기준 문구 자체로 실렸습니다. 두 가지가 핵심이었죠.

  • 약점 영역에 명시적 감점 규칙을 박았다. “AI 슬롭”(흰 카드 위 보라 그라데이션, 템플릿 기본값 등) 패턴이 보이면 점수를 깎으라고 기준에 콕 집어 적었습니다. 독창성 점수를 직접 끌어내리는 장치죠.
  • 기준의 표현에 강도를 실었다. 예컨대 “최고의 디자인은 미술관급 품질이다” 같은 센 문구를 넣자, 그 문구 자체가 결과물을 특정 방향으로 끌고 갔습니다. 원문도 “기준의 표현이 출력의 성격을 직접 빚어냈다”고 말합니다.

즉 여기서 “가중치를 더 준다”는 건 숫자 배점표가 아니라, 점수를 따려면 그쪽에서 잘해야만 하도록 채점 기준의 언어를 설계한 것에 가깝습니다. (참고로 풀스택 단계에서는 “기준마다 통과 임계값”을 둬서, 한 기준이라도 문턱을 못 넘으면 그 작업을 실패 처리하는 방식도 함께 썼습니다 — 통과 문턱을 다르게 두는 것 역시 비중을 다르게 싣는 한 방법입니다.)

그런데 기준만 줘서는 평가자가 같은 디자인을 놓고도 그때그때 다른 점수를 매기거나, 저자의 취향과 어긋나게 채점할 수 있습니다. 그래서 평가자를 소수의 예시(few-shot) 로 보정했습니다.

Definition (few-shot이란)

평가자에게 채점을 시키기 전에 “이런 디자인은 이 정도 점수, 이런 디자인은 저 정도 점수”라는 채점 예시 몇 개를 미리 보여주는 것입니다. 모델은 그 예시를 보고 “아, 이 사람이 말하는 좋은 디자인·나쁜 디자인이 이런 거구나” 하고 채점 감각을 잡습니다. 시험 채점 전에 채점관에게 모범 답안과 점수 견본(채점 기준표)을 먼저 보여주는 것과 같죠.

이때 저자(하네스를 만든 사람 — 원문 글쓴이 Prithvi Rajasekaran)가 평가자(결과물을 채점하는 Claude 에이전트) 에게 예시를 보여줄 때, 단순히 “이건 8점”이라고만 주지 않고 각 기준에서 왜 그 점수가 나왔는지 항목별로 쪼갠 설명(상세한 점수 분해) 까지 함께 줬습니다. 그 덕분에 평가자의 판단이 저자의 취향에 맞춰졌고, 회차를 거듭해도 채점 기준이 흔들리는 것(score drift)이 줄었습니다.

”점수 분해”가 무슨 뜻인지 — 예시로 보기

원문은 실제 예시를 싣지 않았으므로, 아래는 이해를 돕기 위해 제가 구성한 가상의 예시입니다. 같은 결과물(예: 어떤 랜딩 페이지)을 두고 “8점”이라고만 던지는 것과, 각 기준별로 이유까지 쪼개 주는 것의 차이를 보여줍니다.

❌ 그냥 점수만 줄 때

“디자인 8/10.”

→ 평가자(채점하는 Claude)는 “8점이 왜 8점인지” 감을 못 잡습니다. 다음에 비슷한 걸 봐도 7점일지 9점일지 그때그때 달라지기 쉽습니다.

✅ 점수 분해를 함께 줄 때 (few-shot 예시 한 개)

디자인 품질 — 6/10 색·타이포·여백이 따로 노는 느낌. 헤더는 세련됐지만 본문 카드와 무드가 어긋나 “하나의 정체성”으로 안 묶임.

독창성 — 3/10 흰 카드 위 보라색 그라데이션 + 둥근 모서리라는 전형적인 “AI 슬롭” 패턴. 의도적 창작 선택이 안 보임. → 이 기준은 낮게 줄 것.

완성도(craft) — 8/10 타이포 위계·간격·대비는 무난함. 기본기는 합격.

기능성 — 9/10 주요 동작(가입·검색)이 한눈에 보이고 헤매지 않고 끝낼 수 있음.

총평: 기본기(완성도·기능성)는 좋지만 독창성이 발목을 잡는 케이스. 안전한 템플릿 감성을 벗어나야 점수가 오른다.

이렇게 “몇 점인지 + 왜 그 점수인지 + 어떻게 하면 오르는지” 를 묶어 보여주면, 평가자는 저자의 채점 잣대를 그대로 흉내 내게 되고, 다음 채점들도 그 기준에 맞춰 일관돼집니다.

루프는 Claude Agent SDK 위에 만들었습니다. 흐름은 이렇습니다.

Definition (Claude Agent SDK란)

Claude Agent SDK는 Claude를 단순 채팅이 아니라 스스로 도구를 쓰며 일하는 에이전트로 만들 때 쓰는 Anthropic의 개발 키트입니다. 여러 에이전트의 역할을 나누고, 그들이 주고받는 흐름(오케스트레이션 루프)을 짜고, 도구(MCP 등)를 연결하는 일을 직접 밑바닥부터 구현하지 않아도 되게 해줍니다. 이 글의 생성자-평가자 루프도 그 위에서 만들어졌고, 컨텍스트 자동 컴팩션 같은 기능도 SDK가 기본 제공합니다.

  1. 생성자가 사용자 프롬프트를 받아 HTML/CSS/JS 프론트엔드를 만든다.
  2. 평가자는 Playwright MCP로 실제 살아있는 페이지를 직접 돌아다니며 — 스크린샷을 찍고 꼼꼼히 살핀 뒤 — 기준별로 채점하고 상세한 비평을 쓴다.
  3. 그 피드백이 다음 회차 생성자의 입력으로 돌아간다.

회차당 5~15번 반복했고, 평가자가 정적 스크린샷이 아니라 실제로 페이지를 조작했기 때문에 한 사이클에 실제 시간이 꽤 들어 전체 실행이 최대 4시간까지 늘어나기도 했습니다. 생성자에게는 매 평가 후 전략적 판단을 하게 했습니다. 점수가 잘 오르면 그 방향을 다듬고, 안 풀리면 완전히 다른 미감으로 갈아엎으라고요.

네덜란드 미술관 사례

가장 인상적인 예시입니다. “네덜란드 미술관 웹사이트를 만들라”는 프롬프트로 돌렸더니, 9회차에는 깔끔한 다크 테마 랜딩 페이지가 나왔습니다. 잘 만들었지만 예상 범위 안이었죠.

그런데 10회차에서 접근을 통째로 갈아엎었습니다. 사이트를 공간 경험으로 재해석한 겁니다. CSS 원근법으로 그린 체크무늬 바닥의 3D 방, 벽에 자유롭게 걸린 작품들, 스크롤이나 클릭이 아니라 문을 통해 전시실 사이를 이동하는 내비게이션. 단일 패스 생성에서는 본 적 없는 과감한 발상의 전환이었다고 합니다.

흥미로운 부수 효과: 기준에 “최고의 디자인은 미술관급 품질이다” 같은 문구를 넣자 결과물이 특정 시각적 방향으로 수렴했습니다. 기준의 표현 자체가 결과물의 성격을 직접 빚어낸 것이죠.

다만 점수가 늘 깔끔하게 우상향하진 않았습니다. 전체적으로 뒤 회차가 더 나았지만, 중간 회차가 마지막보다 더 마음에 드는 경우도 종종 있었다고 합니다.


풀스택 개발로 확장하기

GAN식 패턴(만드는 쪽과 채점하는 쪽을 따로 두고 서로 주고받으며 품질을 끌어올리는 구조)을 풀스택 개발에 적용합니다. 생성자-평가자 루프는 소프트웨어 개발 흐름에 자연스럽게 맞아떨어집니다. 코드 리뷰와 QA가 디자인 평가자와 똑같은 구조적 역할을 하니까요.

구조는 3-에이전트입니다. 각각이 이전 실험에서 관찰한 구체적 약점을 메웁니다.

  • Planner(기획자) — 예전 하네스는 사용자가 상세 스펙을 직접 줘야 했습니다. 이걸 자동화하려고, 1~4문장짜리 짧은 프롬프트를 받아 완전한 제품 스펙으로 부풀리는 기획자를 뒀습니다. 단, 세세한 기술 구현은 미리 못 박지 말고 제품 맥락과 큰 그림에 집중하게 했습니다. 초반에 기술 디테일을 잘못 박으면 그 오류가 downstream 구현까지 줄줄이 번지기 때문입니다. “무엇을 만들지”만 제약하고 “어떻게”는 작업하며 알아내게 둔 거죠. 또 제품에 AI 기능을 엮을 기회를 찾으라고 시켰습니다.
기획자가 한 문장을 어떻게 부풀리는지 — 실제 예시 (RetroForge)

입력 (사용자가 준 한 문장)

“레벨 에디터, 스프라이트 에디터, 엔티티 동작, 플레이 가능한 테스트 모드를 포함한 2D 레트로 게임 메이커를 만들어라.”

기획자는 이 한 문장을 받아 아래처럼 제품 소개 → 타깃 사용자 → 기능 목록 → 사용자 스토리 → 데이터 모델까지 갖춘 기획서로 키웁니다. (원문 부록의 일부를 발췌·정리한 것입니다.)

RetroForge — 2D 레트로 게임 메이커

개요: 8·16비트 감성의 2D 게임을 코드 없이 만들 수 있는 웹 창작 스튜디오. 네 개의 모듈 — 타일 기반 레벨 에디터, 픽셀아트 스프라이트 에디터, 시각적 엔티티 동작 시스템, 즉시 플레이 테스트 모드 — 을 통합하고, 전 과정에 Claude 기반 AI 보조(스프라이트 생성, 레벨 디자인 등)를 엮는다.

타깃: 레트로 감성을 좋아하지만 현대적 편의를 원하는 창작자.

기능 1. 프로젝트 대시보드 & 관리 모든 작업의 홈 화면. 사용자가 프로젝트를 만들고, 이어서 작업하고, 한눈에 파악할 수 있어야 한다.

사용자 스토리 — 사용자로서 나는:

  • 이름·설명을 붙여 새 프로젝트를 만들 수 있다
  • 기존 프로젝트를 카드 형태(이름·수정일·썸네일)로 한눈에 보고 이어서 작업할 수 있다
  • 프로젝트를 열어 에디터 작업공간에 진입할 수 있다
  • 확인 창과 함께 삭제해 작업공간을 정리할 수 있다
  • 기존 프로젝트를 복제해 재사용할 수 있다

데이터 모델 — 각 프로젝트가 담는 것: 메타데이터(이름·설명·생성/수정 시각), 캔버스 설정(해상도 256×224 등), 타일 크기(8×8/16×16/32×32), 색 팔레트, 그리고 연결된 모든 스프라이트·타일셋·레벨·엔티티 정의.

(… 이런 식으로 기능 2, 3, … 16번까지 이어집니다.)

이렇게 한 줄 → 사용자 스토리와 데이터 모델까지 갖춘 기획서로 부풀려진 덕분에, 뒤따르는 생성자는 “무엇을, 왜 만들어야 하는지”가 명확한 상태에서 작업을 시작할 수 있습니다.

  • Generator(생성자) — 한 번에 기능 하나씩 처리하는 스프린트 방식으로 일하게 했습니다. 각 스프린트는 React + Vite + FastAPI + SQLite(나중엔 PostgreSQL) 스택으로 구현하고, QA에 넘기기 전 스스로 한 번 점검하게 했습니다. 버전 관리를 위한 git도 줬고요.
  • Evaluator(평가자) — 이전 하네스의 앱은 그럴싸해 보여도 막상 써보면 진짜 버그가 있었습니다. 이를 잡으려 평가자에게 Playwright MCP를 줘서, 사용자처럼 앱을 클릭해 보며 UI·API·DB 상태를 점검하게 했습니다. 그리고 발견한 버그와 (제품 깊이·기능성·시각 디자인·코드 품질 같은) 기준으로 각 스프린트를 채점합니다. 기준마다 통과 임계값이 있어서, 하나라도 미달이면 그 스프린트는 실패 처리되고 생성자는 무엇이 잘못됐는지 상세 피드백을 받습니다.

스프린트 계약

Definition (스프린트 계약이란)

코드를 한 줄도 쓰기 전에 생성자(구현)와 평가자(검증)가 “이번 작업에서 ‘완료’가 뭔지”를 미리 합의해 둔 약속입니다. 무엇을 만들지(범위)와 그게 다 됐다고 인정받으려면 어떤 동작이 통과해야 하는지(검증 기준)를 양쪽이 못 박아 둡니다. 공사 시작 전에 시공자와 감리자가 “이번 공정은 여기까지, 이렇게 검사해 합격 처리한다”는 시방서에 서로 합의하는 것에 가깝습니다. 만든 뒤에 “이게 끝난 거냐 아니냐”로 다투지 않도록, 채점 기준을 작업 전에 고정해 두는 장치죠.

각 스프린트 전에 생성자와 평가자는 스프린트 계약(sprint contract) 을 협상했습니다. 코드를 한 줄 쓰기 전에 “이번 작업에서 ‘완료’가 무슨 뜻인지”를 먼저 합의하는 거죠. 제품 스펙이 일부러 큰 그림 수준이라, 사용자 스토리와 테스트 가능한 구현 사이의 간극을 메우는 단계가 필요했습니다. 생성자가 “이걸 이렇게 만들고 이렇게 검증하겠다”를 제안하면 평가자가 검토하고, 둘이 합의할 때까지 주고받습니다.

소통은 전부 파일로 이뤄졌습니다. 한 에이전트가 파일을 쓰면 다른 에이전트가 읽고, 그 파일에 답하거나 새 파일로 응답합니다.


실제로 돌려보기: 레트로 게임 메이커

첫 버전은 Claude Opus 4.5로 돌렸습니다. 비교를 위해 같은 프롬프트를 단일 에이전트(솔로)풀 하네스 양쪽에 줬습니다.

용어

단일 에이전트(솔로): 기획자·평가자 같은 보조 구조 없이, 에이전트 하나에게 프롬프트를 던져 알아서 끝까지 만들게 한 방식입니다. 이 글에서 비교 기준(baseline) 역할을 합니다.

풀 하네스: 이 글에서 만든 Planner(기획) → Generator(구현) → Evaluator(검증) 3-에이전트 구조 전체를 가리킵니다. 같은 한 문장 프롬프트라도 기획자가 스펙으로 부풀리고, 생성자가 만들고, 평가자가 채점·피드백하는 과정을 거칩니다.

프롬프트: “레벨 에디터, 스프라이트 에디터, 엔티티 동작, 플레이 가능한 테스트 모드를 포함한 2D 레트로 게임 메이커를 만들어라.”

하네스실행 시간비용
솔로20분$9
풀 하네스6시간$200

풀 하네스는 20배 이상 비쌌지만, 결과물 품질 차이는 즉시 드러났습니다.

솔로 결과물은 클릭해 보니 문제가 줄줄이 나왔습니다. 고정 높이 패널이 화면 대부분을 비워 공간을 낭비했고, 워크플로가 뻣뻣했으며, 무엇보다 게임 자체가 깨져 있었습니다. 엔티티는 화면에 떴지만 입력에 아무 반응이 없었죠. 엔티티 정의와 게임 런타임 사이 배선이 끊겨 있었습니다.

풀 하네스 결과물은 같은 한 문장 프롬프트에서 출발했습니다. 다만 곧장 만들기 시작하지 않고, 기획자가 그 한 문장을 읽어 “이런 게임 메이커라면 이런 기능들도 있어야 한다”며 구체적인 기획서로 살을 붙였습니다. 그렇게 한 줄짜리 아이디어가 16개 기능을 담은 명세서로 부풀려졌고, 이를 10번의 작업 묶음(스프린트) 으로 나눠 순서대로 만들게 했습니다. 핵심 에디터와 플레이 모드뿐 아니라 스프라이트 애니메이션, 동작 템플릿, 사운드/음악, AI 보조 스프라이트 생성기·레벨 디자이너, 공유 링크가 있는 게임 익스포트까지 포함됐죠. 기획자에게 프론트엔드 디자인 스킬을 줬더니, 그걸 읽고 앱의 시각 디자인 언어까지 스펙에 만들어 넣었습니다.

결과적으로 캔버스가 화면 전체를 쓰고 패널 크기가 합리적이며 일관된 시각 정체성을 갖췄고, 핵심 기능인 “실제로 게임을 플레이”하는 것이 동작했습니다(솔로는 못 했죠). 물리 처리에 캐릭터가 플랫폼과 겹치는 등 거친 부분은 남아 있었지만요.

평가자가 잡아낸 버그들

로그를 보면 평가자가 구현을 스펙에 묶어두는 역할을 톡톡히 했습니다. 스프린트 3은 레벨 에디터 하나에만 27개 기준이 있었고, 평가자의 지적은 추가 조사 없이 바로 고칠 수 있을 만큼 구체적이었습니다.

계약 기준평가자가 찾은 문제
사각형 채우기 도구로 click-drag 하면 선택 영역이 타일로 채워져야 함FAIL — 시작/끝 점에만 타일을 놓음. fillRectangle 함수는 있는데 mouseUp에서 제대로 안 불림
배치된 엔티티 스폰 지점을 선택·삭제할 수 있어야 함FAILLevelEditor.tsx:892의 Delete 핸들러가 selectionselectedEntityId 둘 다 필요. 조건을 selection || (selectedEntityId && activeLayer === 'entity')로 바꿔야 함
API로 애니메이션 프레임 순서를 바꿀 수 있어야 함FAILPUT /frames/reorder 라우트가 /{frame_id} 뒤에 정의됨. FastAPI가 ‘reorder’를 정수 frame_id로 해석해 422 반환

그런데 평가자를 이 수준으로 끌어올리는 데는 품이 들었습니다. 기본 상태의 Claude는 형편없는 QA 담당자였거든요. 초기엔 멀쩡한 문제를 찾아놓고도 “별일 아니네”라며 스스로 통과시키거나, 겉만 훑어 미묘한 버그를 놓쳤습니다. 평가자 로그를 읽어 판단이 저자와 어긋난 지점을 찾고 프롬프트를 고치는 과정을 여러 번 반복하고 나서야 납득할 만한 채점을 했습니다.


하네스를 다이어트하기

첫 결과는 고무적이었지만 무겁고 느리고 비쌌습니다. 다음 단계는 성능을 떨어뜨리지 않으면서 단순화하는 것이었습니다. 여기엔 일반 원칙이 깔려 있습니다.

하네스의 모든 구성 요소는 “모델이 혼자서는 못 하는 것”에 대한 가정을 담고 있습니다. 그 가정은 틀렸을 수도 있고, 모델이 좋아지면 금세 낡습니다. 그러니 “가장 단순한 해법에서 시작해, 필요할 때만 복잡도를 올려라” (Anthropic의 Building Effective Agents).

마침 작업 도중 Opus 4.6 이 나왔습니다. 출시 블로그에 따르면 4.6은 “더 신중하게 계획하고, 에이전트 작업을 더 오래 지속하며, 큰 코드베이스에서 더 안정적이고, 자기 실수를 잡는 코드 리뷰·디버깅 능력이 좋아졌다”고 합니다. 전부 하네스가 보완하려던 능력들이죠.

스프린트 구조를 통째로 제거했습니다. 작업을 잘게 쪼개주던 장치였지만, 4.6이면 그 분해 없이도 모델이 알아서 처리할 만하다고 본 겁니다. (실제로 컨텍스트 불안이 거의 사라져, 이번 하네스에선 컨텍스트 리셋도 빼버리고 한 세션으로 끝까지 돌렸습니다.)

기획자와 평가자는 남겼습니다. 기획자가 없으면 생성자가 스스로 스코프를 작게 잡아 기능이 빈약한 앱을 만들었거든요. 평가자는 스프린트별 채점 대신 실행 끝의 단일 패스로 옮겼습니다.

여기서 중요한 통찰이 나옵니다.

평가자는 켜고 끄는 고정값이 아니다. 그 가치는 작업이 “지금 모델이 혼자 안정적으로 해내는 범위”에서 얼마나 벗어났느냐에 달렸다.

4.5에서는 그 경계가 가까워서 평가자가 거의 모든 빌드에서 의미 있는 문제를 잡았습니다. 4.6에서는 모델의 맨몸 능력이 올라 경계가 바깥으로 밀렸고, 경계 안쪽 작업에서는 평가자가 불필요한 오버헤드가 됐습니다. 하지만 여전히 모델 능력의 가장자리에 있는 부분에서는 평가자가 진짜 도움을 줬습니다.


개선된 하네스 결과: 브라우저 DAW

업데이트한 하네스를 시험하려고 DAW(디지털 오디오 워크스테이션), 즉 작곡·녹음·믹싱용 음악 제작 프로그램을 만들게 했습니다.

여기서 “업데이트한 하네스” 란 앞 절에서 다이어트한 버전을 말합니다. 정리하면, 첫 버전(레트로 게임 메이커)에서 이렇게 바뀌었습니다.

  • 모델: Opus 4.5 → Opus 4.6 로 교체
  • 스프린트 구조: 제거 — 4.6이면 작업을 잘게 쪼개주지 않아도 알아서 일관되게 처리하므로
  • 컨텍스트 리셋: 제거 — 4.6은 컨텍스트 불안이 거의 사라져, 통째로 비우고 새로 시작할 필요 없이 한 세션으로 끝까지 돌림
  • 평가자(QA): 스프린트(한 번에 기능 하나씩 처리하는 작업 묶음 — 앞서 생성자가 일하던 단위)마다 채점하던 것을, 작업을 다 끝낸 뒤 한 번에 몰아서 검사하는 “실행 끝의 단일 패스” 로 옮김
  • 기획자·평가자: 여전히 값을 하므로 그대로 유지
  • 앱 내 AI 기능 프롬프트 보강: 원문 표현을 그대로 옮기면 — “구조적 단순화와 함께, 하네스가 각 앱에 AI 기능을 더 잘 만들어 넣도록 프롬프트도 보강했다. 구체적으로는 생성자가 도구(tool)를 통해 앱 자체의 기능을 구동할 수 있는 제대로 된 에이전트를 만들도록 했다. 관련 지식이 비교적 최신이라 Claude의 학습 데이터에 얇게만 담겨 있어 상당한 반복 튜닝이 필요했지만, 충분히 다듬자 생성자가 에이전트를 올바르게 만들어냈다.” (원문: “getting the generator to build a proper agent that could drive the app’s own functionality through tools … the relevant knowledge is recent enough that Claude’s training data covers it thinly.”)

한마디로 “모델이 4.6으로 좋아진 만큼, 이제 모델이 알아서 하는 부분(스프린트 분해·컨텍스트 리셋)을 떼어내 슬림하게 만든 버전” 입니다.

프롬프트: “Web Audio API를 써서 브라우저에서 완전한 기능의 DAW를 만들어라.”

여전히 길고 비쌌습니다 — 약 4시간, 토큰 비용 $124.70. 대부분의 시간은 빌더가 썼고, 스프린트 분해 없이 2시간 넘게 일관되게 돌았습니다.

여기서 “스프린트 분해 없이 돌았다” 는 건, 예전처럼 작업을 기능 하나씩(스프린트) 으로 쪼개 끊어가며 시키지 않고, 생성자가 한 번에 통으로 2시간 넘게 쉬지 않고 빌드를 이어갔다는 뜻입니다. 4.5 때는 길게 두면 중간에 길을 잃어서 스프린트로 잘게 끊어줘야 했는데, 4.6은 그 받침(스프린트) 없이도 긴 시간 동안 방향을 잃지 않고 일관되게 작업했다는 것이죠.

에이전트 & 단계시간비용
Planner4.7분$0.46
Build (1회차)2시간 7분$71.08
QA (1회차)8.8분$3.24
Build (2회차)1시간 2분$36.89
QA (2회차)6.8분$3.09
Build (3회차)10.9분$5.88
QA (3회차)9.6분$4.06
합계3시간 50분$124.70

평가자(QA)는 여기서도 실제 빈틈을 잡았습니다. 1회차 피드백은 이랬습니다.

디자인 완성도, AI 에이전트, 백엔드 모두 훌륭한 강력한 앱. 가장 큰 실패 지점은 기능 완전성 — 앱은 인상적이고 AI 통합도 잘 되지만, 여러 핵심 DAW 기능이 보여주기만 하고 상호작용 깊이가 없음. 클립을 타임라인에서 드래그/이동할 수 없고, 악기 UI 패널(신스 노브, 드럼 패드)이 없고, EQ 곡선·컴프레서 미터 같은 시각적 이펙트 에디터가 없음. 이건 엣지 케이스가 아니라 DAW를 쓸 만하게 만드는 핵심 상호작용이고, 스펙에 명시돼 있음.

2회차에서도 녹음이 stub뿐, 클립 가장자리 드래그/분할 미구현, 이펙트가 그래프가 아닌 숫자 슬라이더 등 미완성 기능을 짚었습니다. 혼자 두면 생성자는 여전히 디테일을 놓치거나 기능을 stub로 때우기 쉬웠고, QA가 그 마지막 1마일을 잡아준 셈입니다.

최종 앱은 전문 음악 프로그램과는 거리가 멀고, Claude는 소리를 실제로 들을 수 없어 음악적 취향 측면에서 피드백 루프의 효과가 떨어졌습니다. 그래도 동작하는 편곡 뷰·믹서·트랜스포트가 브라우저에서 돌았고, 저자는 프롬프트만으로 짧은 곡 한 토막을 만들 수 있었습니다. 에이전트가 템포·키를 잡고, 멜로디를 깔고, 드럼 트랙을 짜고, 믹서 레벨을 조정하고, 리버브를 더하는 식으로요.


앞으로

모델이 좋아질수록 대략 더 오래, 더 복잡한 작업을 해낼 겁니다. 어떤 경우엔 모델을 둘러싼 **스캐폴드(scaffold — 모델 혼자선 약한 부분을 받쳐주려고 바깥에 덧댄 보조 장치. 여기서는 기획자·평가자·스프린트 같은 하네스 구성 요소를 가리킵니다. 건물을 지을 때 임시로 세웠다가 완성되면 걷어내는 비계(飛階)에 빗댄 말이죠)**의 중요성이 줄어, 다음 모델을 기다리면 문제가 저절로 풀리기도 할 겁니다. 반대로 모델이 좋아질수록 맨몸 모델로는 불가능한 복잡한 작업을 해내는 하네스를 만들 공간도 그만큼 넓어집니다.

저자가 남긴 교훈은 이렇습니다.

  • 직접 만들 대상 모델로 실험하고, 실제 문제에서 트레이스(실행 기록)를 읽고, 원하는 결과가 나오도록 튜닝하라.
  • 복잡한 작업은 쪼개고, 각 측면에 전문 에이전트를 붙이면 여유가 생길 때가 있다.
  • 새 모델이 나오면 하네스를 다시 점검해, 더 이상 성능에 기여하지 않는 부품은 떼어내고 새로 가능해진 능력을 위한 부품을 더하라.

그리고 한 문장으로 요약되는 결론:

흥미로운 하네스 조합의 공간은 모델이 좋아진다고 줄어들지 않는다. 다만 이동할 뿐이다. AI 엔지니어가 할 흥미로운 일은 계속해서 그다음의 새로운 조합을 찾아내는 것이다.