본문 바로가기

블로그

멀티 에이전트 시스템은 어떤 식으로 설계되어 있을까?

5분 분량

팀 대화에서 맡긴 일은 계획과 실행을 거쳐 같은 대화에 결과로 돌아옵니다.
팀 대화에서 맡긴 일은 계획과 실행을 거쳐 같은 대화에 결과로 돌아옵니다.

AI 에이전트에게 일을 맡기는 업무 공간 AXIT에서, 10월 20일 기준 지난 30일 동안 동시에 진행된 작업은 많아야 9건이었습니다. 10월 10일에 14일치를 분 단위로 나눠 보니, 도는 작업이 하나도 없는 시간이 49%, 하나만 도는 시간이 34%였어요.

멀티 에이전트라고 하면 에이전트 수십 개가 한꺼번에 도는 그림을 먼저 떠올리게 됩니다. Claude Code나 Codex가 하위 에이전트를 여러 개 띄워 병렬로 일하는 모습도 이제 익숙하죠. 그런데 숫자로 보면 동시에 도는 작업은 생각보다 적습니다. 대신 작업 하나를 열어 보면, 그 안에서는 AI가 역할을 바꿔 가며 차례로 일합니다.

저희가 만드는 AXIT는 팀 채널에서 맡긴 일을 AI 에이전트가 계획하고 실행해서, 같은 대화로 결과를 올리는 업무 공간입니다. 이 구조를 몇 편에 나눠 정리해 보려고 하는데, 첫 편은 메시지 한 줄이 결과가 되기까지 AI가 몇이나, 어떤 순서로 일하는지입니다.

결론부터 말하면, 작업 하나에 붙는 AI 역할은 넷이지만 작업 폴더를 맡는 실행 에이전트는 한 번에 하나뿐입니다.

역할로 세면 넷이고, 작업 폴더를 붙잡고 도는 실행 프로세스로 세면 하나입니다. 계획, 실행, 감독, 검수 가운데 계획과 감독, 검수는 작업 폴더가 아닌 빈 임시 폴더에서 쓰기 권한 없이 도는 짧은 호출이라, 실제로 파일을 고치는 건 실행 쪽뿐이에요. 늘린 건 동시에 도는 에이전트의 수가 아니라 작업 하나 안의 역할입니다. 동시성도 같은 원칙으로 잘랐습니다. 채널 하나에서는 한 번에 작업 하나만 돌고, 채널끼리만 동시에 돕니다. 9월에 쓴 ‘에이전트를 여러 개 띄우면 정말 더 좋을까’의 결론은, 쓰는 주체는 하나로 두고 판단만 나누며 병렬은 공유 상태를 건드리지 않는 일에만 쓰라는 것이었습니다. AXIT의 구조도 같은 모양이에요.

메시지 하나는 저장, 계획, 실행, 결과 네 정거장을 지납니다.

채널에서 일을 맡기면, 요청을 받아 작업을 관리하는 서버인 컨트롤플레인이 먼저 그 메시지를 저장합니다. 그다음 AI 엔진을 한 번 불러 계획을 세웁니다. 무엇을 어떤 순서로 할지 정해 단계 목록을 내놓는 호출입니다. 계획이 서면 실제 일은 워커로 넘어가요. 화면의 진행 표시는 실행하는 에이전트가 단계마다 시작과 끝을 직접 보고해야 움직입니다.

요청 하나가 저장, 계획, 실행을 거쳐 같은 채널로 돌아오는 순서입니다. 계획은 한 번 묻고 끝나고, 오래 걸리는 일은 워커가 맡아요.
요청 하나가 저장, 계획, 실행을 거쳐 같은 채널로 돌아오는 순서입니다. 계획은 한 번 묻고 끝나고, 오래 걸리는 일은 워커가 맡아요.

실행은 일회용 컨테이너에서 수십 분씩 도는 CLI 프로세스입니다.

워커는 실행할 때마다 새로 뜨는 컨테이너입니다. 컨트롤플레인과 WebSocket 하나로 이어져 실행 계획을 받고, 워크스페이스가 고른 엔진의 CLI를 돌리면서 진행 이벤트와 결과를 같은 소켓으로 돌려보냅니다. 에이전트 하나가 이 안에서 수십 분씩 돌기도 해요.

