Multi-Agent 06

기능이 늘어날수록 단일 Agent가 재사용 어려워지는 이유

처음 만든 Agent에 프롬프트만 계속 추가하면 확장된다고 보기 쉽다.

근거 · 교안 p15-p17

기능이 늘어날수록 단일 Agent가 재사용 어려워지는 이유 대표 이미지

1장: 기능 추가가 항상 좋은 것만은 아니라고요?

솔라는 노트북을 들고 거실로 달려 나왔다. 화면에는 코드 편집기와 결과 창이 반씩 나뉘어 있었다. 얼굴에는 막 새로운 발견을 해낸 사람 특유의 흥분과 뿌듯함이 가득했다. 소파에 앉아 책을 읽던 언니 루나를 향해 솔라가 의기양양하게 외쳤다.

“언니, 이거 봐! 내가 만든 회의록 요약 Agent, 드디어 기능 추가했어. 이제 할 일 목록도 뽑아준다고!”

솔라는 얼마 전 간단한 Agent를 하나 만들었다. 긴 회의록 텍스트를 입력하면 핵심 내용만 간추려주는, 제법 쓸모 있는 녀석이었다. 솔라는 여기에 만족하지 않고 새로운 능력을 부여하기로 마음먹었다. 회의 내용 중 ‘누가 무엇을 언제까지 하기로 했는지’를 따로 정리하는 기능이었다.

루나는 잠시 책에서 시선을 들어 솔라의 노트북 화면을 바라봤다. “오, 좋은데? 어떻게 구현했어?”

“간단했어. 원래 있던 지시사항에 ‘그리고 회의의 액션 아이템을 찾아서 목록으로 만들어줘’라는 문장만 추가했지. LLM은 똑똑하니까, 이 정도는 금방 알아들을 거라고 생각했어.”

솔라의 대답은 자신감에 차 있었다. 마치 레고 블록 하나를 더 얹는 것처럼, 기능 추가는 그저 지시사항 한 줄을 더하는 간단한 작업이라고 믿는 듯했다. 그것이 LLM의 유연성이 주는 매력이기도 했다.

“그럼 어디 한번 볼까? 마침 지난주 우리 팀 회의록이 있네.”

루나가 자신의 노트북에서 회의록 파일을 찾아 솔라에게 건넸다. 솔라가 이전에 테스트용으로 여러 번 사용했던, 그래서 이미 완벽한 요약 결과가 나온다는 것을 알고 있는 바로 그 파일이었다. 솔라는 신나게 파일을 Agent에 입력하고 실행 버튼을 눌렀다. 잠시 후, 결과 창에 새로운 텍스트가 나타났다.

그런데 솔라의 표정이 미묘하게 굳어졌다.

“어…?”

새롭게 추가된 ‘할 일 목록’은 그럭저럭 잘 정리되어 있었다. 하지만 문제는 다른 곳에서 터졌다. 원래 완벽하게 생성되던 ‘핵심 요약’ 부분이 완전히 엉망이 된 것이다. 문장들은 장황해졌고, 논의의 핵심 대신 지엽적인 내용만 담겨 있었다. 이전 버전이 보여주었던 간결하고 통찰력 있는 요약은 온데간데없었다.

“왜 이러지? 할 일 뽑으랬더니 요약하는 법을 까먹었나?”

솔라는 당황해서 코드를 다시 들여다봤다. 하지만 바뀐 것은 정말로 지시사항 마지막에 추가한 한 문장뿐이었다. 기존의 요약 관련 지시는 그대로 있었다. 단지 새로운 임무 하나를 추가했을 뿐인데, 왜 멀쩡하던 기능이 망가지는 걸까? 솔라는 몇 번이고 Agent를 다시 실행해 봤지만, 결과는 마찬가지였다.

그 모습을 조용히 지켜보던 루나가 입을 열었다.

“솔라, 혹시 지금 Agent의 복잡도가 1 더하기 1은 2라고 생각한 거 아니야?”

“응? 무슨 말이야?”

“요약 기능 하나일 때 복잡도가 1이었다면, 할 일 목록 추출 기능이 더해졌을 때 총 복잡도는 2가 되는 게 아니라는 뜻이야.”

루나는 펜과 노트를 가져왔다. 그리고 중앙에 네모 상자 하나를 그렸다. ‘단일 Agent’라고 적었다.

“이 Agent에게 처음엔 ‘요약’이라는 임무 하나만 줬어. Agent는 들어온 정보를 오직 ‘요약’이라는 목표에만 집중해서 처리하면 됐지. 아주 간단한 길이야.”

루나는 ‘정보’에서 네모 상자를 거쳐 ‘요약 결과’로 향하는 화살표 하나를 그렸다.

