따라하기 — 한국어로 묻고 집계 결과 받기
한 줄 요약
에이전트에게 한국어로 묻고 집계 결과를 받습니다. 그리고 나온 숫자가 맞는지 대조해 확인합니다. 이렇게 확인하는 것이 이번 장에서 익힐 가장 실용적인 습관입니다.
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장으로 돌아갑니다. "데이터에 접근할 수 없습니다"라고 하거나, 그럴듯한 숫자를 지어냅니다.
같은 모델인데 결과가 다릅니다. 차이를 만든 것은 모델이 아니라 도구입니다.
스스로 해 보기
- 위의 대조 코드를 실행해 숫자가 맞는지 확인하세요.
- 4절의 실험(규칙 지우기)을 직접 해 보고, 숫자가 얼마나 달라지는지 확인하세요. 원상복구하는 것을 잊지 마세요.
- 모델이 틀린 식을 만들도록 유도해 보세요. 예:
"상품 카테고리별로 판매액을 알려줘"(열 이름을 일부러 다르게 표현). 모델이 오류를 어떻게 복구하는지 보세요. - 같은 것을 다르게 물어 두 답이 같은지 보세요. 예:
"P0003 리뷰 평균 평점은?"/"P0003 리뷰 평점을 전부 더해 건수로 나누면?"식은 모델이 만듭니다. 답이 갈리면 3절의 방법으로 두 식을 나란히 놓고 어느 쪽이 틀렸는지 보세요.
핵심 정리
- 한국어 질문 하나로 집계가 됩니다. 도구는
run_pandas하나뿐입니다. - 나온 숫자를 대조하세요. 정답 식이 있으면 그것으로, 없으면 같은 것을 다르게 물어 두 답을 비교하면 됩니다. 새 종류의 질문을 처음 던질 때는 반드시 합니다.
- 모델이 만든 식은
out["messages"][1].tool_calls에서 볼 수 있습니다. 디버깅의 출발점입니다. - 규칙을 안 알려 주면 오류 없이 잘못된 답이 나옵니다. 오류가 안 나서 더 위험합니다.
- 에이전트가 틀리는 방식은 대개 "오류"가 아니라 "오류 없이 나오는 오답" 이고, 원인은 모델이 알 수 없는 것을 안 알려 준 것입니다.
- 2026년 5월 P0003 판매 12개 vs 재고 3개 — 서로 다른 표에 있는 두 사실입니다. 8장에서 다시 만납니다.
- 같은 모델인데 결과가 다릅니다. 차이를 만든 것은 도구입니다.