์ด๋ฒˆ ํŽธ์—์„œ๋Š” ToolCallingAgent๋ฅผ ์‚ฌ์šฉํ•ด โ€œ์ž…๋ ฅ โ†’ ๋„๊ตฌ ์‹คํ–‰ โ†’ ๊ฒฐ๊ณผ ๊ฒ€์ฆโ€ ํ๋ฆ„์„ ์•ˆ์ •์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฒ•์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ์ดˆ๋ณด์ž๋„ ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์ตœ์†Œ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“  ๋’ค, ์‹ค๋ฌดํ˜• ์ฒดํฌํฌ์ธํŠธ(๋กœ๊ทธ/์˜ค๋ฅ˜/์„ฑ๊ณตํŒ์ •)๋ฅผ ๋ถ™์ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

1) ์™œ ToolCallingAgent๋ฅผ ์“ฐ๋‚˜?

  • LLM์ด ์ง์ ‘ ๋‹ต๋งŒ ์ƒ์„ฑํ•˜๋ฉด, ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ/๊ณ„์‚ฐ/๊ฒ€์ฆ์ด ์•ฝํ•ฉ๋‹ˆ๋‹ค.
  • ToolCallingAgent๋Š” ํ•„์š”ํ•œ ์ˆœ๊ฐ„ ํˆด์„ ํ˜ธ์ถœํ•ด ํ–‰๋™ ๊ฐ€๋Šฅํ•œ ๋‹ต์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ํ•ต์‹ฌ์€ โ€œ์ข‹์€ ํ”„๋กฌํ”„ํŠธโ€๋ณด๋‹ค ์ข‹์€ ์‹คํ–‰ ๋ฃจํ”„(๋กœ๊ทธ, ํŒ์ •, ์‹คํŒจ ๋ณต๊ตฌ) ์ž…๋‹ˆ๋‹ค.

2) ์ „์ฒด ํ๋ฆ„

flowchart TD
  A[์‚ฌ์šฉ์ž ์งˆ์˜] --> B[ToolCallingAgent ๊ณ„ํš]
  B --> C[๋„๊ตฌ ํ˜ธ์ถœ: search_weather]
  C --> D[๋„๊ตฌ ๊ฒฐ๊ณผ ์ˆ˜์‹ ]
  D --> E[๊ฒฐ๊ณผ ๊ฒ€์ฆ: ํ•„์ˆ˜ ํ•„๋“œ/๋‹จ์œ„]
  E --> F[์ตœ์ข… ๋‹ต๋ณ€ ์ƒ์„ฑ]
  E -->|๊ฒ€์ฆ ์‹คํŒจ| G[์žฌ์‹œ๋„ ๋˜๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€]

3) ์‹ค์Šต: ์„œ์šธ ๋‚ ์”จ ์š”์•ฝ ์—์ด์ „ํŠธ

์ค€๋น„ ๋„๊ตฌ

  • Python 3.10+
  • ํŒจํ‚ค์ง€: smolagents, python-dotenv
  • ๋ชจ๋ธ ํ‚ค(์˜ˆ: Hugging Face Inference ๋˜๋Š” OpenAI ํ˜ธํ™˜ ํ‚ค)

ํด๋”/ํŒŒ์ผ

mkdir -p hf-agent-lesson4 && cd hf-agent-lesson4
python3 -m venv .venv
source .venv/bin/activate
pip install -U smolagents python-dotenv

.env

HF_TOKEN=your_hf_token

app.py

from dotenv import load_dotenv
from smolagents import ToolCallingAgent, InferenceClientModel, tool
import requests
 
load_dotenv()
 
@tool
def search_weather(city: str) -> str:
    """๋„์‹œ ์ด๋ฆ„์„ ๋ฐ›์•„ ํ˜„์žฌ ๊ธฐ์˜จ/๋‚ ์”จ๋ฅผ ์งง๊ฒŒ ๋ฐ˜ํ™˜"""
    # ๋ฐ๋ชจ์šฉ ๊ณต๊ฐœ ์—”๋“œํฌ์ธํŠธ (์˜ˆ์‹œ)
    url = f"https://wttr.in/{city}?format=j1"
    r = requests.get(url, timeout=10)
    r.raise_for_status()
    data = r.json()
    current = data["current_condition"][0]
    temp_c = current.get("temp_C", "N/A")
    desc = current.get("weatherDesc", [{"value": "N/A"}])[0]["value"]
    return f"{city} ํ˜„์žฌ {temp_c}ยฐC, {desc}"
 
