📚 Agentic AI - 기업용 자율 에이전트 개발 5장 · 에이전트 ③ CSV 데이터분석 Agentic AI란

따라하기 — 한국어로 묻고 집계 결과 받기

한 줄 요약

에이전트에게 한국어로 묻고 집계 결과를 받습니다. 그리고 나온 숫자가 맞는지 대조해 확인합니다. 이렇게 확인하는 것이 이번 장에서 익힐 가장 실용적인 습관입니다.


1. 실행 — [2] 부분

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

python code/ch05_csv_agent.py
==============================================================
[2] 한국어로 묻고 집계 결과 받기

  Q: 카테고리별 매출 상위 3개를 알려주세요.
  A: 가전제품 90,229,700원, 전자기기 53,967,950원, 스포츠/레저 53,259,600원으로 집계되었습니다.

  Q: P0003 스마트워치의 현재 재고와 재주문 기준을 알려주세요.
  A: P0003 스마트워치의 현재 재고는 3개이며, 재주문 기준은 30개입니다.

  Q: P0003 스마트워치 리뷰의 평균 평점과 3점 이하 리뷰가 몇 건인지 알려주세요.
  A: P0003 스마트워치 리뷰의 평균 평점은 3.8점이며, 3점 이하 리뷰는 5건입니다.

==============================================================
관찰: 4장에서 30줄 남짓 짜던 루프가 create_agent 한 줄로 줄었습니다.
      하는 일은 같습니다 — 생각하고, 도구를 부르고, 결과를 보고 다시 판단합니다.

표현은 조금씩 다를 수 있습니다. 숫자가 같으면 성공입니다.


2. 숫자를 대조해 봅시다

에이전트가 낸 답을 믿지 말고 확인합니다.

아래 pandas 식은 정답 대조용으로 제공하는 것입니다 — 읽지 않고 붙여 넣어도 됩니다. 5장 6절 3번에서 말했듯, 이 과정에서 pandas를 외울 필요는 없습니다.

직접 고쳐 보기agentic_ai/code/ch05_csv_agent.py 를 열어 [2] 블록 아래에 아래를 덧붙인 뒤 다시 실행하세요.

    print("\n" + "=" * 62)
    print("[3] 직접 계산해서 대조하기")
    print("  카테고리 매출 상위 3개:")
    print(run_pandas.invoke({"expr":
        "orders[~orders['status'].isin(['취소','환불'])].groupby('category')['amount'].sum().nlargest(3)"}))
    print("\n  P0003 재고:")
    print(run_pandas.invoke({"expr":
        "inventory[inventory['product_id']=='P0003'][['stock','reorder_level']].to_dict('records')"}))
    print("\n  P0003 리뷰:")
    print(run_pandas.invoke({"expr":
        "[len(reviews[reviews['product_id']=='P0003']), "
        "round(reviews[reviews['product_id']=='P0003']['rating'].mean(), 2), "
        "int((reviews[reviews['product_id']=='P0003']['rating'] <= 3).sum())]"}))
[3] 직접 계산해서 대조하기
  카테고리 매출 상위 3개:
category
가전       90229700
전자기기     53967950
스포츠레저    53259600

  P0003 재고:
[{'stock': 3, 'reorder_level': 30}]

  P0003 리뷰:
[15, 3.8, 5]

전부 일치합니다.

항목 에이전트 답 직접 계산
가전 매출 90,229,700원 90229700 ✓
재고 / 기준 3개 / 30개 3 / 30 ✓
평균 평점 3.8점 3.8 ✓
3점 이하 5건 5 ✓

이 대조 작업이 왜 중요한가5장 5절에서 말한 대로 모델이 만든 식이 오류 없이 잘못된 결과를 낼 수 있습니다. 오류가 안 나면 티가 안 나죠. 새 종류의 질문을 처음 던질 때는 한 번 대조해 보는 것이 습관이 되어야 합니다. 매번 할 필요는 없지만, 그 에이전트를 남에게 쓰게 하기 전에는 반드시 합니다.


