이번 νŽΈμ€ μ—μ΄μ „νŠΈλ₯Ό β€œλŒμ•„κ°€κ²Œβ€ λ§Œλ“œλŠ” 것보닀 ν•œ 단계 더 λ‚˜μ•„κ°€, μ‹€νŒ¨ν•΄λ„ λ‹€μ‹œ μ‹œλ„ν•˜κ³  μ‹€ν–‰ 흔적을 λ‚¨κΈ°λŠ” μš΄μ˜ν˜• νŒ¨ν„΄μ„ 닀룬닀.

flowchart LR
  A[task.txt μž…λ ₯] --> B[CodeAgent μ‹€ν–‰]
  B --> C[tool 호좜]
  C -->|성곡| D[result.json μ €μž₯]
  C -->|μ‹€νŒ¨| E[retry 1회 μž¬μ‹œλ„]
  E -->|μž¬μ„±κ³΅| D
  E -->|μž¬μ‹€νŒ¨| F[error 둜그 μ €μž₯]
  B --> G[run_log.jsonl λˆ„μ ]

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

  1. CodeAgent + μ»€μŠ€ν…€ 도ꡬλ₯Ό μ‹€ν–‰ν•œλ‹€.
  2. 도ꡬ μ‹€νŒ¨ μ‹œ 1회 μžλ™ μž¬μ‹œλ„λ₯Ό 뢙인닀.
  3. μ‹€ν–‰ 둜그(run_log.jsonl)λ₯Ό 남긴닀.
  4. κ²°κ³Ό 파일/둜그 파일/성곡 쑰건으둜 μž¬ν˜„μ„±μ„ κ²€μ¦ν•œλ‹€.

1) μ€€λΉ„

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

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

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. task.txt 생성

  • 도ꡬ: ν…μŠ€νŠΈ 파일
  • μž…λ ₯: μ•„λž˜ ν…μŠ€νŠΈ
  • μ‹€ν–‰λͺ…λ Ή:
cat <<'TXT' > task.txt
이번 μ£Ό 고객문의 둜그λ₯Ό 3쀄 μš”μ•½ν•΄μ€˜.
- μ§€μ—° 배솑 λ¬Έμ˜κ°€ λŠ˜μ—ˆλ‹€.
- 결제 였λ₯˜κ°€ κ°„ν—μ μœΌλ‘œ λ°œμƒν–ˆλ‹€.
- ν™˜λΆˆ λ¬Έμ˜λŠ” μ „μ£Ό λŒ€λΉ„ κ°μ†Œν–ˆλ‹€.
TXT
  • μ„±κ³΅νŒμ •:
test -f task.txt && echo FILE_OK

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

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

  • 도ꡬ: Python 파일
  • μž…λ ₯: μ•„λž˜ μ½”λ“œ
import json
import random
from datetime import datetime, timezone
from pathlib import Path
 
from smolagents import CodeAgent, HfApiModel, tool
 
 
def log_event(path: Path, payload: dict):
    payload["ts"] = datetime.now(timezone.utc).isoformat()
    with path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(payload, ensure_ascii=False) + "\n")
 
 
@tool
def unstable_save(path: str, content: str) -> str:
    """가끔 μ‹€νŒ¨ν•˜λŠ” μ €μž₯ 도ꡬ(μ‹€μŠ΅μš©)."""
    if random.random() < 0.4:
        raise RuntimeError("temporary io error")
    Path(path).write_text(content, encoding="utf-8")
    return f"saved:{path}"
 
 
@tool
def save_with_retry(path: str, content: str) -> str:
    """μ‹€νŒ¨ μ‹œ 1회 μž¬μ‹œλ„ ν›„ μ €μž₯ν•œλ‹€."""
    try:
        return unstable_save(path, content)
    except Exception:
        return unstable_save(path, content)
 
 
def build_agent() -> CodeAgent:
    model = HfApiModel("Qwen/Qwen2.5-72B-Instruct")
    return CodeAgent(
        tools=[save_with_retry],
        model=model,
        max_steps=6,
    )
 
 
