하나의 에이전트인가, 다섯 개인가? AI 코더 팀을 운영하며 배운 점
요약
AI 에이전트 팀을 운영할 때 단순히 에이전트 수를 늘리는 것이 아니라, 작업의 독립성을 기준으로 구조화하는 것이 중요함을 설명합니다. 작업이 서로 의존적이라면 병렬 처리가 아닌 파이프라인 구조를 가져야 효율적입니다.
핵심 포인트
- 에이전트 수는 독립적인 작업 흐름의 수와 일치해야 함
- 상태를 공유하거나 순서가 있는 작업은 병렬 처리 시 오버헤드만 발생
- 플래너, 실행자, 검증자로 역할을 나누는 구조적 접근 필요
- 작업 분해(Decomposition)는 전체 프로세스의 핵심 단계임
약 2주 동안 저는 에이전트가 많을수록 더 많은 결과물이 나올 것이라고 확신했습니다. 만약 한 명의 AI 코더가 뛰어나다면, 다섯 명이 병렬로 실행된다면 분명 다섯 배는 더 나을 것이라고 생각했죠. 그래서 저는 모든 것을 확장하기 시작했습니다. 팀을 구성하고, 작업 목록을 전달한 뒤, 그들이 경주하게 만들었습니다.
하지만 실제로 제가 얻은 결과는 동일한 세 개의 파일을 편집하는 다섯 명의 에이전트였습니다. 그중 세 명은 첫 번째 에이전트가 이미 해결한 버그를 다시 "수정"하고 있었고, 두 명은 함수 시그니처 (function signature)에 대해 의견이 엇갈렸으며, 머지 (merge) 상황을 해결하는 데는 작업을 한 번 직접 수행하는 것보다 더 많은 시간이 걸렸습니다. 더 많은 에이전트가 더 높은 처리량 (throughput)을 가져다주지는 않았습니다. 대신 모두가 동시에 말하는 스탠드업 미팅 (standup meeting) 상황만 만들어냈을 뿐입니다.
그래서 바보 같은 방식으로 먼저 시도해 본 끝에, 언제 하나의 에이전트를 사용해야 하고 언제 여러 개를 사용해야 하는지에 대해 제가 배운 솔직한 내용을 공유하고자 합니다.
질문은 "에이전트가 몇 개인가"가 아니라 "독립적인 조각이 몇 개인가"입니다.
이것이 핵심입니다. 병렬 에이전트 (Parallel agents)는 작업이 서로 영향을 주지 않는 덩어리들로 분해될 때만 승리할 수 있습니다. 에이전트의 수는 진정으로 독립적인 작업 흐름 (work-streams)의 수와 일치해야 합니다. 여러분의 낙관주의나 작업의 규모, 혹은 다섯 개의 터미널이 스크롤되는 것을 보는 멋진 기분과는 상관없습니다.
제가 작업을 확장하기 전에 실행하는 간단한 테스트는 다음과 같습니다: 두 명의 서로 다른 사람이 대화 없이 서로 다른 리포지토리 (repos)에서 이 조각들을 수행할 수 있는가?
- "이름이 변경된 함수의 호출 지점(call sites) 40곳을 마이그레이션하기" → 예, 분할하여 확장하십시오. 각 호출 지점은 독립적입니다.
- "인증(auth)을 추가한 다음, 인증을 사용하는 대시보드 추가하기" → 아니요. 그것은 파이프라인 (pipeline)이지 병렬 작업이 아닙니다. 두 번째 작업은 첫 번째 작업에 의존합니다.
- "이 300라인짜리 모듈 하나를 리팩터링하기" → 아니요. 에이전트 한 명이면 충분합니다. 하나의 파일에 다섯 명의 에이전트를 투입하는 것은 불필요한 단계가 추가된 머지 충돌 (merge conflict)일 뿐입니다.
만약 조각들이 상태 (state)를 공유하거나 순서가 정해져 있다면, 더 많은 에이전트는 병렬 처리의 이점 없이 조정 비용 (coordination cost)만 추가합니다. 오버헤드 (overhead)는 모두 지불하면서 속도 향상은 전혀 얻지 못하게 됩니다.
실제로 작동하는 형태: 확장(fan out)한 후 수렴(funnel)시키기
혼란을 멈추게 한 패턴은 "더 많은 에이전트"나 "더 적은 에이전트"가 아니었습니다. 그것은 군집(swarm)에게 무질서한 자유를 주는 대신 _구조(structure)_를 부여하는 것이었습니다. 세 가지 역할이 필요합니다:
┌─ executor (file A) ─┐
plan ───┼─ executor (file B) ─┼──► verifier ──► done / loop back
└─ executor (file C) ─┘
...
- **하나의 플래너 (One planner)**가 작업을 겹치지 않는 청크(chunks)로 나눕니다. 이것은 제가 예전에 건너뛰곤 했던 단계인데, 이 단계를 건너뛰는 것이 바로 제 에이전트들이 충돌했던 정확한 이유였습니다. 분해(Decomposition)는 작업의 서론이 아니라, 그 자체로 하나의 작업입니다.
- **N개의 실행자 (N executors)**가 각 청크당 하나씩 할당되며, 각자 자신만의 파일을 소유합니다. 공유 파일이 없으면 = 병합 전쟁(merge war)도 없습니다.
- **하나의 검증자 (One verifier)**가 새로운(fresh) 컨텍스트를 가지고 결합된 결과가 원래의 목표와 일치하는지 확인합니다.
마지막 역할은 사람들이 흔히 생략하는 것이지만, 가장 중요한 역할입니다.
에이전트가 자신의 숙제를 채점하게 해서는 안 됩니다
초기에 제 실행자들은 작업을 마치면 승리를 선언하곤 했습니다: "완료! 모든 테스트 통과." 때로는 사실이었지만, 종종 에이전트는 그저 성공의 _형태(shape)_를 패턴 매칭(pattern-matching)하고 있었을 뿐이었습니다. 즉, 무언가 초록색(통과)처럼 보이는 것을 실행하고는 완료라고 부른 것입니다.
해결책은 제가 이제 절대 어기지 않는 엄격한 규칙입니다: 코드를 작성한 에이전트는 절대로 그 코드를 승인하는 에이전트가 되어서는 안 됩니다. 작성(Authoring)과 검토(Reviewing)는 별도의 컨텍스트에서 이루어지는 별개의 단계입니다. 작성자는 "내가 끝냈다"라는 상태에 몰입해 있습니다. 반면, 차이점(diff)에 대해 어떠한 자아(ego)도 없는 새로운 검증자는 불편한 질문을 던집니다. "이것이 실제로 목표를 달성했는가, 그리고 그 증거는 무엇인가?" 만약 그렇지 않다면 다시 루프를 돌립니다.
이것은 단순한 유계 루프(bounded loop)로 매핑됩니다:
plan → execute (parallel) → verify
│
fail ◄──────────┤
...
경계(bound)가 중요합니다. 제한 없이 "통과할 때까지 수정하고 재검증하라"는 방식은 새벽 2시에 에이전트가 똑같은 벽에 머리를 박으며 허우적거리게 만드는 방식입니다. 재시도 횟수를 제한하십시오. 만약 예산을 초과한다면, 그것은 루프가 영원히 돌게 할 신호가 아니라 제가 직접 확인해야 한다는 신호입니다.
작업에 모델을 맞추기
제가 예산을 과다하게 지출했던 또 다른 부분은 모든 작업에 가장 비싼 모델을 사용한 것이었습니다. 코딩 작업의 대부분은 깊은 추론 (Deep Reasoning)이 아니라, 조회 (Lookups), 기계적인 편집 (Mechanical Edits), 테스트 실행 (Running Tests)입니다. 그래서 저는 난이도에 따라 경로를 지정합니다:
- 저렴하고 빠른 모델 (Cheap/fast model) → "X가 어디에 정의되어 있는가", "이것들의 이름을 변경하라", "테스트 스위트를 실행하라."
- 중간 모델 (Mid model) → 표준적인 구현 (Standard Implementation), 실행기 (Executor) 작업의 대부분.
- 최상위 모델 (Top model) → 분해 계획 수립 (Planning the decomposition), 아키텍처 호출 (Architecture calls), 어려운 변경 사항에 대한 검증기 (Verifier)의 판단.
비싼 모델의 판단력은 _작업을 분할 (Splitting the work)_하고 _작업을 검토 (Checking the work)_하는 데에는 가치가 있습니다. 하지만 "이 문자열을 grep으로 찾아라"와 같은 작업에 사용하는 것은 낭비입니다. 모든 곳에 비싼 모델을 사용하는 것은 단지 ls 명령어를 실행하기 위해 프리미엄 요금을 지불하는 것과 같습니다.
그래서: 하나인가, 여러 개인가?
현재 대부분의 날에 제가 내리는 실제 답변은 하나입니다. 즉, 잘 정의된 범위의 작업을 수행하는 하나의 에이전트와, 마지막에 이를 검토하는 두 번째 에이전트의 조합입니다. 저는 작업의 범위가 진정으로 넓을 때만 군집 (Swarm) 방식을 사용합니다. 예를 들어, 수많은 파일에 걸친 마이그레이션 (Migration), 독립적인 수정 사항들의 배치 (Batch), 또는 팬아웃 검색 (Fan-out search) 같은 경우입니다. 작업 조각들이 서로 의존하는 순간, 병렬성 (Parallelism)은 거짓이 되며 저는 다시 파이프라인 (Pipeline) 방식으로 돌아갑니다.
더 많은 에이전트를 사용하는 것은 _깊이 (Depth)_가 아니라 _너비 (Width)_를 위한 도구입니다. 만약 당신의 문제가 깊다면, 유능한 에이전트 하나가 혼란에 빠진 다섯 개의 에이전트보다 언제나 낫습니다. 만약 문제가 넓다면, 먼저 깔끔하게 분할하십시오. 그리고 작업자 (Worker)가 자신의 작업에 대해 스스로 승인하게 하는 일은 절대로, 결코 해서는 안 됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기