12. 다중 에이전트
도구가 늘어나면 모델 하나에 전부 제공하는 대신 업무별 에이전트로 나눌 수 있다. 다만 여러 에이전트가 있다는 사실만으로 협업이 되는 것은 아니다. 누가 요청을 받고 어떤 상태를 넘기며 결과를 어디로 돌려줄지 정해야 한다.
12.1 숙박 에이전트
여행 정보 에이전트는 장소와 날씨를 다루고, 숙박 에이전트는 호텔과 B&B의 가용 객실 및 제안을 조회한다. 정보와 도구의 책임을 나누는 구조다.
12.1.1 호텔 도구
책은 SQLite에 저장된 호텔 자료를 SQL 도구로 제공한다. 모델이 스키마를 확인하고 필요한 조회를 실행할 수 있도록 도구 집합을 연결한다.
일반적인 SQL toolkit은 단일 “호텔 조회” 함수보다 넓은 기능을 노출할 수 있다. 어떤 테이블과 명령이 허용되는지 확인하고 읽기 전용 권한과 실행 제한을 적용해야 한다.
현재 객실과 가격은 변경되는 데이터다. 결과에는 대상 날짜와 객실 수, 통화와 가격 기준을 포함해야 한다. 질문에 날짜가 없다면 임의로 정하기보다 확인이 필요할 수 있다.
12.1.2 B&B 도구
다른 제공자의 REST 서비스를 모의 구현으로 연결한다. 장소와 객실 수 등을 받아 제안 목록을 반환한다.
SQL 행과 API 응답을 같은 의미로 비교하려면 필드와 단위를 맞춰야 한다. 1박 가격과 전체 숙박 가격, 객실 수와 인원 수를 섞으면 자연스러운 답변도 틀릴 수 있다.
빈 결과와 오류도 구분해야 한다. 객실이 없는 것과 외부 API가 응답하지 않은 것은 다른 상황이다.
12.1.3 ReAct 숙박 에이전트
호텔과 B&B 도구를 함께 제공해 조건에 맞는 결과를 모으도록 한다. 숙소 유형을 정하지 않았다면 둘 다 확인하는 정책을 둘 수 있다.
책의 booking이라는 이름에도 실제 예제의 핵심은 가용 객실과 제안 조회다. 목록을 확인하는 기능과 객실을 확보하거나 결제를 실행하는 기능을 같은 것으로 보면 안 된다.
실제 예약을 추가하면 사용자 확인, 재고 재검증, 중복 방지와 취소 절차가 필요하다. 조회 시점에 있던 객실이 예약 시점에도 있다는 보장은 없다.
12.2 Router 기반 여행 도우미
질문을 보고 여행 정보 또는 숙박 에이전트로 한 번 위임한다. 각 전문 에이전트의 도구와 프롬프트는 독립적으로 관리할 수 있다.
12.2.1 라우터 설계
라우터는 사용 가능한 에이전트의 이름과 처리 범위를 알아야 한다. 자유 문자열보다 허용 이름을 가진 구조화된 출력으로 경로를 제한하는 편이 명확하다.
모든 질문이 둘 중 하나에 속하지는 않는다. 범위 밖 요청이나 불명확한 입력을 어떻게 처리할지도 정해야 한다.
12.2.2 라우팅 로직
질문을 분류하고 Command 같은 실행 제어 객체로 대상 노드와 필요한 상태 갱신을 지정할 수 있다.
에이전트 이름을 고르는 것과 업무가 성공하는 것은 다르다. 라우터가 올바른 이름을 반환해도 전달한 질문에서 날짜나 객실 수를 잃었다면 결과가 달라진다.
상태를 그대로 넘기는 경우에도 다른 에이전트가 읽어도 되는 정보인지 확인해야 한다. 메시지 전체를 공유하는 방식은 간단하지만 불필요한 문맥과 민감한 정보가 넓게 퍼질 수 있다.
12.2.3 그래프 구성
상위 경로는 Router에서 전문 에이전트로 이동하고, 전문 에이전트 내부에서는 도구 루프가 돌아간다. 바깥은 제한된 경로 선택이고 안쪽은 모델이 여러 도구를 선택하는 혼합 구조다.
하위 에이전트가 끝났을 때 사용자 응답으로 종료할지 상위로 돌아올지가 중요한 차이다. Router 구조에서는 보통 선택된 한 경로에서 요청을 마친다.
12.2.4 실행 확인
관광지 질문과 빈 객실 질문을 각각 넣어 어느 경로가 선택되는지 확인한다. 이름 분류뿐 아니라 적절한 도구를 사용했는지도 봐야 한다.
“날씨가 좋은 해안 마을을 고르고 그곳의 숙소도 찾아 달라”는 요청은 두 업무를 포함한다. 한 경로로만 보내는 구조에서는 일부 요구를 놓칠 수 있다.
12.3 Supervisor
Supervisor는 전문 에이전트를 작업 도구처럼 호출하고 결과를 받은 뒤 다음 작업을 결정한다. 단순히 한 번 분류하는 Router보다 조정의 범위가 넓다.
12.3.1 에이전트를 조정하는 에이전트
전문 에이전트마다 역할과 입력, 결과 형식을 명확히 해야 한다. Supervisor는 어떤 능력이 있고 어떤 경우에 호출해야 하는지 설명을 보고 위임한다.
이름이 다른 모델 여러 개보다 업무 경계가 중요하다. 같은 모델을 사용해도 서로 다른 도구와 지침, 상태 범위를 가지면 역할을 분리할 수 있다.
12.3.2 결과 회수와 재위임

