Tools

Even an agent that thinks in code needs tools — the functions its code calls to reach beyond itself. smolagents defines them the same minimal way it does everything: a decorated Python function. The twist is that in a code agent, tools are called from within code, which is what makes composing them so natural.

Code agents write code — but that code calls tools to do real work (search, fetch, query, compute). This post covers how smolagents defines tools, how tools work differently when they’re called from within code rather than via JSON, and the built-in tools and integrations available. It’s the same typed-function-as-tool idea as the other frameworks, with a code-agent twist that ties back to why code actions are powerful.

Tools are decorated Python functions

Consistent with smolagents’s minimalism, a tool is a Python function you decorate, with the framework deriving what it needs from the function’s signature and docstring:

# Illustrative shape — see the smolagents docs for exact API.
from smolagents import tool

@tool
def get_population(city: str) -> int:
    """Get the population of a city."""
    return lookup_population(city)   # your implementation

As with Pydantic AI, LangChain, and Strands, you don’t hand-write a schema — smolagents uses the type hints and the docstring (which becomes the tool’s description). So defining a capability is just writing a documented, typed function and marking it a tool. The familiar disciplines apply: clear docstrings (the model reads them to decide when to use the tool), precise type hints, and focused tools. smolagents also supports loading tools from the broader ecosystem (including tools shared on the Hugging Face Hub and, increasingly, via MCP), so you can assemble capabilities rather than build every one.

The twist: tools called from within code

Here’s what makes tools in a code agent distinctive, tying back to the code-action idea (the earlier posts). In a JSON tool-calling agent, the agent calls one tool per action, and the framework runs it. In a code agent, the tools are functions the agent’s code calls — so the agent’s action is code that invokes tools, and it can call multiple tools, use their results, loop over them, and compose them, all within one code action:

# The agent WRITES this as its action; get_population and search are tools:
cities = search("largest cities in France")
pops = [get_population(c) for c in cities[:3]]
total = sum(pops)

This is the code-agent advantage made concrete at the tool level: tools become composable building blocks the agent’s code orchestrates, rather than isolated calls the framework runs one at a time. The tool is just a Python function, and the agent’s code uses it like any function — calling it in a loop, feeding its output to another tool, computing on its results. This is why code actions are expressive (the earlier posts): because tools are called from within code, the full power of code (loops, composition, variables) applies to how tools are used. In a JSON agent, tools are endpoints the framework invokes; in a code agent, tools are functions the model’s code composes — a meaningfully richer relationship.

So tool design in smolagents carries an extra consideration: tools should be composable — designed as clean functions that combine well in code (clear inputs and outputs, predictable behavior), because the agent will call them from within code alongside other tools. A tool that returns well-structured data the agent’s code can loop over or pass to another tool is more valuable in a code agent than one with an awkward interface, precisely because the agent composes tools programmatically.

Built-in tools and the ecosystem

Beyond your own functions, smolagents provides ways to equip an agent:

The combination means equipping a smolagents agent is largely assembling capabilities — your functions plus built-in and ecosystem tools — which the agent’s code then composes. For a code agent, a rich, composable toolset is exactly what you want, because the agent’s power comes from orchestrating those tools in code.

Tools as the code agent’s vocabulary

The mental model to carry: in smolagents, tools are the vocabulary the agent’s code is written in — the functions its code calls to act. Defining them is minimal (a decorated function), and their power is realized when the agent composes them in code (the code-action advantage). This reframes tool design slightly from the JSON-agent world: you’re not just providing endpoints the framework will invoke one at a time; you’re providing composable functions the model will orchestrate programmatically, so clean, composable interfaces matter. Combined with the security of sandboxed execution (the last post — the code that calls these tools runs sandboxed), tools complete the picture of a code agent: minimal functions, composed in model-written code, run safely. The next post covers the models that write that code.

Key takeaways

Further reading

Sources & References

Defining and using tools