생성기와 평가기, 그리고 기획자를 결합한 다중 에이전트 하니스가 장시간 자율 코딩과 고품질 애플리케이션 개발 성능을 어떻게 끌어올렸는지 설명합니다.
Anthropic Labs 팀의 Prithvi Rajasekaran이 작성했습니다.
지난 몇 달 동안 저는 서로 연결된 두 가지 문제를 다뤄 왔습니다. 하나는 Claude가 고품질 프런트엔드 디자인을 만들어 내도록 하는 것이고, 다른 하나는 사람의 개입 없이 완전한 애플리케이션을 구축하도록 하는 것이었습니다. 이 작업은 이전의 프런트엔드 디자인 스킬과 장시간 실행 코딩 에이전트 하니스에 대한 노력에서 출발했습니다. 당시 동료들과 저는 프롬프트 엔지니어링과 하니스 설계를 통해 Claude의 성능을 기준선보다 훨씬 높일 수 있었지만, 두 접근 모두 결국 한계에 부딪혔습니다.
이 한계를 돌파하기 위해 저는 상당히 다른 두 영역 모두에 적용될 수 있는 새로운 AI 엔지니어링 접근을 찾았습니다. 하나는 주관적 취향으로 정의되고, 다른 하나는 검증 가능한 정확성과 사용성으로 정의되는 영역입니다. 생성적 적대 신경망 (GANs)에서 영감을 받아, 저는 생성기 에이전트와 평가기 에이전트로 이루어진 멀티에이전트 구조를 설계했습니다. 결과물을 신뢰성 있게—그리고 안목 있게—채점하는 평가기를 만들기 위해서는, 먼저 “이 디자인이 좋은가?” 같은 주관적 판단을 구체적이고 채점 가능한 기준으로 바꾸는 작업이 필요했습니다.
그다음 저는 이러한 기법을 장시간 자율 코딩에 적용했고, 이전 하니스 작업에서 얻은 두 가지 교훈을 이어받았습니다. 즉, 빌드를 다루기 쉬운 단위로 분해하는 것, 그리고 세션 간 맥락을 넘겨주기 위해 구조화된 산출물을 사용하는 것이었습니다. 최종 결과는 기획자, 생성기, 평가기로 이루어진 3에이전트 아키텍처였고, 이는 여러 시간에 걸친 자율 코딩 세션 동안 풍부한 풀스택 애플리케이션을 만들어 냈습니다.
우리는 이전에 하니스 설계가 장시간 실행되는 에이전트형 코딩의 효과에 상당한 영향을 미친다는 점을 보여준 바 있습니다. 이전 실험에서는 초기화 에이전트를 사용해 제품 명세를 작업 목록으로 분해하고, 코딩 에이전트가 한 번에 하나의 기능씩 구현한 뒤 세션 간 맥락을 전달할 산출물을 넘겨주도록 했습니다. 더 넓은 개발자 커뮤니티도 비슷한 통찰에 수렴해 왔으며, 훅이나 스크립트를 사용해 에이전트를 지속적인 반복 주기에 두는 "Ralph Wiggum" 방식 같은 접근도 등장했습니다.
하지만 몇몇 문제는 계속 남아 있었습니다. 더 복잡한 작업에서는 에이전트가 시간이 지날수록 여전히 궤도를 이탈하는 경향이 있었습니다. 이 문제를 분해해 보면서, 우리는 이런 종류의 작업을 수행하는 에이전트에서 두 가지 공통적인 실패 양상을 관찰했습니다.
첫째는 맥락 창이 차오르면서 모델이 장문의 작업에서 일관성을 잃는 경향입니다. 이에 대해서는 컨텍스트 엔지니어링 글에서도 다뤘습니다. 일부 모델은 이른바 "컨텍스트 불안"도 보이는데, 스스로 생각하는 맥락 한계에 가까워질수록 작업을 너무 일찍 마무리하려 합니다. 컨텍스트 리셋—즉, 맥락 창을 완전히 비우고 새 에이전트를 시작하되, 이전 에이전트의 상태와 다음 단계가 담긴 구조화된 인계 자료를 함께 넘기는 방식—은 이 두 문제를 모두 해결합니다.
이 방식은 압축과는 다릅니다. 압축에서는 같은 에이전트가 짧아진 이력을 바탕으로 계속 작업할 수 있도록 대화의 앞부분을 그 자리에서 요약합니다. 압축은 연속성을 유지하지만, 에이전트에 완전히 새로운 출발점을 주지는 않기 때문에 컨텍스트 불안이 여전히 남을 수 있습니다. 반면 리셋은 깨끗한 출발점을 제공하지만, 다음 에이전트가 작업을 무리 없이 이어받을 수 있을 만큼 인계 산출물에 충분한 상태가 담겨 있어야 하는 비용이 따릅니다. 이전 테스트에서 우리는 Claude Sonnet 4.5가 컨텍스트 불안을 충분히 강하게 보여 압축만으로는 장시간 작업 성능을 충분히 끌어올릴 수 없다는 점을 확인했고, 그래서 컨텍스트 리셋이 하니스 설계의 핵심 요소가 되었습니다. 이는 핵심 문제를 해결하지만, 각 하니스 실행마다 오케스트레이션 복잡성, 토큰 오버헤드, 지연 시간이라는 비용을 추가합니다.
두 번째 문제는 우리가 이전에는 다루지 않았던 자기 평가입니다. 에이전트에게 자신이 만든 작업을 평가하라고 하면, 사람 눈에는 품질이 분명 평범해 보여도 자신 있게 칭찬하는 식으로 반응하는 경향이 있습니다. 이 문제는 디자인처럼 주관적인 작업에서 특히 두드러집니다. 검증 가능한 소프트웨어 테스트에 해당하는 이진 검사 수단이 없기 때문입니다. 어떤 레이아웃이 세련되게 느껴지는지 아니면 평범하게 느껴지는지는 판단의 문제이며, 에이전트는 자신의 작업을 채점할 때 일관되게 후한 점수를 주는 쪽으로 치우칩니다.
하지만 검증 가능한 결과가 있는 작업에서도, 에이전트는 작업을 완수하는 과정에서 성능을 저해하는 좋지 않은 판단을 보일 때가 있습니다. 실제 작업을 수행하는 에이전트와 그것을 판단하는 에이전트를 분리하는 것은 이 문제를 해결하는 강력한 지렛대가 됩니다. 물론 분리만으로 이런 관대함이 즉시 사라지지는 않습니다. 평가기 역시 LLM이며, LLM이 만든 결과물에 후하게 점수를 주려는 성향이 있기 때문입니다. 하지만 독립적인 평가기를 회의적으로 튜닝하는 일은, 생성기가 자기 작업을 비판적으로 보도록 만드는 일보다 훨씬 다루기 쉬운 것으로 드러났습니다. 그리고 일단 외부 피드백이 생기면, 생성기는 그 피드백을 바탕으로 구체적으로 반복 개선할 수 있게 됩니다.
저는 먼저 프런트엔드 디자인에서 실험을 시작했습니다. 자기 평가 문제가 가장 눈에 띄는 영역이었기 때문입니다. 별다른 개입이 없으면 Claude는 대개 안전하고 예측 가능한 레이아웃으로 기울며, 기술적으로는 작동하지만 시각적으로는 두드러지지 않는 결과물을 만드는 경향이 있었습니다.
프런트엔드 디자인용으로 제가 만든 하니스는 두 가지 통찰에서 출발했습니다. 첫째, 미적 감각은 점수 하나로 완전히 환원될 수 없고 개인 취향도 늘 다르겠지만, 디자인 원칙과 선호를 담은 채점 기준을 통해 개선될 수 있다는 점입니다. "이 디자인이 아름다운가?"는 일관되게 답하기 어렵지만, "이것이 우리의 좋은 디자인 원칙을 따르는가?"는 Claude가 기준을 가지고 채점할 수 있게 해 줍니다. 둘째, 프런트엔드 생성과 프런트엔드 채점을 분리하면, 생성기를 더 강한 결과물로 이끄는 피드백 루프를 만들 수 있다는 점입니다.
이를 바탕으로 저는 생성기와 평가기 에이전트 모두의 프롬프트에 넣을 네 가지 채점 기준을 작성했습니다.
저는 완성도와 기능성보다 디자인 품질과 독창성을 더 강조했습니다. Claude는 이미 기본적으로 완성도와 기능성에서는 높은 점수를 받는 편이었고, 필요한 기술적 역량이 모델에 자연스럽게 내재되어 있었기 때문입니다. 그러나 디자인과 독창성 면에서 Claude는 종종 밋밋한 결과물을 냈습니다. 그래서 기준에 매우 일반적인 "AI 슬롭" 패턴에 대한 명시적 감점을 포함했고, 디자인과 독창성에 더 큰 가중치를 두어 모델이 미적으로 더 과감한 시도를 하도록 밀어주었습니다.
저는 자세한 점수 분해가 포함된 퓨샷 예시로 평가기를 보정했습니다. 이를 통해 평가기의 판단이 제 선호와 정렬되도록 했고, 반복 과정에서 점수가 표류하는 현상도 줄였습니다.
이 루프는 Claude Agent SDK 위에 구축했고, 덕분에 오케스트레이션은 비교적 단순하게 유지할 수 있었습니다. 생성기 에이전트는 먼저 사용자 프롬프트를 바탕으로 HTML/CSS/JS 프런트엔드를 만들었습니다. 저는 평가기에 Playwright MCP를 제공했고, 덕분에 평가기는 각 기준에 점수를 매기고 자세한 비평을 작성하기 전에 라이브 페이지와 직접 상호작용할 수 있었습니다. 실제로 평가기는 스스로 페이지를 돌아다니며 스크린샷을 찍고 구현을 꼼꼼히 살핀 뒤 평가를 내렸습니다. 이 피드백은 다음 반복의 입력으로 다시 생성기에 전달되었습니다. 저는 생성당 5회에서 15회까지 반복을 돌렸고, 각 반복은 대체로 평가기의 비평에 반응하면서 생성기를 점점 더 독특한 방향으로 밀어갔습니다. 평가기가 정적인 스크린샷이 아니라 실제 페이지를 탐색하며 채점했기 때문에 각 주기는 실제 벽시계 시간으로도 오래 걸렸습니다. 전체 실행은 최대 4시간까지 늘어났습니다. 또한 각 평가 뒤에 생성기가 전략적 결정을 내리도록 지시했습니다. 점수 추세가 좋으면 현재 방향을 다듬고, 접근이 잘 먹히지 않으면 미학적 방향 자체를 완전히 전환하도록 했습니다.
여러 번의 실행에 걸쳐 평가기의 평가는 반복이 진행될수록 개선되다가 어느 지점에서 정체되었고, 여전히 더 나아질 여지는 남아 있었습니다. 어떤 생성은 점진적으로 다듬어졌고, 어떤 생성은 반복 사이에 미학적으로 급격한 전환을 보였습니다.
기준의 문구는 제가 완전히 예상하지 못한 방식으로 생성기를 유도했습니다. 예를 들어 "최고의 디자인은 박물관 급이어야 한다" 같은 표현을 포함하자, 디자인이 특정한 시각적 수렴점으로 몰리는 경향이 나타났습니다. 이는 기준과 연결된 프롬프트 문구가 결과물의 성격을 직접 형성한다는 점을 시사했습니다.
점수는 대체로 반복에 따라 올라갔지만, 그 패턴이 항상 깔끔하게 선형적이진 않았습니다. 후반 구현이 전체적으로 더 나은 경향은 있었지만, 마지막 반복보다 중간 반복이 더 마음에 드는 경우도 자주 보았습니다. 구현 복잡성도 대체로 반복이 진행될수록 증가했고, 생성기는 평가기의 피드백에 반응해 더 야심찬 해법을 시도했습니다. 첫 반복만 보더라도 아무 프롬프트도 주지 않은 기준선보다 눈에 띄게 더 나은 결과를 냈는데, 이는 기준과 그에 연결된 언어 자체가 평가기 피드백 이전부터 모델을 일반적인 기본값에서 벗어나게 유도했음을 시사합니다.
특히 눈에 띄는 한 사례에서 저는 모델에게 네덜란드 미술관 웹사이트를 만들라고 요청했습니다. 아홉 번째 반복에서 모델은 가상의 미술관을 위한 깔끔한 다크 테마 랜딩 페이지를 만들었습니다. 시각적으로는 세련되었지만 대체로 제 예상 범위 안에 있는 결과였습니다. 그런데 열 번째 주기에서 모델은 그 접근을 완전히 버리고 사이트를 공간적 경험으로 재구상했습니다. CSS 원근법으로 렌더링한 체크무늬 바닥의 3D 방, 벽에 자유로운 위치로 걸린 작품들, 스크롤이나 클릭 대신 문을 통해 갤러리 방 사이를 이동하는 방식이었습니다. 단일 패스 생성에서는 이전에 보지 못했던 창의적 도약이었습니다.
이러한 결과를 바탕으로, 저는 이 GAN에서 영감을 받은 패턴을 풀스택 개발에 적용했습니다. 생성기-평가기 루프는 소프트웨어 개발 생명주기에 자연스럽게 대응되며, 여기서 코드 리뷰와 QA가 디자인 평가기와 같은 구조적 역할을 수행합니다.
이전 장시간 실행 하니스에서는 초기화 에이전트, 한 번에 하나의 기능씩 작업하는 코딩 에이전트, 그리고 세션 사이의 컨텍스트 리셋을 통해 일관된 다중 세션 코딩 문제를 해결했습니다. 컨텍스트 리셋은 핵심적인 돌파구였습니다. 하니스는 Sonnet 4.5를 사용했는데, 앞서 언급한 "컨텍스트 불안" 성향을 보였습니다. 따라서 컨텍스트 리셋을 가로질러도 잘 작동하는 하니스를 만드는 것이 모델이 작업에서 벗어나지 않게 하는 핵심이었습니다. Opus 4.5는 이 행동을 대체로 스스로 제거했기 때문에, 저는 이번 하니스에서는 컨텍스트 리셋을 완전히 제거할 수 있었습니다. 에이전트들은 전체 빌드 동안 하나의 연속 세션으로 실행되었고, Claude Agent SDK의 자동 압축이 그 과정에서 맥락 증가를 처리했습니다.
이번 작업에서는 원래 하니스의 기반 위에 3에이전트 시스템을 구축했습니다. 각 에이전트는 이전 실행에서 제가 관찰한 특정한 공백을 메우도록 설계되었습니다. 시스템에는 다음과 같은 에이전트 페르소나가 포함되었습니다.
기획자: 이전 장시간 실행 하니스에서는 사용자가 처음부터 자세한 명세를 제공해야 했습니다. 저는 그 단계를 자동화하고 싶었고, 그래서 1~4문장 정도의 짧은 프롬프트를 받아 완전한 제품 명세로 확장하는 기획자 에이전트를 만들었습니다. 저는 이 에이전트가 범위 면에서 야심차게 계획하되, 세부 기술 구현보다는 제품 맥락과 높은 수준의 기술 설계에 집중하도록 프롬프트를 작성했습니다. 이는 기획자가 처음부터 세세한 기술 사항을 규정하려다가 틀린 내용을 넣으면, 그 오류가 이후 구현 전반으로 연쇄 확산될 수 있다는 우려 때문이었습니다. 만들어야 할 산출물에 대해서만 에이전트를 제약하고, 실제 경로는 작업하면서 스스로 찾게 두는 편이 더 현명해 보였습니다. 또한 기획자에게 제품 명세 안에 AI 기능을 녹여 넣을 기회를 찾으라고 요청했습니다. 아래 Appendix에 예시가 있습니다.
생성기: 이전 하니스의 한 번에 하나의 기능씩 접근하는 방식은 범위 관리에 효과적이었습니다. 여기서도 비슷한 모델을 적용해, 생성기가 스프린트 단위로 작업하며 명세에서 한 번에 하나의 기능을 집어 들고 구현하도록 지시했습니다. 각 스프린트는 React, Vite, FastAPI, SQLite(이후 PostgreSQL) 스택으로 앱을 구현했고, 생성기는 각 스프린트의 끝에서 자기 평가를 수행한 뒤 QA로 넘기도록 지시받았습니다. 또한 버전 관리를 위해 git도 사용할 수 있었습니다.
평가기: 이전 하니스에서 나온 애플리케이션은 겉보기엔 인상적이었지만, 실제로 써보면 여전히 버그가 있곤 했습니다. 이를 잡아내기 위해 평가기는 Playwright MCP를 사용해 실제 사용자처럼 실행 중인 애플리케이션을 클릭하며 UI 기능, API 엔드포인트, 데이터베이스 상태를 테스트했습니다. 그런 다음 프런트엔드 실험을 바탕으로 모델링한 일련의 기준—여기서는 제품 깊이, 기능성, 시각 디자인, 코드 품질을 다루도록 조정된 기준—에 따라 각 스프린트를 채점했습니다. 각 기준에는 엄격한 임계값이 있었고, 하나라도 그 아래로 떨어지면 스프린트는 실패 처리되었으며 생성기는 무엇이 잘못되었는지에 대한 자세한 피드백을 받았습니다.
각 스프린트 전에 생성기와 평가기는 스프린트 계약을 협상했습니다. 즉, 코드를 쓰기 전에 그 작업 덩어리에서 무엇이 "완료"를 의미하는지 합의하는 절차였습니다. 제품 명세를 의도적으로 높은 수준에 머물게 했기 때문에, 사용자 스토리와 테스트 가능한 구현 사이의 간극을 메우는 단계가 필요했습니다. 생성기는 무엇을 만들 것인지, 성공 여부를 어떻게 검증할 것인지 제안했고, 평가기는 그 제안을 검토해 생성기가 올바른 것을 만들고 있는지 확인했습니다. 둘은 합의에 도달할 때까지 반복했습니다.
의사소통은 파일을 통해 이루어졌습니다. 한 에이전트가 파일을 쓰면, 다른 에이전트가 그 파일을 읽고 같은 파일 안에 답하거나 새로운 파일을 만들어 응답했고, 이전 에이전트는 그것을 다시 읽는 식이었습니다. 그런 뒤 생성기는 합의된 계약에 맞춰 구현을 진행하고 QA에 작업을 넘겼습니다. 이 방식은 너무 이른 시점에 구현을 과도하게 명세하지 않으면서도 작업이 명세에 충실하도록 유지해 주었습니다.
이 하니스의 첫 번째 버전에서는 Claude Opus 4.5를 사용했고, 비교를 위해 사용자 프롬프트를 전체 하니스와 단일 에이전트 시스템 양쪽에 모두 실행했습니다. 이 실험을 시작했을 때 Opus 4.5가 우리의 최고 코딩 모델이었기 때문에 이를 사용했습니다.
저는 다음과 같은 프롬프트를 작성해 레트로 비디오 게임 제작기를 만들었습니다.
레벨 에디터, 스프라이트 에디터, 엔티티 행동, 플레이 가능한 테스트 모드를 포함한 기능을 갖춘 2D 레트로 게임 제작기를 만들어 주세요.
아래 표는 하니스 유형, 실행 시간, 총비용을 보여줍니다.
| 하니스 | 기간 | 비용 |
|---|---|---|
| 단독 | 20분 | $9 |
| 전체 하니스 | 6시간 | $200 |
하니스는 20배 이상 비쌌지만, 결과물의 품질 차이는 즉시 분명하게 드러났습니다.
제가 기대한 것은 레벨과 그 구성 요소들(스프라이트, 엔티티, 타일 배치)을 구성한 뒤 play를 눌러 실제로 레벨을 플레이할 수 있는 인터페이스였습니다. 먼저 단독 실행의 결과물을 열어 보았고, 초기 애플리케이션은 그런 기대에 부합하는 듯 보였습니다.
하지만 클릭해 가며 살펴보자 문제가 드러나기 시작했습니다. 레이아웃은 공간을 낭비했고, 고정 높이 패널 때문에 뷰포트 대부분이 비어 있었습니다. 작업 흐름도 경직되어 있었습니다. 레벨을 채우려고 하면 먼저 스프라이트와 엔티티를 만들라는 요구가 나왔지만, UI 어디에도 그 순서를 안내하는 부분이 없었습니다. 더 중요한 점은 실제 게임이 고장 나 있었다는 것입니다. 제 엔티티는 화면에 나타났지만 입력에 아무 반응도 하지 않았습니다. 코드를 파고들어 보니 엔티티 정의와 게임 런타임 사이의 연결이 깨져 있었고, 어디가 문제인지 겉으로는 전혀 드러나지 않았습니다.
단독 실행을 평가한 뒤, 저는 하니스 실행 결과로 시선을 돌렸습니다. 이 실행은 같은 한 문장 프롬프트에서 시작했지만, 기획 단계가 그것을 10개의 스프린트에 걸친 16개 기능 명세로 확장했습니다. 이는 단독 실행이 시도한 범위를 훨씬 넘어섰습니다. 핵심 에디터와 플레이 모드뿐 아니라, 명세에는 스프라이트 애니메이션 시스템, 행동 템플릿, 효과음과 음악, AI 지원 스프라이트 생성기와 레벨 디자이너, 공유 가능한 링크를 갖춘 게임 내보내기 기능까지 포함되어 있었습니다. 저는 기획자에게 우리의 프런트엔드 디자인 스킬에 대한 접근 권한을 주었고, 기획자는 이를 읽고 명세의 일부로 앱의 시각 디자인 언어를 만들었습니다. 각 스프린트마다 생성기와 평가기는 그 스프린트의 구체적 구현 세부 사항과 완료 검증을 위해 테스트할 동작을 정의하는 계약을 협상했습니다.
앱은 단독 실행보다 훨씬 더 다듬어지고 매끄럽게 보였습니다. 캔버스는 전체 뷰포트를 활용했고, 패널 크기도 합리적이었으며, 인터페이스는 명세의 디자인 방향을 따라가는 일관된 시각 정체성을 갖고 있었습니다. 단독 실행에서 보았던 어색함 일부는 여전히 남아 있었습니다. 예를 들어 레벨을 채우기 전에 먼저 스프라이트와 엔티티를 만들어야 한다는 점이 작업 흐름에서 여전히 분명하지 않았고, 저는 이것저것 눌러 보며 그 사실을 알아내야 했습니다. 이는 하니스가 해결하도록 설계된 문제라기보다 기본 모델의 제품 직관의 공백처럼 보였지만, 동시에 하니스 내부에서 표적화된 반복을 통해 결과 품질을 더 높일 수 있는 지점도 시사했습니다.
에디터들을 실제로 사용해 볼수록, 새 실행의 장점은 단독 대비 더 분명해졌습니다. 스프라이트 에디터는 더 풍부하고 완성도가 높았고, 도구 팔레트는 더 깔끔했으며, 색상 선택기는 더 좋았고, 확대 제어도 더 사용하기 쉬웠습니다.
또한 저는 기획자에게 명세 안에 AI 기능을 녹여 넣으라고 요청했기 때문에, 앱에는 프롬프트를 통해 게임의 다양한 부분을 생성할 수 있는 Claude 통합 기능도 내장되어 있었습니다. 이는 작업 흐름을 크게 가속했습니다.
가장 큰 차이는 플레이 모드였습니다. 저는 실제로 제 엔티티를 움직여 게임을 플레이할 수 있었습니다. 물리 시스템에는 다소 거친 부분이 있었습니다. 예를 들어 캐릭터가 플랫폼 위로 점프했지만 그 위에 겹쳐지는 현상이 있었고, 이는 직관적으로 어색하게 느껴졌습니다. 그래도 핵심적인 부분은 작동했고, 단독 실행은 그조차 해내지 못했습니다. 잠시 움직여 본 뒤에는 AI의 게임 레벨 구성 능력에도 몇 가지 한계를 발견했습니다. 제가 뛰어넘을 수 없는 큰 벽이 있어 거기에 갇혀 버렸습니다. 이는 하니스가 상식적인 개선과 경계 사례를 더 다뤄 앱을 한층 정제할 수 있음을 시사했습니다.
로그를 읽어보면 평가기가 구현을 명세에 맞게 유지했다는 점이 분명했습니다. 각 스프린트마다 평가기는 스프린트 계약의 테스트 기준을 따라가며 Playwright를 통해 실행 중인 애플리케이션을 실제로 조작했고, 예상 동작에서 벗어나는 모든 것에 대해 버그를 제기했습니다. 계약은 세밀했습니다. 예를 들어 스프린트 3만 해도 레벨 에디터를 다루는 27개의 기준이 있었습니다. 또한 평가기의 발견 사항은 추가 조사 없이도 바로 조치할 수 있을 만큼 구체적이었습니다. 아래 표는 우리 평가기가 찾아낸 문제의 몇 가지 예시를 보여 줍니다.
| 계약 기준 | 평가기 발견 사항 |
|---|---|
| 사각형 채우기 도구는 클릭-드래그로 선택한 타일을 직사각형 영역에 채울 수 있어야 함 | 실패 — 도구가 영역을 채우지 않고 드래그 시작점과 끝점에만 타일을 배치함. fillRectangle 함수는 존재하지만 mouseUp에서 제대로 호출되지 않음. |
| 사용자는 배치된 엔티티 생성 지점을 선택하고 삭제할 수 있어야 함 | 실패 — LevelEditor.tsx:892의 Delete 키 핸들러는 selection과 selectedEntityId가 둘 다 설정되어 있어야 작동하지만, 엔티티를 클릭하면 selectedEntityId만 설정됨. 조건은 `selection |
| 사용자는 API를 통해 애니메이션 프레임 순서를 재정렬할 수 있어야 함 | 실패 — PUT /frames/reorder 경로가 /{frame_id} 경로들 뒤에 정의되어 있음. FastAPI가 'reorder'를 frame_id 정수로 매칭하려 하여 422를 반환함: "unable to parse string as an integer." |
평가기의 성능을 이 수준까지 끌어올리는 데는 노력이 필요했습니다. 기본 상태의 Claude는 좋은 QA 에이전트가 아닙니다. 초기 실행에서는 정당한 문제를 찾아놓고도, 스스로 그것이 큰 문제가 아니라고 설득한 뒤 작업을 승인해 버리는 모습을 보았습니다. 또한 경계 사례를 집요하게 파고들기보다 피상적으로 테스트하는 경향이 있어, 더 미묘한 버그가 자주 빠져나갔습니다. 튜닝 루프는 평가기 로그를 읽고, 그 판단이 제 판단과 어긋나는 사례를 찾은 뒤, 그런 문제를 해결하도록 QA 프롬프트를 업데이트하는 방식이었습니다. 평가기가 제가 납득할 만한 방식으로 채점하기까지 이 개발 루프를 여러 차례 돌려야 했습니다. 그럼에도 하니스 결과물은 모델의 QA 능력 한계를 보여 주었습니다. 작은 레이아웃 문제, 곳곳에서 직관적이지 않게 느껴지는 상호작용, 평가기가 깊이 있게 실행해 보지 않은 더 안쪽 기능에 숨어 있는 버그들이 남아 있었습니다. 추가 튜닝으로 확보할 수 있는 검증 여지는 분명히 더 있었습니다. 하지만 애플리케이션의 핵심 기능이 아예 작동하지 않았던 단독 실행과 비교하면, 개선 폭은 분명했습니다.
첫 번째 하니스 결과는 고무적이었지만, 동시에 덩치가 크고 느리며 비쌌습니다. 다음으로 논리적인 단계는 성능을 떨어뜨리지 않으면서 하니스를 단순화할 방법을 찾는 것이었습니다. 이는 일부는 상식의 문제였고, 일부는 더 일반적인 원칙의 문제였습니다. 하니스의 각 구성 요소는 모델이 스스로는 못 할 것이라는 어떤 가정을 담고 있고, 그 가정은 반드시 스트레스 테스트해 볼 가치가 있습니다. 가정이 틀렸을 수도 있고, 모델이 발전함에 따라 금방 낡아질 수도 있기 때문입니다. 우리의 블로그 글 효과적인 에이전트 구축하기는 이 기본 아이디어를 "가능한 가장 단순한 해법을 찾고, 필요할 때만 복잡성을 늘려라"라고 설명하며, 이는 에이전트 하니스를 유지하는 사람이라면 일관되게 마주치는 패턴입니다.
처음 단순화를 시도했을 때, 저는 하니스를 대폭 줄이고 몇 가지 창의적인 새 아이디어를 시도했지만 원래 하니스의 성능을 재현하지 못했습니다. 또한 하니스 설계의 어떤 부분이 실제로 하중을 떠받치고 있었는지, 그리고 어떤 방식으로 그 역할을 하는지 파악하기도 어려워졌습니다. 그 경험을 바탕으로, 저는 한 번에 한 구성 요소씩 제거하고 최종 결과에 어떤 영향을 미치는지 검토하는 보다 체계적인 접근으로 옮겨 갔습니다.
이러한 반복 주기를 거치는 동안 Opus 4.6도 출시되었고, 이는 하니스 복잡성을 줄일 추가적인 동기를 제공했습니다. 4.6이 4.5보다 덜 많은 비계를 필요로 하리라고 기대할 충분한 이유가 있었습니다. 출시 블로그에 따르면, "[Opus 4.6]은 더 신중하게 계획하고, 에이전트형 작업을 더 오래 유지하며, 더 큰 코드베이스에서 더 신뢰성 있게 작동할 수 있고, 스스로의 실수를 포착하는 코드 리뷰와 디버깅 능력이 더 뛰어납니다." 또한 장문맥 검색 성능도 크게 향상되었습니다. 이것들은 모두 기존 하니스가 보완하도록 설계했던 능력들이었습니다.
저는 먼저 스프린트 구조를 완전히 제거하는 것부터 시작했습니다. 스프린트 구조는 작업을 모델이 일관되게 처리할 수 있는 덩어리로 분해하는 데 도움이 되었습니다. 하지만 Opus 4.6의 개선을 고려하면, 모델이 이제는 이런 종류의 분해 없이도 이 일을 기본적으로 처리할 수 있으리라는 충분한 근거가 있었습니다.
저는 기획자와 평가기는 모두 유지했습니다. 둘 다 여전히 분명한 가치를 더하고 있었기 때문입니다. 기획자가 없으면 생성기는 범위를 너무 작게 잡았습니다. 원시 프롬프트만 주어지면, 먼저 자기 작업을 명세하지도 않은 채 바로 만들기 시작했고, 결과적으로 기획자가 만든 것보다 기능이 덜 풍부한 애플리케이션을 만들었습니다.
스프린트 구조를 제거한 뒤에는 평가기를 각 스프린트별 채점이 아니라 실행 마지막의 단일 패스로 옮겼습니다. 모델이 훨씬 더 유능해졌기 때문에, 특정 실행에서 평가기가 얼마나 하중을 지탱하는 요소인지도 달라졌습니다. 그 유용성은 작업이 모델이 스스로 얼마나 안정적으로 수행할 수 있는 범위의 안쪽인지 바깥쪽인지에 달려 있었습니다. 4.5에서는 그 경계가 가까웠습니다. 우리의 빌드는 생성기가 단독으로 잘 해낼 수 있는 한계선 근처에 있었고, 평가기는 빌드 전반에서 의미 있는 문제를 잡아냈습니다. 4.6에서는 모델의 순수 능력이 높아졌고, 그에 따라 경계도 바깥으로 이동했습니다. 예전에는 평가기의 점검이 있어야 일관되게 구현되던 작업들이 이제는 생성기가 단독으로도 잘 처리하는 경우가 많아졌고, 그런 경계 안쪽 작업에서는 평가기가 불필요한 오버헤드가 되었습니다. 하지만 여전히 생성기 능력의 한계선에 걸쳐 있는 빌드의 부분들에 대해서는, 평가기가 계속 실질적인 향상을 제공했습니다.
실무적으로 이것이 뜻하는 바는 평가기가 고정적인 예/아니오 결정이 아니라는 점입니다. 작업이 현재 모델이 단독으로는 신뢰성 있게 처리하지 못하는 범위에 있을 때에는 그 비용을 들일 가치가 있습니다.
이 구조적 단순화와 함께, 저는 각 앱 안에 AI 기능을 더 잘 내장하도록 하니스를 개선하는 프롬프팅도 추가했습니다. 구체적으로는 생성기가 도구를 통해 앱 자신의 기능을 구동할 수 있는 제대로 된 에이전트를 만들도록 유도했습니다. 이 부분은 상당한 반복이 필요했습니다. 관련 지식이 비교적 최근 것이어서 Claude의 학습 데이터가 이를 충분히 다루고 있지 않았기 때문입니다. 하지만 충분히 튜닝한 결과, 생성기는 에이전트를 올바르게 구축하고 있었습니다.
업데이트된 하니스를 시험해 보기 위해, 저는 다음과 같은 프롬프트를 사용해 디지털 오디오 워크스테이션(DAW), 즉 곡을 작곡하고 녹음하고 믹싱하는 음악 제작 프로그램을 만들었습니다.
Web Audio API를 사용해 브라우저에서 완전한 기능을 갖춘 DAW를 구축하세요.
이 실행 역시 여전히 길고 비쌌습니다. 약 4시간이 걸렸고, 토큰 비용은 $124 정도였습니다.
대부분의 시간은 빌더에 쓰였는데, Opus 4.5가 필요로 했던 스프린트 분해 없이도 2시간 넘게 일관성 있게 실행되었습니다.
| 에이전트 및 단계 | 기간 | 비용 |
|---|---|---|
| 기획자 | 4.7분 | $0.46 |
| 빌드 (1라운드) | 2시간 7분 | $71.08 |
| QA (1라운드) | 8.8분 | $3.24 |
| 빌드 (2라운드) | 1시간 2분 | $36.89 |
| QA (2라운드) | 6.8분 | $3.09 |
| 빌드 (3라운드) | 10.9분 | $5.88 |
| QA (3라운드) | 9.6분 | $4.06 |
| 총합 V2 하니스 | 3시간 50분 | $124.70 |
이전 하니스와 마찬가지로, 기획자는 한 줄짜리 프롬프트를 완전한 명세로 확장했습니다. 로그를 보면 생성기 모델이 앱과 에이전트 설계를 계획하고, 에이전트를 연결한 뒤, QA에 넘기기 전에 스스로 테스트하는 일을 꽤 잘 해냈다는 것을 알 수 있었습니다.
그렇다고 해도 QA 에이전트는 여전히 실제 공백을 찾아냈습니다. 첫 번째 라운드 피드백에서 다음과 같이 지적했습니다.
이것은 디자인 완성도, 견고한 AI 에이전트, 좋은 백엔드를 갖춘 강한 앱입니다. 주요 실패 지점은 기능 완성도입니다. 앱은 인상적으로 보이고 AI 통합도 잘 작동하지만, 여러 핵심 DAW 기능이 상호작용 깊이 없이 표시용으로만 존재합니다. 클립은 타임라인에서 드래그하거나 이동할 수 없고, 악기 UI 패널(신스 노브, 드럼 패드)도 없으며, 시각적 이펙트 에디터(EQ 커브, 컴프레서 미터)도 없습니다. 이것들은 경계 사례가 아닙니다. DAW를 실제로 쓸 수 있게 만드는 핵심 상호작용이며, 명세에서도 명시적으로 요구된 부분입니다.
두 번째 라운드 피드백에서도 여러 기능 공백을 다시 잡아냈습니다.
남은 공백:
오디오 녹음은 여전히 스텁 상태임(버튼은 토글되지만 마이크 캡처는 없음)
가장자리 드래그에 의한 클립 크기 조정 및 클립 분할이 구현되지 않음
이펙트 시각화가 숫자 슬라이더일 뿐 그래픽 형태가 아님(EQ 커브 없음)
생성기는 여전히 스스로 작업할 때 세부 사항을 놓치거나 기능을 스텁으로 남겨두는 경향이 있었고, QA는 생성기가 고쳐야 할 마지막 구간의 문제를 잡아내는 데 여전히 가치를 더했습니다.
프롬프트를 바탕으로 제가 기대한 것은 멜로디, 화성, 드럼 패턴을 만들고, 그것들을 곡으로 배열하며, 그 과정에서 통합된 에이전트의 도움을 받을 수 있는 프로그램이었습니다. 아래 영상은 그 결과를 보여 줍니다.
이 앱은 전문적인 음악 제작 프로그램과는 거리가 멀고, 에이전트의 작곡 능력도 분명히 많은 개선이 필요합니다. 게다가 Claude는 실제로 소리를 들을 수 없기 때문에, 음악적 취향에 관한 QA 피드백 루프는 효과가 제한적이었습니다.
그럼에도 최종 앱은 작동하는 음악 제작 프로그램의 핵심 요소를 모두 갖추고 있었습니다. 브라우저에서 동작하는 어레인지먼트 뷰, 믹서, 트랜스포트가 있었고, 그 이상으로 저는 프롬프트만으로 짧은 곡 스니펫을 완성할 수 있었습니다. 에이전트가 템포와 키를 설정하고, 멜로디를 깔고, 드럼 트랙을 만들고, 믹서 레벨을 조정하고, 리버브를 추가했습니다. 곡 작곡의 핵심 기본 요소가 모두 있었고, 에이전트는 도구를 사용해 간단한 프로덕션을 처음부터 끝까지 자율적으로 구동할 수 있었습니다. 아직 음정까지 완벽하다고 말하기는 어렵지만, 분명 그 방향으로 가고 있습니다.
모델이 계속 개선됨에 따라, 우리는 대체로 모델이 더 오래, 더 복잡한 작업을 수행할 수 있게 되리라고 예상할 수 있습니다. 어떤 경우에는 모델을 둘러싼 비계의 중요성이 시간이 갈수록 줄어들 수 있고, 개발자들은 다음 모델을 기다리기만 해도 특정 문제들이 저절로 해결되는 것을 볼 수 있을 것입니다. 반면 모델이 더 좋아질수록, 기준선에서 모델이 할 수 있는 범위를 넘어서는 복잡한 작업을 달성할 수 있는 하니스를 개발할 여지도 더 커집니다.
이 점을 염두에 두면, 이번 작업에서 앞으로도 가져갈 만한 몇 가지 교훈이 있습니다. 먼저, 여러분이 대상으로 삼는 모델을 직접 실험해 보고, 현실적인 문제에서 그 추적 로그를 읽으며, 원하는 결과를 얻기 위해 성능을 튜닝하는 것은 언제나 좋은 실천입니다. 더 복잡한 작업을 다룰 때에는, 작업을 분해하고 문제의 각 측면에 특화된 에이전트를 적용하는 데서 추가 여지가 생길 때가 있습니다. 그리고 새로운 모델이 등장하면, 일반적으로 하니스를 다시 점검해 성능에 더 이상 하중을 지탱하지 않는 요소는 제거하고, 이전에는 불가능했던 더 큰 능력을 달성할 수 있도록 새로운 요소를 추가하는 것이 바람직합니다.
이번 작업을 통해 제가 확신하게 된 것은, 흥미로운 하니스 조합의 공간이 모델이 개선될수록 줄어드는 것이 아니라는 점입니다. 오히려 그 공간은 이동하며, AI 엔지니어에게 중요한 일은 그다음의 새로운 조합을 계속 찾아내는 것입니다.
이 작업에 기여해 준 Mike Krieger, Michael Agaby, Justin Young, Jeremy Hadfield, David Hershey, Julius Tarng, Xiaoyi Zhang, Barry Zhang, Orowa Sidker, Michael Tingley, Ibrahim Madha, Martina Long, Canyon Robbins께 특별히 감사드립니다.
또한 글을 다듬는 데 도움을 준 Jake Eaton, Alyssa Leonard, Stef Sequeira께도 감사드립니다.
기획자 에이전트가 생성한 예시 계획입니다.
RetroForge - 2D 레트로 게임 메이커
개요
RetroForge는 2D 레트로 스타일 비디오 게임을 설계하고 제작하기 위한 웹 기반 크리에이티브 스튜디오입니다. 이 플랫폼은 고전 8비트 및 16비트 게임 미학의 향수를 현대적이고 직관적인 편집 도구와 결합하여, 취미 창작자부터 인디 개발자까지 누구나 전통적인 코드를 작성하지 않고도 자신의 게임 아이디어를 현실로 만들 수 있게 합니다.
이 플랫폼은 네 가지 통합 크리에이티브 모듈을 제공합니다. 게임 월드를 설계하기 위한 타일 기반 레벨 에디터, 시각 자산을 제작하기 위한 픽셀 아트 스프라이트 에디터, 게임 로직을 정의하기 위한 시각적 엔티티 행동 시스템, 그리고 실시간 게임플레이 테스트를 위한 즉시 실행 가능한 플레이 테스트 모드입니다. 전반에 걸쳐 Claude 기반 AI 지원을 녹여 넣음으로써, RetroForge는 사용자가 자연어 상호작용을 통해 스프라이트를 생성하고, 레벨을 설계하고, 행동을 구성하도록 도와 창작 과정을 가속합니다.
RetroForge는 레트로 게임 미학을 사랑하지만 현대적 편의성도 원하는 창작자를 대상으로 합니다. 어린 시절의 플랫폼 게임, RPG, 액션 게임을 재현하든, 레트로 제약 안에서 완전히 새로운 경험을 발명하든, 사용자는 빠르게 프로토타입을 만들고, 시각적으로 반복 개선하고, 자신이 만든 것을 다른 사람과 공유할 수 있습니다.
기능
1. 프로젝트 대시보드 및 관리
프로젝트 대시보드는 RetroForge의 모든 창작 작업을 위한 홈베이스입니다. 사용자는 게임 프로젝트를 관리할 수 있는 명확하고 체계적인 방법이 필요합니다. 즉, 새 프로젝트를 만들고, 진행 중인 작업으로 돌아가고, 각 프로젝트가 무엇을 담고 있는지 한눈에 이해할 수 있어야 합니다.
사용자 스토리: 사용자로서 나는 다음을 원합니다.
- 이름과 설명을 가진 새 게임 프로젝트를 만들어 게임 설계를 시작할 수 있다
- 프로젝트 이름, 마지막 수정 날짜, 썸네일 미리보기를 보여 주는 시각 카드 형태로 기존 프로젝트 전체를 볼 수 있어 작업을 빠르게 찾아 이어갈 수 있다
- 어떤 프로젝트든 열어 전체 게임 에디터 작업 공간으로 들어갈 수 있어 게임 작업을 할 수 있다
- 더 이상 필요 없는 프로젝트를 사고를 방지하는 확인 대화상자와 함께 삭제할 수 있어 작업 공간을 정리할 수 있다
- 기존 프로젝트를 새 게임의 시작점으로 복제할 수 있어 이전 작업을 재사용할 수 있다
프로젝트 데이터 모델: 각 프로젝트는 다음을 포함합니다.
프로젝트 메타데이터(이름, 설명, 생성/수정 타임스탬프)
캔버스 설정(해상도: 예: 256x224, 320x240, 또는 160x144)
타일 크기 설정(8x8, 16x16, 또는 32x32 픽셀)
색상 팔레트 선택
연결된 모든 스프라이트, 타일셋, 레벨, 엔티티 정의
...