그림의 핵심은 전문 에이전트에서 Supervisor로 돌아오는 경로다. 여행 정보에서 정한 마을을 받은 뒤 그 마을의 숙소를 조회할 수 있다. 한 번의 요청 안에서도 같은 전문 에이전트를 다시 호출할 수 있다.
그러나 위임이 많을수록 지연과 비용, 정보 손실이 늘어난다. 전문 에이전트가 원문 근거 대신 짧은 결론만 반환하면 Supervisor가 잘못된 판단을 조사하기 어렵다. 필요한 사실과 출처, 실패 상태를 구조화해서 반환하는 편이 좋다.
| 구분 | Router | Supervisor |
|---|---|---|
| 주된 판단 | 누가 이 요청을 처리할지 | 어떤 작업을 어떤 순서로 맡길지 |
| 결과 경로 | 전문 에이전트가 응답하고 종료 가능 | 결과를 받아 추가 위임과 통합 |
| 적합한 요청 | 분리된 단일 업무 | 여러 역할의 결과가 필요한 업무 |
| 주요 부담 | 오분류와 복합 요청 누락 | 반복 위임, 비용, 상태 전달 |
12.3.3 복합 요청 실행
“해안 마을을 찾고 현재 날씨를 확인한 뒤 객실을 조회”한다면 장소 선정이 먼저다. 숙박 도구가 실행됐다고 전체 성공이 아니라, 선정된 장소와 실제 조회한 장소가 같은지까지 확인해야 한다.
결과에는 어떤 조건을 충족했고 어느 항목을 확인하지 못했는지 남긴다. 외부 서비스 하나가 실패한 경우 다른 에이전트의 성공 결과를 마치 모든 확인이 끝난 것처럼 표현하면 안 된다.
종료 기준과 위임 한도가 필요하다. Supervisor가 더 나은 결과를 찾겠다고 같은 에이전트를 계속 호출할 수 있으므로 요청별 시간과 비용, 반복 횟수를 통제한다.
여러 에이전트가 필요한지 판단하기
업무와 도구를 분리하면 프롬프트 길이와 권한 범위를 줄이고 부분별 평가가 쉬워질 수 있다. 반대로 단순 작업을 인위적으로 여러 에이전트로 나누면 전달과 재해석의 비용만 늘 수 있다.
한 에이전트와 몇 개의 명시적 도구로 충분한지부터 비교해야 한다. 에이전트 수가 시스템의 성숙도를 나타내는 것은 아니다.
질문
Router도 여러 작업을 해결할 수 있을까?
별도의 분해와 반복 경로를 구현하면 가능하다. 이 장에서 비교하는 단순 Router는 한 번의 선택으로 끝나는 구조라 복합 요청에서 한계가 드러난다.
숙소를 조회했으면 예약까지 완료된 것일까?
조회와 실제 거래는 다른 작업이다. 예약 확정 결과가 없으면 완료라고 답해서는 안 된다.