📚 Agentic AI - 기업용 자율 에이전트 개발 8장 · 멀티에이전트 아키텍처 Agentic AI란

실행 — "스마트워치 Fit 5, 어떻게 대응할까요?" 전체 데모

한 줄 요약

이 과정의 결승선입니다. 질문 하나에 여러 종류의 에이전트가 각자 다른 곳을 뒤지고, 그 결과가 하나의 판단으로 합쳐집니다.


1. 실행

터미널에서 실행 — 프로젝트 폴더 agentic_ai 에서, (agentic) 표시를 확인한 뒤.

python code/ch08_multi_agent.py

1분 안팎 걸립니다. 팀장이 작업을 몇 개로 나누느냐에 따라 호출이 10~20번 일어납니다(아래 8번에서 셈해 봅니다).

429 RESOURCE_EXHAUSTED 가 나면 1~2분 기다렸다 다시 실행하세요. 8장은 이 과정에서 호출이 가장 많은 장입니다. 질문 하나를 실행한 뒤 간격을 두고 다음 질문을 실행하세요.


2. 계획

==============================================================
[2] 여러 담당이 필요한 질문
  질문: 승승 스마트워치 Fit 5(P0003), 지금 어떻게 대응해야 할까요?

  [계획]
    → 데이터분석가: 승승 스마트워치 Fit 5(P0003)의 최근 판매 추이를 알려주세요.
    → 데이터분석가: 승승 스마트워치 Fit 5(P0003)의 현재 재고 수량과 재주문 기준을 알려주세요.
    → 데이터분석가: 승승 스마트워치 Fit 5(P0003)의 리뷰 평점과 부정 리뷰 내용을 요약해주세요.
    → 규정담당: 승승 스마트워치 Fit 5(P0003)의 제품 사양(배터리, 방수 등)을 알려주세요.
    → 규정담당: 승승 스마트워치 Fit 5(P0003)의 환불 및 교환 기간 규정을 알려주세요.
    → 시장조사원: 승승 스마트워치 Fit 5(P0003)의 경쟁 제품 정보를 알려주세요.
    → 시장조사원: 승승 스마트워치 Fit 5(P0003)에 대한 외부 사용자 반응을 알려주세요.
    → 시장조사원: 스마트워치 시장 동향을 알려주세요.

작업 8개가 나왔습니다.

이 질문에 불려 나온 담당은 데이터분석가·규정담당·시장조사원 셋입니다. 주문담당은 주문번호가 없으니 부르지 않았습니다 — 팀은 넷이지만 필요한 셋만 불렀습니다. 주문담당은 [3] 의 이어 묻기에서 등장합니다.

실행할 때마다 개수가 다릅니다. 4개일 때도 있고 8개일 때도 있습니다. "한 task 에 한 주제" 규칙 때문에 플래너가 잘게 나누는 정도가 매번 조금씩 다릅니다. 담당 배분이 맞으면 성공입니다.

우리가 짠 것은 "누가 무엇을 맡는가"뿐입니다. 몇 개로 나눌지, 어떤 순서로 할지는 플래너가 정했습니다.


3. 각 담당의 보고

  [데이터분석가 보고]
    승승 스마트워치 Fit 5(P0003)의 최근 판매 추이는 다음과 같습니다.
    ...
    *   2026-03: 445,200원
    *   2026-04: 159,000원
    *   2026-05: 1,876,200원

  [데이터분석가 보고]
    승승 스마트워치 Fit 5(P0003)의 현재 재고는 3개이며, 재주문 기준은 30개입니다.

  [데이터분석가 보고]
    승승 스마트워치 Fit 5(P0003)의 리뷰 평점은 3.8점입니다.
    부정 리뷰 내용은 다음과 같습니다.
    *   GPS를 켜면 배터리가 하루도 못 간다는 불만이 있습니다.
    *   충전을 너무 자주 해야 해서 사용이 불편하다는 의견이 있습니다.

  [규정담당 보고]
    승승 스마트워치 Fit 5(P0003)의 제품 사양은 다음과 같습니다.
    *   **방수 등급:** 5ATM
    *   **배터리(일반):** 약 7일
    *   **배터리(GPS):** 약 18시간
    *   **충전 시간:** 약 90분

  [규정담당 보고]
    환불 및 교환 기간 규정
    *   단순 변심: 상품 수령일로부터 7일 이내
    *   상품 불량·하자: 상품 수령일로부터 30일 이내

  [시장조사원 보고]
    스마트워치 시장은 건강 의식 증가에 힘입어 성장 중이며,
    경쟁사 제품은 10일간의 긴 배터리 수명과 가성비를 강점으로 내세우고 있습니다.

