21장. 전문 에이전트 구현
에이전트를 나누는 기준 — 도구, 프롬프트, 책임
한 줄 요약
에이전트를 어떻게 나눌지는 직감이 아니라 세 가지 기준으로 정합니다. 쓰는 도구가 다른가, 지켜야 할 규칙이 다른가, 잘했는지를 다른 것으로 판단하는가. 하루마켓의 상담 업무를 이 기준으로 나누면 세 영역이 나옵니다.
1. 세 가지 기준
| 기준 | 묻는 것 |
|---|---|
| 도구 | 이 일에 필요한 도구 묶음이 다른가 |
| 프롬프트 | 이 일에서 지켜야 할 규칙이 다른가 |
| 책임 | 이 일을 잘했는지를 다른 것으로 판단하는가 |
셋 가운데 하나라도 뚜렷하게 다르면 나눌 후보입니다. 셋이 모두 비슷하면 나누지 않습니다.
2. 하루마켓에 적용하면
| 주문조회 에이전트 | 정책안내 에이전트 | 요청처리 에이전트 | |
|---|---|---|---|
| 도구 | get_my_orders, get_order_status, get_my_membership, search_products, check_stock |
search_policy |
change_shipping_address, request_exchange, request_refund, get_my_requests, get_my_orders, create_ticket |
| 도구의 성격 | 데이터 읽기 | 문서 검색 | 기록을 남기는 처리 |
| 프롬프트의 핵심 | 도구로 조회한 데이터로만 보고한다 | 검색 결과에 근거하고 조항을 표기한다 | 되묻지 않고 처리한다. 처리하지 못했으면 했다고 말하지 않는다 |
| 잘했는지의 기준 | 조회한 값이 실제 데이터와 같은가 | 근거가 붙었는가, 없는 내용을 없다고 했는가 | 처리가 기록에 남았는가, 보고가 기록과 같은가 |
세 열이 겹치지 않습니다. 도구가 다르고, 규칙이 다르고, 잘했는지의 기준도 다릅니다. 이 표의 열 하나가 에이전트 하나의 설계서입니다.
요청처리 에이전트의 도구 가운데 get_my_orders 하나는 주문조회 에이전트와 겹칩니다. 주문번호 없이 "운동화 교환해 주세요"라는 요청이 왔을 때 어느 주문인지 찾는 데 필요하기 때문입니다. 조회가 목적이 아니라 처리의 준비입니다.
3. 나누면 무엇이 좋아지는가
고를 것이 줄어듭니다. 정책안내 에이전트의 도구는 하나입니다. 잘못 고를 수가 없습니다. 주문조회 에이전트도 열한 개가 아니라 다섯 개 가운데서 고릅니다.
프롬프트가 한 가지 일만 말합니다. 요청처리 에이전트의 프롬프트에는 "조항을 표기하라"가 없고, 정책안내 에이전트의 프롬프트에는 "주문번호를 묻지 마라"가 없습니다. 읽을 줄이 적으면 빠뜨릴 줄도 적습니다.
따로 시험하고 따로 고칩니다. 정책 답변에 근거 표기가 빠지기 시작했다면 정책안내 에이전트의 프롬프트만 고치고, 그 에이전트만 다시 시험합니다. 주문조회 에이전트는 건드리지 않았으므로 다시 볼 필요가 없습니다.
처리 도구를 쥔 쪽이 하나로 좁혀집니다. 주문조회와 정책안내 에이전트의 도구 목록에는 처리 도구가 없습니다. 이 둘은 무슨 질문을 받아도 아무것도 바꿀 수 없습니다. 다음 절에서 이 점을 따로 다룹니다.
4. 나누지 않는 경우
기준은 나누지 말아야 할 때도 알려 줍니다. "배송 추적 에이전트를 주문조회 에이전트에서 또 떼어 내야 할까?"를 따져 봅니다.
| 기준 | 배송 추적 vs 주문 조회 |
|---|---|
| 도구 | 같은 주문 데이터를 같은 도구로 본다 |
| 프롬프트 | "조회한 데이터로만 보고"로 같다 |
| 책임 | 둘 다 "조회한 값이 맞는가"로 판단한다 |
셋이 모두 같습니다. 나누면 에이전트 수와 호출만 늘어납니다. 나누지 않는 것이 맞습니다.
그래서 주문조회 에이전트는 주문만 보는 것이 아니라 상품 검색, 재고 확인, 고객 등급 조회까지 맡습니다. 모두 "데이터를 읽어서 사실을 보고한다"는 같은 종류의 일이기 때문입니다.
같은 이유로 배송지 변경 에이전트와 교환 에이전트를 따로 두지 않습니다. 둘 다 처리 도구를 쓰고, "되묻지 않고 처리하고, 못 했으면 못 했다고 보고한다"는 규칙이 같고, "기록에 남았는가"로 판단합니다. 요청처리 에이전트 하나가 맡습니다.
5. 프롬프트의 한 줄 한 줄에는 이유가 있다
주문조회 에이전트의 시스템 프롬프트에서 몇 줄을 뽑았습니다.
- 고객에게 주문번호를 묻지 마십시오. 주문번호가 없으면 반드시 get_my_orders 를
먼저 호출해 본인 주문 목록에서 해당 주문(상품명·시기)을 직접 찾습니다.
- 재고 확인 절차: search_products 로 상품을 찾아 product_id 를 얻은 뒤
check_stock 을 호출합니다. '확인이 어렵다'고 하기 전에 반드시 이 절차를 시도합니다.
- 재고 수량은 상품 전체 기준입니다. 색상·사이즈 같은 옵션별 수량은 데이터에
없으므로 옵션별 재고처럼 말하지 않습니다. '상품 전체 재고 N개
(옵션별 수량은 데이터에 없음)' 형식으로 보고합니다.
- 상품 설명에 없는 성능·기능은 '설명에 없음'이라고 보고합니다.
규칙마다 지키려는 것이 있습니다.
| 규칙 | 지키려는 것 |
|---|---|
| 주문번호를 묻지 말고 직접 찾는다 | 조회할 수 있는 것은 고객에게 묻지 않고 조회한다 |
| 재고 확인은 검색 → 재고 조회 순서로 | 상품 ID를 먼저 찾아 재고 조회까지 마친다 |
| 재고 수량은 상품 전체 기준 | 데이터에 있는 숫자를 있는 뜻 그대로 전한다 |
| 설명에 없으면 "설명에 없음" | 데이터에 없는 성능·기능은 없다고 보고한다 |
세 번째 줄을 봅니다. check_stock이 돌려주는 숫자는 색상과 사이즈를 모두 합친 상품 전체의 재고입니다. 민트색이 몇 개인지는 데이터에 없습니다. 20장의 재고 Worker에게 "재고 데이터는 상품 단위다"라고 적어 준 것과 같은 사실을 이 에이전트에게도 적었습니다. 데이터가 어떻게 생겼는지는 모델이 알 수 없으므로 개발자가 적어 줍니다. 같은 데이터를 다루는 에이전트마다 같은 줄이 필요합니다.
프롬프트는 돌려 보고, 결과를 확인하고, 한 줄씩 다듬어 완성합니다. 에이전트를 나눠 두면 그 한 줄을 어느 에이전트에 넣을지가 분명해집니다.
핵심 정리
- 에이전트를 나누는 기준은 도구, 프롬프트, 책임 세 가지입니다.
- 하나라도 뚜렷하게 다르면 나누고, 셋이 모두 같으면 나누지 않습니다.
- 나누면 고를 도구가 줄고, 프롬프트가 짧아지고, 따로 시험하고 고칠 수 있고, 처리 도구를 쥔 쪽이 하나로 좁혀집니다.
- 주문조회 에이전트가 상품·재고·등급까지 맡는 것은 모두 "데이터를 읽어 사실을 보고" 하는 같은 일이기 때문입니다. 배송지 변경과 교환을 한 에이전트가 맡는 것도 같은 이유입니다.
- 프롬프트의 규칙은 지키려는 것을 한 줄씩 적은 것입니다. 데이터의 생김새(재고는 상품 전체 기준)도 그 가운데 하나입니다.