실무 Multi-Agent 오케스트레이션 20장 · 복합 요청 분해 처리 7 / 7 ← 이전목차다음 → TechLead Cro

20장. 복합 요청 분해 처리

실습문제와 해답

Planner의 계획을 직접 찍어 보고, 문의의 성격에 따라 어느 구조에 맡길지 골라 봅니다. 먼저 스스로 해 본 뒤 해답을 펼쳐 보세요. 해답은 새 파일로 만들어 실행합니다.


문제 1 — 같은 문의를 19장의 라우터에 넣어 보기

「왜 복합 요청 분해가 필요한가」 절에서 본 결과를 직접 확인합니다. 새 파일 ex20_router_q6.py를 만들어, 20장의 문의를 19장의 그래프에 넣고 경로와 답변을 출력하세요.

  • 힌트: from lesson19_router import graph로 19장의 그래프를 가져옵니다.
  • 답변을 150자에서 자르지 말고 전부 출력합니다.
해답 보기
from lesson19_router import graph

q = ("지난주에 산 운동화가 작아서 반품하고 싶은데 배송비 얼마인지, "
     "그리고 검정 270 재고 있으면 그걸로 교환 가능한지 알려주세요.")
result = graph.invoke({"question": q, "intent": "", "answer": "", "log": []})
print(f"고객: {q}")
print(f"  경로: {' → '.join(result['log'])}")
print(f"하루: {result['answer']}")
$ python ex20_router_q6.py

실행 결과 (문장은 실행할 때마다 달라집니다)

고객: 지난주에 산 운동화가 작아서 반품하고 싶은데 배송비 얼마인지, 그리고 검정 270 재고 있으면 그걸로 교환 가능한지 알려주세요.
  경로: 분류 → 환불교환 → 정책 RAG 노드 처리
하루: 단순 변심 교환의 왕복 배송비는 6,000원이며 고객이 부담합니다(근거: 제4조 ②). 다만, 원하는 옵션의 재고가 없는 경우 교환은 불가하며, 반품 후 환불로 처리됩니다(근거: 제4조 ③). 재고 유무의 경우 제공된 정책 발췌 내용만으로는 확인 불가합니다.

해설 — 경로는 환불교환 → 정책 RAG 노드입니다. 4장의 분류기에는 "환불/반품/교환 관련이면 주문 이야기가 섞여 있어도 환불교환"이라는 규칙이 있었습니다. 분류기는 규칙대로 했고, 라우터는 표대로 했습니다. 정책 노드는 정책 문서에 있는 배송비와 교환 조건을 조항과 함께 답했습니다.

20장의 실행 결과와 나란히 놓습니다.

19장 라우터 20장 Planner-Worker
본 곳 정책 문서 주문 데이터, 정책 문서, 상품 데이터
주문 — 쿠션 운동화(화이트/250)
배송비 교환 6,000원 교환 6,000원, 반품 3,000원
재고 정책 문서로는 확인 불가 옵션별 재고는 확인 필요
LLM 호출 2번 8번 안팎

두 결과 모두 자기가 본 곳에 있는 내용만 답했습니다. 차이는 본 곳의 수입니다. 한 가지를 묻는 문의에는 호출 두 번의 라우터가 알맞고, 여러 가지를 묻는 문의에는 작업마다 알맞은 곳을 보는 Planner-Worker가 알맞습니다.


문제 2 — 계획만 찍어 보고, 하나를 끝까지 실행하기

Worker를 실행하지 않고 계획만 세워 보면, Planner가 문의를 어떻게 읽는지 빠르고 싸게 확인할 수 있습니다.

(1) 새 파일 ex20_plan_only.py를 만들어 아래 네 문의의 계획을 출력하세요.

  1. "단순 변심 반품이면 배송비 얼마예요?"
  2. "제 최근 주문 지금 어디까지 왔어요?"
  3. "저 VIP인데요, 단순 변심 반품해도 배송비 내야 해요?"
  4. "이어폰 배송 어디쯤인지 보고, 취소하면 환불 언제 되는지 알려주세요."

