์ด๋ฒˆ ํŽธ์€ Hugging Face Agents Course์˜ **Hands-on ์ฒ ํ•™(์ž‘๊ฒŒ ๋งŒ๋“ค๊ณ , ๋ฐ”๋กœ ๊ฒ€์ฆํ•˜๊ณ , ์ˆ˜์น˜๋กœ ๊ฐœ์„  ํ™•์ธ)**์„ ๋”ฐ๋ผ, ๋ฐฐํฌ ์Šน์ธ ์ „์— ์ž์ฃผ ์“ฐ๋Š” ๋ฆด๋ฆฌ์ฆˆ ๊ฒŒ์ดํŠธ ์˜์‚ฌ๊ฒฐ์ • ๋ฏธ๋‹ˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค.

ํ•ต์‹ฌ์€ ๊ฐ„๋‹จํ•˜๋‹ค.

  • ์—์ด์ „ํŠธ๊ฐ€ ๋ณ€๊ฒฝ์š”์ฒญ์„ ์ฝ๊ณ 
  • ๋ฆฌ์Šคํฌ๋ฅผ ํŒ๋‹จํ•œ ๋’ค
  • ํ…Œ์ŠคํŠธ ๋ฒ”์œ„/๋ฐฐํฌ ์œˆ๋„์šฐ๋ฅผ ์ œ์•ˆํ•˜๊ณ 
  • FINAL ํ˜•์‹์œผ๋กœ ๊ตฌ์กฐํ™” ๊ฒฐ๊ณผ๋ฅผ ๋‚จ๊ธด๋‹ค.

์ด์ „ ํŽธ(๋ณธํŽธ 02)์—์„œ ๋‹ค๋ฃฌ ToolCallingAgent ํŒจํ„ด์„ ๊ทธ๋Œ€๋กœ ์‹ค๋ฌด์„ฑ ์žˆ๊ฒŒ ํ™•์žฅํ•œ๋‹ค.

ํ•œ ์ค„ ๊ฒฐ๋ก 

ToolCallingAgent + ๋ช…์‹œ์  ๋„๊ตฌ ์ฒด์ธ + ๋ฐฐ์น˜ ํ‰๊ฐ€(eval) ์กฐํ•ฉ์ด๋ฉด, ์ดˆ๋ณด์ž๋„ 30๋ถ„ ์•ˆ์— ๋ฐฐํฌ ๊ฒŒ์ดํŠธ ์ž๋™ํ™”์˜ ์ตœ์†Œํ˜•์„ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ณต์‹ ๊ทผ๊ฑฐ ๋ฐ”๋กœ๋ณด๊ธฐ

flowchart LR
  A[๋ณ€๊ฒฝ ์š”์ฒญ ์ž…๋ ฅ] --> B[detect_change_type]
  B --> C[assess_release_risk]
  C --> D[choose_test_plan]
  D --> E[choose_deploy_window]
  E --> F[FINAL: type/risk/test/window]
  F --> G[๋ฐฐํฌ ์Šน์ธ ํšŒ์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ ๋ฐ˜์˜]

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

  • smolagents์˜ ToolCallingAgent๋กœ ๋ฆด๋ฆฌ์ฆˆ ๊ฒŒ์ดํŠธ ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
  • selfcheck -> single -> eval ์ˆœ์„œ๋กœ ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์‹คํ–‰ ๋ฃจํ”„๋ฅผ ๋งŒ๋“ ๋‹ค.
  • score ๊ธฐ์ค€์œผ๋กœ ์•ˆ์ •์„ฑ(์žฌํ˜„์„ฑ)์„ ํ™•์ธํ•œ๋‹ค.

1) ํ™˜๊ฒฝ ์ค€๋น„

  • ๋„๊ตฌ: Python 3.10+, ํ„ฐ๋ฏธ๋„
  • ์ž…๋ ฅ: requirements.txt
  • ์‹คํ–‰๋ช…๋ น:
cd /home/tw2/Documents/n8n/data/shared/syn/8.quartz/Agent/๐Ÿค—\ HF-Agents-Course/downloads
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt
  • ์„ฑ๊ณตํŒ์ •:
    • (.venv) ํ”„๋กฌํ”„ํŠธ ํ‘œ์‹œ
    • ํŒจํ‚ค์ง€ ์„ค์น˜ ์—๋Ÿฌ ์—†์ด ์ข…๋ฃŒ