“그런데 여기에 ‘할 일 찾기’라는 임무를 추가했어.”

루나는 네모 상자에서 ‘할 일 목록’으로 향하는 화살표를 하나 더 그렸다. 이제 상자에서는 두 개의 화살표가 뻗어 나가고 있었다.

“Agent는 이제 들어온 문장이 요약에 필요한 내용인지, 할 일 목록에 포함될 내용인지, 아니면 둘 다에 해당하는지, 혹은 둘 다 아닌지를 판단해야 해. 그냥 임무가 두 개가 된 게 아니라, 임무들 사이의 관계와 판단 기준까지 새로 생긴 거야.”

루나는 두 개의 결과 화살표 사이에 여러 개의 점선을 복잡하게 연결했다. 마치 거미줄처럼 보였다.

“기능 하나를 추가하는 건, 단순히 작업 하나를 더하는 게 아니야. 기존 기능들과의 상호작용, 역할 충돌 가능성, 판단의 우선순위 같은 숨겨진 연결을 기하급수적으로 늘리는 일이지. 마치 조용한 방에 사람 한 명을 더 들일 때, 대화의 가짓수가 단순히 하나 느는 게 아닌 것처럼.”

솔라는 루나의 그림을 멍하니 바라봤다. 화살표 두 개 사이에 얽히고설킨 점선들이 마치 방금 전 망가져버린 자신의 요약 결과처럼 느껴졌다. 하나의 지시사항을 추가한 대가가 이렇게 클 줄은 몰랐다.

“아… 그래서 그랬구나. 나는 그냥 블록 하나 더 쌓는다고 생각했는데. 실제로는 보이지 않는 거미줄을 잔뜩 만들어낸 거였어. 기능 추가가 복잡도를 증폭시키는 스위치 같네.”

솔라는 고개를 끄덕였다. 처음 Agent를 만들었을 때의 단순함과 명쾌함이 왜 기능 하나를 추가하자마자 사라졌는지, 그 구조적 원인을 어렴풋이 알 것 같았다. 작은 변경이 전체 시스템에 예측 불가능한 영향을 미친다는 것, 그 위험성을 눈으로 직접 확인한 셈이다. 기능이 늘어날수록 단일 Agent는 점점 더 다루기 힘든 존재가 될 터였다.

문득 솔라의 머릿속에 새로운 질문이 떠올랐다.

“언니, 이렇게 복잡하게 얽히는 건 알겠어. 그래서 수정하기 어려운 거고. 그런데 이게 왜 ‘재사용’을 어렵게 만드는 거야? 기능이 10개인 복잡한 Agent가 있어도, 필요할 때 그중 ‘요약’ 기능 하나만 쏙 빼서 쓸 수는 없는 걸까?”

2장: 왜 로직이 밀집되면 재사용이 어려운가요?

솔라는 이전의 실패에 굴하지 않고, 자신의 생각을 증명해 보기로 마음먹었다. 언니의 ‘복잡도 증폭’이라는 말은 이해했지만, 여전히 미련이 남았다. ‘그래도 잘 만든 기능 하나쯤은 부품처럼 떼어다 쓸 수 있지 않을까?’

솔라는 노트북에 두 개의 창을 나란히 띄웠다. 왼쪽은 방금 전 요약 기능이 망가졌던 ‘회의록 요약 및 할 일 정리 Agent’였다. 오른쪽은 예전에 만들어 두었던 ‘이메일 분류 Agent’였다. 이 Agent는 이메일 본문을 읽고 ‘업무’, ‘광고’, ‘개인’으로 분류하는 단순한 역할을 했다.

“좋아, 이 이메일 분류 Agent에 ‘요약 기능’을 이식해 보는 거야.”

솔라는 왼쪽 Agent의 지시문에서 ‘핵심 내용 요약’에 해당하는 부분을 조심스럽게 복사했다. 그리고 오른쪽 Agent의 지시문 아래에 붙여넣었다. ‘이메일을 읽고, 중요도에 따라 분류해. 그리고 이메일의 핵심 내용을 세 문장으로 요약해 줘.’ 완벽한 계획처럼 보였다. 기능 블록 하나를 떼어 다른 장난감에 붙이는 것처럼 간단하게 느껴졌다.

솔라는 테스트용 업무 이메일 하나를 찾아 Agent에게 던져주고 실행했다. 과연 이메일을 ‘업무’로 분류하고, 깔끔한 요약문을 덧붙여줄까? 기대에 찬 솔라의 눈에 들어온 결과는 처참했다.

분류: 요약 결과: 본 이메일은 업무, 광고, 개인으로 분류할 수 있으며, 핵심 내용을 요약하는 기능을 가지고 있습니다.

