Una implementación de codificación para construir sistemas de inteligencia artificial de múltiples agentes con SmolAgents mediante ejecución de código, llamada de herramientas y orquestación dinámica

En este tutorial, creamos un sistema de agentes avanzado y listo para producción utilizando SmolAgents y demostramos cómo los agentes de IA modernos y livianos pueden razonar, ejecutar código, administrar herramientas dinámicamente y colaborar entre múltiples agentes. Comenzamos instalando dependencias y configurando un backend LLM potente pero eficiente, y luego diseñamos progresivamente herramientas personalizadas, incluidas utilidades matemáticas, almacenamiento de memoria y capacidades de búsqueda web. Exploramos los paradigmas CodeAgent y ToolCallingAgent, entendemos cómo se administran las herramientas dinámicamente a través del diccionario agent.tools e implementamos la orquestación de múltiples agentes.

importar subproceso, sys def pip(*args): subproceso.check_call([sys.executable, “-m”, “pip”, “install”, “-q”, *args]) pip(“smolagentes[all]”, “duckduckgo-search”, “wikipedia”, “rich”) importar sistema operativo, matemáticas, ajuste de texto desde rich.console import Consola desde rich.panel importar Panel desde rich.table importar Tabla desde rich import imprimir como rprint console = Console() def sección(título: str, color: str = “bold cian”): console.rule(f”[{color}]{título}[/{color}]”) def show(etiqueta: cadena, valor): console.print(Panel(cadena(valor), título=f”[bold yellow]{etiqueta}[/bold yellow]”, expand=False)) import getpass OPENAI_API_KEY = os.getenv(“OPENAI_API_KEY”) si no OPENAI_API_KEY: OPENAI_API_KEY = getpass.getpass(“🔑 Ingrese su clave API de OpenAI: “) os.environ[“OPENAI_API_KEY”] = OPENAI_API_KEY consola.print(“[green]✓ Clave API OpenAI cargada.[/green]”) sección(“SECCIÓN 1 · Arquitectura SmolAgents”) console.print(Panel(“”” SmolAgents (HuggingFace) es un marco de agente minimalista. Versión estable actual: 1.24.0 | Uso: OpenAI gpt-4o-mini ABSTRACCIONES PRINCIPALES Herramienta agent.tools (dict) ToolCollection LiteLLMModel CodeAgent ToolCallingAgent MULTI-AGENT (v1.8+ API) Pasar subagentes directamente a través de Managed_agents=[sub_agent]
Los subagentes necesitan nombre= y descripción= establecidos en init. La clase contenedora ManagedAgent se eliminó en la versión 1.8.0. BUCLE DE EJECUCIÓN (CodeAgent) Tarea ── ► LLM ​​escribe Python ── ► sandbox lo ejecuta ◄── observación (salida de herramienta/excepción) ◄── Repite hasta max_steps, luego llama a final_answer(…) “””, title=”[bold green]Arquitectura[/bold green]”))

Instalamos todas las dependencias necesarias y configuramos el entorno de ejecución. Configuramos la carga segura de claves API e inicializamos las ricas utilidades de la consola para formatear la salida estructurada. También presentamos la descripción general arquitectónica de SmolAgents para establecer una base conceptual sólida antes de construir agentes.

sección(“SECCIÓN 2 · Creación de herramientas personalizadas”) de la herramienta de importación smolagents, herramienta @tool def celsius_to_fahrenheit(celsius: float) -> str: return f”{celsius}°C = {celsius * 9/5 + 32:.2f}°F” class PrimeTool(Tool): nombre = “prime_checker” descripción = (“Si es compuesto, devuelve el factor primo más pequeño.” ) entradas = { “n”: {“type”: “integer”, “description”: “Entero positivo a probar.”} } output_type = “string” def forward(self, n: int) -> str: si n < 2: devuelve f"{n} no es primo (debe ser >= 2)”. para i en range(2, int(math.isqrt(n)) + 1): si n % i == 0: devuelve f”{n} NO es primo. Factor más pequeño: {i}.” return f”{n} ¡ES primo!” class MemoTool(Tool): nombre = “memory_store” descripción = ( “Almacena o recupera pares clave-valor. ” “action=’set’ almacena clave+valor; ” “action=’get’ recupera por clave; ” “action=’list’ muestra todas las claves.” ) inputs = { “action”: {“type”: “string”, “description”: “set | get | list”}, “key”: {“type”: “string”, “description”: “Clave de memoria (saltar para list)”, “nullable”: True}, “value”: {“type”: “string”, “description”: “Valor para almacenar (solo establecer)”, “nullable”: True}, } output_type = “string” def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._store: dict[str, str] = {} def adelante(self, acción: str, clave: str = Ninguno, valor: str = Ninguno) -> str: if action == “set”: self._store[key] = valor return f”Stored ‘{key}’ = ‘{value}'” elif action == “get”: return self._store.get(key, f”Key ‘{key}’ no encontrada.”) elif action == “list”: return “Claves: ” + “, “.join(self._store.keys()) if self._store else “Memoria vacía”. devolver “Acción desconocida. Uso: establecer | obtener | lista”

