์ด๋ฒˆ ํŽธ์€ ToolCallingAgent๋กœ ๊ณ ๊ฐ๋ฌธ์˜๋ฅผ ์ž๋™ ๋ถ„๋ฅ˜ํ•˜๋Š” ๊ฐ€์žฅ ์‹ค๋ฌด์ ์ธ ์ž…๋ฌธ ํŒจํ„ด์„ ๋‹ค๋ฃฌ๋‹ค.
ํ•ต์‹ฌ์€ โ€œ์˜ˆ์˜๊ฒŒ ๋‹ตํ•˜๊ธฐโ€๊ฐ€ ์•„๋‹ˆ๋ผ, ์นดํ…Œ๊ณ ๋ฆฌ/์šฐ์„ ์ˆœ์œ„๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ๋ฝ‘์•„ ํ›„์† ์ž๋™ํ™”์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

flowchart LR
  A[inquiries.jsonl ์ž…๋ ฅ] --> B[ToolCallingAgent]
  B --> C[classify_inquiry ๋„๊ตฌ]
  C --> D[์นดํ…Œ๊ณ ๋ฆฌ/์šฐ์„ ์ˆœ์œ„ JSON]
  D --> E[save_result ๋„๊ตฌ]
  E --> F[triage_results.jsonl ์ €์žฅ]
  F --> G[์‚ฌ๋žŒ ๊ฒ€ํ†  ํ›„ ํ‹ฐ์ผ“ ์‹œ์Šคํ…œ ๋ฐ˜์˜]

์‹ค์Šต ๋ชฉํ‘œ

  1. ToolCallingAgent๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
  2. ๋ฌธ์˜ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ์ปค์Šคํ…€ ๋„๊ตฌ๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค.
  3. ๊ฒฐ๊ณผ๋ฅผ triage_results.jsonl๋กœ ์ €์žฅํ•œ๋‹ค.
  4. ์„ฑ๊ณต ํŒ์ •(ํŒŒ์ผ ์ƒ์„ฑ, ๋ผ์ธ ์ˆ˜ ์ผ์น˜, ํ•„์ˆ˜ ํ•„๋“œ ์กด์žฌ)์œผ๋กœ ์žฌํ˜„์„ฑ์„ ํ™•์ธํ•œ๋‹ค.

1) ์ค€๋น„

Step 1-1. ์ž‘์—… ํด๋” ์ƒ์„ฑ

  • ๋„๊ตฌ: ํ„ฐ๋ฏธ๋„
  • ์ž…๋ ฅ: ์—†์Œ
  • ์‹คํ–‰๋ช…๋ น:
mkdir -p ~/hf-agents-day17 && cd ~/hf-agents-day17
  • ์„ฑ๊ณตํŒ์ •: pwd๊ฐ€ ~/hf-agents-day17

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. inquiries.jsonl ๋งŒ๋“ค๊ธฐ

  • ๋„๊ตฌ: ํ…์ŠคํŠธ ํŒŒ์ผ
  • ์ž…๋ ฅ: ์•„๋ž˜ ์ƒ˜ํ”Œ
  • ์‹คํ–‰๋ช…๋ น:
cat <<'JSONL' > inquiries.jsonl
{"id":"q1","text":"๊ฒฐ์ œ๋Š” ๋๋Š”๋ฐ ์ฃผ๋ฌธํ™•์ธ์ด ์•ˆ ๋– ์š”"}
{"id":"q2","text":"์–ด์ œ ๋ฐ›์€ ํ‚ค๋ณด๋“œ๊ฐ€ ์ž…๋ ฅ์ด ์•ˆ ๋ฉ๋‹ˆ๋‹ค"}
{"id":"q3","text":"์„ธ๊ธˆ๊ณ„์‚ฐ์„œ ๋ฐœํ–‰ ๋ฐฉ๋ฒ• ์•Œ๋ ค์ฃผ์„ธ์š”"}
{"id":"q4","text":"๋ฐฐ์†ก์ด 3์ผ์งธ ๋ฉˆ์ถฐ ์žˆ์–ด์š”"}
JSONL
  • ์„ฑ๊ณตํŒ์ •:
wc -l inquiries.jsonl

4 inquiries.jsonl์ด๋ฉด ์ •์ƒ.


3) ์—์ด์ „ํŠธ ์ฝ”๋“œ ์ž‘์„ฑ