실행을 서버 밖으로 뺀 건 격리와 안정 때문입니다. 9월 중순에는 에이전트 시도 하나가 서버 메모리를 0.56GB에서 13.22GB까지 올린 적이 있어요. 한 사람의 작업이 같은 서버를 쓰는 다른 사람의 화면까지 느리게 만들 수 있는 구조였죠. 10월 16일부터 워커가 기본이 됐고, 10월 17일부터 28일까지 실행된 작업의 98%가 워커에서 돌았습니다. 실행 하나가 수십 분 이어지는 사이에는 서버가 멈추거나 바뀔 수도 있습니다. 그래서 지금 이 실행의 주인이 누구인지 정하는 일이 생각보다 어렵습니다.

작업마다 새 워커가 뜨고, 채널 하나의 작업 폴더에는 한 번에 한 작업만 붙습니다. 채널끼리는 따로 돌아요.
작업마다 새 워커가 뜨고, 채널 하나의 작업 폴더에는 한 번에 한 작업만 붙습니다. 채널끼리는 따로 돌아요.

판단만 하는 AI 둘이 실행을 지켜봅니다.

에이전트에게 일을 맡기면 조사만 하고 끝내거나, 하지 않은 일을 했다고 보고하는 일이 생깁니다. 그래서 실행하는 에이전트와 따로, 판단만 하는 짧은 호출을 둡니다. 실행하는 쪽 지시문에도 푸시했다거나 PR을 열었다고 말하기 전에 실제 성공 출력을 확인하라는 내용이 포함돼 있어요.

실행이 60초 넘게 조용하면 감독이 끼어듭니다. 최근 작업 기록 8줄을 보고 ‘정상:’이나 ‘주의:’로 시작하는 한 줄만 남기고, 실행은 멈추지 않습니다. 오래 생각하느라 조용한 것일 수도 있어서, 점검이 끝나면 60초를 새로 잽니다. 작업 하나에 세 번까지, 워크스페이스마다 한 번에 하나만 돌고, 질문 카드에 사람의 답을 기다리는 시간이나 실행할 서버·워커가 나기를 기다리는 시간은 침묵으로 치지 않아요.

검수는 실행이 성공으로 끝났는데 완료를 보고하지 않은 단계가 남았거나 완료 기준이 있을 때 돕니다. 요청과 완료 기준, 보고의 끝부분을 보고 ‘완료’ 또는 ‘미완: 이유’로만 답합니다. 미완이면 같은 작업 폴더에서 최대 두 번 이어서 돌리고, 같은 이유가 연달아 나오면 진전이 없다고 보고 멈춘 뒤 결과에 미완이라고 적습니다. 끝없이 다시 돌리는 것보다 표시해 두는 편이 낫다고 본 거예요.

둘 다 새 모델이 아닙니다. 워크스페이스의 주 엔진을 낮은 추론 수준으로 한 번 더 부를 뿐이고, 10월 17일부터 28일까지 Claude로 돈 감독·검수 호출은 한 번에 중앙값 5초였습니다. 형식에 맞지 않는 답은 버립니다. 실행 기록에 섞인 지시문이 판정 행세를 하지 못하게 하려는 거예요. 판정 호출 자체가 실패하면 작업을 막지 않고 통과시킵니다. 다만 검수는 에이전트의 보고만 봅니다. 결과물 속 숫자가 원본과 맞는지까지는 알지 못하고, 검수가 실제로 얼마나 자주 ‘미완’을 잡아내는지도 아직 세어 보지 않았습니다.

검수까지 지나면 결과는 지시한 자리로 돌아옵니다. 사람끼리 이야기하다 @AXIT를 불러 맡기는 톡 채널이면, 그 지시 글의 스레드에 계획과 진행, 결과가 차례로 붙습니다. 열어 둔 화면에는 바로 뜨고, 휴대폰에는 푸시 알림이 갑니다.

작업 하나에 붙는 역할은 넷이지만 작업 폴더에 쓰는 건 실행 하나뿐입니다. 검수는 에이전트의 보고만 보고 판단하고, 결과는 맡긴 대화로 돌아와요.
작업 하나에 붙는 역할은 넷이지만 작업 폴더에 쓰는 건 실행 하나뿐입니다. 검수는 에이전트의 보고만 보고 판단하고, 결과는 맡긴 대화로 돌아와요.

