{"id":732,"date":"2026-04-16T12:38:31","date_gmt":"2026-04-16T04:38:31","guid":{"rendered":"https:\/\/connectword.dpdns.org\/?p=732"},"modified":"2026-04-16T12:38:31","modified_gmt":"2026-04-16T04:38:31","slug":"a-coding-implementation-to-build-multi-agent-ai-systems-with-smolagents-using-code-execution-tool-calling-and-dynamic-orchestration","status":"publish","type":"post","link":"https:\/\/connectword.dpdns.org\/?p=732","title":{"rendered":"A Coding Implementation to Build Multi-Agent AI Systems with SmolAgents Using Code Execution, Tool Calling, and Dynamic Orchestration"},"content":{"rendered":"<p>In this tutorial, we build an advanced, production-ready agentic system using <a href=\"https:\/\/github.com\/huggingface\/smolagents\"><strong>SmolAgents<\/strong><\/a> and demonstrate how modern, lightweight AI agents can reason, execute code, dynamically manage tools, and collaborate across multiple agents. We start by installing dependencies and configuring a powerful yet efficient LLM backend, and then progressively design custom tools, including mathematical utilities, memory storage, and web search capabilities. We explore both CodeAgent and ToolCallingAgent paradigms, understand how tools are managed dynamically through the agent.tools dictionary, and implement multi-agent orchestration.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">import subprocess, sys\n\n\ndef pip(*args):\n   subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", *args])\n\n\npip(\"smolagents[all]\", \"duckduckgo-search\", \"wikipedia\", \"rich\")\n\n\nimport os, math, textwrap\nfrom rich.console import Console\nfrom rich.panel   import Panel\nfrom rich.table   import Table\nfrom rich         import print as rprint\n\n\nconsole = Console()\n\n\ndef section(title: str, color: str = \"bold cyan\"):\n   console.rule(f\"[{color}]{title}[\/{color}]\")\n\n\ndef show(label: str, value):\n   console.print(Panel(str(value), title=f\"[bold yellow]{label}[\/bold yellow]\", expand=False))\n\n\nimport getpass\n\n\nOPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\")\nif not OPENAI_API_KEY:\n   OPENAI_API_KEY = getpass.getpass(\"<img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f511.png\" alt=\"\ud83d\udd11\" class=\"wp-smiley\" \/> Enter your OpenAI API key: \")\n   os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY\n\n\nconsole.print(\"[green]\u2713 OpenAI API key loaded.[\/green]\")\n\n\nsection(\"SECTION 1 \u00b7 SmolAgents Architecture\")\n\n\nconsole.print(Panel(\"\"\"\nSmolAgents (HuggingFace) is a minimalist agent framework.\nCurrent stable release: 1.24.0   |   Using: OpenAI gpt-4o-mini\n\n\nCORE ABSTRACTIONS\n Tool\n agent.tools (dict)\n ToolCollection\n LiteLLMModel\n CodeAgent\n ToolCallingAgent\n\n\nMULTI-AGENT  (v1.8+ API)\n Pass sub-agents directly via  managed_agents=[sub_agent]\n Sub-agents need  name=  and  description=  set at init.\n ManagedAgent wrapper class was removed in v1.8.0.\n\n\nEXECUTION LOOP (CodeAgent)\n Task \u2500\u2500\u25ba LLM writes Python \u2500\u2500\u25ba sandbox executes it\n      \u25c4\u2500\u2500 observation (tool output \/ exception) \u25c4\u2500\u2500\n Repeats up to max_steps, then calls final_answer(...)\n\"\"\", title=\"[bold green]Architecture[\/bold green]\"))<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We install all required dependencies and set up the execution environment. We configure secure API key loading and initialize the rich console utilities for structured output formatting. We also introduce the architectural overview of SmolAgents to establish a strong conceptual foundation before building agents.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">section(\"SECTION 2 \u00b7 Building Custom Tools\")\n\n\nfrom smolagents import Tool, tool\n\n\n@tool\ndef celsius_to_fahrenheit(celsius: float) -&gt; str:\n   return f\"{celsius}\u00b0C = {celsius * 9\/5 + 32:.2f}\u00b0F\"\n\n\nclass PrimeTool(Tool):\n\n\n   name        = \"prime_checker\"\n   description = (\n       \"If composite, returns the smallest prime factor.\"\n   )\n   inputs = {\n       \"n\": {\"type\": \"integer\", \"description\": \"Positive integer to test.\"}\n   }\n   output_type = \"string\"\n\n\n   def forward(self, n: int) -&gt; str:\n       if n &lt; 2:\n           return f\"{n} is not prime (must be &gt;= 2).\"\n       for i in range(2, int(math.isqrt(n)) + 1):\n           if n % i == 0:\n               return f\"{n} is NOT prime. Smallest factor: {i}.\"\n       return f\"{n} IS prime!\"\n\n\nclass MemoTool(Tool):\n\n\n   name        = \"memory_store\"\n   description = (\n       \"Stores or retrieves key-value pairs. \"\n       \"action='set' stores key+value; \"\n       \"action='get' retrieves by key; \"\n       \"action='list' shows all keys.\"\n   )\n   inputs = {\n       \"action\": {\"type\": \"string\", \"description\": \"set | get | list\"},\n       \"key\":    {\"type\": \"string\", \"description\": \"Memory key (skip for list)\", \"nullable\": True},\n       \"value\":  {\"type\": \"string\", \"description\": \"Value to store (set only)\",  \"nullable\": True},\n   }\n   output_type = \"string\"\n\n\n   def __init__(self, *args, **kwargs):\n       super().__init__(*args, **kwargs)\n       self._store: dict[str, str] = {}\n\n\n   def forward(self, action: str, key: str = None, value: str = None) -&gt; str:\n       if action == \"set\":\n           self._store[key] = value\n           return f\"Stored '{key}' = '{value}'\"\n       elif action == \"get\":\n           return self._store.get(key, f\"Key '{key}' not found.\")\n       elif action == \"list\":\n           return \"Keys: \" + \", \".join(self._store.keys()) if self._store else \"Memory empty.\"\n       return \"Unknown action. Use: set | get | list\"<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We define custom tools using both decorator-based and class-based approaches to demonstrate flexibility in tool creation. We implement mathematical reasoning and a stateful memory tool to enable persistent interactions across agent steps. We structure the tools with clear schemas so the agents can interpret and invoke them correctly.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">class DuckDuckGoTool(Tool):\n\n\n   name        = \"web_search\"\n   description = \"Performs a web search and returns top results as plain text.\"\n   inputs = {\n       \"query\":       {\"type\": \"string\",  \"description\": \"The search query.\"},\n       \"max_results\": {\"type\": \"integer\", \"description\": \"Results to return (1-10).\", \"nullable\": True},\n   }\n   output_type = \"string\"\n\n\n   def forward(self, query: str, max_results: int = 3) -&gt; str:\n       try:\n           from duckduckgo_search import DDGS\n           with DDGS() as ddgs:\n               results = [\n                   f\"* {r['title']}n  {r['href']}n  {r['body'][:200]}\"\n                   for r in ddgs.text(query, max_results=max_results)\n               ]\n           return \"nn\".join(results) if results else \"No results found.\"\n       except Exception as e:\n           return f\"Search failed: {e}\"\n\n\n@tool\ndef factorial(n: int) -&gt; str:\n   return f\"{n}! = {math.factorial(n)}\"\n\n\nshow(\"celsius_to_fahrenheit(100)\", celsius_to_fahrenheit(100))\nshow(\"PrimeTool \u2014 97\",             PrimeTool().forward(97))\nshow(\"PrimeTool \u2014 100\",            PrimeTool().forward(100))\nm = MemoTool()\nm.forward(\"set\", \"author\", \"Ada Lovelace\")\nshow(\"MemoTool get 'author'\",      m.forward(\"get\", \"author\"))\n\n\nsection(\"SECTION 3 \u00b7 Managing Tools  (agent.tools dict)\")\n\n\nconsole.print(Panel(\"\"\"\nThe Toolbox class was removed in v1.x.\nTools live in  agent.tools, a plain Python dict keyed by tool name.\n\"\"\", title=\"[bold green]Tools Dict[\/bold green]\"))\n\n\nsection(\"SECTION 4 \u00b7 LLM Engines\")\n\n\nconsole.print(Panel(\"\"\"\nSmolAgents supports multiple LLM backends via  LiteLLMModel.\nWe use  gpt-4o-mini.\n\"\"\", title=\"[bold green]Engine Options[\/bold green]\"))\n\n\nfrom smolagents import LiteLLMModel\n\n\nMODEL_ID = \"openai\/gpt-4o-mini\"\nengine   = LiteLLMModel(model_id=MODEL_ID, api_key=OPENAI_API_KEY)\nconsole.print(f\"[green]Engine ready:[\/green] {MODEL_ID}\")<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We extend the system with a web search tool and a factorial utility to broaden the agent\u2019s capabilities. We test the tools independently to verify correctness before integrating them into agents. We also initialize the LLM engine using LiteLLMModel, preparing the core reasoning backend for execution.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">section(\"SECTION 5 \u00b7 CodeAgent\")\n\n\nfrom smolagents import CodeAgent\n\n\ncode_agent = CodeAgent(\n   tools           = [celsius_to_fahrenheit, PrimeTool(), MemoTool(), DuckDuckGoTool()],\n   model           = engine,\n   max_steps       = 6,\n   verbosity_level = 1,\n)\n\n\nconsole.print(\"n[bold]Initial agent.tools keys:[\/bold]\", list(code_agent.tools.keys()))\ncode_agent.tools[\"factorial\"] = factorial\nconsole.print(\"[dim]After adding factorial:[\/dim]\", list(code_agent.tools.keys()))\n\n\nconsole.print(\"n[bold yellow]Task 1:[\/bold yellow]\")\nresult1 = code_agent.run(\n   \"Convert boiling point (100C) and body temperature (37C) to Fahrenheit. \"\n   \"Which is higher and by how much?\"\n)\nshow(\"CodeAgent \u2014 Task 1\", result1)\n\n\nconsole.print(\"n[bold yellow]Task 2:[\/bold yellow]\")\nresult2 = code_agent.run(\"What is 17 times 19? Is that result prime? Also check 7919.\")\nshow(\"CodeAgent \u2014 Task 2\", result2)\n\n\nconsole.print(\"n[bold yellow]Task 3:[\/bold yellow]\")\nresult3 = code_agent.run(\"Compute 10! using the factorial tool.\")\nshow(\"CodeAgent \u2014 Task 3\", result3)<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We construct a CodeAgent that can write and execute Python dynamically to solve multi-step problems. We demonstrate runtime tool injection by adding a new tool without rebuilding the agent. We then execute progressively complex reasoning tasks to validate chaining, arithmetic computation, and tool coordination.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\" no-line-numbers\"><code class=\" no-wrap language-php\">section(\"SECTION 6 \u00b7 ToolCallingAgent (ReAct)\")\n\n\nfrom smolagents import ToolCallingAgent\n\n\nreact_agent = ToolCallingAgent(\n   tools           = [celsius_to_fahrenheit, PrimeTool(), MemoTool()],\n   model           = engine,\n   max_steps       = 5,\n   verbosity_level = 1,\n)\n\n\nconsole.print(\"n[bold yellow]Task 4:[\/bold yellow]\")\nresult4 = react_agent.run(\n   \"Then retrieve both facts and summarise them.\"\n)\nshow(\"ToolCallingAgent \u2014 Task 4\", result4)\n\n\nsection(\"SECTION 7 \u00b7 Multi-Agent Orchestration  (v1.8+ API)\")\n\n\nmath_agent = CodeAgent(\n   tools           = [PrimeTool()],\n   model           = engine,\n   max_steps       = 4,\n   name            = \"math_specialist\",\n   description     = \"Handles mathematical questions and primality checks.\",\n   verbosity_level = 0,\n)\n\n\nresearch_agent = ToolCallingAgent(\n   tools           = [DuckDuckGoTool(), MemoTool()],\n   model           = engine,\n   max_steps       = 4,\n   name            = \"research_specialist\",\n   description     = \"Searches the web and stores or retrieves facts from memory.\",\n   verbosity_level = 0,\n)\n\n\nmanager_agent = CodeAgent(\n   tools           = [],\n   model           = engine,\n   managed_agents  = [math_agent, research_agent],\n   max_steps       = 8,\n   verbosity_level = 1,\n)\n\n\nconsole.print(\"n[bold yellow]Task 5:[\/bold yellow]\")\nresult5 = manager_agent.run(\n   \"Find out what year Python was first released (use research_specialist), \"\n   \"then check whether that year is a prime number (use math_specialist).\"\n)\nshow(\"Manager Agent \u2014 Task 5\", result5)<\/code><\/pre>\n<\/div>\n<\/div>\n<p>We build a ToolCallingAgent to showcase structured ReAct-style reasoning with controlled tool invocation. We then implement a multi-agent orchestration system where specialized agents collaborate under a manager agent. We demonstrate delegation, coordination, and cross-agent reasoning to solve compound tasks efficiently.<\/p>\n<p>In conclusion, we constructed a fully functional multi-agent system capable of reasoning, searching, calculating, storing memory, and delegating tasks between specialized agents. We demonstrated how SmolAgents enables flexible tool integration, runtime extensibility, and structured collaboration without unnecessary architectural complexity. We showed how CodeAgent executes real Python logic for advanced chaining, while ToolCallingAgent ensures structured, auditable reasoning loops. Finally, we implemented a manager agent that coordinates specialized sub-agents, proving how scalable orchestration can be achieved with minimal overhead.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n<p>Check out\u00a0the<strong><a href=\"https:\/\/arxiv.org\/pdf\/2604.06425\" target=\"_blank\" rel=\"noreferrer noopener\">\u00a0<\/a><a href=\"https:\/\/github.com\/Marktechpost\/AI-Agents-Projects-Tutorials\/blob\/main\/AI%20Agents%20Codes\/smolagents_advanced_multi_agent_orchestration_Marktechpost.ipynb\" target=\"_blank\" rel=\"noreferrer noopener\">Full Implementation Code and Notebook<\/a><\/strong>.<strong>\u00a0<\/strong>Also,\u00a0feel free to follow us on\u00a0<strong><a href=\"https:\/\/x.com\/intent\/follow?screen_name=marktechpost\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Twitter<\/mark><\/a><\/strong>\u00a0and don\u2019t forget to join our\u00a0<strong><a href=\"https:\/\/www.reddit.com\/r\/machinelearningnews\/\" target=\"_blank\" rel=\"noreferrer noopener\">130k+ ML SubReddit<\/a><\/strong>\u00a0and Subscribe to\u00a0<strong><a href=\"https:\/\/www.aidevsignals.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">our Newsletter<\/a><\/strong>. Wait! are you on telegram?\u00a0<strong><a href=\"https:\/\/t.me\/machinelearningresearchnews\" target=\"_blank\" rel=\"noreferrer noopener\">now you can join us on telegram as well.<\/a><\/strong><\/p>\n<p>Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.?\u00a0<strong><a href=\"https:\/\/forms.gle\/MTNLpmJtsFA3VRVd9\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Connect with us<\/mark><\/a><\/strong><\/p>\n<p>The post <a href=\"https:\/\/www.marktechpost.com\/2026\/04\/15\/a-coding-implementation-to-build-multi-agent-ai-systems-with-smolagents-using-code-execution-tool-calling-and-dynamic-orchestration\/\">A Coding Implementation to Build Multi-Agent AI Systems with SmolAgents Using Code Execution, Tool Calling, and Dynamic Orchestration<\/a> appeared first on <a href=\"https:\/\/www.marktechpost.com\/\">MarkTechPost<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we build an &hellip;<\/p>\n","protected":false},"author":1,"featured_media":29,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-732","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/posts\/732","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=732"}],"version-history":[{"count":0,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/posts\/732\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=\/wp\/v2\/media\/29"}],"wp:attachment":[{"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=732"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/connectword.dpdns.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}