TL;DR:
- smolagents from Hugging Face is a minimal Python library for building LLM agents that write and execute Python code as their action mechanism
- Tools are just Python functions with type hints and docstrings — no JSON schemas or special wrappers
- It supports OpenAI, Anthropic, and any Hugging Face Inference API model, making it model-agnostic out of the box
Most agent frameworks grow complex fast. You end up with YAML configuration, graph abstractions, custom serialisation formats, and a steep learning curve before you’ve written a single useful tool. smolagents, released by Hugging Face in late 2024 and reaching production stability in 2025, takes the opposite approach: keep the framework small enough that you can read the whole source in an afternoon.
The central idea is that the agent’s action language is Python itself. Rather than the agent calling structured JSON tool calls (as in the standard tool-use API), it writes Python code that calls your tools, which gets executed. This makes multi-step reasoning more natural — the agent can write a loop, assign variables between steps, or use Python’s standard library without any special framework support.
How Code Agents Work
A traditional tool-calling agent asks the LLM to produce JSON like {"tool": "search", "args": {"query": "..."}}, parses it, calls the function, and feeds the result back. The agent takes one action per turn.
A code agent asks the LLM to write Python code:
results = search(query="current UK mortgage rates")
summary = []
for r in results[:3]:
summary.append(r['title'] + ': ' + r['snippet'])
final_answer('\n'.join(summary))
This code runs in a sandboxed interpreter. The agent can do multiple tool calls, conditionals, and data manipulation in one step. For tasks that naturally involve processing lists, filtering results, or chaining lookups, the code execution model is more efficient than one-tool-at-a-time.
Getting Started
pip install smolagents
Define tools as plain Python functions:
from smolagents import tool
@tool
def get_weather(location: str) -> str:
"""
Fetches current weather for a given location.
Args:
location: City name or postcode, e.g. 'London' or 'SW1A 1AA'
Returns:
A string describing current weather conditions.
"""
# your weather API call here
return f"Overcast, 14°C, light wind in {location}"
That’s all a tool needs — a function, type hints, and a docstring that the LLM uses to understand what the tool does and how to call it. No JSON schema writing, no separate registration step.
Build and run an agent:
from smolagents import CodeAgent, LiteLLMModel
model = LiteLLMModel(model_id="claude-sonnet-4-6")
agent = CodeAgent(
tools=[get_weather],
model=model,
max_steps=10
)
result = agent.run("What's the weather in Edinburgh, and should I bring an umbrella?")
print(result)
Model Support
smolagents uses LiteLLM under the hood for model calls, so you can point it at any supported provider:
# OpenAI
model = LiteLLMModel(model_id="gpt-4o")
# Anthropic
model = LiteLLMModel(model_id="claude-sonnet-4-6")
# Hugging Face Inference API (free tier available)
from smolagents import HfApiModel
model = HfApiModel(model_id="meta-llama/Llama-3.3-70B-Instruct")
# Local Ollama
model = LiteLLMModel(model_id="ollama/llama3.2", api_base="http://localhost:11434")
For production deployments where cost matters, smaller open models like Qwen2.5-Coder work well for straightforward tool-calling tasks via the Hugging Face Inference API.
Multi-Agent Setups
smolagents supports a managed agent pattern where a manager agent delegates to specialist agents:
from smolagents import CodeAgent, ManagedAgent
web_agent = CodeAgent(tools=[search_tool, visit_url], model=model)
calc_agent = CodeAgent(tools=[python_interpreter], model=model)
managed_web = ManagedAgent(agent=web_agent, name="web_researcher",
description="Searches the web and reads web pages")
managed_calc = ManagedAgent(agent=calc_agent, name="calculator",
description="Performs calculations and data analysis")
manager = CodeAgent(tools=[managed_web, managed_calc], model=model)
result = manager.run("Research UK energy prices for the past 5 years and calculate the average annual increase")
The manager can call specialist agents exactly like it calls any other tool — the sub-agent receives the task, executes it with its own tools, and returns the result.
When smolagents Makes Sense
smolagents is a strong choice when:
- You want to ship quickly: the framework is genuinely thin — you can have a working agent in under 50 lines of Python including tool definitions
- Your task involves data processing: the code execution model handles loops and variable assignment naturally, which JSON tool calls cannot
- You’re prototyping with different models: model-agnostic from the start, no provider-specific wrapping needed
- You want to understand what the framework does: the source is small enough to read, which matters when you’re debugging unexpected agent behaviour
It’s less suited to:
- Structured workflow orchestration with explicit state machines and approval gates (LangGraph or Temporal fit better)
- Long-running durable agents that need to survive restarts mid-task (you’d want a durable execution layer)
- Production deployments with strict tool sandboxing requirements: the Python code execution requires careful sandboxing to prevent the agent running arbitrary code on your infrastructure
Security Note on Code Execution
The code execution model is smolagents’ main differentiator and its main risk. By default, the agent’s code runs in the same process as your application. For production use, you should run agents in an isolated environment — Docker containers, E2B sandboxes, or Modal functions. smolagents supports a LocalPythonInterpreter with a restricted set of allowed imports, but proper process isolation is the safer approach for any untrusted task input.
The full documentation and examples are at the smolagents GitHub repository and Hugging Face docs.