세 곳에서 온 사실들입니다.

어디서 무엇
orders.csv, inventory.csv, reviews.csv 5월 매출 급증, 재고 3개/기준 30개, 평점 3.8, 배터리 불만 5장
제품매뉴얼_스마트워치.pdf, 환불교환정책.pdf 배터리 7일/18시간, 환불 7일/30일 6장
인터넷 시장 성장세, 경쟁사는 배터리 10일 4장

4. 종합 — 결정적인 두 줄

**① 확인된 사실을 근거와 함께 정리**

2. **고객 피드백 및 제품 사양:**
   *   주요 부정 리뷰 내용은 GPS 사용 시 배터리가 하루도 못 간다는 불만과
       잦은 충전의 불편함입니다. (근거: 데이터분석가 보고)
   *   제품 사양상 배터리 수명은 일반 사용 시 약 7일, GPS 사용 시 약 18시간으로
       명시되어 있습니다. (근거: 규정담당 보고)

이 두 줄이 나란히 놓인 것이 이 과정의 결승선입니다.

[CSV]  "GPS 켜면 하루도 못 간다"        ← 고객이 겪은 것
[RAG]  "GPS 사용 시 약 18시간"          ← 매뉴얼에 적힌 것
        ↓
    18시간 ≈ 하루 미만. 고객 말이 맞다.
    그런데 매뉴얼대로다. 제품은 정상이다.
    고객은 "일주일"만 보고 샀다.
        ↓
    결함이 아니라 표기 문제다.

그리고 권고가 나옵니다.

2. **배터리 성능 관련 고객 불만 대응:** GPS 사용 시 배터리 지속 시간에 대한
   고객 불만이 제품 사양(GPS 사용 시 약 18시간)과 실제 사용자 경험 간의 괴리를
   시사하므로, ... 제품 설명 페이지에 GPS 사용 시 배터리 소모에 대한 상세 안내를
   추가하여 고객의 기대치를 명확히 설정해야 합니다.

"제품 설명 페이지에 상세 안내를 추가하라" — 표기를 고치라는 것입니다.


5. 한 종류만 썼다면

직접 비교해 보세요.

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

# 5장 에이전트만
from ch05_csv_agent import ask
print(ask("승승 스마트워치 Fit 5(P0003), 지금 어떻게 대응해야 할까요?"))

# 6장 에이전트만
from ch06_rag_agent import answer
print(answer("승승 스마트워치 Fit 5, 지금 어떻게 대응해야 할까요?")["answer"])

각자 자기 자리에서 멈춥니다.

에이전트 어디까지
CSV 분석만 "재고 3개, 평점 3.8점입니다" — 왜 낮은지 모름
RAG만 "배터리 7일/18시간입니다" — 고객 불만을 모름
웹만 "시장은 성장세입니다" — 우리 상품 상태를 모름

세 관점이 합쳐질 때만 "표기가 오해를 부른다"가 나옵니다.

1장 1절에서 보여 준 화면을 다시 보세요. 그때 "지금 이해할 필요 없다"고 했던 그 화면입니다. 지금은 한 줄 한 줄 어디서 왔는지 아실 겁니다.


6. 이어서 묻기 — 멀티턴 + 담당이 바뀝니다