2) ๋„๊ตฌ ์…€ํ”„์ฒดํฌ (๋ชจ๋ธ ํ˜ธ์ถœ ์ „)

  • ๋„๊ตฌ: day7_release_gate_handson.py
  • ์ž…๋ ฅ: ๋‚ด์žฅ ์ฒดํฌ ์ผ€์ด์Šค(๋ณ€๊ฒฝ์œ ํ˜•/๋ฆฌ์Šคํฌ/ํ…Œ์ŠคํŠธ/๋ฐฐํฌ์œˆ๋„์šฐ)
  • ์‹คํ–‰๋ช…๋ น:
python day7_release_gate_handson.py --mode selfcheck
  • ์„ฑ๊ณตํŒ์ •:
    • ์ถœ๋ ฅ JSON์— "tools_ok": true

3) ๋‹จ์ผ ์š”์ฒญ ์‹คํ–‰ (ํ•ธ์ฆˆ์˜จ)

  • ๋„๊ตฌ: day7_release_gate_handson.py
  • ์ž…๋ ฅ:
    • change: ๊ฒฐ์ œ API ์žฅ์•  ๊ธด๊ธ‰ hotfix ๋ฐฐํฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    • users: 1200
    • payment: 1
  • ์‹คํ–‰๋ช…๋ น:
# .env์— OPENAI_API_KEY ๋˜๋Š” HF_TOKEN ํ•„์š”
python day7_release_gate_handson.py \
  --mode single \
  --provider auto \
  --change "๊ฒฐ์ œ API ์žฅ์•  ๊ธด๊ธ‰ hotfix ๋ฐฐํฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค." \
  --users 1200 \
  --payment 1
  • ์„ฑ๊ณตํŒ์ •:
    • parsed.parse_ok = true
    • parsed.risk = "high"
    • parsed.test = "FULL_REGRESSION"์— ๊ทผ์ ‘ํ•œ ๊ฒฐ๊ณผ

4) ๋ฐฐ์น˜ ํ‰๊ฐ€ (์žฌํ˜„์„ฑ ์ ๊ฒ€)

  • ๋„๊ตฌ: day7_release_gate_handson.py, sample_tasks_day7.json
  • ์ž…๋ ฅ: ์ƒ˜ํ”Œ ๋ณ€๊ฒฝ์š”์ฒญ 3๊ฑด(๊ธฐ๋Œ€๊ฐ’ ํฌํ•จ)
  • ์‹คํ–‰๋ช…๋ น:
python day7_release_gate_handson.py \
  --mode eval \
  --provider auto \
  --input sample_tasks_day7.json
  • ์„ฑ๊ณตํŒ์ •:
    • "pass": true ๋˜๋Š”
    • "score" >= 0.66

5) ์‹ค๋ฌด ํ™•์žฅ ํฌ์ธํŠธ

  • ํŒ€๋ณ„ ๋ฆด๋ฆฌ์ฆˆ ์ •์ฑ…์„ ๋„๊ตฌ ํ•จ์ˆ˜์— ๋ฐ˜์˜ (payment_path ์™ธ์— db_migration, rollback_ready ๋“ฑ)
  • ๋ณ€๊ฒฝ์š”์ฒญ ์ž…๋ ฅ์„ Jira/Linear ํ•„๋“œ์™€ ๋งคํ•‘
  • eval ๊ฒฐ๊ณผ๋ฅผ ์ฃผ๊ฐ„ ์šด์˜ ์ง€ํ‘œ๋กœ ๋ˆ„์ (๋ฐฐํฌ ์‹คํŒจ์œจ๊ณผ ํ•จ๊ป˜ ๊ด€๋ฆฌ)

ํ˜„์žฅํ˜• ๋ฏธ๋‹ˆ ์‚ฌ๋ก€

์‚ฌ๋ก€ A) ํ•ซํ”ฝ์Šค์ธ๋ฐ ํ…Œ์ŠคํŠธ ๋ฒ”์œ„๊ฐ€ ๊ณผ์†Œ ์ œ์•ˆ๋œ ๊ฒฝ์šฐ

์šด์˜ ์ค‘ ๊ฒฐ์ œ ์žฅ์• ์˜€์ง€๋งŒ users ๊ฐ’์ด ๋‚ฎ์•„ ์ค‘๊ฐ„ ๋ฆฌ์Šคํฌ๋กœ ๋ถ„๋ฅ˜๋๋‹ค. payment=1 ์กฐ๊ฑด์— ๊ฐ•ํ•œ ๊ฐ€์ค‘์น˜๋ฅผ ์ฃผ๊ณ  hotfix ํ‚ค์›Œ๋“œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์˜ฌ๋ฆฌ์ž ์ž˜๋ชป๋œ ์ œ์•ˆ์ด ์ค„์—ˆ๋‹ค.