Agent는 이메일 본문을 요약하는 대신, 자기 자신의 기능을 설명하고 있었다. 이메일 분류조차 제대로 하지 못했다. 마치 케이크 레시피 중간에 스테이크 굽는 법을 끼워 넣었더니, 밀가루로 스테이크를 구우려는 어처구니없는 결과가 나온 것 같았다.

“이게… 뭐야. 왜 시키지도 않은 자기소개를 하고 있어?”

솔라의 허탈한 목소리에, 소파에서 그 모습을 지켜보던 루나가 다가왔다. 루나는 솔라의 실패한 결과물을 잠시 들여다보더니, 어깨를 툭 쳤다.

“솔라, 혹시 ‘요약 기능’이라는 부품이 따로 존재한다고 생각한 거야?”

루나는 솔라가 이전 대화에서 펼쳐 놓았던 노트를 다시 가져왔다. 그리고 새로운 페이지에 두 개의 그림을 그리기 시작했다. 첫 번째 그림은 깔끔한 상자 안에 ‘요약’, ‘분류’, ‘추출’이라고 적힌 벽돌들이 가지런히 쌓여 있는 모습이었다.

“이게 아마 솔라 네가 생각한 이상적인 Agent의 모습일 거야. 기능들이 독립적인 부품처럼 존재해서, 필요할 때마다 하나씩 쏙쏙 빼서 쓸 수 있는 구조. ‘요약’ 벽돌이 필요하면 그냥 꺼내서 다른 곳에 끼우면 그만이지.”

솔라는 고개를 끄덕였다. 바로 자신이 원했던 모습이었다.

“하지만 실제 네가 만든 Agent는 이렇지 않아.”

루나는 그 옆에 두 번째 그림을 그렸다. 이번에는 상자 안에 그림이 아니었다. 파란색, 빨간색, 노란색 물감을 한데 부어 마구 휘저어 놓은 것 같은, 복잡한 마블링 무늬였다. 각 색깔이 어디서 시작해서 어디서 끝나는지, 다른 색과 어떻게 섞여 있는지 구분할 수 없었다.

“네가 만든 ‘회의록 Agent’의 ‘요약’은 저 파란색 물감 같은 거야. 처음부터 ‘회의록’이라는 특정 재료와 ‘할 일 추출’이라는 빨간색 물감과 함께 섞여 있었어. ‘회의의 맥락에서 중요한 내용을 간추리되, 실행할 과제는 따로 명시해야 하니 그 부분을 제외하고 나머지를 엮어라’는 식으로, 모든 판단 로직이 서로에게 기대고 얽혀 있는 거지.”

루나가 펜으로 마블링 무늬의 한 부분을 가리켰다.

“여기서 파란색만 깨끗하게 분리해낼 수 있을까? 불가능해. 파란색을 떼어내려고 하면 빨간색과 노란색이 덕지덕지 묻어 나올 수밖에 없어. 네가 ‘요약’ 지시문을 복사했을 때, 그 지시문에 보이지 않게 묻어 있던 ‘회의록’이라는 특수한 문제 상황과 ‘할 일 목록’이라는 다른 역할의 흔적까지 함께 딸려간 거야. 새로운 Agent는 그 낯선 흔적들 때문에 혼란에 빠진 거고.”

솔라는 두 그림을 번갈아 보았다. 가지런한 벽돌 그림과 혼란스러운 마블링 그림. 자신의 실패가 어디서 비롯되었는지 선명하게 보였다. ‘요약 기능’이라는 독립적인 부품은 처음부터 존재하지 않았다. 단지 여러 기능과 판단 기준이 한데 엉겨 붙어 있는 하나의 덩어리, 즉 ‘로직이 밀집된 구조’만 있었을 뿐이다. 특정 문제에 너무나 강하게 결합되어 있어, 일부만 떼어내는 것이 원천적으로 불가능한 구조였다.

“아… ‘요약’이라는 역할이 따로 있었던 게 아니라, ‘회의록을 요약하고 할 일을 뽑는 존재’라는 정체성만 있었던 거구나. 정체성의 일부를 떼서 다른 애한테 붙이려고 하니 될 리가 없지.”

솔라는 한숨을 쉬며 중얼거렸다. 이제 Agent를 볼 때, 단순히 어떤 기능들이 있는지 목록을 보는 것만으로는 부족하다는 것을 깨달았다. 그 기능들이 얼마나 서로 얽혀 있는지, 이 ‘로직 밀집도’를 파악하는 것이 훨씬 중요했다.

그때, 솔라의 머릿속에 새로운 의문이 피어올랐다.

