LangChain이 너무 복잡하다고 느낀 적이 있다면 smolagents가 답입니다. Hugging Face가 만든 이 프레임워크는 핵심 코드가 약 1,000줄입니다. 그러면서 CodeAgent, MCP 연동, 멀티에이전트 오케스트레이션, 샌드박스 실행을 다 지원합니다. 2026년 3월 기준 GitHub 스타 26,000+, MCP 통합 깊이가 현존 에이전트 프레임워크 중 가장 깊습니다.
왜 smolagents인가 — CodeAgent의 핵심 아이디어
대부분의 에이전트 프레임워크는 모델이 액션을 JSON이나 텍스트로 출력하고, 프레임워크가 이를 파싱해서 툴을 호출하는 구조입니다. smolagents는 다릅니다.
smolagents의 CodeAgent는 액션을 Python 코드 스니펫으로 작성합니다. 모델이 JSON을 출력하는 대신 실제로 실행 가능한 Python 코드를 생성하고, 프레임워크가 이를 샌드박스에서 실행해서 결과를 다시 모델에 피드백합니다. 표준 툴 콜링 방식 대비 LLM 호출 횟수를 약 30% 줄이고 복잡한 벤치마크에서 더 높은 성능을 보입니다.
JSON 파싱 실패나 툴 파라미터 타입 오류 같은 문제가 사라지는 게 실전에서 가장 체감되는 차이입니다. Python 코드는 실행되거나 안 되거나 둘 중 하나입니다.
모델 유연성도 강점입니다. Hugging Face Hub 모델, Ollama 로컬 모델, OpenAI, Anthropic, 그 외 LiteLLM이 지원하는 모든 모델을 그대로 쓸 수 있습니다.
설치 및 기본 세팅
pip install smolagents
# MCP 지원 포함
pip install smolagents[mcp]
# E2B 샌드박스 실행 포함
pip install smolagents e2b-code-interpreter
CodeAgent 첫 번째 에이전트 만들기
from smolagents import CodeAgent, LiteLLMModel, tool
# 모델 설정 — Claude, GPT, Gemini, 로컬 모델 모두 가능
model = LiteLLMModel(model_id="claude-sonnet-4-6")
# 또는 OpenAI
# model = LiteLLMModel(model_id="gpt-5.5")
# 또는 로컬 Ollama
# model = LiteLLMModel(model_id="ollama/qwen3:14b")
# 커스텀 툴 정의 — 데코레이터 하나로 끝
@tool
def get_stock_price(ticker: str) -> str:
"""
주식 티커 심볼로 현재 주가를 조회합니다.
Args:
ticker: 주식 티커 심볼 (예: NVDA, AAPL)
Returns:
현재 주가와 변동률 문자열
"""
import requests
# 실제로는 yfinance나 금융 API 사용
# 여기선 예시
return f"{ticker}: $850.20 (+2.3%)"
@tool
def calculate_portfolio_value(holdings: dict) -> float:
"""
보유 주식의 총 포트폴리오 가치를 계산합니다.
Args:
holdings: 티커와 수량의 딕셔너리 (예: {"NVDA": 10, "AAPL": 5})
Returns:
총 포트폴리오 가치 (달러)
"""
total = 0.0
prices = {"NVDA": 850.20, "AAPL": 195.50, "MSFT": 420.30}
for ticker, quantity in holdings.items():
total += prices.get(ticker, 0) * quantity
return total
# 에이전트 생성
agent = CodeAgent(
tools=[get_stock_price, calculate_portfolio_value],
model=model,
max_steps=10, # 최대 추론 스텝
verbosity_level=1, # 0=조용, 1=스텝별, 2=상세
planning_interval=3, # N 스텝마다 재계획
add_base_tools=True, # 기본 툴(웹 검색 등) 추가
)
# 실행
result = agent.run(
"NVDA 10주, AAPL 5주를 보유하고 있어. "
"총 포트폴리오 가치와 각 주식의 현재 가격을 알려줘."
)
print(result)
내부에서 에이전트는 이런 Python 코드를 생성해서 실행합니다:
# 에이전트가 자동 생성하는 코드 (실제 실행됨)
nvda_price = get_stock_price("NVDA")
aapl_price = get_stock_price("AAPL")
holdings = {"NVDA": 10, "AAPL": 5}
total_value = calculate_portfolio_value(holdings)
print(f"NVDA: {nvda_price}")
print(f"AAPL: {aapl_price}")
print(f"총 포트폴리오 가치: ${total_value:,.2f}")
MCP 서버 연동 — 한 줄로 툴 수백 개 추가
smolagents의 MCP 통합은 ToolCollection.from_mcp()로 MCP 서버의 모든 툴을 한 번에 가져올 수 있습니다.
from smolagents import ToolCollection, CodeAgent, LiteLLMModel
from mcp import StdioServerParameters
model = LiteLLMModel(model_id="claude-sonnet-4-6")
# GitHub MCP 서버 연동
github_params = StdioServerParameters(
command="uvx",
args=["mcp-server-github"],
env={"GITHUB_TOKEN": "YOUR_GITHUB_TOKEN"}
)
# Notion MCP 서버 연동
notion_params = StdioServerParameters(
command="uvx",
args=["mcp-server-notion"],
env={"NOTION_TOKEN": "YOUR_NOTION_TOKEN"}
)
# 여러 MCP 서버를 동시에 연동
with ToolCollection.from_mcp(github_params, trust_remote_code=True) as github_tools, \
ToolCollection.from_mcp(notion_params, trust_remote_code=True) as notion_tools:
agent = CodeAgent(
tools=[*github_tools.tools, *notion_tools.tools],
model=model,
max_steps=15,
additional_authorized_imports=["json", "datetime"]
)
# GitHub PR 목록을 읽어서 Notion에 정리
result = agent.run(
"anthropics/claude-code 레포의 최근 열린 PR 5개를 가져와서 "
"제목, 작성자, 날짜를 Notion 데이터베이스에 정리해줘."
)
print(result)
멀티에이전트 시스템 — 매니저가 서브에이전트를 오케스트레이션
smolagents의 멀티에이전트는 매니저 에이전트가 전문화된 서브에이전트에게 위임하는 계층 구조입니다.
from smolagents import CodeAgent, ToolCallingAgent, LiteLLMModel, tool
from smolagents.agents import ManagedAgent
model = LiteLLMModel(model_id="claude-sonnet-4-6")
fast_model = LiteLLMModel(model_id="claude-haiku-4-5")
# 1. 웹 리서치 전문 에이전트
@tool
def search_web(query: str) -> str:
"""웹에서 정보를 검색합니다."""
# 실제 구현에서는 DuckDuckGo API나 SerpAPI 사용
return f"'{query}' 검색 결과: ..."
research_agent = ToolCallingAgent(
tools=[search_web],
model=fast_model,
max_steps=5,
name="research_agent",
description="웹에서 정보를 검색하고 요약하는 전문 에이전트"
)
# 2. 데이터 분석 전문 에이전트
@tool
def load_csv(file_path: str) -> str:
"""CSV 파일을 로드하고 기본 통계를 반환합니다."""
import pandas as pd
df = pd.read_csv(file_path)
return df.describe().to_string()
@tool
def create_chart(data: str, chart_type: str, title: str) -> str:
"""데이터로 차트를 생성합니다."""
return f"{chart_type} 차트 '{title}' 생성 완료"
analysis_agent = CodeAgent(
tools=[load_csv, create_chart],
model=model,
max_steps=10,
name="analysis_agent",
description="데이터를 분석하고 시각화하는 전문 에이전트",
additional_authorized_imports=["pandas", "numpy", "matplotlib"]
)
# 3. 보고서 작성 전문 에이전트
@tool
def save_markdown(content: str, filename: str) -> str:
"""마크다운 파일로 저장합니다."""
with open(filename, "w", encoding="utf-8") as f:
f.write(content)
return f"'{filename}' 저장 완료"
writer_agent = ToolCallingAgent(
tools=[save_markdown],
model=model,
max_steps=5,
name="writer_agent",
description="분석 결과를 읽기 좋은 보고서로 작성하는 전문 에이전트"
)
# 4. 매니저 에이전트 — 서브에이전트들을 오케스트레이션
manager_agent = CodeAgent(
tools=[
ManagedAgent(research_agent, name="researcher", description=research_agent.description),
ManagedAgent(analysis_agent, name="analyst", description=analysis_agent.description),
ManagedAgent(writer_agent, name="writer", description=writer_agent.description),
],
model=model,
max_steps=20,
planning_interval=5
)
# 전체 워크플로우 실행
result = manager_agent.run(
"2026년 AI 칩 시장 동향을 리서치하고, "
"sales_data.csv 데이터를 분석해서 "
"시장 트렌드와 데이터를 결합한 보고서를 report.md로 저장해줘."
)
샌드박스 실행 — 보안 코드 실행
에이전트가 생성한 코드를 로컬에서 그냥 실행하면 보안 위험이 있습니다. smolagents는 E2B, Docker, Modal 샌드박스를 지원합니다.
from smolagents import CodeAgent, LiteLLMModel
from smolagents.execution import E2BExecutor # E2B 클라우드 샌드박스
model = LiteLLMModel(model_id="claude-sonnet-4-6")
# E2B 샌드박스 사용 — 격리된 환경에서 코드 실행
agent = CodeAgent(
tools=[],
model=model,
executor_type="e2b", # 클라우드 샌드박스
# 또는 "docker"로 로컬 Docker 컨테이너 사용
additional_authorized_imports=["numpy", "pandas", "requests"],
max_steps=10
)
# 샌드박스 안에서 안전하게 실행
result = agent.run(
"requests로 https://jsonplaceholder.typicode.com/posts에서 "
"데이터를 받아서 pandas로 분석하고 요약해줘."
)
print(result)
로컬 Docker 샌드박스 설정:
# Docker 이미지 빌드
docker build -t smolagents-sandbox .
# 실행 시 Docker 컨테이너 자동 사용
agent = CodeAgent(
tools=[...],
model=model,
executor_type="docker",
docker_image="smolagents-sandbox:latest"
)
Agentic RAG — 문서 기반 멀티스텝 추론
단순 RAG는 한 번 검색하고 끝이지만, Agentic RAG는 에이전트가 필요에 따라 여러 번 검색하고, 정보를 교차 검증하며, 더 나은 답을 찾을 때까지 반복합니다.
from smolagents import CodeAgent, LiteLLMModel, tool
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyPDFLoader
# 벡터 스토어 구성
def build_vector_store(pdf_paths: list[str]):
loader_docs = []
for path in pdf_paths:
loader = PyPDFLoader(path)
loader_docs.extend(loader.load())
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
docs = splitter.split_documents(loader_docs)
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
return FAISS.from_documents(docs, embeddings)
vector_store = build_vector_store(["research_papers.pdf", "market_report.pdf"])
# RAG 툴 정의
@tool
def search_documents(query: str, k: int = 5) -> str:
"""
내부 문서에서 관련 정보를 검색합니다.
Args:
query: 검색 쿼리
k: 반환할 문서 수
Returns:
관련 문서 내용
"""
docs = vector_store.similarity_search(query, k=k)
return "\n\n---\n\n".join([doc.page_content for doc in docs])
model = LiteLLMModel(model_id="claude-sonnet-4-6")
rag_agent = CodeAgent(
tools=[search_documents],
model=model,
max_steps=8,
planning_interval=3
)
# 에이전트가 스스로 여러 번 검색하며 답을 구성
result = rag_agent.run(
"2026년 AI 반도체 시장에서 NVIDIA의 경쟁 우위 요소는 무엇이며, "
"AMD와 커스텀 ASIC 대비 어떤 위험 요소가 있나요?"
)
print(result)
OpenTelemetry 트레이싱 — 프로덕션 모니터링
from smolagents import CodeAgent, LiteLLMModel
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from openinference.instrumentation.smolagents import SmolagentsInstrumentor
import phoenix as px
# Phoenix 트레이싱 서버 시작
px.launch_app()
# OpenTelemetry 설정
tracer_provider = TracerProvider()
SmolagentsInstrumentor().instrument(tracer_provider=tracer_provider)
model = LiteLLMModel(model_id="claude-sonnet-4-6")
agent = CodeAgent(tools=[], model=model)
# 이제 모든 에이전트 실행이 자동으로 트레이싱됨
result = agent.run("태스크 실행")
# http://0.0.0.0:6006에서 트레이스 확인
LangChain·LangGraph와 비교 — 언제 smolagents를 써야 하나
smolagents의 가장 강한 점은 MCP 통합 깊이와 CodeAgent 방식입니다. LangGraph는 복잡한 상태 머신과 체크포인팅이 필요할 때 유리하고, CrewAI는 역할 기반 멀티에이전트 협업에 특화돼 있습니다.
기준 smolagents LangGraph CrewAI
| 코드 복잡도 | 낮음 (1천 줄 코어) | 높음 | 중간 |
| CodeAgent | ✅ 핵심 기능 | ❌ | ❌ |
| MCP 통합 | ✅ 최고 수준 | 제한적 | 제한적 |
| 상태 관리 | 기본 | ✅ 강력 | 중간 |
| 학습 곡선 | 낮음 | 높음 | 중간 |
| 샌드박스 실행 | ✅ E2B/Docker | 직접 구현 | 직접 구현 |
✅ 결론
- smolagents는 LangChain 대비 훨씬 적은 코드로 에이전트를 만들 수 있는 실용적 선택입니다
- CodeAgent의 Python 코드 실행 방식이 JSON 툴 콜링보다 복잡한 태스크에서 30% 효율적입니다
- MCP 서버 연동이 한 줄로 되는 게 2026년 시점에서 결정적 강점입니다
- 프로덕션에서는 반드시 E2B 또는 Docker 샌드박스를 쓰세요
❌ 주의
- CodeAgent는 임의 코드를 실행하므로 샌드박스 없이 프로덕션에 쓰면 위험합니다
- max_steps를 적게 설정하고 시작하세요 — 높으면 토큰 폭발 위험이 있습니다
- LangGraph 대비 복잡한 상태 머신·체크포인팅이 필요한 워크플로우에는 적합하지 않습니다
- additional_authorized_imports에 없는 라이브러리는 에이전트가 임포트할 수 없습니다 — 미리 명시하세요
'AI Agent' 카테고리의 다른 글
| "계획 먼저, 실행 나중" — Deep Research + Antigravity로 Plan-and-Execute 에이전트 만들기 (0) | 2026.06.12 |
|---|---|
| n8n AI 에이전트 워크플로우 실전 — 코드 없이 에이전트 만드는 법 (0) | 2026.06.10 |
| AI 에이전트 거버넌스 — Workday·OWASP·NIST가 그리는 안전한 에이전트 기준 (0) | 2026.06.05 |
| AI 에이전트 Autopilot Scout 분석 — Microsoft의 장기 실행 에이전트 아키텍처 (0) | 2026.06.05 |
| LangGraph vs PydanticAI vs CrewAI vs Google ADK — 2026년 에이전트 프레임워크 4파전 (0) | 2026.05.29 |