본문 바로가기

AI Agent

smolagents 시작 가이드 — HuggingFace 초경량 에이전트 30분에 완성

반응형

LangGraph는 너무 복잡하고, CrewAI는 설정이 많고.

그냥 빠르게 에이전트 하나 만들고 싶을 때 있잖아요.

smolagents가 그 자리예요. HuggingFace가 만든 초경량 에이전트 라이브러리예요.

pip install smolagents

설치 끝. 이게 다예요.


다른 프레임워크랑 뭐가 다른가

일반 에이전트 vs smolagents Code Agent

일반 에이전트 (ReAct 방식):
LLM → "search_tool 호출해줘" → 실행 → LLM으로 결과 전달
→ LLM → "calculate 호출해줘" → 실행 → LLM으로 결과 전달
→ LLM → "format 호출해줘" → 실행 → 최종 답변

LLM 호출: 4회

smolagents Code Agent:
LLM → Python 코드 작성 → 한 번에 실행:

result = search("최신 AI 뉴스")
numbers = extract_numbers(result)
answer = format_output(numbers)
print(answer)

LLM 호출: 1회

같은 작업에 LLM 호출 횟수가 줄어요. 비용도 줄고 속도도 빨라요.


설치 및 환경 설정

pip install smolagents

# 추가 툴 사용 시
pip install smolagents[toolkit]  # 기본 툴 모음
pip install smolagents[litellm]  # 다양한 LLM 지원

모델 옵션:

from smolagents import HfApiModel, LiteLLMModel

# 방법 1: HuggingFace API (무료 티어 있음)
model = HfApiModel(
    model_id="Qwen/Qwen2.5-Coder-32B-Instruct"
    # HF_TOKEN 환경변수 필요
)

# 방법 2: OpenAI
model = LiteLLMModel(model_id="gpt-4o")

# 방법 3: Anthropic
model = LiteLLMModel(model_id="anthropic/claude-sonnet-4-6")

# 방법 4: 로컬 Ollama
model = LiteLLMModel(
    model_id="ollama/qwen2.5-coder:7b",
    api_base="http://localhost:11434"
)

기본 사용법

가장 간단한 에이전트

from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel

agent = CodeAgent(
    tools=[DuckDuckGoSearchTool()],
    model=HfApiModel()
)

result = agent.run("Claude Opus 4.7 벤치마크 점수 알려줘")
print(result)

실행하면 에이전트가 이런 코드를 직접 작성하고 실행해요:

# smolagents가 자동으로 생성하는 코드
results = web_search("Claude Opus 4.7 benchmark score SWE-bench")
answer = f"Claude Opus 4.7 SWE-bench Pro: {extract_score(results)}"
print(answer)

커스텀 툴 만들기

smolagents의 툴 정의 방법이에요. 진짜 간단해요.

from smolagents import tool

# 데코레이터 하나로 툴 등록
@tool
def get_github_stars(repo: str) -> str:
    """
    GitHub 레포지토리의 스타 수를 가져옵니다.

    Args:
        repo: 레포 이름 (예: 'huggingface/smolagents')

    Returns:
        스타 수 문자열
    """
    import requests
    response = requests.get(f"https://api.github.com/repos/{repo}")
    data = response.json()
    return f"{repo}: {data['stargazers_count']:,}개 스타"

@tool
def calculate_cost(
    input_tokens: int,
    output_tokens: int,
    model: str = "claude-sonnet-4-6"
) -> str:
    """
    LLM API 비용을 계산합니다.

    Args:
        input_tokens: 입력 토큰 수
        output_tokens: 출력 토큰 수
        model: 모델 이름

    Returns:
        예상 비용 문자열 (USD)
    """
    pricing = {
        "claude-opus-4-7": (5.0, 25.0),
        "claude-sonnet-4-6": (3.0, 15.0),
        "gpt-5.4": (5.0, 25.0),
    }

    input_price, output_price = pricing.get(model, (3.0, 15.0))
    cost = (input_tokens / 1_000_000 * input_price +
            output_tokens / 1_000_000 * output_price)

    return f"예상 비용: ${cost:.4f} USD"

커스텀 툴로 에이전트 실행

from smolagents import CodeAgent, LiteLLMModel

agent = CodeAgent(
    tools=[get_github_stars, calculate_cost],
    model=LiteLLMModel(model_id="anthropic/claude-sonnet-4-6")
)

result = agent.run(
    "smolagents와 langchain 레포 스타 수 비교하고, "
    "각각 하루 1000번 API 호출 시 예상 비용 계산해줘"
)
print(result)

실전 예시 1 — 뉴스 요약 에이전트

from smolagents import CodeAgent, DuckDuckGoSearchTool, LiteLLMModel
import anthropic

# Claude로 요약하는 커스텀 툴
@tool
def summarize_with_claude(text: str, language: str = "Korean") -> str:
    """
    텍스트를 Claude로 요약합니다.

    Args:
        text: 요약할 텍스트
        language: 출력 언어

    Returns:
        요약된 텍스트
    """
    client = anthropic.Anthropic()
    response = client.messages.create(
        model="claude-haiku-4-5",  # 요약은 Haiku로 절약
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": f"다음을 {language}로 3줄 요약해줘:\n\n{text}"
        }]
    )
    return response.content[0].text

