이번 νŽΈμ€ β€œCSV 원본 β†’ μ—μ΄μ „νŠΈ 뢄석 β†’ Markdown λ³΄κ³ μ„œ μ €μž₯” 흐름을 ν•œ λ²ˆμ— μž¬ν˜„ν•œλ‹€.
핡심은 ν™”λ €ν•œ 데λͺ¨κ°€ μ•„λ‹ˆλΌ, νŒ€μ—μ„œ 맀일 반볡 κ°€λŠ₯ν•œ μžλ™ν™” νŒ¨ν„΄μ„ λ§Œλ“œλŠ” 것이닀.

flowchart LR
  A[orders.csv μž…λ ₯] --> B[CodeAgent]
  B --> C[load_orders 도ꡬ]
  B --> D[top_products 도ꡬ]
  B --> E[write_report 도ꡬ]
  E --> F[daily_report.md 생성]
  F --> G[μ‚¬λžŒ κ²€ν†  ν›„ 곡유]

μ‹€μŠ΅ λͺ©ν‘œ

  1. smolagents CodeAgentλ₯Ό μ‹€ν–‰ν•œλ‹€.
  2. CSVλ₯Ό μ½λŠ” μ»€μŠ€ν…€ 도ꡬλ₯Ό μ—°κ²°ν•œλ‹€.
  3. μ—μ΄μ „νŠΈκ°€ 뢄석 ν›„ daily_report.mdλ₯Ό μ €μž₯ν•˜κ²Œ ν•œλ‹€.
  4. 성곡 νŒμ • κΈ°μ€€(파일 생성/핡심 수치 포함)으둜 μž¬ν˜„μ„±μ„ ν™•μΈν•œλ‹€.

1) μ€€λΉ„

Step 1-1. μž‘μ—… 폴더 생성

  • 도ꡬ: 터미널
  • μž…λ ₯: μ—†μŒ
  • μ‹€ν–‰λͺ…λ Ή:
mkdir -p ~/hf-agents-day16 && cd ~/hf-agents-day16
  • μ„±κ³΅νŒμ •: pwdκ°€ ~/hf-agents-day16

Step 1-2. κ°€μƒν™˜κ²½ + νŒ¨ν‚€μ§€ μ„€μΉ˜

  • 도ꡬ: Python 3.10+
  • μž…λ ₯: μ—†μŒ
  • μ‹€ν–‰λͺ…λ Ή:
python3 -m venv .venv
source .venv/bin/activate
pip install -U smolagents
  • μ„±κ³΅νŒμ •:
python -c "import smolagents; print('OK')"

좜λ ₯ OK

Step 1-3. λͺ¨λΈ 인증 ν‚€ μ„€μ •

  • 도ꡬ: ν™˜κ²½λ³€μˆ˜
  • μž…λ ₯: HF_TOKEN (λ˜λŠ” ν™˜κ²½μ— λ§žλŠ” λͺ¨λΈ ν‚€)
  • μ‹€ν–‰λͺ…λ Ή:
export HF_TOKEN="hf_xxx"
  • μ„±κ³΅νŒμ •:
echo ${HF_TOKEN:+set}

좜λ ₯ set


2) μƒ˜ν”Œ 데이터 λ§Œλ“€κΈ°

Step 2-1. CSV 생성

  • 도ꡬ: ν…μŠ€νŠΈ 파일
  • μž…λ ₯: μ•„λž˜ λ‚΄μš©
  • μ‹€ν–‰λͺ…λ Ή:
cat <<'CSV' > orders.csv
order_id,product,qty,unit_price,channel
1001,Keyboard,2,45000,smartstore
1002,Mouse,1,25000,coupang
1003,Keyboard,1,45000,smartstore
1004,Monitor,1,220000,11st
1005,Mouse,3,25000,coupang
CSV
  • μ„±κ³΅νŒμ •:
wc -l orders.csv

6 orders.csv이면 정상(헀더 1 + 데이터 5)


3) μ—μ΄μ „νŠΈ μ½”λ“œ μž‘μ„±

Step 3-1. day16_csv_report.py μ €μž₯

  • 도ꡬ: Python 파일
  • μž…λ ₯: μ•„λž˜ μ½”λ“œ
  • μ‹€ν–‰λͺ…λ Ή: 파일 생성 ν›„ μ €μž₯