(2) 새 파일 ex20_vip.py를 만들어 3번 문의를 plan_and_execute로 끝까지 실행하세요.

  • 힌트: from lesson20_planner_worker import make_plan, from lesson20_planner_worker import plan_and_execute
  • 실행하기 전에 문의마다 작업이 몇 개 나올지 적어 보세요.
  • 3번 문의의 고객은 스스로 VIP라고 말했습니다. 계획은 이 말을 어떻게 다룰까요?
해답 보기

(1) 계획만 찍기

from lesson20_planner_worker import make_plan

QUESTIONS = [
    "단순 변심 반품이면 배송비 얼마예요?",
    "제 최근 주문 지금 어디까지 왔어요?",
    "저 VIP인데요, 단순 변심 반품해도 배송비 내야 해요?",
    "이어폰 배송 어디쯤인지 보고, 취소하면 환불 언제 되는지 알려주세요.",
]

for q in QUESTIONS:
    plan = make_plan(q)                      # 계획만 세운다. Worker 는 실행하지 않는다
    print(f"\n문의: {q}")
    print(f"  작업 수: {len(plan.tasks)}")
    for i, t in enumerate(plan.tasks, 1):
        print(f"    {i}. [{t.task_type.value}] {t.instruction}")
$ python ex20_plan_only.py

실행 결과 (문장은 실행할 때마다 달라집니다)

문의: 단순 변심 반품이면 배송비 얼마예요?
  작업 수: 1
    1. [정책확인] 단순 변심 반품 시 발생하는 배송비 규정을 확인한다.

문의: 제 최근 주문 지금 어디까지 왔어요?
  작업 수: 1
    1. [주문조회] 고객의 최근 주문 번호와 현재 배송 상태를 확인한다.

문의: 저 VIP인데요, 단순 변심 반품해도 배송비 내야 해요?
  작업 수: 2
    1. [주문조회] 고객의 VIP 등급 및 주문 정보를 확인한다.
    2. [정책확인] VIP 회원의 단순 변심 반품 시 배송비 면제 정책이 있는지 확인한다.

문의: 이어폰 배송 어디쯤인지 보고, 취소하면 환불 언제 되는지 알려주세요.
  작업 수: 2
    1. [주문조회] 고객의 이어폰 주문 배송 상태를 확인한다.
    2. [정책확인] 현재 배송 상태에 따른 주문 취소 시 환불 소요 기간을 확인한다.

세 번 실행했을 때 작업 수와 작업 유형은 세 번 모두 같았습니다(1, 1, 2, 2). 달라진 것은 지시문의 문장뿐입니다.

  • 묻는 것이 하나인 문의는 작업도 하나입니다. 1번과 2번이 그렇습니다. "문의를 최소 작업으로 분해한다. 불필요한 작업을 만들지 않는다"는 Planner의 지시가 지켜졌습니다.
  • 3번 문의의 첫 작업은 등급 확인입니다. 고객이 "저 VIP인데요"라고 말했지만, 계획은 그 말을 그대로 믿지 않고 등급을 먼저 조회하도록 세워졌습니다. 그다음에 VIP의 반품 배송비 규정을 찾습니다.
  • 4번 문의는 두 곳을 봅니다. 배송 상태는 주문 데이터에, 환불 기간은 정책 문서에 있습니다.

이 확인에 든 것은 문의마다 LLM 호출 한 번입니다. 계획이 데이터로 먼저 나오기 때문에, Worker를 한 번도 실행하지 않고 Planner만 따로 볼 수 있습니다.

(2) 3번 문의를 끝까지 실행하기

from lesson20_planner_worker import plan_and_execute

q = "저 VIP인데요, 단순 변심 반품해도 배송비 내야 해요?"
print(f"고객: {q}\n")
print(f"\n하루: {plan_and_execute(q)}")
$ python ex20_vip.py

실행 결과 (문장은 실행할 때마다 달라집니다)

고객: 저 VIP인데요, 단순 변심 반품해도 배송비 내야 해요?

  [Plan]
    1. [주문조회] 고객의 VIP 등급 및 주문 내역을 확인한다.
    2. [정책확인] VIP 회원의 단순 변심 반품 시 배송비 면제 혜택이 있는지 확인한다.
  [Worker 1 완료] - 고객 멤버십 등급: VIP (보유 포인트: 12,500P)