Step 3-1. day17_triage.py ์ €์žฅ

  • ๋„๊ตฌ: Python ํŒŒ์ผ
  • ์ž…๋ ฅ: ์•„๋ž˜ ์ฝ”๋“œ
  • ์‹คํ–‰๋ช…๋ น: ํŒŒ์ผ ์ƒ์„ฑ ํ›„ ์ €์žฅ
import json
from pathlib import Path
 
from smolagents import ToolCallingAgent, HfApiModel, tool
 
 
@tool
def classify_inquiry(text: str) -> str:
    """๋ฌธ์˜ ํ…์ŠคํŠธ๋ฅผ ์นดํ…Œ๊ณ ๋ฆฌ์™€ ์šฐ์„ ์ˆœ์œ„๋กœ ๋ถ„๋ฅ˜ํ•ด JSON ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค."""
    t = text.strip()
    if any(k in t for k in ["์•ˆ ๋ผ", "๋ถˆ๋Ÿ‰", "๊ณ ์žฅ", "์ž…๋ ฅ"]):
        result = {"category": "์ œํ’ˆ๋ฌธ์ œ", "priority": "high"}
    elif any(k in t for k in ["๊ฒฐ์ œ", "์ฃผ๋ฌธํ™•์ธ", "ํ™˜๋ถˆ"]):
        result = {"category": "์ฃผ๋ฌธ/๊ฒฐ์ œ", "priority": "high"}
    elif any(k in t for k in ["๋ฐฐ์†ก", "ํƒ๋ฐฐ", "๋„์ฐฉ"]):
        result = {"category": "๋ฐฐ์†ก", "priority": "medium"}
    else:
        result = {"category": "์ผ๋ฐ˜๋ฌธ์˜", "priority": "low"}
    return json.dumps(result, ensure_ascii=False)
 
 
@tool
def save_result(path: str, line: str) -> str:
    """JSONL ๋ผ์ธ์„ ํŒŒ์ผ ๋์— ์ถ”๊ฐ€ ์ €์žฅํ•œ๋‹ค."""
    with open(path, "a", encoding="utf-8") as f:
        f.write(line + "\n")
    return f"saved:{path}"
 
 
def build_agent() -> ToolCallingAgent:
    model = HfApiModel("Qwen/Qwen2.5-72B-Instruct")
    return ToolCallingAgent(
        tools=[classify_inquiry, save_result],
        model=model,
        max_steps=6,
    )
 
 
if __name__ == "__main__":
    in_path = Path("inquiries.jsonl")
    out_path = Path("triage_results.jsonl")
    if out_path.exists():
        out_path.unlink()
 
    agent = build_agent()
 
    for raw in in_path.read_text(encoding="utf-8").splitlines():
        item = json.loads(raw)
        prompt = f"""
๋‹ค์Œ ๊ณ ๊ฐ๋ฌธ์˜๋ฅผ ๋ถ„๋ฅ˜ํ•ด.
๋ฌธ์˜: {item['text']}
 
๊ทœ์น™:
1) classify_inquiry ๋„๊ตฌ๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ
2) ๊ฒฐ๊ณผ๋ฅผ {{id, category, priority}} JSON ํ•œ ์ค„๋กœ ๋งŒ๋“ค ๊ฒƒ
3) save_result ๋„๊ตฌ๋กœ triage_results.jsonl์— ์ €์žฅ
"""
        result = agent.run(prompt)
        print(f"[DONE] {item['id']} -> {result}")
 
    print("[FINISH] triage completed")
  • ์„ฑ๊ณตํŒ์ •:
python -m py_compile day17_triage.py

์˜ค๋ฅ˜ ์—†์ด ์ข…๋ฃŒ๋˜๋ฉด ํ†ต๊ณผ.


4) ์‹คํ–‰ ๋ฐ ๊ฒ€์ฆ

Step 4-1. ์—์ด์ „ํŠธ ์‹คํ–‰

  • ๋„๊ตฌ: day17_triage.py
  • ์ž…๋ ฅ: inquiries.jsonl
  • ์‹คํ–‰๋ช…๋ น:
python day17_triage.py
  • ์„ฑ๊ณตํŒ์ •: ์ถœ๋ ฅ ๋งˆ์ง€๋ง‰์— [FINISH] triage completed ํ‘œ์‹œ