“알겠어. 이렇게 엉겨 붙어 있으면 재사용은 글렀네. 그런데 이게 그냥 재사용만 못하고 끝나는 문제야? 아니면 이걸 억지로 고쳐 쓰려고 하면 더 큰 문제가 생기는 걸까?”

3장: 새로 만드는 게 더 빠르다고요?

솔라는 포기하지 않았다. 언니가 그려준, 물감이 뒤섞인 마블링 그림을 노려보며 다짐했다. ‘재사용이 안 되는 건 알겠어. 그럼 고쳐 쓰면 되잖아.’ 아무리 복잡하게 엉겨 붙어 있어도, 못 고칠 것은 없다고 생각했다. 개발자의 끈기는 이런 상황에서 빛을 발하는 법이었다. 이건 게으름의 문제가 아니라, 의지의 문제라고 솔라는 믿었다.

솔라는 다시 ‘회의록 요약 및 할 일 정리 Agent’ 파일을 열었다. 지난번의 실패로 엉망이 된 상태 그대로였다. 이번 목표는 기능 추가나 이식이 아니었다. 기존 기능의 ‘개선’이었다.

“좋아, 이번엔 할 일 목록의 출력 형식을 바꿔보는 거야. 그냥 목록으로 나열하지 말고, ‘담당자’, ‘업무 내용’, ‘기한’으로 표를 만들게 시켜야지.”

이건 아주 작은 수정처럼 보였다. 이미 할 일을 잘 찾아내고 있으니, 그 결과를 표 형태로 보여달라는 지시만 추가하면 될 일이었다. 솔라는 신중하게 지시문을 수정했다. ‘…그리고 회의의 액션 아이템을 찾아, 담당자, 업무 내용, 기한을 열로 하는 표 형태로 정리해줘.’

솔라는 숨을 참고 실행 버튼을 눌렀다. 잠시 후 나타난 결과는 솔라의 마지막 남은 낙관론마저 부숴버렸다.

[회의 요약] | 담당자 | 업무 내용 | 기한 | |---|---|---| | 솔라 | 이 Agent는 회의록을 요약하는 기능과 | 알 수 없음 | | 루나 | 할 일 목록을 표로 만드는 기능을 가지고 있습니다. | 오늘까지 |

Agent는 엉뚱한 표를 만들어냈다. 심지어 회의 내용이 아니라 자기 자신의 기능을 분석해서 표 안에 채워 넣기까지 했다. 더 최악인 것은, 그나마 형체는 유지하고 있던 ‘핵심 요약’ 부분이 아예 표의 일부로 빨려 들어가 버렸다는 점이다. 시스템 전체가 녹아내려 뒤섞이는 것 같았다.

“아니, 이건 아니지!”

솔라는 오기가 생겼다. ‘표는 액션 아이템에만 적용해야지, 요약문은 그냥 텍스트로 둬야 한다고!’ 그녀는 지시문을 더 정교하게 다듬었다. 30분 동안 지시문과 씨름하며 수십 번을 다시 실행했다. 하지만 결과는 나아지지 않았다. 한 부분을 고치면 다른 부분이 망가지는 ‘풍선효과’만 계속될 뿐이었다. 요약 기능이 아예 사라지거나, 있지도 않은 담당자를 만들어내기도 했다.

결국 솔라는 두 손을 들었다. 그리고 키보드의 Ctrl+Z를 연타하기 시작했다. 화면 속 코드가 한 줄씩 과거로 돌아갔다. 표를 만들려던 시도, 할 일 목록을 추가하려던 시도가 모두 사라지고, 마침내 맨 처음 만들었던 ‘회의록 요약 Agent’의 깨끗하고 단순한 코드만 남았다. 솔라는 허탈한 한숨을 내쉬었다. 지난 몇 시간을 통째로 날려버린 기분이었다. 차라리 이 단순한 버전에서 출발해 ‘할 일 목록 표 생성 Agent’를 새로 만드는 게 훨씬 빨랐을 것이다.

그때 조용히 다가온 루나가 솔라의 화면을 보며 말했다.

“결국, 처음으로 돌아왔네.”

“응… 고쳐 쓰는 것보다 새로 만드는 게 더 빠르다는 말을, 이제는 알 것 같아. 이건 의지의 문제가 아니었어.”

루나는 책상 위에 놓인 작은 화분 두 개를 가리켰다. 하나는 여러 종류의 식물이 빽빽하게 심겨 하나의 덩어리처럼 자란 화분이었고, 다른 하나는 빈 화분이었다.

“저 빽빽한 화분이 네가 계속 고치려던 Agent야. 저기서 특정 식물의 잎 모양만 살짝 바꾸고 싶은데, 뿌리랑 줄기가 다른 식물들과 전부 얽혀있어서 건드릴 수가 없는 거지. 잎 하나 바꾸려다 다른 식물들까지 다 죽일 수 있으니까.”