import csv
import json
from collections import Counter
from pathlib import Path
 
from smolagents import CodeAgent, HfApiModel, tool
 
 
@tool
def load_orders(csv_path: str) -> str:
    """μ£Όλ¬Έ CSVλ₯Ό 읽어 총맀좜/μ΄μˆ˜λŸ‰/주문건수λ₯Ό JSON λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€."""
    rows = []
    with open(csv_path, "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        rows = list(reader)
 
    total_qty = 0
    total_revenue = 0
    for r in rows:
        qty = int(r["qty"])
        unit_price = int(r["unit_price"])
        total_qty += qty
        total_revenue += qty * unit_price
 
    return json.dumps(
        {
            "orders": len(rows),
            "total_qty": total_qty,
            "total_revenue": total_revenue,
        },
        ensure_ascii=False,
    )
 
 
@tool
def top_products(csv_path: str, top_n: int = 3) -> str:
    """νŒλ§€μˆ˜λŸ‰ κΈ°μ€€ μƒμœ„ μƒν’ˆμ„ JSON λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€."""
    counter = Counter()
    with open(csv_path, "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for r in reader:
            counter[r["product"]] += int(r["qty"])
 
    top = counter.most_common(top_n)
    return json.dumps(
        [{"product": p, "qty": q} for p, q in top],
        ensure_ascii=False,
    )
 
 
@tool
def write_report(path: str, content: str) -> str:
    """λ§ˆν¬λ‹€μš΄ 리포트λ₯Ό 파일둜 μ €μž₯ν•œλ‹€."""
    Path(path).write_text(content, encoding="utf-8")
    return f"saved:{path}"
 
 
def build_agent() -> CodeAgent:
    model = HfApiModel("Qwen/Qwen2.5-72B-Instruct")
    return CodeAgent(
        tools=[load_orders, top_products, write_report],
        model=model,
        max_steps=6,
    )
 
 
if __name__ == "__main__":
    agent = build_agent()
    prompt = """
λ‹€μŒ μž‘μ—…μ„ μˆœμ„œλŒ€λ‘œ μˆ˜ν–‰ν•΄μ€˜.
1) orders.csvλ₯Ό μ½μ–΄μ„œ 총주문건수, μ΄μˆ˜λŸ‰, μ΄λ§€μΆœμ„ 계산
2) νŒλ§€μˆ˜λŸ‰ κΈ°μ€€ μƒμœ„ 2개 μƒν’ˆ μΆ”μΆœ
3) μ•„λž˜ ν˜•μ‹μ˜ Markdown을 λ§Œλ“€μ–΄ daily_report.md둜 μ €μž₯
 
ν˜•μ‹:
# Daily Sales Report
- orders: <숫자>
- total_qty: <숫자>
- total_revenue: <숫자>
- top_products: <μƒν’ˆλͺ…(μˆ˜λŸ‰), μƒν’ˆλͺ…(μˆ˜λŸ‰)>
- note: μžλ™ 생성 리포트 (human review required)
 
λ°˜λ“œμ‹œ write_report 도ꡬλ₯Ό ν˜ΈμΆœν•΄ νŒŒμΌμ„ μ €μž₯ν•΄.
"""
 
    result = agent.run(prompt)
    print("[AGENT_RESULT]", result)
  • μ„±κ³΅νŒμ •:
python -m py_compile day16_csv_report.py

였λ₯˜ 없이 μ’…λ£Œλ˜λ©΄ 톡과.


4) μ‹€ν–‰ 및 검증

Step 4-1. μ—μ΄μ „νŠΈ μ‹€ν–‰

  • 도ꡬ: day16_csv_report.py
  • μž…λ ₯: orders.csv
  • μ‹€ν–‰λͺ…λ Ή:
python day16_csv_report.py
  • μ„±κ³΅νŒμ •: 좜λ ₯에 saved:daily_report.md λ˜λŠ” daily_report.md μ €μž₯ λ©”μ‹œμ§€ 포함

Step 4-2. κ²°κ³Ό 파일 검증

  • 도ꡬ: 터미널
  • μž…λ ₯: μƒμ„±λœ daily_report.md
  • μ‹€ν–‰λͺ…λ Ή:
test -f daily_report.md && echo "FILE_OK"
grep -E "^# Daily Sales Report" daily_report.md && echo "TITLE_OK"
grep -E "total_revenue" daily_report.md && echo "METRIC_OK"
  • μ„±κ³΅νŒμ •: FILE_OK, TITLE_OK, METRIC_OK 3개 λͺ¨λ‘ 좜λ ₯

5) 초보자용 μ‰¬μš΄ μ„€λͺ…

  • @tool ν•¨μˆ˜λŠ” μ—μ΄μ „νŠΈκ°€ μ‚¬μš©ν•  업무 λ²„νŠΌμ΄λ‹€.
  • 이번 μ‹€μŠ΅μ€ λ²„νŠΌ 3개만 λ§Œλ“ λ‹€.
    • load_orders: μš”μ•½ 수치 계산
    • top_products: μƒμœ„ μƒν’ˆ 집계
    • write_report: 파일 μ €μž₯
  • μ—μ΄μ „νŠΈλŠ” β€œλ¬΄μŠ¨ λ²„νŠΌμ„ μ–΄λ–€ μˆœμ„œλ‘œ λˆ„λ₯Όμ§€β€λ₯Ό κ²°μ •ν•˜κ³ , μš°λ¦¬λŠ” μ„±κ³΅νŒμ • 체크둜 κ²°κ³Όλ₯Ό κ²€μ¦ν•œλ‹€.