병렬의 단위는 에이전트 수가 아니라 채널 수입니다.

채널마다 작업 폴더가 하나라서, 한 채널에서는 한 번에 한 작업만 실행합니다. 같은 채널에 두 번째 작업이 들어오면 계획까지는 세우고, ‘이 채널의 앞선 작업이 끝나기를 기다리고 있어요’를 띄운 채 기다립니다. 이 자리는 DB에 적는 실행 임대(lease)가 정해서, 컨트롤플레인이 여러 대여도 한 폴더에 에이전트 둘이 붙지 않아요. 채널이 다르면 폴더 자리를 두고 서로 기다리지는 않습니다.

서버가 여러 대라서 생긴 버그도 있었습니다. 9월 말 운영에서 주인이 아닌 서버가 되살린 세션 사본이 채널 자리를 쥐는 바람에, 같은 채널의 다음 작업이 폴더를 다른 작업이 쓰고 있다며 실패한 일이 세 번 있었어요. 지금은 사본이 자리를 쥐지 않게 고쳤습니다.

실제로 겹치는 일은 드뭅니다. 앞서 본 14일 분포에서 동시에 도는 작업이 2개인 시간은 11%, 3개는 3.5%, 4개 이상은 2%였고, 가장 많을 때가 8개였어요. 기간을 9월 28일부터 한 달로 옮겨 봐도, 가장 많았던 순간은 교육 행사가 열린 10월 24일 오후의 10건이었습니다.

이 모양은 사람 쪽 설계도 바꿨습니다. 실습 강의안을 짤 때 팀이 워크 채널(올린 글이 곧 AI 작업 지시가 되는 채널) 두 개를 번갈아 쓰게 했습니다. 웹페이지 하나 만드는 작업이 중앙값 17분 걸리니, 한 채널이 도는 동안 다른 채널에 다음 지시를 쓰거나 결과를 검토하게 한 거죠. 첫 맡기기는 워커를 쓰지 않는 톡 채널 대화 답으로 하게 했는데, 이쪽은 중앙값 14초면 답이 와요. 한 채널에 일을 몰면 줄만 길어집니다. 결국 병렬의 폭은 에이전트 수보다 사람이 채널을 어떻게 나누느냐에 달려 있습니다.

이 제품을 만드는 유니크굿에서도 에이전트로 일합니다.

10월 28일 11시부터 29일 12시까지 약 25시간 동안, Claude Code 세션 하나에서 회사 일에 돌린 워크플로(에이전트 여러 개를 단계별로 띄우는 스크립트)만 세어도 15개, 에이전트는 104개였습니다. 그 세션에서 가장 많을 때는 워크플로 6개, 에이전트 14개가 동시에 일했어요. 단계 이름을 모아 보면 구현→검토→고침, 훑기→검증→비평, 조사→권고→반박, 만들기→심사 같은 패턴 몇 개가 되풀이됩니다. 규칙도 몇 가지로 정해 두었습니다. 찾는 쪽과 깨는 쪽은 다른 에이전트로 두고, 고치기는 한 번만 하고, 머지와 배포, 외부 발송은 사람이 정합니다. 하위 에이전트는 사람과 나눈 대화를 보지 못하니, 전해 들은 ‘하라고 했다’는 말은 승인으로 치지 않습니다. 에이전트가 늘수록 사람이 정할 일도 함께 늘었는데, 이 이야기와 실행의 주인 문제는 이어지는 글에서 풀어 보겠습니다.

에이전트를 업무에 붙이려는 팀이라면 순서를 바꿔 볼 만합니다. 에이전트 수를 늘리기 전에 쓰는 쪽과 판단하는 쪽부터 나누고, 병렬은 채널이나 폴더처럼 공유 상태가 없는 단위로 자르고, 판단 호출에는 좁은 답 형식과 횟수 상한을 두는 겁니다. 다시 돌리기에도 상한을 두고, 진전이 없으면 멈춘 채 표시를 남기는 편이 낫습니다. 그러면 에이전트가 몇 개 돌든 누가 무엇을 고쳤는지 따라갈 수 있습니다.

멀티 에이전트의 다음 경쟁은 몇 개를 띄우느냐보다 어디서 나누고 누가 판단하느냐에서 갈릴 듯싶습니다.

https://axit.team