์ด๋ฒ ํธ์ โ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[์ฌ๋ ๊ฒํ ํ ๊ณต์ ]
์ค์ต ๋ชฉํ
- smolagents
CodeAgent๋ฅผ ์คํํ๋ค. - CSV๋ฅผ ์ฝ๋ ์ปค์คํ ๋๊ตฌ๋ฅผ ์ฐ๊ฒฐํ๋ค.
- ์์ด์ ํธ๊ฐ ๋ถ์ ํ
daily_report.md๋ฅผ ์ ์ฅํ๊ฒ ํ๋ค. - ์ฑ๊ณต ํ์ ๊ธฐ์ค(ํ์ผ ์์ฑ/ํต์ฌ ์์น ํฌํจ)์ผ๋ก ์ฌํ์ฑ์ ํ์ธํ๋ค.
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.csv6 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_OK3๊ฐ ๋ชจ๋ ์ถ๋ ฅ
5) ์ด๋ณด์์ฉ ์ฌ์ด ์ค๋ช
@toolํจ์๋ ์์ด์ ํธ๊ฐ ์ฌ์ฉํ ์ ๋ฌด ๋ฒํผ์ด๋ค.- ์ด๋ฒ ์ค์ต์ ๋ฒํผ 3๊ฐ๋ง ๋ง๋ ๋ค.
load_orders: ์์ฝ ์์น ๊ณ์ฐtop_products: ์์ ์ํ ์ง๊ณwrite_report: ํ์ผ ์ ์ฅ
- ์์ด์ ํธ๋ โ๋ฌด์จ ๋ฒํผ์ ์ด๋ค ์์๋ก ๋๋ฅผ์งโ๋ฅผ ๊ฒฐ์ ํ๊ณ , ์ฐ๋ฆฌ๋ ์ฑ๊ณตํ์ ์ฒดํฌ๋ก ๊ฒฐ๊ณผ๋ฅผ ๊ฒ์ฆํ๋ค.
์ฆ, LLM์ ๋ฌธ์ฅ ํ์ง์๋ง ๊ธฐ๋์ง ์๊ณ , ๋๊ตฌ ์ค์ฌ์ผ๋ก ๊ฒฐ๊ณผ๋ฌผ์ ๊ณ ์ ํ๋ ๋ฐฉ์์ด๋ค.
6) ์ค๋ฌด ์ ์ฉ ํฌ์ธํธ
- ์ผ์ผ ๋ฆฌํฌํธ ์๋ํ: ์ผํ๋ชฐ/๊ด๊ณ /CS CSV๋ฅผ ๊ฐ์ ํจํด์ผ๋ก ๋ณด๊ณ ์ํ.
- ๊ฒ์ฆ ๊ธฐ์ค ์ฌ์ ํฉ์:
ํ์ผ ์์ฑ + ํต์ฌ ์งํ ํฌํจ๊ฐ์ ๊ธฐ์ค์ ํ ๋ฃฐ๋ก ๊ณ ์ . - ํด๋จผ ๋ฆฌ๋ทฐ ๊ฒ์ดํธ: ๋ณด๊ณ ์ ํ๋จ์
human review required๋ฅผ ๋ฃ์ด ๋ฌด๊ฒํ ๋ฐฐํฌ ๋ฐฉ์ง. - ํ์ฅ ๊ฒฝ๋ก: ๋ค์ ๋จ๊ณ์์ Slack/Notion ์ ๋ก๋ ๋๊ตฌ๋ฅผ ์ถ๊ฐํ๋ฉด ์ด์ ์๋ํ๋ก ์ฐ๊ฒฐ ๊ฐ๋ฅ.
์ฒดํฌ๋ฆฌ์คํธ
- ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ
smolagents์ค์น ์๋ฃ -
orders.csv์์ฑ ํ์ธ(6์ค) -
day16_csv_report.py๋ฌธ๋ฒ ๊ฒ์ฌ ํต๊ณผ - ์คํ ํ
daily_report.md์์ฑ -
total_revenueํฌํจ ์ฌ๋ถ ํ์ธ - ์ฌ๋์ด ๊ฒฐ๊ณผ ์์น 1ํ ๊ฒํ
์ฐธ๊ณ ๋งํฌ (์ฐ์ ์์)
- https://github.com/huggingface/agents-course
- https://huggingface.co/learn/agents-course
- https://huggingface.co/docs/smolagents
์์ฑํ AI ํ์ฉ ๊ณ ์ง
์ด ๋ฌธ์๋ ์์ฑํ AI๋ฅผ ํ์ฉํด ์ด์์ ์์ฑํ๊ณ , ์์ ์ฝ๋/์ ์ฐจ/ํํ์ ์ฌ๋ ๊ฒํ ํ ํ์ ํ๋ค.