if __name__ == "__main__":
    random.seed(7)  # μž¬ν˜„ κ°€λŠ₯ν•œ μ‹€μŠ΅μ„ μœ„ν•œ κ³ μ • μ‹œλ“œ
 
    run_log = Path("run_log.jsonl")
    out_file = Path("result.json")
    task_text = Path("task.txt").read_text(encoding="utf-8")
 
    if run_log.exists():
        run_log.unlink()
    if out_file.exists():
        out_file.unlink()
 
    agent = build_agent()
    prompt = f"""
μ•„λž˜ ν…μŠ€νŠΈλ₯Ό ν•œκ΅­μ–΄ 3μ€„λ‘œ μš”μ•½ν•΄.
λ°˜λ“œμ‹œ save_with_retry 도ꡬλ₯Ό μ‚¬μš©ν•΄μ„œ result.json에 μ•„λž˜ JSON ν˜•νƒœλ‘œ μ €μž₯ν•΄.
{{"summary": ["...", "...", "..."]}}
 
μž…λ ₯:
{task_text}
"""
 
    log_event(run_log, {"event": "start"})
    try:
        result = agent.run(prompt)
        log_event(run_log, {"event": "finish", "result": str(result)})
        print("[FINISH] run completed")
    except Exception as e:
        log_event(run_log, {"event": "error", "message": str(e)})
        print(f"[ERROR] {e}")
  • μ„±κ³΅νŒμ •:
python -m py_compile day18_observe_retry.py

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


4) μ‹€ν–‰ 및 검증

Step 4-1. μ‹€ν–‰

  • 도ꡬ: day18_observe_retry.py
  • μž…λ ₯: task.txt
  • μ‹€ν–‰λͺ…λ Ή:
python day18_observe_retry.py
  • μ„±κ³΅νŒμ •: [FINISH] run completed 좜λ ₯

Step 4-2. 검증

  • 도ꡬ: 터미널
  • μž…λ ₯: result.json, run_log.jsonl
  • μ‹€ν–‰λͺ…λ Ή:
test -f result.json && echo RESULT_OK
test -f run_log.jsonl && echo LOG_OK
grep -E '"summary"' result.json >/dev/null && echo FIELD_OK
  • μ„±κ³΅νŒμ •: RESULT_OK, LOG_OK, FIELD_OK 3개 λͺ¨λ‘ 좜λ ₯

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

  • μ—μ΄μ „νŠΈλŠ” 잘 λ™μž‘ν•  λ•Œλ³΄λ‹€, 가끔 μ‹€νŒ¨ν•  λ•Œ 운영 λ‚œλ„κ°€ κΈ‰κ²©νžˆ μ˜¬λΌκ°„λ‹€.
  • 이번 νŒ¨ν„΄μ€ μ•„μ£Ό λ‹¨μˆœν•˜λ‹€.
    1. μ‹€νŒ¨ κ°€λŠ₯ 도ꡬλ₯Ό 감싼닀.
    2. 1회 μž¬μ‹œλ„ν•œλ‹€.
    3. μ‹œμž‘/μ’…λ£Œ/였λ₯˜λ₯Ό 둜그둜 남긴닀.
  • 이 3κ°€μ§€λ§Œ 해도 β€œμ™œ μ‹€νŒ¨ν–ˆλŠ”μ§€ λͺ¨λ₯΄λŠ” μƒνƒœβ€λ₯Ό 크게 쀄일 수 μžˆλ‹€.

6) 싀무 적용 포인트

  1. μ•Όκ°„ 배치 μ•ˆμ •ν™”: μΌμ‹œ 였λ₯˜(λ„€νŠΈμ›Œν¬/파일락)둜 전체 μ‹€νŒ¨ν•˜λŠ” λΉ„μœ¨ κ°μ†Œ.
  2. μž₯μ•  뢄석 μ‹œκ°„ 단좕: run_log.jsonl둜 μ‹€νŒ¨ 지점 좔적이 μ‰¬μ›Œμ§.
  3. 운영 ν‘œμ€€ν™”: λͺ¨λ“  도ꡬ에 λ™μΌν•œ retry/log 래퍼λ₯Ό 적용 κ°€λŠ₯.
  4. ν™•μž₯ λ°©ν–₯: λ‹€μŒ λ‹¨κ³„μ—μ„œ μž¬μ‹œλ„ 횟수, λ°±μ˜€ν”„, μ•Œλ¦Ό(μŠ¬λž™/이메일) μΆ”κ°€.

체크리슀트

  • smolagents μ„€μΉ˜ μ™„λ£Œ
  • task.txt 생성 μ™„λ£Œ
  • day18_observe_retry.py 문법 검사 톡과
  • μ‹€ν–‰ ν›„ result.json 생성
  • μ‹€ν–‰ ν›„ run_log.jsonl 생성
  • summary ν•„λ“œ 쑴재 확인

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

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

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

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