==============================================================
[3] 이어서 묻기 — 계획이 달라지고, 앞 대화를 기억합니다
  질문: 그 상품을 산 주문 O001203은 지금 어떤 상태인가요?
        그리고 재주문 기준을 채우려면 몇 개를 발주해야 하나요?

  [계획]
    → 주문담당: 주문번호 O001203의 상태를 조회해 주세요.
    → 데이터분석가: 승승 스마트워치 Fit 5(P0003)의 재주문 기준을 채우려면
                    몇 개를 발주해야 하는지 알려주세요.

  [주문담당 보고]
    주문번호 O001203은 2026년 5월 14일에 주문되었으며, 현재 '배송완료' 상태입니다.
    고객님은 오지우님이시며, 승승 스마트워치 Fit 5 1개를 159,000원에 구매하셨습니다.

  [데이터분석가 보고]
    승승 스마트워치 Fit 5(P0003)의 재주문 기준을 채우려면 27개를 발주해야 합니다.

  [최종 답변]
① 확인된 사실을 근거와 함께 정리
*   주문번호 O001203은 2026년 5월 14일에 오지우 고객이 '승승 스마트워치 Fit 5' 1개를
    159,000원에 구매한 주문이며, 현재 '배송완료' 상태입니다. (근거: 주문담당 보고)
*   '승승 스마트워치 Fit 5(P0003)'의 재주문 기준을 채우려면 27개를 발주해야 합니다.
    (근거: 데이터분석가 보고)

② 그래서 무엇을 해야 하는지 권고
*   주문 O001203은 배송이 완료된 상태이므로 추가 조치는 필요하지 않습니다.
*   재주문 기준에 따라 27개 발주를 검토하여 재고를 확보해야 합니다.

네 가지가 한꺼번에 동작했습니다.

① "그 상품"이 통했다 — 7장

질문에는 상품 이름이 없습니다. 플래너가 대화 기록에서 찾아 승승 스마트워치 Fit 5(P0003) 로 바꿔 썼습니다.

아래는 code/ch08_multi_agent.py 의 일부입니다 — 위에서 이미 붙여 넣었으니 다시 넣지 마세요.

result = planner.invoke([{"role": "system", "content": planner_prompt()}] + state["messages"])
                                                                     └─ 지난 대화가 여기 있다

② 담당이 바뀌었다 — 3장 에이전트가 여기서 쓰입니다

"주문 O001203은 어떤 상태인가요?"  →  주문담당    (get_order_status)
"재주문 기준을 채우려면 몇 개?"     →  데이터분석가 (run_pandas)

질문 하나에 담당 둘이 붙었습니다. 둘 다 CSV를 보지만 하는 일이 다르기 때문입니다 — 하나는 정해진 조회, 하나는 매번 다른 계산.

1장 표에서 ①과 ③을 나눠 둔 이유가 여기서 실제로 드러납니다.

③ 계획이 달라졌다

첫 질문은 8개 작업, 이번엔 2개. 필요한 것만 부릅니다.

planner_prompt()"필요 없는 팀원은 부르지 않는다" 가 적용된 결과입니다.

④ 담당이 맞았다 — 2절의 그 사고를 고친 결과

"재주문 기준"이 데이터분석가에게 갔습니다. 역할 설명을 고치기 전에는 규정담당에게 가서 "문서에 없음"이라는 오답이 나왔죠.


7. 27개는 어떻게 나왔나

재주문 기준 30개 - 현재 재고 3개 = 27개

데이터분석가가 run_pandas 로 계산했습니다. 머릿속으로 뺀 게 아닙니다.

확인해 보세요.

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

out = WORKERS["데이터분석가"].invoke({"messages": [{"role": "user",
    "content": "승승 스마트워치 Fit 5(P0003)의 재주문 기준을 채우려면 몇 개를 발주해야 하는지 알려주세요."}]})
for m in out["messages"]:
    print(f"  {type(m).__name__:14s} {str(m.content)[:70]}")

ToolMessage 가 있으면 도구를 쓴 것입니다.

5장의 "숫자는 반드시 도구로 계산한다" 가 8장까지 이어진 것이죠.


8. 호출 수를 세어 봅시다

[플래너]        1번
[워커 8개 작업]  각 작업마다 최소 2번 = 16번   ← 도구를 여러 번 쓰면 더 늘어남
[종합]          1번
                ─────
                합계 18번  (약 73초)