3. 모델이 만든 식을 직접 보기

앞 절에서 배운 방법입니다.

직접 고쳐 보기agentic_ai/code/ch05_csv_agent.py 를 열어 아래처럼 바꾸거나 덧붙인 뒤 다시 실행하세요.

out = agent.invoke({"messages": [
    {"role": "user", "content": "카테고리별 매출 상위 3개를 알려주세요."}]})
for m in out["messages"]:
    print(f"  {type(m).__name__:14s} {str(m.content)[:60]}")
print("\n  만든 식:", out["messages"][1].tool_calls[0]["args"]["expr"])
  HumanMessage   카테고리별 매출 상위 3개를 알려주세요.
  AIMessage
  ToolMessage    category
가전       90229700
전자기기     53967950
스포츠레저    5325
  AIMessage      카테고리별 매출 상위 3개는 다음과 같습니다:

*   가전: 90,229,700원

  만든 식: orders[~orders['status'].isin(['취소','환불'])].groupby('category')['amount'].sum().nlargest(3)

모델이 만든 식에 ~orders['status'].isin(['취소','환불']) 이 들어 있습니다. 독스트링의 규칙을 지킨 것이죠.

디버깅의 출발점입니다. 답이 이상하면 ① 어떤 식을 만들었나 → ② 그 식이 맞나 → ③ 실행 결과가 맞나 순서로 봅니다. 대부분 ①에서 원인이 잡힙니다.


4. 규칙을 지우면 어떻게 되는지 확인

5장 3절 「스스로 해 보기」 2번에서 예고한 실험입니다. 독스트링에서 이 줄을 지워 보세요.

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

    규칙 1: 매출을 집계할 때는 status 가 '취소'·'환불'인 행을 반드시 제외한다.

그리고 시스템 지시에서도 지웁니다.

직접 고쳐 보기agentic_ai/code/ch05_csv_agent.py 를 열어 아래처럼 한 줄을 주석 처리한 뒤 다시 실행하세요. 확인이 끝나면 되돌려 놓으세요.

SYSTEM = (
    "너는 승승장구몰의 데이터 분석가다. "
    "숫자는 반드시 run_pandas 도구로 계산하고, 머릿속으로 계산하지 않는다. "
    # "매출 집계에서는 취소·환불 건을 제외한다. "     ← 주석 처리
    "결과는 한국어로, 숫자에는 천단위 쉼표를 붙여 간결하게 설명한다."
)

같은 질문을 던지면, 모델이 만드는 식이 이렇게 바뀔 수 있습니다.

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

orders.groupby('category')['amount'].sum().nlargest(3)      # 필터가 없다

숫자가 커집니다. 취소·환불 건이 매출에 포함됐으니까요.

그런데 오류는 안 납니다. 답도 자신 있게 나옵니다. 틀린 줄 모르고 쓰게 됩니다.

이 실험이 이 장에서 가장 중요합니다. 에이전트는 대개 "오류를 내는 방식"이 아니라 "오류 없이 잘못된 답을 내는 방식" 으로 틀립니다. 그리고 그 원인은 모델이 알 수 없는 것을 우리가 안 알려 줘서입니다.


5. 더 물어보기

questions 목록에 추가해 실행해 보세요.

직접 고쳐 보기agentic_ai/code/ch05_csv_agent.py 를 열어 questions 목록에 아래 네 줄을 덧붙인 뒤 다시 실행하세요.

    questions = [
        "카테고리별 매출 상위 3개를 알려주세요.",
        "P0003 스마트워치의 현재 재고와 재주문 기준을 알려주세요.",
        "P0003 스마트워치 리뷰의 평균 평점과 3점 이하 리뷰가 몇 건인지 알려주세요.",
        # ↓ 추가해 보기
        "2026년 5월 P0003 스마트워치는 몇 개 팔렸나요? 직전 3개월과 비교해 주세요.",
        "재고가 재주문 기준보다 적은 상품이 몇 개인가요?",
        "평점이 가장 낮은 상품 3개는 무엇인가요?",
        "월별 총 매출 추이를 최근 6개월만 알려주세요.",
    ]

