AI 멀티 에이전트 시스템을 직접 설계하는 법
하네스 엔지니어링을 시작하려는 사람들이 가장 흔하게 저지르는 실수가 있다. 처음부터 멀티 에이전트 시스템을 설계하려는 것이다. 플래너를 만들고, 제너레이터를 만들고, 이밸류에이터를 붙이고, 이들 사이의 소통 프로토콜을 정의하고. 이렇게 접근하면 거의 확실하게 실패한다. 왜냐하면 문제가 무엇인지도 모르는 상태에서 해법을 설계하는 것이기 때문이다.
Anthropic의 프리트비 라자세카란이 3-에이전트 하네스를 만든 과정을 되짚어보면, 그 출발점은 화려한 아키텍처가 아니었다. 출발점은 단일 에이전트의 실패를 관찰하는 것이었다. 하나의 AI에게 작업을 시키고, 그 결과물을 직접 써보고, 로그를 꼼꼼히 읽으면서 "어디서, 왜 실패하는가"를 분류한 것이다. 컨텍스트 불안, 자기 평가의 실패, 범위 축소, 기능 스텁(Stub) 처리 같은 구체적인 실패 모드들이 이 관찰에서 나왔고, 하네스의 각 구성 요소는 이 특정 실패 모드들에 대한 직접적인 해법으로 설계되었다.
그래서 하네스 엔지니어링의 첫 번째 단계는 반드시 베이스라인 측정이다. 하네스 없이, 단일 에이전트에게 당신이 해결하려는 과제를 그대로 맡겨보라. 그리고 결과물을 실제 사용자의 관점에서 평가하라. 코드를 짜라고 했으면 실제로 실행해보라. 디자인을 만들라고 했으면 실제로 클릭해보라. 보고서를 쓰라고 했으면 실제로 읽어보라. 이 과정에서 발견하는 문제들을 분류하는 것이 하네스 설계의 진정한 출발점이다.
실패 모드를 분류할 때 유용한 프레임워크가 있다. 실패를 크게 세 가지 범주로 나누는 것이다.
첫 번째 범주는 방향의 실패(Direction Failure)다. 모델이 애초에 잘못된 것을 만들고 있는 경우다. 사용자가 원하는 것과 모델이 만드는 것 사이에 근본적인 괴리가 있다. 범위가 너무 좁거나, 핵심 요구사항을 놓치거나, 아예 다른 것을 만들고 있는 경우가 여기에 해당한다. Anthropic의 실험에서 플래너 없이 제너레이터에게 원시 프롬프트를 그대로 주었을 때, 제너레이터가 범위를 축소하고 덜 풍부한 애플리케이션을 만든 것이 이 범주의 실패다.
두 번째 범주는 실행의 실패(Execution Failure)다. 방향은 맞지만 구현 과정에서 문제가 발생하는 경우다. 코드에 버그가 있거나, 기능이 반만 구현되어 있거나, 핵심 기능 간의 연결이 끊어져 있는 경우다. 단일 에이전트가 만든 레트로 게임 메이커에서 엔티티 정의와 게임 런타임 사이의 와이어링이 끊어져 있던 것이 전형적인 실행의 실패다.
세 번째 범주는 품질의 실패(Quality Failure)다. 방향도 맞고 기능도 작동하지만, 결과물의 수준이 기대에 못 미치는 경우다. 디자인이 평범하거나, 사용자 경험이 거칠거나, 엣지 케이스가 처리되지 않은 경우가 여기에 해당한다. Claude가 기본적으로 만드는 보라색 그라디언트 위의 하얀 카드 레이아웃이 품질의 실패에 속한다.
각 범주의 실패에는 서로 다른 하네스 구성 요소가 필요하다. 방향의 실패에는 플래너가 필요하고, 실행의 실패에는 평가 에이전트와 피드백 루프가 필요하며, 품질의 실패에는 구체적 채점 기준과 반복적 개선 루프가 필요하다. 실패 모드를 정확히 진단하지 않으면, 불필요한 구성 요소를 추가하거나, 정작 필요한 구성 요소를 빠뜨리게 된다.
로그를 읽는 것도 결과물을 평가하는 것만큼 중요하다. 결과물만 보면 "무엇이 잘못되었는가"만 알 수 있지만, 로그를 읽으면 "왜 잘못되었는가"를 알 수 있다. 모델이 작업 중간에 방향을 갑자기 바꾼 것은 컨텍스트가 가득 차서였는가, 아니면 이전 작업과의 일관성을 잃어서였는가. 기능을 스텁으로 처리한 것은 구현 방법을 몰라서인가, 아니면 컨텍스트 불안 때문에 서둘러 마무리하려 한 것인가. 버그를 놓친 것은 테스트를 안 해서인가, 아니면 테스트를 했는데 문제를 문제로 인식하지 못한 것인가. 같은 증상이라도 원인이 다르면 해법도 달라진다.
프리트비가 평가 에이전트를 튜닝한 과정이 정확히 이 패턴을 따른다. 그는 평가 에이전트의 로그를 읽고, 자신의 판단과 괴리가 있는 부분을 찾고, 그 특정 괴리를 해결하는 방향으로 프롬프트를 수정했다. 이것을 여러 차례 반복한 끝에야 합리적인 수준의 평가 에이전트를 얻었다. 한 번에 완벽한 하네스가 나오는 것이 아니라, 관찰과 수정의 반복을 통해 점진적으로 하네스가 정교해지는 것이다.
정리하자면, 하네스 엔지니어링의 올바른 순서는 이렇다. 먼저 단일 에이전트로 돌린다. 결과물을 직접 사용하고 평가한다. 로그를 읽고 실패 모드를 분류한다. 각 실패 모드에 대한 구체적 해법을 설계한다. 그 해법이 하네스의 구성 요소가 된다. 이 순서를 건너뛰고 처음부터 복잡한 멀티 에이전트 시스템을 설계하는 것은, 진단 없이 처방을 내리는 것과 같다.
실패 모드를 파악했다면, 다음 질문은 자연스럽게 "어떻게 역할을 나눌 것인가"가 된다. 멀티 에이전트 시스템의 핵심은 단순히 에이전트 수를 늘리는 것이 아니라, 각 에이전트가 명확하게 정의된 역할을 맡아 해당 역할에만 집중하도록 하는 것이다. 그런데 역할을 어떤 기준으로 나눠야 하는가. 이것은 기술적 질문이기도 하지만, 본질적으로는 조직 설계의 문제다.
Anthropic이 도달한 3-에이전트 구조, 즉 플래너-제너레이터-이밸류에이터는 소프트웨어 개발 조직의 역할 분리를 그대로 반영한다. 프로덕트 매니저(플래너), 개발자(제너레이터), QA 엔지니어(이밸류에이터). 이 분리가 우연이 아닌 이유는, 인간 조직이 수십 년에 걸쳐 시행착오를 통해 이 분리가 효과적임을 검증해왔기 때문이다. AI 에이전트 시스템도 같은 논리가 적용된다.
역할 분리의 첫 번째 원칙은 인지적 충돌이 있는 역할을 분리하라는 것이다. 하나의 에이전트에게 "이것을 만들어라"와 "이것이 잘 만들어졌는지 평가하라"를 동시에 시키면, 두 역할이 충돌한다. 만드는 과정에서 이미 결과물에 대한 심리적 투자가 발생하기 때문에, 같은 에이전트가 평가할 때 객관성이 훼손된다. 이것은 앞선 글에서 상세히 다룬 자기 평가의 실패다. 마찬가지로, 기획과 구현을 같은 에이전트에게 시키면, 기획 단계에서 구현의 어려움을 예상하고 범위를 무의식적으로 축소하는 경향이 나타난다. "이것은 구현하기 어려울 것 같으니 명세에서 빼자"라는 판단이 기획 단계에서 은밀하게 일어나는 것이다. 플래너를 분리하면 이 문제가 해소된다. 플래너는 구현의 난이도를 걱정하지 않고 제품적으로 가치 있는 기능을 자유롭게 구상할 수 있다.
두 번째 원칙은 추상화 수준이 다른 역할을 분리하라는 것이다. 기획은 "무엇을 만들 것인가"라는 고수준(High-Level)의 질문이고, 구현은 "어떻게 만들 것인가"라는 저수준(Low-Level)의 질문이며, 평가는 "제대로 만들어졌는가"라는 메타 수준(Meta-Level)의 질문이다. 이 세 가지는 요구하는 사고의 성격이 다르다. 기획은 확산적 사고(Divergent Thinking)가 필요하다. 가능성을 넓게 탐색하고, 야심적으로 범위를 잡아야 한다. 구현은 수렴적 사고(Convergent Thinking)가 필요하다. 명세에 정의된 것을 정확하고 효율적으로 실현해야 한다. 평가는 비판적 사고(Critical Thinking)가 필요하다. 결과물에서 문제를 찾아내고, 기준에 비추어 판단해야 한다. 하나의 에이전트에게 이 세 가지 사고 모드를 번갈아가며 수행하라고 요구하면, 어느 것도 제대로 수행되지 않는다.
세 번째 원칙은 분리의 이점이 조정의 비용을 넘어설 때만 분리하라는 것이다. 이것은 종종 간과되는 원칙이다. 에이전트를 분리할 때마다 조정 비용(Coordination Cost)이 발생한다. 에이전트 간 소통을 위한 프로토콜을 설계해야 하고, 정보 손실을 최소화해야 하며, 전체 실행 시간과 토큰 비용이 증가한다. 분리로 인한 품질 향상이 이 비용을 상쇄하지 못하면, 분리하지 않는 것이 낫다.
Anthropic의 실험에서 이 원칙이 명확히 드러나는 지점이 있다. Opus 4.5에서 4.6으로 모델이 업그레이드되었을 때, 스프린트 분해라는 구성 요소가 불필요해졌다. 스프린트 분해는 제너레이터의 작업을 작은 단위로 쪼개서 일관성을 유지하게 하는 역할이었는데, Opus 4.6이 자체적으로 긴 작업을 일관되게 수행할 수 있게 되면서, 분해의 이점이 조정의 비용보다 작아진 것이다. 반면 플래너와 이밸류에이터의 분리는 모델이 업그레이드된 후에도 여전히 이점이 비용을 넘어섰다.
실전에서 역할 분리를 판단할 때 유용한 질문이 몇 가지 있다. "이 두 역할을 같은 에이전트에게 시키면, 한쪽 역할의 품질이 다른 쪽 때문에 저하되는가?" 그렇다면 분리해야 한다. "이 역할을 독립 에이전트로 분리했을 때, 그 에이전트의 프롬프트를 역할에 특화되게 튜닝할 수 있는 여지가 크게 늘어나는가?" 그렇다면 분리의 가치가 있다. 평가 에이전트를 분리하면 "까다롭고 회의적으로 평가하라"는 프롬프팅이 가능해지고, 이것은 생성과 평가를 동시에 하는 에이전트에게는 적용하기 어려운 종류의 지시다. "분리 없이도 모델이 이 작업을 충분히 잘 수행하는가?" 그렇다면 분리하지 마라. 불필요한 복잡도는 디버깅을 어렵게 만들고, 비용을 높이고, 유지 보수의 부담을 가중시킨다.
모든 과제에 3-에이전트 구조가 필요한 것은 아니라는 점도 명심해야 한다. 어떤 과제는 Generator-Evaluator의 2-에이전트만으로 충분하고, 어떤 과제는 플래너 없이 상세한 명세를 사용자가 직접 제공하는 것이 더 효과적일 수 있다. 역할 분리의 정답은 과제의 성격과 사용하는 모델의 역량에 따라 달라진다. 핵심은 "에이전트를 몇 개 만들 것인가"가 아니라, "각 에이전트에게 어떤 역할을 부여하면 전체 시스템의 성능이 최대화되는가"다.
역할을 나눴다면, 평가 에이전트에게 "무엇을 기준으로 평가하라"고 알려줘야 한다. 이 채점 기준(Grading Criteria)의 설계는 하네스 엔지니어링에서 가장 미묘하면서도 가장 영향력이 큰 작업이다. 기준이 모호하면 평가가 일관되지 않고, 기준이 잘못되면 개선 방향 자체가 틀어진다. Anthropic의 실험에서 채점 기준은 단순한 평가 도구가 아니라, 결과물의 성격을 결정하는 스티어링 메커니즘으로 작동했다.
채점 기준을 설계하는 첫 번째 단계는 평가 대상 영역의 분해(Decomposition)다. "이 결과물이 좋은가?"라는 단일 질문은 AI가 일관되게 답할 수 없다. 하지만 "이 결과물의 X 측면은 어떤가?"라는 구체적 질문은 답할 수 있다. 프리트비가 프론트엔드 디자인에 대해 만든 네 기준(디자인 품질, 독창성, 완성도, 기능성)이 정확히 이 분해를 수행한 것이다. "이 디자인이 좋은가?"를 네 개의 독립된 축으로 분해함으로써, 각 축에 대해 구체적이고 일관된 평가가 가능해졌다.
분해할 때 중요한 것은 축들이 가능한 한 독립적이어야 한다는 것이다. 디자인 품질과 독창성은 서로 다른 것을 측정한다. 디자인 품질은 전체적 통일감과 정체성을 보고, 독창성은 관습적 패턴에서의 이탈을 본다. 통일감이 있되 독창적이지 않을 수 있고(잘 만든 템플릿), 독창적이되 통일감이 없을 수도 있다(실험적이지만 산만한 디자인). 이렇게 축이 독립적이면, 평가 에이전트가 "디자인 품질은 높지만 독창성이 낮다"라는 식의 구분된 피드백을 줄 수 있고, 생성 에이전트는 이 피드백을 받아 "통일감은 유지하면서 더 독창적인 선택을 하겠다"는 구체적 방향을 설정할 수 있다.
두 번째 단계는 각 기준에 대한 구체적 설명을 작성하는 것이다. "독창성이 높아야 한다"는 지시는 너무 추상적이다. AI는 이것을 자의적으로 해석할 수 있고, 해석의 일관성도 보장되지 않는다. Anthropic이 한 것처럼, 좋은 것과 나쁜 것의 구체적 예시를 기준 설명에 포함시켜야 한다. "수정되지 않은 기본 컴포넌트, 보라색 그라디언트 위의 하얀 카드 같은 AI 생성의 전형적 징후가 보이면 이 기준에서 실패한다"라는 식의 네거티브 예시가 특히 효과적이다. AI에게 "좋은 것을 만들어라"고 말하는 것보다, "이런 것은 만들지 마라"고 말하는 것이 종종 더 강력한 가이드가 된다.
세 번째 단계는 가중치 배분이다. 모든 기준이 동등하게 중요한 것은 아니다. Anthropic은 디자인 품질과 독창성에 완성도와 기능성보다 높은 가중치를 부여했다. 그 이유는 모델이 이미 잘하는 것(완성도, 기능성)에 높은 가중치를 두면, 평가 점수가 쉽게 올라가면서 실제로 개선이 필요한 영역(디자인 품질, 독창성)에 대한 압력이 약해지기 때문이다. 가중치는 모델의 현재 강점과 약점을 반영해야 한다. 모델이 이미 잘하는 영역에는 낮은 가중치를, 개선이 필요한 영역에는 높은 가중치를 부여하는 것이 피드백 루프의 효과를 극대화한다.
이것은 직관에 반할 수 있다. 기능성이 디자인 품질보다 덜 중요하다는 뜻이 아니다. 최종 제품에서는 둘 다 중요하다. 하지만 채점 기준의 목적이 "현재 상태에서 가장 효과적으로 개선을 유도하는 것"이라면, 이미 높은 수준에 있는 영역보다 개선 여지가 큰 영역에 압력을 집중하는 것이 합리적이다. 가중치는 고정이 아니다. 모델이 개선되거나 과제의 성격이 달라지면 재조정해야 한다.
네 번째 단계는 퓨샷 캘리브레이션(Few-Shot Calibration)이다. 기준을 텍스트로 아무리 잘 설명해도, 평가 에이전트가 그 기준을 사람의 의도와 정확히 같은 수준으로 적용한다는 보장이 없다. 프리트비는 이 문제를 퓨샷 예시, 즉 구체적인 결과물과 그에 대한 상세한 점수 분석 사례를 보여주는 것으로 해결했다. "이 디자인은 디자인 품질 8점, 독창성 6점, 완성도 9점, 기능성 8점이다. 디자인 품질이 8점인 이유는 이러이러하고, 독창성이 6점인 이유는 이러이러하다"라는 식의 예시를 여러 개 제공하면, 평가 에이전트의 기준선이 설계자의 취향과 정렬된다.
퓨샷 예시를 만들 때 중요한 것은 다양한 점수대의 예시를 포함하는 것이다. 높은 점수의 예시만 보여주면 평가 에이전트가 높은 점수에 편향되고, 낮은 점수의 예시만 보여주면 지나치게 엄격해진다. 높은 점수, 중간 점수, 낮은 점수에 해당하는 예시를 골고루 포함시켜야 평가의 변별력이 확보된다.
다섯 번째이자 가장 미묘한 단계는 기준 문구의 스티어링 효과를 인식하고 활용하는 것이다. Anthropic의 실험에서 발견된 중요한 현상이 있다. 채점 기준은 생성 에이전트에게도 공유되었는데, 기준의 표현 방식이 생성 에이전트의 출력 특성에 직접적인 영향을 미쳤다. "최고의 디자인은 뮤지엄 퀄리티다"라는 문구는 단순히 평가의 기준점을 설정한 것이 아니라, 생성 에이전트가 목표로 삼는 미적 방향 자체를 설정한 것이다.
이것은 의도적으로 활용할 수 있는 레버다. 기준 문구에 특정 미적 방향이나 품질 수준을 암시하는 표현을 의도적으로 포함시키면, 생성 에이전트가 그 방향으로 이끌린다. 반대로, 중립적이고 기술적인 언어만 사용하면 생성 에이전트가 안전한 기본값에 머무를 가능성이 높다. 채점 기준을 쓸 때, 당신은 단지 평가 체계를 설계하는 것이 아니다. 결과물의 성격을 설계하고 있는 것이다.
풀스택 개발에 적용할 때는 기준의 성격이 달라진다. 프론트엔드 디자인에서는 주관적 미학이 핵심 축이었지만, 소프트웨어 개발에서는 제품 깊이(Product Depth), 기능성(Functionality), 시각 디자인(Visual Design), 코드 품질(Code Quality)로 축이 재구성된다. 여기서 제품 깊이라는 축이 특히 주목할 만하다. 이것은 기능이 화면에 표시만 되는 것(Display-Only)이 아니라 실제로 상호작용할 수 있는 깊이를 갖추고 있는가를 평가한다. DAW 하네스에서 평가 에이전트가 "클립을 타임라인에서 드래그할 수 없다", "악기 UI 패널(신스 노브, 드럼 패드)이 없다"고 지적한 것이 이 축에 해당한다. 기능이 존재는 하지만 껍데기만 있는 스텁 상태인지, 실제로 사용 가능한 수준인지를 구분하는 것이다.
채점 기준 설계를 요약하면 이렇다. 평가 대상을 독립적인 축으로 분해하고, 각 축에 좋은 것과 나쁜 것의 구체적 예시를 포함한 설명을 작성하고, 모델의 강약점을 반영하여 가중치를 배분하고, 퓨샷 예시로 기준선을 캘리브레이션하고, 기준 문구의 스티어링 효과를 의식적으로 활용하라. 이 과정이 채점 기준 설계의 전체 그림이다.
채점 기준을 만들었다고 해서 평가 에이전트가 자동으로 좋은 평가를 하는 것은 아니다. Anthropic의 실험에서 반복적으로 확인된 사실이 있다. 기본 상태의 Claude는 좋은 QA 에이전트가 아니다. 문제를 발견하고도 "크게 문제될 것은 아니다"라고 판단을 번복하고, 표면적인 확인에 그치며, 엣지 케이스를 파고들지 않는다. 채점 기준이 뼈대라면, 평가 에이전트의 튜닝은 그 뼈대에 근육을 붙이는 작업이다.
평가 에이전트를 까다롭게 만드는 첫 번째 방법은 프롬프트에서 명시적으로 회의적 태도를 요구하는 것이다. 단순히 "평가하라"가 아니라, "결함을 적극적으로 찾아라", "작동하는 것처럼 보이더라도 실제로 확인하라", "괜찮아 보이는 것과 실제로 괜찮은 것은 다르다"라는 식의 지시가 필요하다. LLM은 기본적으로 긍정적이고 도움을 주려는 성향이 있기 때문에, 이 성향을 의도적으로 역방향으로 밀어야 한다. 비판적이고 회의적인 페르소나를 부여하는 것이 효과적이다.
여기서 핵심적인 발견이 있다. 생성 에이전트를 자기 비판적으로 만드는 것보다, 독립된 평가 에이전트를 회의적으로 만드는 것이 훨씬 쉽다. 이것은 구조적 이유가 있다. 생성 에이전트에게 "만들면서 동시에 비판적으로 봐라"고 하면, 생성 모드와 비판 모드가 충돌한다. 만드는 과정에서는 낙관과 추진력이 필요하고, 평가하는 과정에서는 회의와 검증이 필요하다. 하나의 에이전트가 이 두 모드를 번갈아가는 것은 인지적으로 비효율적이다. 반면 평가만 전담하는 에이전트는 처음부터 끝까지 비판 모드에 머물 수 있기 때문에, 프롬프팅으로 그 비판의 강도를 조절하는 것이 훨씬 수월하다.
두 번째 방법은 평가 에이전트에게 실제 상호작용 도구를 부여하는 것이다. Anthropic이 사용한 Playwright MCP가 대표적이다. Playwright는 브라우저 자동화 도구로, 평가 에이전트가 실행 중인 애플리케이션을 실제 사용자처럼 탐색할 수 있게 해준다. 버튼을 클릭하고, 폼을 작성하고, 페이지를 이동하고, 스크린샷을 찍는 것이 모두 가능하다.
이것이 정적 코드 리뷰나 스크린샷 기반 평가와 결정적으로 다른 점은, 실제 사용 과정에서만 드러나는 버그를 잡을 수 있다는 것이다. 코드를 읽으면 기능이 구현되어 있는 것처럼 보이지만, 실제로 클릭해보면 작동하지 않는 경우가 빈번하다. FastAPI에서 라우트 순서 때문에 특정 엔드포인트가 잘못 매칭되는 버그, 이벤트 핸들러의 조건문이 실제 사용 시나리오와 맞지 않는 버그 같은 것들은, 코드를 읽는 것만으로는 발견하기 어렵지만, 실제로 클릭해보면 즉시 드러난다.
평가 에이전트에게 Playwright를 주면서 중요한 지시를 함께 해야 한다. "스크린샷을 찍고 주의 깊게 살펴봐라"는 지시다. Anthropic의 실험에서 평가 에이전트는 페이지를 직접 탐색하면서 스크린샷을 찍고, 각 화면을 꼼꼼히 살펴본 후에야 평가를 작성했다. 이 "살펴보기" 단계가 없으면, 평가 에이전트가 페이지를 기계적으로 빠르게 훑고 지나가면서 시각적 문제를 놓칠 수 있다.
세 번째 방법은 하드 임계값(Hard Threshold)을 설정하는 것이다. 채점 기준에 따라 점수를 매기되, 특정 점수 이하이면 해당 스프린트 또는 빌드를 자동으로 실패 처리하는 것이다. 이것은 평가 에이전트의 관대함을 구조적으로 제한한다. 임계값이 없으면, 평가 에이전트가 낮은 점수를 주면서도 "전반적으로는 괜찮으니 통과"라고 판정할 수 있다. 임계값이 있으면, 아무리 다른 영역이 좋아도 하나의 기준이 기준선 아래로 떨어지면 무조건 재작업이 요구된다. 이것은 평가 에이전트의 "인심 좋은" 경향을 시스템 수준에서 차단하는 장치다.
네 번째이자 가장 중요한 방법은 반복적 로그 기반 교정이다. 이것이 Anthropic이 실제로 평가 에이전트를 튜닝한 핵심 방법이다. 프로세스는 이렇다. 하네스를 실행한다. 평가 에이전트의 로그를 읽는다. 평가 에이전트의 판단과 자신의 판단이 괴리가 있는 지점을 찾는다. 그 괴리를 해소하는 방향으로 평가 에이전트의 프롬프트를 수정한다. 다시 실행한다. 이것을 반복한다.
구체적인 괴리의 유형은 다양하다. 평가 에이전트가 실제 버그를 발견하고도 심각도를 낮게 판정하는 경우가 있다. "이 기능이 작동하지 않지만, 전체적인 앱의 완성도를 고려하면 크게 문제되지 않는다"는 식의 판단이다. 이런 경우 프롬프트에 "핵심 기능의 버그는 심각도와 무관하게 실패로 처리하라"는 지시를 추가한다. 평가 에이전트가 표면적인 테스트만 하고 엣지 케이스를 탐색하지 않는 경우도 있다. 주요 기능이 기본 시나리오에서 작동하는 것만 확인하고, 비정상적 입력이나 경계 조건을 테스트하지 않는 것이다. 이런 경우 "각 기능에 대해 최소 세 가지 시나리오를 테스트하라: 정상 경로, 엣지 케이스, 그리고 오류 경로"라는 식의 지시를 추가한다.
이 교정 과정에서 경계해야 할 것은 과도한 엄격성이다. 평가 에이전트를 너무 까다롭게 만들면, 생성 에이전트가 모든 반복에서 실패 판정을 받아 피드백 루프가 수렴하지 않는다. 이상적인 상태는 평가 에이전트의 판단이 "엄격하되 합리적"인 수준이다. 실제 사용자가 문제로 느낄 것은 문제로 잡되, 사소한 취향 차이까지 실패로 처리하지는 않는 수준이다. 이 균형점을 찾는 것이 반복적 교정의 목표다.
프리트비 자신의 말처럼, 이 교정 과정에는 여러 차례의 반복이 필요했다. 한 번에 완벽한 평가 에이전트가 나오는 것이 아니다. 매번 실행할 때마다 평가 에이전트의 판단을 사람이 검토하고, 괴리를 수정하는 과정을 거쳐야 한다. 이것은 시간이 걸리는 작업이지만, 평가 에이전트의 품질이 전체 하네스의 효과를 결정하기 때문에, 여기에 투자하는 시간은 하네스 성능으로 직접 환산된다.
에이전트를 분리하고 각각의 역할과 평가 기준을 정의했다면, 다음으로 해결해야 할 문제는 이 에이전트들이 어떻게 소통하느냐다. 멀티 에이전트 시스템에서 에이전트 간 소통의 품질은 전체 시스템의 성능에 직접적인 영향을 미친다. 정보가 전달 과정에서 손실되면 다음 에이전트의 작업 품질이 떨어지고, 소통 프로토콜이 불명확하면 에이전트들이 서로 다른 것을 이야기하게 된다.
Anthropic이 선택한 소통 방식은 파일 기반 프로토콜(File-Based Protocol)이다. 하나의 에이전트가 파일을 작성하면, 다른 에이전트가 그 파일을 읽고 같은 파일에 응답을 추가하거나 새로운 파일로 회신한다. 이 방식은 단순하지만 여러 가지 장점이 있다.
첫째, 모든 소통 내용이 명시적으로 기록된다. 에이전트 간의 대화가 파일로 남기 때문에, 하네스 개발자가 나중에 어느 지점에서 소통이 잘못되었는지를 추적할 수 있다. 에이전트 A가 에이전트 B에게 전달한 내용이 무엇이었는지, B가 그것을 어떻게 해석했는지가 파일에 고스란히 남는다.
둘째, 구조화가 용이하다. 파일에 특정 형식을 강제하면 정보의 누락을 방지할 수 있다. 예를 들어 평가 에이전트가 작성하는 피드백 파일에 "각 채점 기준별 점수, 발견된 버그 목록, 구체적 개선 제안"이라는 섹션을 강제하면, 평가 에이전트가 점수만 매기고 구체적 피드백을 생략하는 것을 구조적으로 방지할 수 있다.
셋째, 컨텍스트 관리가 수월하다. 에이전트의 컨텍스트 윈도우에 전체 대화 이력을 유지할 필요 없이, 현재 작업에 필요한 파일만 읽으면 된다. 이것은 특히 컨텍스트 리셋을 사용하는 구조에서 중요하다. 새로운 에이전트가 시작될 때, 이전 에이전트와의 모든 대화 이력 대신 핵심 인수인계 파일만 읽으면 작업을 이어갈 수 있다.
파일 기반 소통의 구체적 설계에서 중요한 원칙이 몇 가지 있다. 하나는 파일의 목적과 구조를 사전에 정의하는 것이다. "플래너는 product_spec.md를 작성하고, 이 파일에는 제품 개요, 기능 목록, 각 기능의 유저 스토리가 포함된다. 제너레이터는 이 파일을 읽고 sprint_contract.md를 작성하여 현재 스프린트의 구현 범위와 성공 기준을 제안한다. 이밸류에이터는 sprint_contract.md를 읽고 같은 파일에 피드백을 추가하거나 승인한다"라는 식으로, 파일의 이름, 내용 구조, 작성 주체, 소비 주체를 명확히 정의해야 한다.
또 하나의 원칙은 정보의 적절한 추상화 수준을 유지하는 것이다. 플래너가 제너레이터에게 전달하는 명세는 "무엇을 만들 것인가"에 집중하되 "어떻게 만들 것인가"는 열어둬야 한다. 이것은 Anthropic의 실험에서 검증된 설계 결정이다. 플래너가 세부적인 기술 구현까지 명시하면, 명세의 오류가 구현 전체에 전파된다. 반대로 평가 에이전트가 제너레이터에게 전달하는 피드백은 구체적이고 실행 가능해야 한다. "디자인 개선 필요"가 아니라 "상단 네비게이션의 여백 불일치, 본문 행간 과소, 강조색과 배경 간 대비 부족"이어야 한다.
이 소통 구조에서 Anthropic이 도입한 가장 독창적인 요소가 스프린트 계약(Sprint Contract)이다. 이것은 제너레이터와 이밸류에이터가 각 작업 단위의 시작 전에 "무엇을 완료로 볼 것인가"를 사전에 합의하는 프로세스다. 제너레이터가 "이번에 이것을 만들겠다, 테스트 기준은 이것이다"라고 제안하면, 이밸류에이터가 이를 검토하여 기준이 충분한지, 빠진 것은 없는지, 테스트 가능한 형태로 기술되어 있는지를 확인한다. 양쪽이 합의할 때까지 계약이 수정된 후에야 구현이 시작된다.
스프린트 계약의 효용은 여러 차원에서 작용한다. 먼저, 제너레이터가 잘못된 것을 만드는 것을 사전에 방지한다. 명세가 고수준이기 때문에 해석의 여지가 있는데, 스프린트 계약에서 이밸류에이터가 그 해석을 검증한다. 또한 평가 기준이 사전에 합의되어 있기 때문에, 나중에 평가 단계에서 "이것은 명세에 없었다"나 "이것은 내가 의도한 것이 아니다"라는 식의 모호함이 제거된다. 제너레이터는 정확히 무엇을 달성해야 하는지를 알고 작업하고, 이밸류에이터는 정확히 무엇을 테스트해야 하는지를 알고 평가한다.
스프린트 계약의 세밀도는 과제의 복잡도에 비례해야 한다. Anthropic의 레트로 게임 메이커 실험에서 레벨 에디터 스프린트 하나에 27개의 기준이 포함된 것은, 레벨 에디터 자체가 복잡한 기능이기 때문이다. 더 단순한 기능이라면 기준이 5~10개면 충분할 수도 있다. 기준의 수가 중요한 것이 아니라, 각 기준이 테스트 가능한 형태로 기술되어 있는가가 중요하다. "레벨 에디터가 잘 작동해야 한다"는 테스트 불가능한 기준이다. "사각형 채우기 도구가 클릭-드래그로 선택된 타일로 사각 영역을 채울 수 있다"는 테스트 가능한 기준이다.
스프린트 구조를 제거한 업데이트된 하네스에서도 이 소통 원칙의 핵심은 유지된다. 스프린트별 계약은 없어졌지만, 플래너의 명세가 제너레이터에게 전달되고, 이밸류에이터가 빌드 완료 후 상세한 피드백을 파일로 전달하는 구조는 동일하다. 핵심은 에이전트 간의 모든 소통이 명시적이고, 구조화되어 있으며, 추적 가능하다는 것이다.
Generator-Evaluator 구조의 효과는 피드백 루프가 제대로 돌아가느냐에 달려 있다. 생성 에이전트가 만들고, 평가 에이전트가 평가하고, 그 평가를 반영하여 생성 에이전트가 다시 만드는 이 순환이 곧 하네스의 심장이다. 그런데 이 루프를 설계할 때 생각보다 많은 결정이 필요하다. 몇 번 반복할 것인가. 언제 현재 방향을 유지하고 언제 피벗할 것인가. 언제 루프를 멈출 것인가.
Anthropic의 프론트엔드 디자인 실험에서 한 번의 실행당 5회에서 15회의 반복이 이루어졌다. 이 범위는 어떻게 정해진 것일까. 핵심은 수확 체감(Diminishing Returns)의 지점을 찾는 것이다. 초기 반복들은 가장 큰 품질 향상을 가져온다. 명백한 문제들이 먼저 수정되고, 디자인의 기본 방향이 잡힌다. 중간 반복들은 디테일의 정제가 이루어진다. 후기 반복들은 점진적 개선이 점점 작아지면서, 때로는 과도한 복잡성이 도입되기도 한다.
Anthropic의 실험에서 평가 점수는 반복을 거듭하면서 개선된 후 고원(Plateau)에 도달하는 패턴을 보였다. 이 고원이 루프를 멈출 자연스러운 지점이다. 점수가 더 이상 의미 있게 올라가지 않으면, 추가 반복은 비용만 증가시키고 품질은 정체된다. 실전에서는 고원 감지를 자동화할 수 있다. 최근 N회 반복의 점수 변화량이 특정 임계값 이하이면 루프를 종료하는 식이다.
하지만 단순한 점수 추적만으로는 포착할 수 없는 현상이 있다. 프리트비가 보고한 것처럼, 마지막 반복의 결과물보다 중간 반복의 결과물을 선호하는 경우가 종종 있었다. 반복이 진행될수록 구현의 복잡도가 증가하는 경향이 있는데, 이 복잡도가 항상 품질 향상으로 이어지지는 않는다. 더 야심 찬 구현이 더 많은 버그나 시각적 혼잡을 동반할 수 있기 때문이다. 이런 현상에 대비하는 한 가지 방법은, 각 반복의 결과물을 스냅샷으로 보존하고 최종적으로 가장 좋은 버전을 선택할 수 있게 하는 것이다. Git을 사용한 버전 관리가 이 목적으로 효과적이다.
피벗(Pivot)에 대한 설계도 중요하다. Anthropic의 하네스에서 생성 에이전트는 각 평가 후에 전략적 결정을 내리도록 설계되었다. 점수가 상승 추세이면 현재 방향을 더 정제하고, 점수가 정체되었거나 접근법이 작동하지 않으면 완전히 다른 미학적 방향으로 전환하라는 것이다. 네덜란드 미술관 웹사이트의 10번째 반복에서 일어난 극적인 전환이 이 피벗 메커니즘의 결과였다. 9번의 반복 동안 점진적으로 개선되던 다크 테마 랜딩 페이지가, 10번째에서 갑자기 3D 공간 경험으로 재구상된 것은 생성 에이전트가 "현재 방향의 개선 여지가 소진되었다"고 판단하고 피벗한 결과다.
피벗의 조건을 명시적으로 정의하는 것이 좋다. "연속 N회 반복에서 점수 개선이 X 미만이면 피벗을 시도하라"는 식의 규칙이다. 다만 피벗은 위험도 수반한다. 이전에 쌓아온 것을 버리고 새로 시작하는 것이므로, 새로운 방향이 이전보다 나을 것이라는 보장이 없다. 그래서 피벗 시에도 이전 버전을 보존하고, 새로운 방향이 일정 수준 이상의 점수를 달성하지 못하면 이전 버전으로 돌아갈 수 있는 안전장치가 필요하다.
풀스택 개발 하네스에서 피드백 루프의 구조는 프론트엔드 디자인과 다소 다르다. 업데이트된 하네스에서는 빌드와 QA가 교대로 실행되었다. 제너레이터가 빌드하고, 이밸류에이터가 전체를 평가하고, 이밸류에이터의 피드백을 받아 제너레이터가 수정하고, 다시 이밸류에이터가 평가하는 식이다. DAW 실험에서 이 사이클이 3회 반복되었다. 빌드-QA-빌드-QA-빌드-QA의 6단계를 거친 것이다.
각 사이클에서 소요되는 시간과 비용이 다르다는 점도 설계에 반영해야 한다. DAW 실험에서 첫 번째 빌드는 2시간 7분이 걸렸지만, 세 번째 빌드는 11분이었다. QA는 매번 7~10분 정도로 비교적 일정했다. 이것은 초기 빌드에서 대부분의 기능이 구현되고, 후속 빌드에서는 QA 피드백에 대한 수정과 보완이 이루어지기 때문이다. 즉, 첫 번째 빌드가 가장 비용이 크고, 이후 빌드는 점진적으로 가벼워진다.
반복 횟수를 결정할 때의 현실적 고려사항은 비용과 시간이다. 반복할수록 결과물이 좋아지지만, 각 반복에는 토큰 비용과 실행 시간이 든다. DAW 실험의 전체 비용 125달러 중 빌드 비용이 대부분을 차지했다. 피드백 루프의 반복 횟수는 "추가 반복의 예상 품질 향상"과 "추가 반복의 비용"을 저울질해서 결정해야 한다. 프리트비의 실험에서 3회의 빌드-QA 사이클이 사용된 것은, 이 정도면 주요 버그와 기능 간극이 대부분 해소되면서도 비용이 과도하게 늘어나지 않는 균형점이었기 때문으로 보인다.
하네스를 처음 설계할 때는 많은 구성 요소를 넣게 된다. 실패 모드마다 하나의 해법을 추가하다 보면, 하네스가 복잡하고 무거워진다. Anthropic의 첫 번째 하네스가 6시간, 200달러였던 것이 그 증거다. 하네스 엔지니어링의 후반부 작업은 이 하네스를 경량화하는 것이다. 무엇을 빼고 무엇을 남길 것인가.
이 경량화의 기저에는 하나의 핵심 원칙이 있다. Anthropic이 "효과적인 에이전트 만들기" 블로그에서 제시한 것이다. "가능한 가장 단순한 해법을 찾고, 필요할 때만 복잡도를 높여라." 이 원칙은 하네스의 초기 설계에도 적용되지만, 경량화 단계에서 특히 중요해진다.
경량화의 출발점은 각 구성 요소가 실제로 성능에 기여하고 있는가(Load-Bearing)를 검증하는 것이다. 프리트비는 이것을 두 가지 방법으로 시도했다. 첫 번째는 급진적 축소(Radical Simplification)였다. 하네스를 대폭 줄이고 새로운 아이디어를 시도한 것이다. 하지만 이 접근은 실패했다. 원래 하네스의 성능을 재현하지 못했고, 더 문제인 것은 어떤 부분이 성능에 기여하고 있는지를 파악하기 어려워졌다는 것이다. 여러 구성 요소를 동시에 바꾸면, 결과의 변화가 어떤 변경 때문인지 알 수 없다.
이 경험을 바탕으로 프리트비는 두 번째 방법, 즉 체계적 제거(Systematic Ablation)로 전환했다. 한 번에 하나의 구성 요소만 제거하고, 그것이 최종 결과에 어떤 영향을 미치는지를 관찰하는 것이다. 이것은 과학 실험에서의 변인 통제와 같은 원리다. A, B, C, D라는 네 구성 요소가 있을 때, A만 빼고 나머지를 유지한 채로 실행하여 A의 기여도를 측정하고, B만 빼고 나머지를 유지한 채로 실행하여 B의 기여도를 측정하는 식이다.
이 방법이 시간이 더 걸리지만, 각 구성 요소의 기여도에 대한 정확한 이해를 제공한다. 프리트비가 이 과정을 통해 발견한 것은 이런 것들이다. 스프린트 분해를 제거해도 Opus 4.6에서는 성능이 유지되었다(모델의 향상된 역량이 스프린트 분해의 역할을 대체). 컨텍스트 리셋을 제거해도 Opus 4.6에서는 성능이 유지되었다(컨텍스트 불안의 감소). 플래너를 제거하면 성능이 떨어졌다(제너레이터가 범위를 축소). 이밸류에이터를 제거하면 작업 난이도에 따라 영향이 달랐다(쉬운 작업에서는 미미, 어려운 작업에서는 유의미한 품질 저하).
모델 업그레이드는 경량화의 자연스러운 계기다. 새로운 모델이 나오면, 기존 하네스의 각 구성 요소가 여전히 필요한지를 재검증해야 한다. 하네스의 모든 구성 요소는 "현재 모델이 할 수 없는 것"에 대한 가정을 인코딩하고 있기 때문이다. 모델이 개선되면 일부 가정이 무효화되고, 해당 구성 요소는 불필요한 오버헤드가 된다.
재검증의 실전적 프로세스는 이렇다. 새 모델이 나오면, 먼저 단일 에이전트(하네스 없이)로 기존 과제를 돌려본다. 결과물을 기존 하네스의 결과물과 비교한다. 이전에 실패했던 부분이 개선되었는지를 확인한다. 개선된 부분에 대응하는 하네스 구성 요소를 후보로 식별한다. 해당 구성 요소를 제거한 하네스로 실행하여 성능 영향을 확인한다. 성능 저하가 무시할 만하면 제거를 확정한다.
경량화에서 주의해야 할 함정이 있다. 특정 구성 요소가 대부분의 경우에는 불필요하지만, 특정 조건에서는 여전히 필수적인 경우다. Anthropic의 이밸류에이터가 정확히 이 패턴을 보인다. 모델의 역량 범위 안에 있는 작업에서는 이밸류에이터가 불필요한 오버헤드이지만, 역량 경계에 걸치는 작업에서는 여전히 실질적 기여를 한다. 이런 경우 구성 요소를 완전히 제거하기보다, 조건부로 활성화하는 방식이 효과적일 수 있다. 과제의 복잡도나 첫 번째 빌드의 품질에 따라 이밸류에이터를 동적으로 투입하거나 생략하는 식이다.
경량화의 반대 방향, 즉 새로운 구성 요소의 추가도 모델 업그레이드와 함께 고려해야 한다. 더 나은 모델로 이전에 불가능했던 과제를 시도할 수 있게 되면, 그 과제를 위한 새로운 하네스 구성 요소가 필요해질 수 있다. 프리트비가 업데이트된 하네스에서 AI 기능 구현을 위한 프롬프팅을 추가한 것이 이 예다. 이전 모델에서는 에이전트 기반 AI 기능을 앱에 내장하는 것이 어려웠지만, 개선된 모델에서는 적절한 프롬프팅으로 가능해졌다.
하네스 경량화의 핵심을 한 문장으로 요약하면 이렇다. 빼도 성능이 유지되는 것은 빼고, 빼면 성능이 떨어지는 것은 남겨라. 그리고 이 판단은 모델이 바뀔 때마다 반복하라.
여기까지 하네스 엔지니어링의 원리, 방법론, 사례를 모두 살펴보았다. 마지막으로 이 모든 것을 하나의 실행 가능한 체크리스트로 정리한다. 내일 당장 자신만의 하네스를 설계하려는 사람을 위한 단계별 가이드다.
첫 번째 단계는 과제를 정의하는 것이다. 하네스는 특정 과제를 해결하기 위한 시스템이다. "모든 것을 잘하는 범용 하네스"는 존재하지 않는다. 당신이 해결하려는 과제가 무엇인지를 명확히 하라. 프론트엔드 디자인인가, 풀스택 애플리케이션 개발인가, 보고서 작성인가, 데이터 분석인가. 과제의 성격이 하네스의 모든 설계 결정을 결정한다.
두 번째 단계는 베이스라인을 측정하는 것이다. 하네스 없이, 가장 단순한 방법으로 과제를 수행하라. 단일 에이전트에게 프롬프트를 주고 결과물을 받아라. 결과물을 실제 사용자의 관점에서 평가하라. 동시에 에이전트의 작업 로그를 꼼꼼히 읽어라. 이 단계에서 "현재 어떤 수준인가"와 "어디서 실패하는가"를 파악한다.
세 번째 단계는 실패 모드를 분류하는 것이다. 관찰된 실패들을 방향의 실패, 실행의 실패, 품질의 실패로 분류하라. 각 실패의 원인을 가능한 한 구체적으로 파악하라. "코드에 버그가 있다"가 아니라, "기능 간 와이어링이 끊어져 있다. 원인은 에이전트가 기능을 독립적으로 구현하면서 통합 테스트를 하지 않았기 때문이다"라는 수준까지 파고들어라. 실패의 진단이 구체적일수록, 해법도 구체적이 된다.
네 번째 단계는 최소한의 하네스를 설계하는 것이다. 모든 실패 모드에 대한 해법을 한꺼번에 구현하려 하지 마라. 가장 영향이 큰 실패 모드 한두 개를 골라, 그것에 대한 최소한의 해법을 먼저 구현하라. 자기 평가의 실패가 가장 큰 문제라면, Generator-Evaluator 2-에이전트 구조를 먼저 구현하라. 방향의 실패가 가장 큰 문제라면, 플래너를 추가하라. 한 번에 하나의 구성 요소를 추가하면서, 각 추가가 실제로 성능을 개선하는지를 확인하라.
다섯 번째 단계는 채점 기준을 설계하는 것이다. 평가 에이전트를 사용한다면, 채점 기준이 필수다. 평가 대상을 독립적 축으로 분해하라. 각 축에 구체적 설명과 긍정/부정 예시를 포함시켜라. 모델이 이미 잘하는 영역에는 낮은 가중치를, 개선이 필요한 영역에는 높은 가중치를 부여하라. 퓨샷 예시로 평가 에이전트의 기준선을 캘리브레이션하라. 기준 문구의 스티어링 효과를 의식적으로 활용하라.
여섯 번째 단계는 소통 프로토콜을 정의하는 것이다. 에이전트 간의 소통 방식, 파일 이름과 구조, 각 에이전트가 읽고 쓰는 파일의 명세를 사전에 정의하라. 가능하다면 스프린트 계약 같은 사전 합의 메커니즘을 도입하여, 작업 시작 전에 "무엇을 완료로 볼 것인가"를 명확히 하라.
일곱 번째 단계는 실행, 관찰, 수정의 반복이다. 하네스를 실행하고 결과물을 평가하라. 평가 에이전트의 로그를 읽고, 자신의 판단과 괴리가 있는 지점을 찾아 수정하라. 생성 에이전트의 로그를 읽고, 평가 피드백을 어떻게 반영하고 있는지를 확인하라. 피드백 루프가 의도대로 작동하고 있는지, 점수가 실제로 개선되고 있는지를 추적하라. 이 과정을 여러 차례 반복하면서 하네스의 각 부분을 정교하게 다듬어라.
여덟 번째 단계는 경량화다. 하네스가 원하는 수준의 결과물을 만들어내기 시작하면, 경량화를 시작하라. 한 번에 하나의 구성 요소를 제거하고, 성능 영향을 확인하라. 제거해도 성능이 유지되는 구성 요소는 제거하여 비용과 복잡도를 줄여라.
아홉 번째 단계는 모델 업그레이드에 대응하는 것이다. 새로운 모델이 나오면, 하네스 전체를 재검증하라. 단일 에이전트로 과제를 다시 돌려보고, 이전에 실패했던 부분이 개선되었는지 확인하라. 불필요해진 구성 요소를 제거하고, 새로운 모델의 역량으로 가능해진 새로운 구성 요소의 추가를 검토하라.
이 아홉 단계가 하네스 엔지니어링의 전체 사이클이다. 이 사이클에서 한 가지 더 강조할 점이 있다. 하네스 엔지니어링은 일회성 작업이 아니라 지속적인 프로세스라는 것이다. 모델은 계속 발전하고, 과제의 요구사항도 변하며, 하네스도 그에 맞춰 진화해야 한다. Anthropic의 프리트비가 말한 것처럼, 흥미로운 하네스 조합의 영역은 줄어들지 않는다. 이동할 뿐이다. 하네스 엔지니어링의 본질은 이 이동하는 영역을 추적하면서, 현재 모델의 역량 경계에서 최대의 성능을 끌어내는 구조를 설계하는 것이다.
결국 하네스 엔지니어링이란 AI를 위한 조직 설계다. 인간 조직이 수십 년에 걸쳐 역할 분리, 프로세스 설계, 품질 관리 체계를 발전시켜온 것처럼, AI 에이전트 시스템도 같은 원리의 적용을 받는다. 차이가 있다면, AI 조직은 구성원의 역량이 수개월 단위로 급격히 변한다는 것이다. 그래서 하네스 엔지니어는 단순히 좋은 구조를 한 번 만드는 사람이 아니라, 변화하는 모델 역량에 맞춰 구조를 지속적으로 재설계할 수 있는 사람이어야 한다. 이것이 하네스 엔지니어링이라는 기술 영역의 핵심이며, 지금 이 순간부터 시작할 수 있는 기술이다.