- 최근 주문 내역: 총 8건 (HR20260...
  [Worker 2 완료] 발췌 내용에 따른 확인 결과는 다음과 같습니다.

* **[표 2] 등급별 혜택 요약** 및 **제2조 (등...

하루: 안녕하세요, 하루마켓 상담원 '하루'입니다. 

고객님은 VIP 등급이시며, 단순 변심 반품 배송비 면제 혜택은 월 1회 제공되어 자동 적용됩니다. 다만, 월 2회째부터는 일반 기준인 편도 3,000원이 적용되는 점 참고 부탁드립니다. 반품을 원하시면 채팅에서 바로 접수를 도와드리겠습니다.

해설 — 답변의 두 사실이 각각 어디서 왔는지 봅니다.

답변의 내용 근거가 된 보고 그 Worker가 본 곳
"고객님은 VIP 등급이시며" Worker 1 고객 데이터 (get_my_membership)
"월 1회 면제, 2회째부터 편도 3,000원" Worker 2 멤버십 정책 문서

Worker 1의 보고에 등급 VIP와 보유 포인트 12,500이 들어 있습니다. 고객이 말한 등급이 아니라 조회한 등급입니다. worker_order에 get_my_membership 도구를 함께 준 덕분에 "등급 확인"이라는 작업을 맡을 수 있었습니다. Worker 2는 그 뒤에 VIP의 혜택 조항을 찾았고, 취합이 둘을 한 답으로 묶었습니다.

세 번 실행했을 때 세 번 모두 계획은 주문조회(등급 확인) → 정책확인이었고, 답변에는 VIP 등급과 월 1회 면제가 들어 있었습니다.


문제 3 — 어느 구조에 맡길 것인가

다음 세 문의를 각각 19장의 라우터, 20장의 Planner-Worker, 9장의 ReAct 루프 가운데 어디에 맡기는 것이 좋을지 고르고 이유를 쓰세요. (코드를 실행하지 않고 글로 답합니다.)

  1. "하루클럽 골드 등급 혜택이 뭐예요?"
  2. "지난달에 산 이불커버 교환 배송비가 얼마인지, 화이트 재고가 있는지, 그리고 제 포인트로 배송비를 낼 수 있는지 알려 주세요."
  3. "주문한 게 안 와요. 뭐가 문제인지 좀 봐 주세요."
해답 보기
문의 맡길 곳 이유
1. 골드 등급 혜택 라우터 묻는 것이 하나이고 답이 정책 문서 한곳에 있습니다. 분류 1번, 답변 1번이면 됩니다. 계획과 취합을 거칠 이유가 없습니다
2. 교환 배송비 + 재고 + 포인트 Planner-Worker 문의만 읽어도 할 일을 셀 수 있습니다(주문·포인트 확인, 정책 확인, 재고 확인). 볼 곳이 여럿이라 작업으로 나눕니다
3. 주문한 게 안 와요 ReAct 루프 무엇을 조회해야 할지 해 봐야 압니다. 주문 목록을 보고, 배송 중인 것이 있으면 상태를 보고, 결제만 된 주문이면 다른 안내를 해야 합니다. 앞 결과에 따라 다음 행동이 달라지므로 계획을 미리 세우기 어렵습니다

고르는 기준은 두 가지 질문입니다.

  • 묻는 것이 하나인가, 여럿인가? 하나면 라우터로 충분합니다.
  • 할 일을 미리 셀 수 있는가? 셀 수 있으면 Planner-Worker, 해 봐야 알면 ReAct 루프입니다.

2번의 "포인트로 배송비를 낼 수 있는지"는 두 가지를 봐야 답할 수 있습니다. 고객의 포인트 잔액은 주문조회 Worker가 get_my_membership으로 확인하고, 포인트 사용 규정은 정책확인 Worker가 정책 문서에서 찾습니다. 문제 2에서 등급을 조회한 것과 같은 방식입니다.

세 구조는 하나만 골라 쓰는 것이 아닙니다. 한 서비스 안에서도 문의의 성격에 따라 섞어 씁니다.

← 이전 절정리와 체크리스트21장 →왜 전문 에이전트가 필요한가 — 다 할 줄 아는 하나보다, 하나씩 맡은 셋
오명운 · macro@prag-ai.com