# 뉴스 요약 에이전트
news_agent = CodeAgent(
    tools=[DuckDuckGoSearchTool(), summarize_with_claude],
    model=LiteLLMModel(model_id="anthropic/claude-sonnet-4-6"),
    max_steps=5  # 최대 5스텝으로 제한
)

result = news_agent.run(
    "오늘 AI 개발자 관련 뉴스 3개 찾아서 한국어로 요약해줘"
)
print(result)

실전 예시 2 — 코드 분석 에이전트

from smolagents import CodeAgent, LiteLLMModel
from pathlib import Path

@tool
def read_python_file(filepath: str) -> str:
    """
    Python 파일 내용을 읽습니다.

    Args:
        filepath: 파일 경로

    Returns:
        파일 내용 문자열
    """
    return Path(filepath).read_text(encoding='utf-8')

@tool
def count_functions(code: str) -> dict:
    """
    Python 코드에서 함수 수를 셉니다.

    Args:
        code: Python 코드 문자열

    Returns:
        함수 정보 딕셔너리
    """
    import ast
    tree = ast.parse(code)
    functions = [
        node.name for node in ast.walk(tree)
        if isinstance(node, ast.FunctionDef)
    ]
    return {
        "count": len(functions),
        "names": functions
    }

@tool
def find_todos(code: str) -> list:
    """
    코드에서 TODO 주석을 찾습니다.

    Args:
        code: 소스 코드

    Returns:
        TODO 목록
    """
    todos = []
    for i, line in enumerate(code.split('\n'), 1):
        if 'TODO' in line or 'FIXME' in line:
            todos.append(f"Line {i}: {line.strip()}")
    return todos

# 코드 분석 에이전트
code_agent = CodeAgent(
    tools=[read_python_file, count_functions, find_todos],
    model=LiteLLMModel(model_id="anthropic/claude-sonnet-4-6")
)

result = code_agent.run(
    "src/api/users.py 파일을 읽어서 "
    "함수 수, TODO 목록, 개선할 점을 분석해줘"
)
print(result)

실전 예시 3 — 멀티스텝 데이터 파이프라인

from smolagents import CodeAgent, LiteLLMModel
import json

@tool
def fetch_api_data(url: str) -> dict:
    """
    API에서 데이터를 가져옵니다.

    Args:
        url: API 엔드포인트 URL

    Returns:
        JSON 응답 데이터
    """
    import requests
    response = requests.get(url, timeout=10)
    return response.json()

@tool
def save_to_file(data: str, filename: str) -> str:
    """
    데이터를 파일로 저장합니다.

    Args:
        data: 저장할 데이터 (문자열)
        filename: 저장할 파일명

    Returns:
        저장 결과 메시지
    """
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(data)
    return f"저장 완료: {filename}"

pipeline_agent = CodeAgent(
    tools=[fetch_api_data, save_to_file],
    model=LiteLLMModel(model_id="anthropic/claude-sonnet-4-6"),
    max_steps=10
)

result = pipeline_agent.run("""
다음을 순서대로 실행해줘:
1. https://api.github.com/repos/huggingface/smolagents 에서 데이터 가져오기
2. 레포 이름, 스타 수, 포크 수, 최신 업데이트 날짜 추출
3. 결과를 smolagents_info.json으로 저장
""")
print(result)

ToolCollection으로 툴 묶음 관리

from smolagents import ToolCollection, CodeAgent, LiteLLMModel

# 툴을 묶음으로 관리
dev_tools = ToolCollection(tools=[
    get_github_stars,
    calculate_cost,
    read_python_file,
    find_todos,
])

# HuggingFace Hub에서 툴 가져오기
# (커뮤니티 공유 툴 사용 가능)
hub_tools = ToolCollection.from_hub(
    "huggingface-tools/text-to-image"
)

agent = CodeAgent(
    tools=[*dev_tools, *hub_tools],
    model=LiteLLMModel(model_id="anthropic/claude-sonnet-4-6")
)

실행 제어 옵션

agent = CodeAgent(
    tools=[...],
    model=model,

    # 최대 실행 스텝 (무한 루프 방지)
    max_steps=10,

    # 코드 실행 타임아웃 (초)
    # 기본값: 30초
    # 긴 작업은 늘려야 함

    # 추가 컨텍스트 (항상 포함)
    additional_args={
        "project_name": "cell-devlog",
        "language": "Korean"
    }
)

# 실행 시 추가 컨텍스트
result = agent.run(
    "분석해줘",
    additional_args={"target_file": "main.py"}
)

LangGraph vs CrewAI vs smolagents 선택 기준

smolagents 써야 할 때:
✅ 빠른 프로토타입
✅ 코드 실행 중심 에이전트
✅ HuggingFace 모델 쓸 때 (무료)
✅ 단순한 단일 에이전트
✅ LLM 호출 최소화가 중요할 때

LangGraph 써야 할 때:
✅ 복잡한 조건 분기
✅ 장기 실행, 체크포인트 필요
✅ 프로덕션 안정성 중요

CrewAI 써야 할 때:
✅ 역할 기반 멀티에이전트 팀
✅ 빠른 멀티에이전트 프로토타입

 

반응형