model = InferenceClientModel()
agent = ToolCallingAgent(
    tools=[search_weather],
    model=model,
    max_steps=4,
)
 
query = "์„œ์šธ ์˜ค๋Š˜ ๋‚ ์”จ๋ฅผ ํ•œ ์ค„๋กœ ์š”์•ฝํ•ด์ค˜"
result = agent.run(query)
print(result)

์‹คํ–‰ ๋ช…๋ น

python app.py

์„ฑ๊ณต ํŒ์ •

์•„๋ž˜ 3๊ฐœ๋ฅผ ๋งŒ์กฑํ•˜๋ฉด ์„ฑ๊ณต์ž…๋‹ˆ๋‹ค.

  1. ์‹คํ–‰ ์ค‘ ๋„๊ตฌ ํ˜ธ์ถœ ํ”์ ์ด ๋กœ๊ทธ์— ๋ณด์ธ๋‹ค. (search_weather)
  2. ์ถœ๋ ฅ์— ๋„์‹œ๋ช…/๊ธฐ์˜จ/์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ๋‹ค. (์˜ˆ: ์„œ์šธ ํ˜„์žฌ 22ยฐC, Partly cloudy)
  3. ์˜ˆ์™ธ ์—†์ด ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋œ๋‹ค. (exit code 0)

4) ์ดˆ๋ณด์ž ์‹ค์ˆ˜์™€ ๋น ๋ฅธ ๋ณต๊ตฌ

  • API/ํ† ํฐ ๋ˆ„๋ฝ: .env์™€ ์‰˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ค‘๋ณต ํ™•์ธ
  • ๋„๊ตฌ ํƒ€์ž„์•„์›ƒ: requests.get(..., timeout=10) ์œ ์ง€
  • ์ถœ๋ ฅ ํฌ๋งท ํ”๋“ค๋ฆผ: ๋„๊ตฌ ๋ฐ˜ํ™˜ ๋ฌธ์ž์—ด์„ ๊ณ ์ • ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ œํ•œ

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

  • ํˆด ํ•จ์ˆ˜๋Š” โ€œ์งง๊ณ  ๊ฒฐ์ •์ (deterministic)โ€์œผ๋กœ ์„ค๊ณ„
  • ์—์ด์ „ํŠธ ์‘๋‹ต ์‹ ๋ขฐ์„ฑ์€ ๋ชจ๋ธ๋ณด๋‹ค ๋„๊ตฌ ์Šคํ‚ค๋งˆ + ๊ฒ€์ฆ ๊ทœ์น™์ด ์ขŒ์šฐ
  • ์šด์˜ ์‹œ ์ตœ์†Œ 3๊ฐœ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ์„ธ์š”: ์ž…๋ ฅ, ํˆด ๊ฒฐ๊ณผ, ์ตœ์ข… ์‘๋‹ต

6) ๋‹ค์Œ ํŽธ ์˜ˆ๊ณ 

๋‹ค์Œ ๋ณธํŽธ์—์„œ๋Š” ToolCallingAgent์— ๋‹ค์ค‘ ๋„๊ตฌ ๋ผ์šฐํŒ…(๊ฒ€์ƒ‰+๊ณ„์‚ฐ+ํฌ๋งทํ„ฐ) ์„ ๋ถ™์—ฌ ์—…๋ฌด ์ž๋™ํ™” ํ…œํ”Œ๋ฆฟ์œผ๋กœ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.


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

์ด ๋ฌธ์„œ๋Š” ์ƒ์„ฑํ˜• AI๋กœ ์ดˆ์•ˆ์„ ๋งŒ๋“ค๊ณ , Hugging Face ๊ณต์‹ ์ž๋ฃŒ(์ฝ”์Šค/๋ฌธ์„œ) ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์‹ค๊ด€๊ณ„์™€ ์‹ค์Šต ๋‹จ๊ณ„๋ฅผ ๊ฒ€ํ† ยท๋ณด์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.