Definimos herramientas personalizadas utilizando enfoques basados ​​en decoradores y basados ​​en clases para demostrar flexibilidad en la creación de herramientas. Implementamos razonamiento matemático y una herramienta de memoria con estado para permitir interacciones persistentes entre los pasos de los agentes. Estructuramos las herramientas con esquemas claros para que los agentes puedan interpretarlas e invocarlas correctamente.

clase DuckDuckGoTool(Tool): nombre = “web_search” descripción = “Realiza una búsqueda web y devuelve los mejores resultados como texto sin formato.” inputs = { “query”: {“type”: “string”, “description”: “La consulta de búsqueda.”}, “max_results”: {“type”: “integer”, “description”: “Resultados a devolver (1-10).”, “nullable”: True}, } output_type = “string” def forward(self, query: str, max_results: int = 3) -> str: try: from duckduckgo_search importar DDGS con DDGS() como ddgs: resultados = [
f”* {r[‘title’]}\n {r[‘href’]}\n {r[‘body’][:200]}” para r en ddgs.text(consulta, max_results=max_results) ]devuelve “\n\n”.join(resultados) si los resultados son “No se encontraron resultados”. excepto Excepción como e: devuelve f”La búsqueda falló: {e}” @tool def factorial(n: int) -> str: devuelve f”{n}! = {math.factorial(n)}” show(“celsius_to_fahrenheit(100)”, celsius_to_fahrenheit(100)) show(“PrimeTool — 97”, PrimeTool().forward(97)) show(“PrimeTool — 100”, PrimeTool().forward(100)) m = MemoTool() m.forward(“set”, “autor”, “Ada Lovelace”) show(“MemoTool get ‘author'”, m.forward(“get”, “author”)) sección(“SECCIÓN 3 · Administración de herramientas (agent.tools dict)”) console.print(Panel(“”” La clase Toolbox se eliminó en v1.x. Las herramientas se encuentran en agent.tools, un simple dictado de Python codificado por nombre de herramienta. “””, title=”[bold green]Dictado de herramientas[/bold green]”)) sección(“SECCIÓN 4 · Motores LLM”) console.print(Panel(“”” SmolAgents admite múltiples backends LLM a través de LiteLLMModel. Usamos gpt-4o-mini. “””, title=”[bold green]Opciones de motor[/bold green]”)) de smolagents import LiteLLMModel MODEL_ID = “openai/gpt-4o-mini” motor = LiteLLMModel(model_id=MODEL_ID, api_key=OPENAI_API_KEY) console.print(f”[green]Motor listo:[/green] {MODEL_ID}”)

Ampliamos el sistema con una herramienta de búsqueda web y una utilidad factorial para ampliar las capacidades del agente. Probamos las herramientas de forma independiente para verificar su corrección antes de integrarlas en los agentes. También inicializamos el motor LLM usando LiteLLMModel, preparando el backend de razonamiento central para su ejecución.

sección(“SECCIÓN 5 · CodeAgent”) de smolagents import CodeAgent code_agent = CodeAgent( herramientas = [celsius_to_fahrenheit, PrimeTool(), MemoTool(), DuckDuckGoTool()]modelo = motor, max_steps = 6, verbosity_level = 1, ) console.print(“\n[bold]Claves iniciales de agent.tools:[/bold]”, lista(code_agent.tools.keys())) code_agent.tools[“factorial”] = consola factorial.print(“[dim]Después de agregar factorial:[/dim]”, lista(code_agent.tools.keys())) console.print(“\n[bold yellow]Tarea 1:[/bold yellow]”) resultado1 = code_agent.run( “Convierte el punto de ebullición (100 °C) y la temperatura corporal (37 °C) a grados Fahrenheit. ” “¿Cuál es mayor y en cuánto?” ) show(“CodeAgent — Tarea 1”, resultado1) console.print(“\n[bold yellow]Tarea 2:[/bold yellow]”) resultado2 = code_agent.run(“¿Cuánto es 17 por 19? ¿Ese resultado es primo? Verifique también 7919.”) show(“CodeAgent — Tarea 2”, resultado2) console.print(“\n[bold yellow]Tarea 3:[/bold yellow]”) resultado3 = code_agent.run(“¡Calcule 10! usando la herramienta factorial.”) show(“CodeAgent — Tarea 3”, resultado3)

Construimos un CodeAgent que puede escribir y ejecutar Python dinámicamente para resolver problemas de varios pasos. Demostramos la inyección de herramientas en tiempo de ejecución agregando una nueva herramienta sin reconstruir el agente. Luego ejecutamos tareas de razonamiento progresivamente complejas para validar el encadenamiento, el cálculo aritmético y la coordinación de herramientas.

sección(“SECCIÓN 6 · ToolCallingAgent (ReAct)”) de smolagents import ToolCallingAgent react_agent = ToolCallingAgent( herramientas = [celsius_to_fahrenheit, PrimeTool(), MemoTool()]modelo = motor, max_steps = 5, verbosity_level = 1, ) console.print(“\n[bold yellow]Tarea 4:[/bold yellow]”) resultado4 = reaccionar_agent.run( “Luego recupere ambos hechos y resúmalos.” ) show(“ToolCallingAgent — Tarea 4”, resultado4) sección(“SECCIÓN 7 · Orquestación multiagente (v1.8+ API)”) math_agent = CodeAgent( herramientas = [PrimeTool()]modelo = motor, max_steps = 4, nombre = “math_specialist”, descripción = “Maneja preguntas matemáticas y comprobaciones de primalidad.”, verbosity_level = 0, ) research_agent = ToolCallingAgent( herramientas = [DuckDuckGoTool(), MemoTool()]modelo = motor, max_steps = 4, nombre = “research_specialist”, descripción = “Busca en la web y almacena o recupera datos de la memoria.”, verbosity_level = 0, ) manager_agent = CodeAgent( herramientas = []modelo = motor, agentes_administrados = [math_agent, research_agent]max_steps = 8, verbosity_level = 1, ) console.print(“\n[bold yellow]Tarea 5:[/bold yellow]”) result5 = manager_agent.run( “Averigüe en qué año se lanzó Python por primera vez (use research_specialist), ” “luego verifique si ese año es un número primo (use math_specialist)”. ) show(“Manager Agent — Tarea 5”, resultado5)

Creamos un ToolCallingAgent para mostrar un razonamiento estructurado estilo ReAct con invocación controlada de herramientas. Luego implementamos un sistema de orquestación de múltiples agentes donde agentes especializados colaboran bajo un agente administrador. Demostramos delegación, coordinación y razonamiento entre agentes para resolver tareas compuestas de manera eficiente.

En conclusión, construimos un sistema multiagente completamente funcional capaz de razonar, buscar, calcular, almacenar memoria y delegar tareas entre agentes especializados. Demostramos cómo SmolAgents permite la integración flexible de herramientas, la extensibilidad del tiempo de ejecución y la colaboración estructurada sin complejidad arquitectónica innecesaria. Mostramos cómo CodeAgent ejecuta lógica Python real para encadenamiento avanzado, mientras que ToolCallingAgent garantiza bucles de razonamiento estructurados y auditables. Finalmente, implementamos un agente administrador que coordina subagentes especializados, lo que demuestra cómo se puede lograr una orquestación escalable con una sobrecarga mínima.

Consulte el código de implementación completo y el cuaderno. Además, no dude en seguirnos en Twitter y no olvide unirse a nuestro SubReddit de más de 130.000 ML y suscribirse a nuestro boletín. ¡Esperar! estas en telegrama? Ahora también puedes unirte a nosotros en Telegram.

¿Necesita asociarse con nosotros para promocionar su repositorio de GitHub O su página principal de Hugging O su lanzamiento de producto O seminario web, etc.? Conéctate con nosotros