루나는 말을 이었다.

“우리가 처음 만드는 간단한 Agent는 보통 개념 증명(PoC) 단계야. ‘이 아이디어가 작동하는가?’를 빠르게 확인하는 게 목표지. 저 빽빽한 화분처럼, 일단 이것저것 심어서 꽃이 피는지만 보는 거야. 그런데 그 PoC가 성공했다고 해서, 그 화분 위에 건물을 올릴 수는 없어.”

“건물?”

“응. PoC를 실제 서비스로 확장하는 건, 화분 위에 2층, 3층 집을 짓는 것과 같아. 저렇게 뿌리가 뒤엉킨 화분은 2층의 무게를 버틸 수 없어. 집을 지으려면, 빈 화분에 처음부터 튼튼한 기초 공사를 하고, 각 층을 지탱할 기둥을 설계해야 해. 어떤 식물(기능)을 어디에 심을지 미리 계획해야 하는 것처럼.”

루나의 비유에 솔라는 고개를 끄덕였다. 자신의 실패가 눈앞에 선명하게 그려졌다. 단일 Agent는 빠르게 아이디어를 확인할 수 있는 훌륭한 PoC였지만, 그게 전부였다. 기능이 추가되고 로직이 얽히면서, 수정 비용은 눈덩이처럼 불어났다. 결국 새로 만드는 것보다 훨씬 비싼 대가를 치르게 되는 구조. 그래서 실무에서는 ‘고쳐 쓰기’보다 ‘새로 만들기’를 택하는 거였다. PoC가 서비스로 확장되지 못하고 자꾸만 엎어지는 이유도 바로 이것이었다.

“그럼… 이 문제는 결국 더 똑똑한 정원사가 와도 해결 못 하는 거네? 아무리 뛰어난 사람이라도 이미 뒤엉킨 뿌리를 풀 수는 없으니까.”

솔라의 말에 루나가 희미하게 웃었다. 그 순간, 솔라의 머릿속에 한 가지 희망 섞인 의문이 떠올랐다.

“잠깐만, 언니. 만약에… 정원사 말고, 식물 자체가 엄청나게 똑똑하다면 어떨까? 우리가 쓰는 LLM 모델을 훨씬 더 강력한 걸로 바꾸면, 이런 복잡한 지시도 알아서 잘 처리해주지 않을까? 이건 Agent의 설계가 아니라, 그냥 모델 성능이 부족해서 그런 거 아닐까?”

4장: 모델 성능 문제가 아니라고요?

솔라는 이전의 좌절을 딛고 새로운 희망에 불타올랐다. ‘그래, 어쩌면 이건 정원사의 문제가 아니라 식물 자체의 문제일지도 몰라.’ 지난번 언니와의 대화 끝에 떠올린 생각이었다. 엉망으로 뒤얽힌 화분의 식물들이 아니라, 어떤 환경에서도 스스로 길을 찾는 아주 똑똑한 식물을 심는다면?

솔라는 노트북 앞에 앉아 결의에 찬 표정으로 키보드를 두드렸다. 그녀는 최근에 큰 화제를 모은, 기존 모델보다 훨씬 강력하다고 알려진 최신 LLM의 API 접속 권한을 막 얻은 참이었다. 마치 전설의 검을 손에 넣은 용사처럼, 솔라는 이 새로운 모델이 모든 문제를 해결해 줄 것이라 굳게 믿었다.

“이거라면 될 거야.”

솔라는 자신이 ‘Ctrl+Z’를 연타하며 과거로 되돌려 놓았던 바로 그 Agent, ‘회의록 요약 및 할 일 목록 표 생성 Agent’의 가장 복잡하고 문제가 많았던 버전을 다시 불러왔다. ‘요약’과 ‘할 일 목록’과 ‘표 서식’이라는 세 가지 요구사항이 위태롭게 뒤섞여 있던 바로 그 버전이었다.

이전 모델은 이 복잡한 지시 앞에서 완전히 길을 잃었다. 하지만 이번엔 달랐다. 솔라는 Agent의 핵심 엔진을 최신 LLM으로 교체했다. 마치 낡은 경차의 엔진을 떼어내고 F1 레이싱카의 엔진을 이식하는 것과 같았다.

“이 정도 성능의 모델이라면, 내가 조금은 뭉뚱그려 말해도 찰떡같이 알아듣겠지. ‘요약’ 따로, ‘표’ 따로, 알아서 구분해서 처리해 줄 거야.”

