์ด๋ฒ ํธ์ Hugging Face Agents Course์ **Hands-on ์ฒ ํ(์๊ฒ ๋ง๋ค๊ณ , ๋ฐ๋ก ๊ฒ์ฆํ๊ณ , ์์น๋ก ๊ฐ์ ํ์ธ)**์ ๋ฐ๋ผ, ๋ฐฐํฌ ์น์ธ ์ ์ ์์ฃผ ์ฐ๋ ๋ฆด๋ฆฌ์ฆ ๊ฒ์ดํธ ์์ฌ๊ฒฐ์ ๋ฏธ๋ ํ๋ก์ ํธ๋ฅผ ๋ง๋ ๋ค.
ํต์ฌ์ ๊ฐ๋จํ๋ค.
- ์์ด์ ํธ๊ฐ ๋ณ๊ฒฝ์์ฒญ์ ์ฝ๊ณ
- ๋ฆฌ์คํฌ๋ฅผ ํ๋จํ ๋ค
- ํ ์คํธ ๋ฒ์/๋ฐฐํฌ ์๋์ฐ๋ฅผ ์ ์ํ๊ณ
FINALํ์์ผ๋ก ๊ตฌ์กฐํ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ธด๋ค.
์ด์ ํธ(๋ณธํธ 02)์์ ๋ค๋ฃฌ ToolCallingAgent ํจํด์ ๊ทธ๋๋ก ์ค๋ฌด์ฑ ์๊ฒ ํ์ฅํ๋ค.
- ์ด์ ํธ: ๐ค 06. ๋ณธํธ 02
ํ ์ค ๊ฒฐ๋ก
ToolCallingAgent + ๋ช
์์ ๋๊ตฌ ์ฒด์ธ + ๋ฐฐ์น ํ๊ฐ(eval) ์กฐํฉ์ด๋ฉด, ์ด๋ณด์๋ 30๋ถ ์์ ๋ฐฐํฌ ๊ฒ์ดํธ ์๋ํ์ ์ต์ํ์ ์ฌํํ ์ ์๋ค.
๊ณต์ ๊ทผ๊ฑฐ ๋ฐ๋ก๋ณด๊ธฐ
- Agents Course(์ปค๋ฆฌํ๋ผ): https://huggingface.co/learn/agents-course
- Course ์ ์ฅ์(์ค์ต ์ฝ๋): https://github.com/huggingface/agents-course
- smolagents ๋ฌธ์(Agent/Tool ํจํด): https://huggingface.co/docs/smolagents
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
- ์ถ๋ ฅ JSON์
3) ๋จ์ผ ์์ฒญ ์คํ (ํธ์ฆ์จ)
- ๋๊ตฌ:
day7_release_gate_handson.py - ์
๋ ฅ:
change:๊ฒฐ์ API ์ฅ์ ๊ธด๊ธ hotfix ๋ฐฐํฌ๊ฐ ํ์ํฉ๋๋ค.users:1200payment: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 = trueparsed.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๊ฐ์ง)
-
ModuleNotFoundError: dotenv/smolagents- ์์ธ: ๊ฐ์ํ๊ฒฝ ๋ฏธํ์ฑ ๋๋ ์์กด์ฑ ๋ฏธ์ค์น
- ํด๊ฒฐ:
source .venv/bin/activate pip install -r requirements.txt
-
๋ชจ๋ธ ํค๋ฅผ ์ฐพ์ง ๋ชปํ์ต๋๋ค๋ฐํ์ ์๋ฌ- ์์ธ:
.env์OPENAI_API_KEY/HF_TOKEN์์ - ํด๊ฒฐ: ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ์คํ ๊ฒฝ๋ก์
.env์์ฑ ํ ํค ์ค์
- ์์ธ:
-
No such file or directory(์ด๋ชจ์ง/๊ณต๋ฐฑ ๊ฒฝ๋ก)- ์์ธ:
๐ค HF-Agents-Course๊ฒฝ๋ก ์ธ์ฉ(quoting) ๋๋ฝ - ํด๊ฒฐ: ๊ฒฝ๋ก ์ ์ฒด๋ฅผ ๋ฐ์ดํ๋ก ๊ฐ์ธ๊ฑฐ๋ ๊ณต๋ฐฑ ์ด์ค์ผ์ดํ(
\) ์ฌ์ฉ
- ์์ธ:
-
parse_ok = false- ์์ธ: ๋ชจ๋ธ ์ถ๋ ฅ ๋ง์ง๋ง ์ค์ด
FINAL:๊ณ์ฝ ํ์์ ์งํค์ง ์์ - ํด๊ฒฐ: ํ๋กฌํํธ์ ์ถ๋ ฅ ๊ณ์ฝ ๋ฌธ๊ตฌ๋ฅผ ์ ์งํ๊ณ ,
FINAL์ ๊ท์ ์กฐ๊ฑด์ ์์ ๋ณ๊ฒฝํ์ง ์๊ธฐ
- ์์ธ: ๋ชจ๋ธ ์ถ๋ ฅ ๋ง์ง๋ง ์ค์ด
-
์ ๋ ฅ JSON ๋ฃจํธ๋ list์ฌ์ผ ํฉ๋๋ค- ์์ธ:
sample_tasks_day7.json๋ฃจํธ ๊ตฌ์กฐ๊ฐ ๊ฐ์ฒด({})๋ก ๋ฐ๋ - ํด๊ฒฐ: ๋ฃจํธ๋ฅผ ๋ฐฐ์ด(
[])๋ก ์ ์งํ๊ณ ๊ฐ ํญ๋ชฉ์expectedํ๋ ํฌํจ
- ์์ธ:
์ฒดํฌ๋ฆฌ์คํธ
-
selfcheck์ฑ๊ณต (tools_ok=true) -
single๋ชจ๋์์parse_ok=trueํ์ธ -
eval์ ์(score) ๊ธฐ๋ก - ํ ์ ์ฑ (๋ฆฌ์คํฌ ๊ธฐ์ค/๋ฐฐํฌ ์๋์ฐ) 1๊ฐ ์ด์ ์ปค์คํฐ๋ง์ด์ฆ
์ฐธ๊ณ ๋งํฌ (์ฐ์ ์์)
- https://github.com/huggingface/agents-course
- https://huggingface.co/learn/agents-course
- https://huggingface.co/docs/smolagents
์ค์ต ํ์ผ ๋ค์ด๋ก๋
- Day7 ์ค์ต ๊ฐ์ด๋ README
- day7_release_gate_handson.py
- sample_tasks_day7.json
- hf-agents-day7-release-gate-handson.zip
๋ณด๊ฐ ์ถ๊ฐ: ํ ์บ๋ฆฐ๋/์จ์ฝ ์ ์ฑ 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๋ฅผ ํ์ฉํด ์ด์ ์์ฑ ๋ฐ ๊ตฌ์กฐํ๋ฅผ ์ํํ์ผ๋ฉฐ, ์ต์ข ๋ฐํ ์ ์ฌ๋์ด ์ฌ์ค๊ด๊ณ์ ์ฌํ ์ ์ฐจ๋ฅผ ์ ๊ฒํ๋ค.