네 번째 질문의 답을 눈여겨보세요.

Q: 2026년 5월 P0003 스마트워치는 몇 개 팔렸나요? 직전 3개월과 비교해 주세요.
A: 2026년 5월에는 12개가 판매되었습니다. 직전 3개월(2026년 2~4월)에는 각각
   2개, 3개, 1개가 판매되어, 5월 판매량이 크게 증가했습니다.

5월에 12개, 직전 3개월은 2·3·1개. 갑자기 6배로 뛰었습니다. 그런데 재고는 3개뿐입니다.

이 두 사실은 서로 다른 표에 있어서, 따로 보면 안 보입니다. 합쳐 놓으면 "지금 발주해야 한다"가 보입니다. 8장에서 이 이야기를 다시 합니다.


6. 도구가 없으면 어떻게 되나

시스템 지시의 힘을 확인하는 실험입니다.

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

llm = get_chat(temperature=0)
print(llm.invoke("승승장구몰의 카테고리별 매출 상위 3개를 알려주세요.").text)

도구 없이 모델만 부르면 — 1장으로 돌아갑니다. "데이터에 접근할 수 없습니다"라고 하거나, 그럴듯한 숫자를 지어냅니다.

같은 모델인데 결과가 다릅니다. 차이를 만든 것은 모델이 아니라 도구입니다.


스스로 해 보기

  1. 위의 대조 코드를 실행해 숫자가 맞는지 확인하세요.
  2. 4절의 실험(규칙 지우기)을 직접 해 보고, 숫자가 얼마나 달라지는지 확인하세요. 원상복구하는 것을 잊지 마세요.
  3. 모델이 틀린 식을 만들도록 유도해 보세요. 예: "상품 카테고리별로 판매액을 알려줘" (열 이름을 일부러 다르게 표현). 모델이 오류를 어떻게 복구하는지 보세요.
  4. 같은 것을 다르게 물어 두 답이 같은지 보세요. 예: "P0003 리뷰 평균 평점은?" / "P0003 리뷰 평점을 전부 더해 건수로 나누면?" 식은 모델이 만듭니다. 답이 갈리면 3절의 방법으로 두 식을 나란히 놓고 어느 쪽이 틀렸는지 보세요.

핵심 정리

  • 한국어 질문 하나로 집계가 됩니다. 도구는 run_pandas 하나뿐입니다.
  • 나온 숫자를 대조하세요. 정답 식이 있으면 그것으로, 없으면 같은 것을 다르게 물어 두 답을 비교하면 됩니다. 새 종류의 질문을 처음 던질 때는 반드시 합니다.
  • 모델이 만든 식은 out["messages"][1].tool_calls 에서 볼 수 있습니다. 디버깅의 출발점입니다.
  • 규칙을 안 알려 주면 오류 없이 잘못된 답이 나옵니다. 오류가 안 나서 더 위험합니다.
  • 에이전트가 틀리는 방식은 대개 "오류"가 아니라 "오류 없이 나오는 오답" 이고, 원인은 모델이 알 수 없는 것을 안 알려 준 것입니다.
  • 2026년 5월 P0003 판매 12개 vs 재고 3개 — 서로 다른 표에 있는 두 사실입니다. 8장에서 다시 만납니다.
  • 같은 모델인데 결과가 다릅니다. 차이를 만든 것은 도구입니다.
← 이전 절07. 남의 코드를 실행한다는 것 안전장치 걸기다음 절 →09. 4장 코드와 나란히 놓고 보기