์‚ฌ๋ก€ B) ๋ฐฐํฌ ์œˆ๋„์šฐ ์ถ”์ฒœ์ด ํŒ€ ์šด์˜์‹œ๊ฐ„๊ณผ ์ถฉ๋Œํ•œ ๊ฒฝ์šฐ

์—์ด์ „ํŠธ๊ฐ€ ์‹ฌ์•ผ ์œˆ๋„์šฐ๋ฅผ ์ถ”์ฒœํ–ˆ์ง€๋งŒ ํŒ€ ์˜จ์ฝœ ์ฒด๊ณ„์™€ ๋งž์ง€ ์•Š์•„ ์‹คํ–‰์ด ์ง€์—ฐ๋๋‹ค. ํŒ€ ์บ˜๋ฆฐ๋”/๊ทผ๋ฌด๊ทœ์น™์„ ๋ฐ˜์˜ํ•œ ์œˆ๋„์šฐ ๋งต์„ ์ถ”๊ฐ€ํ•ด ์šด์˜ ์ ํ•ฉ์„ฑ์ด ์˜ฌ๋ผ๊ฐ”๋‹ค.

25๋ถ„ ๋ณด๊ฐ• ๋ฃจํ‹ด

  • 5๋ถ„: ์ตœ๊ทผ ๋ฐฐํฌ ์‹คํŒจ/์ง€์—ฐ 2๊ฑด ํšŒ๊ณ 
  • 5๋ถ„: ๋ฆฌ์Šคํฌ ๊ทœ์น™(assess_release_risk) ๋ณด์ •
  • 5๋ถ„: ํ…Œ์ŠคํŠธ ์ •์ฑ…(choose_test_plan) ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ
  • 5๋ถ„: sample_tasks_day7.json์— ์‹ค์ œ ๋ณ€๊ฒฝ์š”์ฒญ 2๊ฑด ์ถ”๊ฐ€
  • 5๋ถ„: eval ์žฌ์‹คํ–‰ ํ›„ score์™€ ์‹คํŒจ์›์ธ ๊ธฐ๋ก

ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… (์ž์ฃผ ๋ง‰ํžˆ๋Š” 5๊ฐ€์ง€)

  1. ModuleNotFoundError: dotenv / smolagents

    • ์›์ธ: ๊ฐ€์ƒํ™˜๊ฒฝ ๋ฏธํ™œ์„ฑ ๋˜๋Š” ์˜์กด์„ฑ ๋ฏธ์„ค์น˜
    • ํ•ด๊ฒฐ:
      source .venv/bin/activate
      pip install -r requirements.txt
  2. ๋ชจ๋ธ ํ‚ค๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ

    • ์›์ธ: .env์— OPENAI_API_KEY/HF_TOKEN ์—†์Œ
    • ํ•ด๊ฒฐ: ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋˜๋Š” ์‹คํ–‰ ๊ฒฝ๋กœ์— .env ์ƒ์„ฑ ํ›„ ํ‚ค ์„ค์ •
  3. No such file or directory (์ด๋ชจ์ง€/๊ณต๋ฐฑ ๊ฒฝ๋กœ)

    • ์›์ธ: ๐Ÿค— HF-Agents-Course ๊ฒฝ๋กœ ์ธ์šฉ(quoting) ๋ˆ„๋ฝ
    • ํ•ด๊ฒฐ: ๊ฒฝ๋กœ ์ „์ฒด๋ฅผ ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ๊ฑฐ๋‚˜ ๊ณต๋ฐฑ ์ด์Šค์ผ€์ดํ”„(\ ) ์‚ฌ์šฉ
  4. parse_ok = false

    • ์›์ธ: ๋ชจ๋ธ ์ถœ๋ ฅ ๋งˆ์ง€๋ง‰ ์ค„์ด FINAL: ๊ณ„์•ฝ ํ˜•์‹์„ ์ง€ํ‚ค์ง€ ์•Š์Œ
    • ํ•ด๊ฒฐ: ํ”„๋กฌํ”„ํŠธ์˜ ์ถœ๋ ฅ ๊ณ„์•ฝ ๋ฌธ๊ตฌ๋ฅผ ์œ ์ง€ํ•˜๊ณ , FINAL ์ •๊ทœ์‹ ์กฐ๊ฑด์„ ์ž„์˜ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ธฐ
  5. ์ž…๋ ฅ JSON ๋ฃจํŠธ๋Š” list์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค

    • ์›์ธ: sample_tasks_day7.json ๋ฃจํŠธ ๊ตฌ์กฐ๊ฐ€ ๊ฐ์ฒด({})๋กœ ๋ฐ”๋€œ
    • ํ•ด๊ฒฐ: ๋ฃจํŠธ๋ฅผ ๋ฐฐ์—ด([])๋กœ ์œ ์ง€ํ•˜๊ณ  ๊ฐ ํ•ญ๋ชฉ์— expected ํ•„๋“œ ํฌํ•จ

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

  • selfcheck ์„ฑ๊ณต (tools_ok=true)
  • single ๋ชจ๋“œ์—์„œ parse_ok=true ํ™•์ธ
  • eval ์ ์ˆ˜(score) ๊ธฐ๋ก
  • ํŒ€ ์ •์ฑ…(๋ฆฌ์Šคํฌ ๊ธฐ์ค€/๋ฐฐํฌ ์œˆ๋„์šฐ) 1๊ฐœ ์ด์ƒ ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ

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

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

