A smolagents tutorial is most useful when it ends with a working agent, not just a pile of imports. smolagents is Hugging Face’s compact library for building agents that call tools, write Python code, and return a result you can inspect. It sits between a raw chat completion and a heavyweight agent framework: small enough to read, structured enough to keep a model from improvising into trouble.
This walkthrough goes from install to a working CodeAgent, with a custom tool, a comparison with ToolCallingAgent, and the debugging habits that save the most time. The example is a currency converter because you can check the answer by hand.
What smolagents actually does
smolagents is not a model. It is the layer that gives a model a job, a set of tools, and a stopping condition. The library’s main trick is that CodeAgent writes actions as Python instead of JSON. That lets it call a tool, multiply the result, filter a list, and return a final value in one step. ToolCallingAgent takes the conventional route: it emits structured tool calls and waits for results.
Both agent types use tools defined with Python functions. A tool needs a name, type hints, and a docstring that tells the model what the function does and what each argument means. That docstring is prompt text, not decoration. If you want the loop underneath the library, this walkthrough of building AI agents with Python is a good companion; smolagents packages that same cycle into a smaller API.
Install smolagents and pick a model
Start with a clean virtual environment:
pip install smolagents
For models routed through LiteLLM, use pip install 'smolagents[litellm]' and set the provider key. With Hugging Face Inference Providers, set HF_TOKEN. Pick a model that writes competent Python: Qwen2.5-Coder, GPT-4o-mini through LiteLLM, or a comparable instruct model. A tiny model can handle a two-tool demo, but it will struggle when a task needs a loop or error recovery.
Build a tool the agent can use
Here is a deliberately boring tool that converts an amount at a fixed rate:
from smolagents import CodeAgent, InferenceClientModel, tool
@tool
def convert_currency(amount: float, rate: float) -> float:
"""Convert an amount using a supplied exchange rate.
Args:
amount: The amount to convert.
rate: The multiplier for the target currency.
"""
return round(amount * rate, 2)
The @tool decorator turns the function into something the agent can call. Type hints tell the model what arguments to supply; the docstring tells it when to use the tool. Keep tools narrow. A function called do_everything with six optional arguments is harder to use well than three small functions with clear names. Return simple values where possible, and turn failures into readable error messages instead of exceptions that end the run.
Run your first CodeAgent
Wire the tool to a model and give the agent a task:
model = InferenceClientModel(
model_id='Qwen/Qwen2.5-Coder-32B-Instruct'
)
agent = CodeAgent(
tools=[convert_currency],
model=model,
max_steps=6
)
result = agent.run(
'Convert 240 euros to dollars at a rate of 1.08. '
'Return the number and a one-line explanation.'
)
print(result)
The agent should write a short Python action that calls convert_currency(240, 1.08) and formats the answer. Read the intermediate steps. They show which tool was called, with what arguments, and whether the model tried to do arithmetic itself instead of using your function.
If the task needs standard-library modules, authorize only what is necessary, such as additional_authorized_imports=['datetime']. Do not hand over a blank check for imports.
CodeAgent or ToolCallingAgent?
Use CodeAgent when the job involves composition: convert a value, filter a list, calculate a total, then write a summary. It often needs fewer steps and less latency. Use ToolCallingAgent when you want strict tool boundaries and a log of JSON calls that is easy to audit.
- CodeAgent fits data cleanup, arithmetic, and multi-tool workflows where the model needs to inspect intermediate values.
- ToolCallingAgent fits simple lookups, regulated workflows, and teams that need a predictable call log.
- Neither is right when one deterministic function solves the problem. Agents add cost and uncertainty.
If your problem is several specialists passing work to each other, one agent can become a bottleneck. This AutoGen step-by-step multi-agent research assistant tutorial shows the other shape: separate agents for search, synthesis, and review. Start with one agent until you have evidence you need more.
Debug the code, not just the answer
Most smolagents failures are ordinary programming failures wearing a costume. The model called a tool with a string when the function expected a float. The docstring described a parameter that no longer exists. The agent tried to import pandas without permission. The API timed out on step four and the model retried with the same broken argument.
Three habits help. Log every run with the task, steps, and final result. Cap max_steps at six to ten for a first workflow. Test each tool directly before the agent touches it; a one-line unit test catches more problems than another round of prompt tweaking.
For anything that executes model-written code against untrusted input, use a sandbox. Running CodeAgent on your laptop is fine for a toy converter. It is not fine for an agent reading inbound emails or customer uploads. Put the executor in a container or hosted sandbox, restrict network access, and keep secrets out of the prompt and working directory.
A practical first project: expense triage
A useful next step is an expense triage agent. Give it two tools: one converts currency, the other maps a merchant description to a category. The task might be: “Lunch in Berlin, 38 EUR, rate 1.08. Categorize it and return the USD amount.” CodeAgent can call both tools and return “Meals, 41.04 USD.”
Keep the category tool deterministic. A dictionary of merchant keywords is less glamorous than a second model call, but it is cheaper, faster, and easier to test. Save model calls for parts that genuinely need language understanding.
Where to take your smolagents project next
Replace the toy tool with one real integration: a weather API, a CRM lookup, or a read-only database query. Keep the interface narrow and return plain data. Build a small evaluation set of 20 tasks with known answers and run it after every change. Track pass rate, average steps, and cost per run. A demo that works once is easy; an agent that works on Tuesday and again on Friday is the milestone.
Add a second tool only when the evaluation set shows a clear gap. More tools increase prompt size and the number of ways a run can go sideways. The best smolagents projects look less like autonomous coworkers and more like tightly scoped assistants with good tools, short logs, and a clear stopping point.