솔라는 기대감에 부풀어 실행 버튼을 눌렀다. 이전 모델이 30분간의 씨름에도 해결하지 못했던 문제였다. 과연 최첨단 지성은 이 난관을 어떻게 돌파할까?

결과가 화면에 나타났다. 솔라는 순간 숨을 멈췄다. 결과물은… 놀랍도록 완벽한 형태의 표였다. 깔끔한 선, 정확한 열 구분, 흠잡을 데 없는 서식이었다.

“오! 역시!”

하지만 솔라의 탄성은 오래가지 못했다. 표의 ‘내용’을 읽어본 그녀의 얼굴이 순식간에 굳어졌다.

담당자업무 내용기한
회의록본 문서의 목적은 정보 전달이며가능한 빠르게
Agent주어진 지시에 따라 최선의 결과를 생성해야 함상시 대기
솔라더 나은 성능의 모델을 통해 문제를 해결하고자 함바로 지금

새로운 Agent는 회의록 내용이 아니라, 자신이 처한 상황과 솔라의 의도까지 분석해서 그럴듯한 표를 만들어냈다. 더 강력해진 추론 능력이 오히려 엉뚱한 방향으로 발휘된 것이다. 마치 너무 유능한 신입사원에게 애매하게 업무를 지시했더니, 자기 마음대로 회사 비전과 목표를 재해석해서 보고서를 써 온 것과 같은 상황이었다. 문제는 전혀 해결되지 않았고, 오히려 더 복잡하고 예측하기 어려운 방식으로 꼬여버렸다.

솔라가 망연자실한 표정으로 화면을 보고 있자, 어느새 다가온 루나가 조용히 입을 열었다.

“새로운 정원사는 어때? 역시 화분을 되살리지 못했나 보네.”

“정원사가 아니라 식물을 바꿨는데도 그래. 훨씬 더 똑똑한 식물인데도… 아니, 오히려 너무 똑똑해서 문제인 것 같아. 내 머릿속까지 읽어서 표를 만들고 있잖아.”

솔라가 허탈하게 웃으며 말했다. 루나는 솔라의 책상에서 이면지 한 장을 가져와 펜으로 간단한 그림을 그렸다. 한쪽에는 ‘세계 최고의 전문가’라고 적고, 다른 한쪽에는 기다란 메모지를 그렸다.

“솔라, 네가 세계적인 명성을 가진 최고의 컨설턴트를 고용했다고 상상해봐. 그리고 그에게 이런 메모를 주는 거야.”

루나는 메모지 그림 안에 글씨를 써 내려갔다.

“이 수십 페이지짜리 보고서의 핵심을 시적으로 요약해 주되, 재무 관련 수치는 모두 제외하세요. 그리고 보고서에 언급된 모든 인물의 다음 주 일정을 예측해서 표로 만드세요. 단, 표의 양식은 자유롭게 하되 미학적으로 아름다워야 합니다. 이 모든 작업은 한 번에, 동시에, 완벽하게 처리해야 합니다.”

“이런 지시를 받은 컨설턴트는 어떻게 반응할까? 아무리 뛰어난 사람이라도 혼란스러울 수밖에 없어. ‘시적인 요약’과 ‘데이터 기반 일정 예측’은 서로 다른 종류의 사고방식을 요구하거든. 이 전문가는 자신의 지능 대부분을 ‘이 모순적인 요구사항을 어떻게 해석해야 하는가’를 고민하는 데 써버릴 거야. 실제 업무가 아니라, 뒤죽박죽인 지시를 해독하는 데 에너지를 낭비하는 거지.”

루나는 솔라가 새로 실행한 Agent의 결과물을 가리켰다.

“지금 네 Agent가 딱 그 상황이야. 더 강력한 모델을 썼다는 건, 그냥 더 똑똑한 전문가를 고용했다는 뜻일 뿐이야. 문제의 본질은 전문가의 능력이 아니었어. 처음부터 여러 역할과 책임을 한 사람에게 전부 떠넘기는, 이 비효율적인 ‘업무 지시 구조’ 자체가 문제였던 거지.”

루나의 말에 솔라는 머리를 한 대 맞은 듯한 충격을 받았다. 그랬다. 자신은 계속 ‘누가’ 이 일을 할 것인가에만 집중했다. 더 똑똑한 모델, 더 뛰어난 지능. 하지만 진짜 문제는 ‘어떻게’ 일을 시킬 것인가에 있었다.

“아…! 이건 모델의 지능 문제가 아니라, 내가 일을 시키는 방식, 이 구조 자체가 문제였구나.”

