On this tutorial, we construct a complicated, production-ready agentic system utilizing SmolAgents and display how trendy, light-weight AI brokers can motive, execute code, dynamically handle instruments, and collaborate throughout a number of brokers. We begin by putting in dependencies and configuring a strong but environment friendly LLM backend, after which progressively design customized instruments, together with mathematical utilities, reminiscence storage, and net search capabilities. We discover each CodeAgent and ToolCallingAgent paradigms, perceive how instruments are managed dynamically by means of the agent.instruments dictionary, and implement multi-agent orchestration.
import subprocess, sys
def pip(*args):
subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", *args])
pip("smolagents[all]", "duckduckgo-search", "wikipedia", "wealthy")
import os, math, textwrap
from wealthy.console import Console
from wealthy.panel import Panel
from wealthy.desk import Desk
from wealthy import print as rprint
console = Console()
def part(title: str, colour: str = "daring cyan"):
console.rule(f"[{color}]{title}[/{color}]")
def present(label: str, worth):
console.print(Panel(str(worth), title=f"[bold yellow]{label}[/bold yellow]", increase=False))
import getpass
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
OPENAI_API_KEY = getpass.getpass("🔑 Enter your OpenAI API key: ")
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
console.print("[green]✓ OpenAI API key loaded.[/green]")
part("SECTION 1 · SmolAgents Structure")
console.print(Panel("""
SmolAgents (HuggingFace) is a minimalist agent framework.
Present secure launch: 1.24.0 | Utilizing: OpenAI gpt-4o-mini
CORE ABSTRACTIONS
Device
agent.instruments (dict)
ToolCollection
LiteLLMModel
CodeAgent
ToolCallingAgent
MULTI-AGENT (v1.8+ API)
Go sub-agents instantly through managed_agents=[sub_agent]
Sub-agents want title= and description= set at init.
ManagedAgent wrapper class was eliminated in v1.8.0.
EXECUTION LOOP (CodeAgent)
Activity ──► LLM writes Python ──► sandbox executes it
◄── statement (instrument output / exception) ◄──
Repeats as much as max_steps, then calls final_answer(...)
""", title="[bold green]Structure[/bold green]"))
We set up all required dependencies and arrange the execution atmosphere. We configure safe API key loading and initialize the wealthy console utilities for structured output formatting. We additionally introduce the architectural overview of SmolAgents to ascertain a powerful conceptual basis earlier than constructing brokers.
part("SECTION 2 · Constructing Customized Instruments")
from smolagents import Device, instrument
@instrument
def celsius_to_fahrenheit(celsius: float) -> str:
return f"{celsius}°C = {celsius * 9/5 + 32:.2f}°F"
class PrimeTool(Device):
title = "prime_checker"
description = (
"If composite, returns the smallest prime issue."
)
inputs = {
"n": {"kind": "integer", "description": "Constructive integer to check."}
}
output_type = "string"
def ahead(self, n: int) -> str:
if n < 2:
return f"{n} is just not prime (should be >= 2)."
for i in vary(2, int(math.isqrt(n)) + 1):
if n % i == 0:
return f"{n} is NOT prime. Smallest issue: {i}."
return f"{n} IS prime!"
class MemoTool(Device):
title = "memory_store"
description = (
"Shops or retrieves key-value pairs. "
"motion='set' shops key+worth; "
"motion='get' retrieves by key; "
"motion='listing' exhibits all keys."
)
inputs = {
"motion": listing",
"key": {"kind": "string", "description": "Reminiscence key (skip for listing)", "nullable": True},
"worth": {"kind": "string", "description": "Worth to retailer (set solely)", "nullable": True},
}
output_type = "string"
def __init__(self, *args, **kwargs):
tremendous().__init__(*args, **kwargs)
self._store: dict[str, str] = {}
def ahead(self, motion: str, key: str = None, worth: str = None) -> str:
if motion == "set":
self._store[key] = worth
return f"Saved '{key}' = '{worth}'"
elif motion == "get":
return self._store.get(key, f"Key '{key}' not discovered.")
elif motion == "listing":
return "Keys: " + ", ".be a part of(self._store.keys()) if self._store else "Reminiscence empty."
return "Unknown motion. Use: set | get | listing"
We outline customized instruments utilizing each decorator-based and class-based approaches to display flexibility in instrument creation. We implement mathematical reasoning and a stateful reminiscence instrument to allow persistent interactions throughout agent steps. We construction the instruments with clear schemas so the brokers can interpret and invoke them accurately.
class DuckDuckGoTool(Device):
title = "web_search"
description = "Performs an online search and returns high outcomes as plain textual content."
inputs = {
"question": {"kind": "string", "description": "The search question."},
"max_results": {"kind": "integer", "description": "Outcomes to return (1-10).", "nullable": True},
}
output_type = "string"
def ahead(self, question: str, max_results: int = 3) -> str:
attempt:
from duckduckgo_search import DDGS
with DDGS() as ddgs:
outcomes = [
f"* {r['title']}n {r['href']}n {r['body'][:200]}"
for r in ddgs.textual content(question, max_results=max_results)
]
return "nn".be a part of(outcomes) if outcomes else "No outcomes discovered."
besides Exception as e:
return f"Search failed: {e}"
@instrument
def factorial(n: int) -> str:
return f"{n}! = {math.factorial(n)}"
present("celsius_to_fahrenheit(100)", celsius_to_fahrenheit(100))
present("PrimeTool — 97", PrimeTool().ahead(97))
present("PrimeTool — 100", PrimeTool().ahead(100))
m = MemoTool()
m.ahead("set", "writer", "Ada Lovelace")
present("MemoTool get 'writer'", m.ahead("get", "writer"))
part("SECTION 3 · Managing Instruments (agent.instruments dict)")
console.print(Panel("""
The Toolbox class was eliminated in v1.x.
Instruments stay in agent.instruments, a plain Python dict keyed by instrument title.
""", title="[bold green]Instruments Dict[/bold green]"))
part("SECTION 4 · LLM Engines")
console.print(Panel("""
SmolAgents helps a number of LLM backends through LiteLLMModel.
We use gpt-4o-mini.
""", title="[bold green]Engine Choices[/bold green]"))
from smolagents import LiteLLMModel
MODEL_ID = "openai/gpt-4o-mini"
engine = LiteLLMModel(model_id=MODEL_ID, api_key=OPENAI_API_KEY)
console.print(f"[green]Engine prepared:[/green] {MODEL_ID}")
We lengthen the system with an online search instrument and a factorial utility to broaden the agent’s capabilities. We take a look at the instruments independently to confirm correctness earlier than integrating them into brokers. We additionally initialize the LLM engine utilizing LiteLLMModel, getting ready the core reasoning backend for execution.
part("SECTION 5 · CodeAgent")
from smolagents import CodeAgent
code_agent = CodeAgent(
instruments = [celsius_to_fahrenheit, PrimeTool(), MemoTool(), DuckDuckGoTool()],
mannequin = engine,
max_steps = 6,
verbosity_level = 1,
)
console.print("n[bold]Preliminary agent.instruments keys:[/bold]", listing(code_agent.instruments.keys()))
code_agent.instruments["factorial"] = factorial
console.print("[dim]After including factorial:[/dim]", listing(code_agent.instruments.keys()))
console.print("n[bold yellow]Activity 1:[/bold yellow]")
result1 = code_agent.run(
"Convert boiling level (100C) and physique temperature (37C) to Fahrenheit. "
"Which is increased and by how a lot?"
)
present("CodeAgent — Activity 1", result1)
console.print("n[bold yellow]Activity 2:[/bold yellow]")
result2 = code_agent.run("What's 17 instances 19? Is that end result prime? Additionally test 7919.")
present("CodeAgent — Activity 2", result2)
console.print("n[bold yellow]Activity 3:[/bold yellow]")
result3 = code_agent.run("Compute 10! utilizing the factorial instrument.")
present("CodeAgent — Activity 3", result3)
We assemble a CodeAgent that may write and execute Python dynamically to resolve multi-step issues. We display runtime instrument injection by including a brand new instrument with out rebuilding the agent. We then execute progressively complicated reasoning duties to validate chaining, arithmetic computation, and power coordination.
part("SECTION 6 · ToolCallingAgent (ReAct)")
from smolagents import ToolCallingAgent
react_agent = ToolCallingAgent(
instruments = [celsius_to_fahrenheit, PrimeTool(), MemoTool()],
mannequin = engine,
max_steps = 5,
verbosity_level = 1,
)
console.print("n[bold yellow]Activity 4:[/bold yellow]")
result4 = react_agent.run(
"Then retrieve each information and summarise them."
)
present("ToolCallingAgent — Activity 4", result4)
part("SECTION 7 · Multi-Agent Orchestration (v1.8+ API)")
math_agent = CodeAgent(
instruments = [PrimeTool()],
mannequin = engine,
max_steps = 4,
title = "math_specialist",
description = "Handles mathematical questions and primality checks.",
verbosity_level = 0,
)
research_agent = ToolCallingAgent(
instruments = [DuckDuckGoTool(), MemoTool()],
mannequin = engine,
max_steps = 4,
title = "research_specialist",
description = "Searches the net and shops or retrieves information from reminiscence.",
verbosity_level = 0,
)
manager_agent = CodeAgent(
instruments = [],
mannequin = engine,
managed_agents = [math_agent, research_agent],
max_steps = 8,
verbosity_level = 1,
)
console.print("n[bold yellow]Activity 5:[/bold yellow]")
result5 = manager_agent.run(
"Discover out what 12 months Python was first launched (use research_specialist), "
"then test whether or not that 12 months is a main quantity (use math_specialist)."
)
present("Supervisor Agent — Activity 5", result5)
We construct a ToolCallingAgent to showcase structured ReAct-style reasoning with managed instrument invocation. We then implement a multi-agent orchestration system the place specialised brokers collaborate beneath a supervisor agent. We display delegation, coordination, and cross-agent reasoning to resolve compound duties effectively.
In conclusion, we constructed a completely practical multi-agent system able to reasoning, looking out, calculating, storing reminiscence, and delegating duties between specialised brokers. We demonstrated how SmolAgents allows versatile instrument integration, runtime extensibility, and structured collaboration with out pointless architectural complexity. We confirmed how CodeAgent executes actual Python logic for superior chaining, whereas ToolCallingAgent ensures structured, auditable reasoning loops. Lastly, we carried out a supervisor agent that coordinates specialised sub-agents, proving how scalable orchestration will be achieved with minimal overhead.
Take a look at the Full Implementation Code and Notebook. Additionally, be happy to comply with us on Twitter and don’t neglect to affix our 130k+ ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.
Have to associate with us for selling your GitHub Repo OR Hugging Face Web page OR Product Launch OR Webinar and so on.? Connect with us