Step 4-2. ๊ฒฐ๊ณผ ๊ฒ€์ฆ

  • ๋„๊ตฌ: ํ„ฐ๋ฏธ๋„
  • ์ž…๋ ฅ: triage_results.jsonl
  • ์‹คํ–‰๋ช…๋ น:
test -f triage_results.jsonl && echo "FILE_OK"
[ "$(wc -l < triage_results.jsonl)" -eq 4 ] && echo "COUNT_OK"
grep -E '"category"' triage_results.jsonl >/dev/null && echo "FIELD_OK"
  • ์„ฑ๊ณตํŒ์ •: FILE_OK, COUNT_OK, FIELD_OK 3๊ฐœ ๋ชจ๋‘ ์ถœ๋ ฅ

5) ์ดˆ๋ณด์ž์šฉ ์‰ฌ์šด ์„ค๋ช…

  • ToolCallingAgent๋Š” ๋„๊ตฌ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ •ํ•ด์ง„ ํ˜•์‹ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค ๋•Œ ํŠนํžˆ ์œ ๋ฆฌํ•˜๋‹ค.
  • ์ด๋ฒˆ ์‹ค์Šต์—์„œ LLM์€ โ€œ์ƒ๊ฐโ€์„ ํ•˜๊ณ , ์‹ค์ œ ๋ถ„๋ฅ˜ ๊ทœ์น™์€ classify_inquiry๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค.
  • ๊ทธ๋ž˜์„œ ์ถœ๋ ฅ ํ’ˆ์งˆ์ด ํ”๋“ค๋ ค๋„, **์ตœ์ข… ์ €์žฅ ๊ตฌ์กฐ(id/category/priority)**๋Š” ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€๋œ๋‹ค.

6) ์‹ค๋ฌด ์ ์šฉ ํฌ์ธํŠธ

  1. CS ํ‹ฐ์ผ“ ์„ ๋ถ„๋ฅ˜ ์ž๋™ํ™”: ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋‹ด๋‹น์ž ๋ผ์šฐํŒ… ์—ฐ๊ฒฐ.
  2. SLA ๋Œ€์‘: priority=high๋งŒ ์ฆ‰์‹œ ์•Œ๋ฆผ(์Šฌ๋ž™/๋ฌธ์ž)๋กœ ๋ถ„๊ธฐ.
  3. ์šด์˜ ์•ˆ์ •์„ฑ: ๊ฒฐ๊ณผ๋ฅผ JSONL๋กœ ๊ณ ์ •ํ•ด BI/๋Œ€์‹œ๋ณด๋“œ ์—ฐ๋™์ด ์‰ฝ๋‹ค.
  4. ํ™•์žฅ ๊ฒฝ๋กœ: ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ FAQ ๊ฒ€์ƒ‰ ๋„๊ตฌ๋ฅผ ์ถ”๊ฐ€ํ•ด 1์ฐจ ์ž๋™์‘๋‹ต๊นŒ์ง€ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ.

์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ ๋ฐ smolagents ์„ค์น˜ ์™„๋ฃŒ
  • inquiries.jsonl 4์ค„ ์ƒ์„ฑ ํ™•์ธ
  • day17_triage.py ๋ฌธ๋ฒ• ๊ฒ€์‚ฌ ํ†ต๊ณผ
  • ์‹คํ–‰ ํ›„ triage_results.jsonl ์ƒ์„ฑ
  • ๋ผ์ธ ์ˆ˜ ์ผ์น˜(์ž…๋ ฅ 4 = ์ถœ๋ ฅ 4)
  • ์‚ฌ๋žŒ์ด ์ƒ˜ํ”Œ 2๊ฑด ์ด์ƒ ์ˆ˜๋™ ๊ฒ€ํ† 

์ฐธ๊ณ  ๋งํฌ (์šฐ์„ ์ˆœ์œ„)

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

์ƒ์„ฑํ˜• AI ํ™œ์šฉ ๊ณ ์ง€

์ด ๋ฌธ์„œ๋Š” ์ƒ์„ฑํ˜• AI๋ฅผ ํ™œ์šฉํ•ด ์ดˆ์•ˆ์„ ์ž‘์„ฑํ–ˆ๊ณ , ์˜ˆ์‹œ ์ฝ”๋“œ/์ ˆ์ฐจ/ํ‘œํ˜„์€ ์‚ฌ๋žŒ ๊ฒ€ํ†  ํ›„ ํ™•์ •ํ–ˆ๋‹ค.