즉, LLM의 λ¬Έμž₯ ν’ˆμ§ˆμ—λ§Œ κΈ°λŒ€μ§€ μ•Šκ³ , 도ꡬ μ€‘μ‹¬μœΌλ‘œ 결과물을 κ³ μ •ν•˜λŠ” 방식이닀.


6) 싀무 적용 포인트

  1. 일일 리포트 μžλ™ν™”: μ‡Όν•‘λͺ°/κ΄‘κ³ /CS CSVλ₯Ό 같은 νŒ¨ν„΄μœΌλ‘œ λ³΄κ³ μ„œν™”.
  2. 검증 κΈ°μ€€ μ‚¬μ „ν•©μ˜: 파일 생성 + 핡심 μ§€ν‘œ 포함 같은 기쀀을 νŒ€ 룰둜 κ³ μ •.
  3. 휴먼 리뷰 게이트: λ³΄κ³ μ„œ ν•˜λ‹¨μ— human review requiredλ₯Ό λ„£μ–΄ 무검토 배포 λ°©μ§€.
  4. ν™•μž₯ 경둜: λ‹€μŒ λ‹¨κ³„μ—μ„œ Slack/Notion μ—…λ‘œλ“œ 도ꡬλ₯Ό μΆ”κ°€ν•˜λ©΄ 운영 μžλ™ν™”λ‘œ μ—°κ²° κ°€λŠ₯.

체크리슀트

  • κ°€μƒν™˜κ²½ 생성 및 smolagents μ„€μΉ˜ μ™„λ£Œ
  • orders.csv 생성 확인(6쀄)
  • day16_csv_report.py 문법 검사 톡과
  • μ‹€ν–‰ ν›„ daily_report.md 생성
  • total_revenue 포함 μ—¬λΆ€ 확인
  • μ‚¬λžŒμ΄ κ²°κ³Ό 수치 1회 κ²€ν† 

μ°Έκ³  링크 (μš°μ„ μˆœμœ„)

  1. https://github.com/huggingface/agents-course
  2. https://huggingface.co/learn/agents-course
  3. https://huggingface.co/docs/smolagents

μƒμ„±ν˜• AI ν™œμš© κ³ μ§€

이 λ¬Έμ„œλŠ” μƒμ„±ν˜• AIλ₯Ό ν™œμš©ν•΄ μ΄ˆμ•ˆμ„ μž‘μ„±ν–ˆκ³ , μ˜ˆμ‹œ μ½”λ“œ/절차/ν‘œν˜„μ€ μ‚¬λžŒ κ²€ν†  ν›„ ν™•μ •ν–ˆλ‹€.