솔라는 방금 전까지 자신이 가졌던 막연한 기대감이 얼마나 순진했는지 깨달았다. 단일 Agent의 한계는 모델의 성능 부족 때문이 아니었다. 모든 종류의 판단과 추론, 생성을 단 하나의 통로, 단 하나의 LLM에 몰아넣는 구조적 설계의 필연적인 결과였다. 더 좋은 엔진을 단다고 해서, 설계 자체가 잘못된 자동차가 F1 트랙을 완주할 수는 없는 노릇이었다.

관점이 완전히 뒤바뀌는 순간이었다. 이제 솔라는 Agent를 볼 때 모델의 이름이나 성능부터 확인하지 않을 것이다. 대신 그 Agent가 어떤 구조로 설계되었는지를 먼저 보게 될 터였다. ‘설계 관점 전환 필터’가 머릿속에 장착된 기분이었다.

그렇다면 다음 질문은 명확했다.

“언니, 알겠어. 구조가 문제라는 거. 그럼 도대체, 이 단일 Agent라는 구조의 어떤 점이 그렇게 치명적인 문제를 일으키는 거야? 구체적으로 뭐가 어떻게 잘못된 건데?”

5장: 단일 Agent를 병들게 하는 구조적 원인들

솔라는 자신의 노트북 화면을 노려보고 있었다. 화면에는 실패한 Agent의 코드가 띄워져 있었다. 이제는 너무 익숙해져 버린, 회의록 요약과 할 일 목록 표 생성을 동시에 시도하다 장렬히 실패한 바로 그 코드였다. 구조가 문제라는 언니의 말은 뼈저리게 이해했다. 하지만 ‘구조’라는 말은 너무 막연했다. 건물의 어느 기둥에 금이 갔는지 알아야 보수 공사를 할 텐데, 지금 솔라는 안개 속에서 건물의 실루엣만 더듬는 기분이었다.

‘어디서부터 잘못된 거지?’ 솔라는 디버깅의 가장 기본적인 원칙을 따르기로 했다. 오류의 원인을 추적하는 것. 그녀는 Agent의 지시문을 한 단어씩 뜯어보았다. ‘요약하라’, ‘표로 만들어라’… 어느 지점에서 두 지시가 충돌하며 모든 것을 엉망으로 만들었을까? 솔라는 중간 과정을 확인하기 위해 지시문 사이에 ‘현재까지의 생각 정리해봐’ 같은 문장을 끼워 넣어 보았다. 하지만 Agent는 그 디버깅용 지시마저도 최종 결과물에 대한 새로운 요구사항으로 해석해 버렸다. 결과는 더 기괴해질 뿐이었다. 마치 수프 맛이 이상해서 원인을 찾으려 국자로 휘저었더니, 국자까지 녹아 수프의 일부가 되어버린 것 같았다.

“아, 미치겠네! 속을 들여다볼 수가 없잖아!”

솔라의 외침에 루나가 조용히 다가왔다. 루나는 솔라의 키보드 옆에 놓여 있던 빈 메모지 한 장을 가져와 가운데에 네모난 상자 하나를 그렸다. ‘만능 Agent’라고 이름 붙였다.

“솔라, 지금 네가 하려는 건 수술실에 들어가지 않고 환자를 진단하려는 것과 같아. 이 상자 안에서 모든 일이 일어나니까, 밖에서는 원인을 알 수 없는 게 당연해.”

루나는 펜 끝으로 상자를 톡톡 두드렸다.

“이 ‘만능 Agent’가 일을 시작하기 전에, 어떤 정보들을 머릿속에 집어넣어야 하는지 전부 말해볼래?”

“음… 일단 내가 입력한 회의록 전문이 필요하고, ‘요약해달라’는 지시, ‘표로 만들어달라’는 지시도 알아야지. 그리고… 내가 이전에 어떤 질문을 했는지 같은 대화 기록도 참고할 거고. 아, 더 좋은 결과를 위해 인터넷 검색을 하도록 설정했다면 검색 결과도 포함되겠네.”

솔라가 말하는 동안 루나는 상자 바깥에서 온갖 종류의 화살표를 그려 상자 안으로 향하게 했다. 메모지는 순식간에 복잡해졌다. ‘사용자 입력’, ‘과거 대화’, ‘지시사항들’, ‘도구 결과’…

“좋아. 그럼 이 모든 정보를 받은 Agent는 안에서 무슨 일들을 해야 할까? 역할극을 한다고 생각해 봐.”

“일단… 받은 정보들을 바탕으로 뭘 먼저 해야 할지 ‘계획’을 세워야겠지? ‘아, 요약이랑 표 만들기를 둘 다 해야 하는구나.’ 하고. 그다음엔 계획에 따라 실제로 글을 ‘실행’해서 요약문도 쓰고 표도 만들고. 마지막으론 자기가 만든 결과물이 괜찮은지 스스로 ‘평가’도 해볼 거야.”

