Multi-Agent 17
Router 병렬 분기와 Fan-in 병합 설계
Router는 항상 하나의 Agent만 고르는 구조라고 오해하기 쉽다.
근거 · 교안 p62-p68
1장: 하나가 아닌, 복수의 전문가에게 요청하기
솔라의 손에 들린 작은 메모지 위로 볼펜 끝이 불안하게 오가고 있었다. 방금 막 정리한 내용인데, 첫 문장부터 무언가 꽉 막힌 듯 더 나아가지 못했다.
복수 전문가 Router는 필요한 여러 Agent를 Send로 병렬 실행하고, 각 결과를 expert_notes에 Reducer로 누적한 뒤 synthesize_agent가 하나의 답변으로 병합한다.
문장을 이루는 단어들은 대부분 아는 것이었다. Router, Agent, 병렬 실행. 하지만 단어들을 조립한 문장은 머릿속에 선명한 그림을 그려주지 않았다. 오히려 익숙한 단어가 발목을 잡았다. 솔라는 볼펜을 내려놓고 고개를 갸웃거렸다.
“언니, 잠깐만.”
거실 테이블 맞은편에서 조용히 책을 읽던 루나가 고개를 들었다.
“이것 좀 봐봐. ‘라우터’는 원래 길을 안내해주는 거잖아. 갈림길이 나오면 왼쪽, 오른쪽, 혹은 직진. 딱 한 군데만 골라서 신호를 보내주는 역할. 내가 알던 라우터는 그런데…”
솔라가 메모지를 루나 쪽으로 밀었다.
“여기서는 라우터가 여러 전문가를 선택한대. 이건 마치… 사거리에서 동서남북 모든 방향으로 동시에 가라고 소리치는 거랑 같잖아. 라우터가 어떻게 하나 이상의 경로를 고를 수 있는 거지?”
솔라의 머릿속에 그려진 이미지는 명확했다. 데이터 패킷이 교차로에 도착하면, 라우팅 테이블을 쓱 훑어본 뒤 가장 효율적인 단 하나의 출구로 보내주는 모습. 그게 라우터의 당연한 임무라고 생각했다. 여러 곳으로 동시에 보낸다는 개념 자체가 어색했다.
루나는 솔라가 밀어준 메모를 잠시 들여다보더니, 고개를 끄덕였다.
“솔라 네가 아는 라우터의 역할이 맞아. 보통은 그렇지. 그런데 만약 네가 답을 찾아주는 앱을 만들고 있다고 상상해볼까? 아주 똑똑한 맛집 추천 앱이야.”
“맛집 추천 앱?”
“응. 어떤 사용자가 이렇게 질문했다고 해봐. ‘강남역 근처에서 파스타도 맛있고, 디저트도 특별한 카페가 붙어있는 곳 좀 알려줘.’ 자, 이 질문에 완벽하게 답하려면 어떤 전문가의 도움이 필요할까?”
루나의 말에 솔라는 잠시 생각에 잠겼다. 질문은 하나였지만, 그 안에는 두 가지의 뚜렷한 정보가 필요했다.
“음… 일단 강남역 근처의 파스타 맛집을 잘 아는 ‘이탈리안 요리 전문가’가 있어야겠네. 그리고… 그것만으로는 부족하지. ‘디저트 카페 전문가’도 필요해. 그 전문가가 특별한 디저트가 있는 곳을 알아야 하니까.”
말을 내뱉는 순간, 솔라의 눈이 동그래졌다.
“아! 두 명이네. 질문은 하나인데, 필요한 전문가는 둘이야.”
“바로 그거야.”
루나가 부드럽게 말을 이었다.
“이런 상황에서 ‘라우터 에이전트’는 교통경찰처럼 하나의 길만 알려주는 역할이 아니야. 질문을 받은 뒤 그 의도를 똑똑하게 분석하는 ‘총괄 매니저’에 더 가까워. 매니저가 질문을 딱 보더니, ‘아, 이건 파스타 전문가와 디저트 전문가 둘 다의 의견이 필요하겠군.’ 하고 판단하는 거지.”
루나는 양손을 펼쳐 보였다. 한 손은 ‘파스타 전문가’, 다른 한 손은 ‘디저트 전문가’를 상징하는 것처럼 보였다.
“그리고는 두 전문가에게 동시에 ‘출동’ 신호를 보내는 거야. ‘강남역 근처’라는 공통된 조건과 함께, 한 명에게는 파스타 정보를, 다른 한 명에게는 디저트 정보를 요청하는 거지. 갈림길에서 한쪽 길만 택하는 게 아니라, 필요한 모든 길로 동시에 전문가를 보내는 셈이야.”
솔라는 그제야 고개를 끄덕였다. 머릿속을 맴돌던 사거리의 교통경찰 이미지가 사라지고, 여러 명의 팀원에게 동시에 업무를 지시하는 유능한 프로젝트 매니저의 모습이 떠올랐다. 막혀 있던 생각의 물꼬가 트이는 기분이었다.
솔라는 다시 자신의 메모지를 끌어당겨 첫 구절을 읽었다.
Router Agent가 사용자 입력의 의도를 분석 후, 필요한 복수의 전문가 Agent 선택...
“아하! 그러니까 ‘복수의 전문가를 선택한다’는 게 바로 이런 뜻이었구나. 라우터가 혼자서는 완벽한 답을 만들기 어려운 복합적인 질문을 받았을 때, 관련된 전문가들을 전부 호출하는 거네. 하나만 고르는 게 아니라.”
스스로 내린 결론에 만족하며 솔라는 미소를 지었다. 이제야 문장의 첫 단추가 제대로 끼워진 느낌이었다. 하지만 그 만족감은 길지 않았다. 곧바로 또 다른 질문이 꼬리를 물고 떠올랐다.
“좋아, 거기까지는 알겠어. 총괄 매니저가 파스타 전문가랑 디저트 전문가한테 동시에 일을 시켰다고 치자. 그런데 그 다음은? 한 명은 ‘A 파스타가 최고예요!’라고 외치고, 다른 한 명은 ‘B 카페 케이크가 환상적이죠!’라고 동시에 말하면 어떡해? 둘의 답변이 제각각 날아올 텐데, 이 정신없는 상황을 어떻게 정리해서 하나의 깔끔한 추천으로 만들지?“
2장: 여러 전문가를 동시에 움직이고, 의견 모으기
솔라의 볼펜이 하얀 메모지 위에서 길을 잃은 듯 헤매고 있었다. 머릿속에 떠오른 ‘총괄 매니저’의 이미지는 명쾌했지만, 그 매니저가 실제로 일하는 방식은 여전히 안갯속이었다. 솔라는 매니저가 ‘파스타 전문가’와 ‘디저트 전문가’를 동시에 호출하는 장면까지는 쉽게 그릴 수 있었다. 하지만 바로 그 다음 단계에서 그림이 엉망으로 꼬였다.
솔라는 두 전문가를 상징하는 네모 상자를 그리고, 그 상자들로부터 뻗어 나오는 화살표를 그리기 시작했다. 한 전문가의 보고가 끝나면 다음 전문가가 보고하는 순차적인 흐름을 그려보았다. “이건 ‘동시’가 아니잖아.” 그녀는 중얼거리며 고개를 저었다. 그럼 동시에 보고한다면? 두 개의 화살표가 하나의 도착점을 향해 마구잡이로 돌진하는 그림이 그려졌다. 결과는 뒤죽박죽 섞여버릴 게 뻔했다. 솔라는 결국 볼펜을 내려놓고 어지러운 낙서가 된 메모지를 멍하니 바라보았다.
“거기서 길이 막혔구나.”
루나의 목소리였다. 솔라의 복잡한 심경이 그대로 드러난 낙서를 본 루나가 조용히 입을 열었다.
“총괄 매니저가 두 전문가를 동시에 호출한 건 좋은데, 그들의 보고를 어떻게 질서 있게 받을지가 문제인 거지?”
“응. 한 명씩 줄을 세우자니 ‘병렬 처리’라는 말이 무색해지고, 동시에 말하라고 하자니 완전 시장판이 될 것 같아. ‘A 파스타가 최고!’랑 ‘B 케이크가 환상적!’이라는 말이 허공에서 부딪혀서 깨져버리는 느낌이라고.”
솔라의 비유에 루나는 희미하게 미소 지으며 자신의 노트북을 펼쳤다. 빈 화면에 간단한 다이어그램을 그리기 시작했다.
“매니저가 그렇게 허술하게 일을 처리하진 않아. 솔라 네가 생각한 것보다 훨씬 체계적인 시스템이 있거든. 자, 이걸 봐.”
루나는 화면 중앙에 ‘라우터’라고 적은 뒤, 양옆으로 ‘파스타 전문가’와 ‘디저트 전문가’ 상자를 배치했다. 그리고는 라우터에서 두 전문가 상자로 향하는 화살표를 각각 그렸다.
“매니저, 즉 라우터가 할 일을 정하면, 특정 전문가들에게 ‘이 일을 하세요’라고 편지를 보내. 이 과정을 **Send**라고 불러. 여러 전문가에게 동시에 Send하면, 편지를 받은 각 전문가들은 각자의 자리에서 즉시 일을 시작하지. 마치 여러 갈래로 일이 쫙 퍼져나가는 부채(Fan) 같다고 해서 **‘Fan-out’**이라고도 해.”
“Fan-out… 일이 부채처럼 펼쳐진다라. 이름 한번 잘 지었네. 그럼 이제 각자 일을 시작했어. 그 다음이 중요하잖아. 결과 보고는 어떻게 해?”
솔라의 질문에 루나는 다이어그램에 새로운 상자 하나를 추가했다. 두 전문가 상자 아래에 놓인 큼지막한 상자였다. 루나는 그 안에 expert_notes라고 적었다.
“모든 전문가에게는 공동으로 사용하는 ‘결과 보고용 노트’가 주어져. 이게 바로 expert_notes야.”
루나는 ‘파스타 전문가’ 상자에서 expert_notes 상자로, ‘디저트 전문가’ 상자에서도 expert_notes 상자로 화살표를 그렸다. 여러 갈래로 퍼져나갔던 화살표들이 다시 하나의 상자를 향해 모여드는 모양새였다.
“여기에는 아주 중요한 규칙이 있어. 일을 마친 전문가는 이 노트의 빈 곳에 자기 보고 내용을 적어야 해. 그런데 절대 남이 써놓은 내용을 지우거나 덮어쓰면 안 돼. 무조건 그 뒤에 이어서 써야 하지. 파스타 전문가가 먼저 일을 끝냈으면 파스타 추천 내용을 적고, 잠시 뒤 디저트 전문가가 일을 끝내면 바로 그 아랫줄에 디저트 추천 내용을 추가하는 식이야.”
솔라의 눈이 반짝였다. “아! 그럼 순서에 상관없이 결과가 도착하는 대로 차곡차곡 쌓이겠네?”
“정확해. 덕분에 두 전문가가 서로 끝날 때까지 기다릴 필요도 없고, 두 사람의 보고가 허공에서 부딪혀 깨질 일도 없지. 이렇게 기존의 값에 새로운 값을 더하거나 목록에 추가하는 식으로 데이터를 합치는 특별한 규칙을 **Reducer**라고 불러. 이 Reducer 규칙 덕분에 병렬로 처리된 결과들이 안전하게 하나의 리스트로 누적되는 거야.”
솔라는 루나의 노트북 화면에 그려진 다이어그램을 유심히 들여다보았다. 처음의 혼란스럽던 낙서와는 비교도 안 되게 명료했다. 하나의 지점에서 여러 전문가에게로 일이 뻗어 나가고(Fan-out), 각 전문가가 처리한 결과는 다시 하나의 노트(expert_notes)로 깔끔하게 모여든다.
솔라는 자신의 메모지를 뒤집어 새로운 면에 직접 그림을 그리기 시작했다. 중앙의 ‘라우터’에서 뻗어 나가는 ‘Send’ 화살표들. 각자의 일을 처리하는 ‘전문가’들. 그리고 전문가들의 결과물이 ‘Reducer(덧붙이기)’ 규칙에 따라 차곡차곡 쌓이는 expert_notes 상자까지.
Conditional Edge + Send를 통해 선택된 전문가 Agent들이 동시에 실행되고, Reducer를 통해 결과가 하나의 리스트로 누적된다...
메모지에 적혀 있던 문장이 이제야 비로소 살아 움직이는 듯했다.
“알겠다! 동시에 일을 시키는 것(병렬 실행)과 그 결과를 안전하게 모으는 것(결과 누적)은 완전히 분리된 단계였구나. ‘Fan-out’으로 일을 뿌리고, Reducer가 적용된 expert_notes로 거둬들이는 거네.”
스스로 그린 깔끔한 다이어그램을 보며 솔라는 만족스럽게 중얼거렸다. 이제 두 전문가의 의견은 expert_notes라는 노트 안에 안전하게 모였다.
하지만 만족감도 잠시, 솔라는 expert_notes 상자를 볼펜으로 톡톡 두드렸다. 그 안에는 이런 내용이 적혀 있을 것이다. ["파스타 추천: A 레스토랑의 알리오 올리오", "디저트 추천: B 카페의 딸기 케이크"]
“좋아. 보고서는 깔끔하게 모였어. 그런데… 이걸 이대로 사용자한테 보여줄 순 없잖아? ‘파스타 추천은 A 레스토랑의 알리오 올리오이고, 디저트 추천은 B 카페의 딸기 케이크입니다’ 하고 멋지게 한 문장으로 다듬어 줘야지. 이 흩어진 메모들을 최종 보고서로 종합하는 건 대체 누가 하는 거지?“
3장: 개별 의견을 하나의 최종 답변으로 종합하기
솔라의 볼펜이 expert_notes라고 적힌 상자를 톡톡 두드렸다. 그 안에는 두 전문가가 남긴 보고서가 가지런히 담겨 있었다. 어지럽게 흩어질 뻔했던 정보들이 하나의 노트 안에 안전하게 모였다는 사실은 만족스러웠다. 하지만 그 만족감은 노트를 들고 다음 단계로 나아가려는 순간, 어색한 장벽에 부딪혔다.
솔라는 새 메모지를 꺼내 들었다. 마치 자기가 맛집 추천 앱이 된 것처럼, 최종 답변을 작성해 보기로 했다. 맨 위에 ‘최종 답변’이라고 적고는, expert_notes 상자 안에 있을 법한 내용을 그대로 옮겨 적었다.
- 파스타 추천: A 레스토랑의 알리오 올리오
- 디저트 추천: B 카페의 딸기 케이크
솔라는 자기가 쓴 글을 소리 내어 읽어보았다. “파스타 추천은 A 레스토랑의 알리오 올리오. 디저트 추천은 B 카페의 딸기 케이크입니다.” 딱딱하고 기계적인 느낌. 마치 서로 다른 두 사람이 쓴 메모를 아무런 가공 없이 그냥 붙여놓은 것 같았다. 질문을 던진 사용자는 유기적으로 연결된 하나의 멋진 추천을 기대했을 텐데, 이건 그냥 정보의 나열일 뿐이었다.
“이건 아니야.”
솔라는 자기가 쓴 답변에 가위표를 그었다. 보고서가 모이긴 했지만, 이걸 어떻게 하나의 목소리로 다듬어야 할지 막막했다. 각자 자기 분야만 파고든 전문가들의 날것 그대로의 의견을 모아놓는 것만으로는 부족했다. 이 조각들을 녹여 하나의 완성된 문장으로 빚어낼 마지막 장인이 필요했다.
“그 마지막 장인도, 하나의 에이전트야.”
솔라의 고민을 지켜보던 루나가 나지막이 말했다. 루나는 솔라가 그려놓은 다이어그램을 손가락으로 가리켰다. 라우터에서 ‘파스타 전문가’와 ‘디저트 전문가’로 화살표가 뻗어 나가고(Fan-out), 두 전문가의 결과물이 다시 expert_notes 상자로 모여드는 그림이었다.
루나는 볼펜을 들어 expert_notes 상자 바로 아래에 새로운 네모 상자를 하나 더 그렸다. 그리고 expert_notes에서 그 새로운 상자로 향하는 화살표를 이었다.
“이 시스템에는 또 다른 종류의 전문가가 있어. 이 전문가의 유일한 임무는 expert_notes에 적힌 모든 메모를 읽고, 그것들을 종합해서 사용자가 이해하기 쉬운, 아주 자연스러운 하나의 최종 보고서를 작성하는 거야.”
루나는 새로 그린 상자 안에 synthesize_agent (종합 에이전트)라고 적어 넣었다.
“여러 갈래로 흩어졌던 일이 다시 하나로 모이는 거지. 부채(Fan)가 펼쳐졌다가 다시 접히는 것처럼. 그래서 이 마지막 단계를 **‘Fan-in’**이라고 불러. 여러 전문가의 의견을 종합하는 단계야.”
Fan-in. 솔라는 그 단어를 입안에서 굴려보았다. Fan-out으로 일을 분산시키고, Fan-in으로 결과를 종합한다. 펼치고, 모은다. 비로소 전체 그림의 대칭이 완벽하게 맞춰지는 느낌이었다.
“자, 그럼 솔라 네가 직접 ‘종합 에이전트’가 되어볼래?”
루나가 솔라가 가위표를 쳐놓은 메모지를 가리켰다. 그 위에는 여전히 두 개의 분리된 정보가 남아있었다.
- 파스타 추천: A 레스토랑의 알리오 올리오
- 디저트 추천: B 카페의 딸기 케이크
솔라는 잠시 생각에 잠겼다. 질문은 ‘파스타도 맛있고 디저트도 특별한 곳’이었다. 두 정보를 단순히 나열하는 게 아니라, 하나의 경험처럼 엮어줘야 했다. 솔라는 숨을 한번 고르고, 새로운 메모지에 천천히 문장을 써 내려가기 시작했다.
“강남역 근처에서 맛있는 파스타와 특별한 디저트를 함께 즐길 곳을 찾으시는군요! ‘A 레스토랑’의 알리오 올리오를 추천해 드려요. 식사를 마친 뒤에는 바로 옆 ‘B 카페’에서 환상적인 딸기 케이크로 완벽한 마무리를 해보시는 건 어떠세요?”
스스로 쓴 문장을 읽어본 솔라의 얼굴에 환한 미소가 번졌다. 딱딱했던 두 개의 메모가 부드럽게 연결되어 하나의 근사한 제안이 되었다. 이게 바로 ‘종합’의 힘이었다.
그 순간, 솔라는 책상 한쪽에 놓여있던, 모든 혼란의 시작이었던 첫 메모지를 끌어당겼다.
복수 전문가 Router는 필요한 여러 Agent를 Send로 병렬 실행하고, 각 결과를 expert_notes에 Reducer로 누적한 뒤 synthesize_agent가 하나의 답변으로 병합한다.
이제야 비로소 문장이 한눈에 들어왔다. 솔라는 손가락으로 문장을 하나씩 짚어가며 스스로 해설을 붙였다.
“‘복수 전문가 Router’가 ‘파스타 전문가’와 ‘디저트 전문가’를 고르고… Send로 동시에 일을 시키고(Fan-out)… 각자의 결과는 expert_notes에 차곡차곡 쌓이고… 마지막으로 ‘synthesize_agent’가 노트를 읽고 멋진 최종 답변으로 병합(Fan-in)하는구나!”
마치 복잡한 기계의 설계도를 완벽하게 이해하게 된 듯한 짜릿함이 밀려왔다.
“언니, 그럼 만약에… 사용자가 ‘내일 서울 날씨와 그 날씨에 어울리는 옷차림 추천해 줘’라고 물어보면…?”
솔라는 질문을 던짐과 동시에 스스로 답을 찾아 나갔다. 그녀는 망설임 없이 새 다이어그램을 그리기 시작했다.
- 라우터가 ‘날씨 정보 에이전트’와 ‘패션 추천 에이전트’를 선택한다.
- 두 에이전트에게 동시에 일을 보낸다(Fan-out).
- 두 에이전트는 각자의 결과를
expert_notes에 적는다.["내일 서울: 맑음, 최고 25도", "추천 옷차림: 반팔, 얇은 가디건"] synthesize_agent가 이 노트를 읽고 최종 답변을 만든다(Fan-in).
솔라는 마지막 종합 에이전트의 역할까지 상상하며 최종 결과물을 중얼거렸다.
“내일 서울은 대체로 맑고 낮 최고 기온은 25도로 예상됩니다. 활동하기 좋은 날씨이니, 가벼운 반팔에 얇은 가디건을 챙기시면 좋겠네요.”
더 이상 루나의 설명은 필요 없었다. 솔라는 이제 어떤 복합적인 질문이 들어와도 여러 전문가를 동원하고 그 결과를 종합해 하나의 완성된 답변을 만들어내는 전체 과정을 스스로 설계할 수 있게 된 것이다. 그녀의 손끝에서, 흩어져 있던 점들이 마침내 하나의 견고한 선으로 이어졌다.