์‹ค์Šต ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ

๋ณด๊ฐ• ์ถ”๊ฐ€: ํŒ€ ์บ˜๋ฆฐ๋”/์˜จ์ฝœ ์ •์ฑ… YAML ์˜ˆ์‹œ

๋ฐฐํฌ ์œˆ๋„์šฐ ์ถ”์ฒœ์„ ํ˜„์‹คํ™”ํ•˜๋ ค๋ฉด ํŒ€ ์šด์˜ ๊ทœ์น™์„ ๋ฐ์ดํ„ฐ๋กœ ๊ณ ์ •ํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.

release_policy:
  timezone: "Asia/Seoul"
  preferred_windows:
    weekday: ["10:00-11:30", "14:00-16:00"]
    friday: ["10:00-12:00"]
  blocked_windows:
    - "weekday 12:00-13:00"   # ์ ์‹ฌ
    - "weekday 18:30-09:30"   # ์•ผ๊ฐ„
 
oncall:
  required: true
  min_engineers: 2
  payment_path_requires_senior: true
 
risk_rules:
  high_requires:
    - "FULL_REGRESSION"
    - "rollback_plan"
    - "oncall_ack"

์ด YAML์„ ๊ธฐ์ค€์œผ๋กœ choose_deploy_window๋ฅผ ํŠœ๋‹ํ•˜๋ฉด, ์ถ”์ฒœ ๊ฒฐ๊ณผ๊ฐ€ ํŒ€ ์šด์˜๊ณผ ์ถฉ๋Œํ•˜๋Š” ๋นˆ๋„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

ํ’ˆ์งˆ ์ ๊ฒ€ํ‘œ (2026-02-28)

  • ์žฌํ˜„์„ฑ: 9.0/10
  • ๊ณต์‹ ๊ทผ๊ฑฐ ์—ฐ๊ฒฐ: 9.0/10
  • ์šด์˜ ์ ์šฉ์„ฑ: 9.5/10
  • ๋ฌธ์„œ ๊ฐ€๋…์„ฑ: 9.0/10

์ฆ‰์‹œ ๋ณด๊ฐ• ํฌ์ธํŠธ 1๊ฐœ

  • YAML ์ •์ฑ… ๋ณ€๊ฒฝ ์ „/ํ›„๋กœ ์ถ”์ฒœ ์œˆ๋„์šฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‹ฌ๋ผ์ง€๋Š”์ง€ ๋น„๊ต ๋กœ๊ทธ ์˜ˆ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์šด์˜์ž ์ดํ•ด๋„๋ฅผ ๋†’์ธ๋‹ค.

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

์ด ๋ฌธ์„œ๋Š” ์ƒ์„ฑํ˜• AI๋ฅผ ํ™œ์šฉํ•ด ์ดˆ์•ˆ ์ž‘์„ฑ ๋ฐ ๊ตฌ์กฐํ™”๋ฅผ ์ˆ˜ํ–‰ํ–ˆ์œผ๋ฉฐ, ์ตœ์ข… ๋ฐœํ–‰ ์ „ ์‚ฌ๋žŒ์ด ์‚ฌ์‹ค๊ด€๊ณ„์™€ ์žฌํ˜„ ์ ˆ์ฐจ๋ฅผ ์ ๊ฒ€ํ•œ๋‹ค.