질문 하나에 18번입니다. 2장 7절에서 예고한 그대로죠.

작업이 4개로 나뉘면 10번쯤입니다. 플래너가 잘게 나눌수록 비용이 늡니다.

얻는 것 내주는 것
검색이 정확해진다 (한 주제씩) 호출이 는다
보고가 명확해진다 시간이 는다

이것도 맞바꾸기입니다. "한 task 에 한 주제" 규칙은 정확도를 높이기 위해 비용을 더 들인 것입니다. 실제 서비스라면 동시 실행(6절)으로 시간만이라도 줄일 수 있습니다.


9. 다른 질문도 던져 보세요

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

    print("\n" + "=" * 62)
    print("[4] 다른 질문들")
    for q in [
        "가전 카테고리에서 재고가 재주문 기준보다 적은 상품이 있나요?",
        "평점이 가장 낮은 상품 3개와, 그중 매뉴얼이 있는 상품의 사양을 알려주세요.",
        "VIP 고객이 불량 상품을 반품하려면 어떤 절차인가요?",
        "고객이 '배터리가 일주일 간다더니 하루도 안 간다'고 항의합니다. 우리 잘못인가요?",
    ]:
        print(f"\n  질문: {q}")
        print(f"  답변: {ask(q, thread_id='테스트')}")

계획이 질문마다 어떻게 달라지는지 보세요.

  • 첫 번째 → 데이터분석가 한 명
  • 두 번째 → 데이터분석가 + 규정담당
  • 세 번째 → 규정담당 한 명 (또는 두 작업)
  • 네 번째 → 데이터분석가 + 규정담당

네 번째는 1장 1절의 ③번 질문입니다. 그때는 "이 과정의 산출물"이라고만 하고 넘어갔죠. 이제 답이 나옵니다 — 리뷰 불만(CSV)과 매뉴얼 사양(RAG)을 붙이면 "제품은 사양대로 동작한다. 표기가 오해를 부른 것" 이라는 판단이 나옵니다. 이 절 4번에서 본 그 결론과 같은 것입니다.


스스로 해 보기

  1. 전체를 실행하고 계획에 몇 개의 작업이 나오는지 세어 보세요. 두 번 실행하면 같은가요?
  2. 7번의 확인 코드로 27개가 도구로 계산됐는지 확인하세요.
  3. 5번의 비교를 직접 해 보세요. 한 종류만 쓰면 어디까지 나오는지 확인하세요.
  4. [3] 의 질문을 "그거 리뷰는 어땠죠?" 로 바꿔 보세요. "그거"가 통하나요?
  5. 9번의 질문들을 던져 계획이 어떻게 달라지는지 보세요. 네 번째 질문(1장 ③번) 은 특히 유심히 보세요 — 이 과정이 처음에 약속한 질문입니다.

핵심 정리

  • 질문 하나에 여러 종류의 에이전트가 각자 다른 곳을 뒤졌습니다.
  • 우리가 짠 것은 "누가 무엇을 맡는가" 뿐입니다. 몇 개로 나눌지, 어떤 순서로 할지는 플래너가 정했습니다.
  • 계획의 작업 수는 실행할 때마다 다릅니다. 담당 배분이 맞으면 성공입니다.
  • 결승선"GPS 켜면 하루도 못 간다"(CSV)와 "GPS 사용 시 18시간"(RAG)이 나란히 놓여 "결함이 아니라 표기 문제" 라는 판단이 나옵니다.
  • 한 종류만 썼다면 각자 자기 자리에서 멈춥니다.
  • 이어 묻기에서 네 가지가 함께 동작합니다 — "그 상품"이 통하고(7장), 담당이 바뀌고(주문담당 등장), 계획이 줄고, 담당 배분이 맞습니다.
  • 27개는 도구로 계산했습니다. 5장의 원칙이 8장까지 이어집니다.
  • 질문 하나에 호출 18번, 약 73초. 정확도를 높이기 위해 비용을 더 들인 것입니다.
← 이전 절07. 따라하기 여러 보고를 하나의 판단으로 합치기다음 절 →09. 한 담당이 실패해도 나머지는 살리기