루나는 솔라의 대답을 듣는 대신, 상자 안에 작은 글씨로 ‘계획’, ‘실행’, ‘평가’라고 적어 넣고는 그 세 단어를 마구 휘저어 하나의 원으로 뭉개버렸다.

솔라는 그 그림을 보고 순간 할 말을 잃었다. 자신이 방금 겪었던 답답함의 정체가 눈앞에 그려져 있었다.

루나가 입을 열었다. “단일 Agent의 구조적 질병은 보통 세 가지 증상을 함께 동반해. 첫 번째는 방금 네가 직접 그린 ‘컨텍스트 과부하’야. 관련 있는 정보든 없는 정보든 일단 한 상자에 다 쑤셔 넣으니, 정작 중요한 정보가 무엇인지 길을 잃기 시작하지. 마치 너무 많은 참고서를 한 번에 펼쳐놓고 공부하는 것 같아.”

루나는 뭉개진 원을 펜으로 가리켰다.

“두 번째는 ‘역할 혼합’이야. 네 말대로 Agent는 계획도 하고, 실행도 하고, 평가도 해야 해. 그런데 단일 구조에서는 이 역할들이 분리되지 않아. 계획을 세우면서 동시에 글을 쓰고, 글을 쓰면서 동시에 스스로를 평가해. 축구 선수가 감독이자 선수이자 심판까지 하려는 셈이지. 그러니 추론 과정에서 혼선이 생기고, 엉뚱한 결과가 나오는 거야. 네 Agent가 자기 기능을 분석해서 표를 만든 것처럼 말이야.”

마지막으로 루나는 상자 전체를 가리키며 말했다.

“그리고 이 두 가지가 합쳐지면, 솔라 네가 방금 경험한 세 번째 증상, ‘오류 전파와 디버깅 불가’ 상태가 돼. 컨텍스트는 넘쳐나고 역할은 뒤섞여 있으니, 어디서 문제가 처음 시작됐는지 추적할 수가 없어. 계획이 잘못됐나? 실행이 잘못됐나? 평가를 잘못했나? 알 수가 없지. 작은 오류 하나가 순식간에 시스템 전체로 퍼져나가고, 개발자는 그걸 고치기 위해 모든 걸 처음부터 다시 만드는 길을 택하게 되는 거야.”

컨텍스트 과부하, 역할 혼합, 오류 전파. 솔라는 세 가지 원인이 따로 노는 문제가 아니라, 서로가 서로의 원인이자 결과가 되는 악순환의 고리라는 것을 깨달았다. 마치 병의 근원을 진단하는 키트를 손에 쥔 기분이었다.

“아… 그래서 그랬구나. 나는 계속 증상만 고치려고 했는데, 병의 원인이 완전히 다른 곳에 있었네. 컨텍스트, 역할, 디버깅… 이 세 가지를 확인하면 되겠어.”

솔라는 더 이상 실패한 코드를 들여다보지 않았다. 대신 깨끗한 새 파일을 열었다. 키보드에 손을 올렸지만, 코드를 치는 대신 주석 기호(//)를 사용해 글을 쓰기 시작했다. 마치 새로운 Agent의 설계도를 그리듯.

// Agent 구조 개선 보고서 초안

// 기존 문제: 하나의 Agent가 [요약], [할 일 표 생성] 등 모든 역할을 수행하며 컨텍스트 과부하, 역할 혼합, 오류 전파 문제 발생.

// 제안 구조: 역할 분리 // 1. [계획 Agent]: 사용자 요청 분석. '요약'과 '표 생성' 작업 필요 판단. 작업 지시 생성. // 2. [요약 Agent]: '계획 Agent'로부터 '요약' 작업만 지시받음. 회의록 텍스트만 전달받아 요약에만 집중. // 3. [표 생성 Agent]: '계획 Agent'로부터 '표 생성' 작업만 지시받음. 회의록 텍스트만 전달받아 표 생성에만 집중. // 4. [종합 Agent]: 각 Agent의 결과물을 취합하여 최종 보고서 형태로 조립.

한 줄 한 줄 써 내려가는 솔라의 손가락에는 더 이상 좌절감이 없었다. 복잡하게 얽힌 뿌리를 풀어헤치려는 대신, 각 식물이 잘 자랄 수 있는 독립된 화분들을 설계하고 있었다. 문제가 발생하면 어느 화분에 문제가 있는지 명확히 알 수 있는 구조였다.

그 모습을 지켜보던 루나가 희미하게 미소 지으며 말했다.

“이제 제대로 된 설계도를 그리기 시작했네.”