un LLM local. Lindo.
Pero después de las primeras charlas, quizás te preguntes: ¿qué más puedo hacer con él?
Bueno, ¿qué tal si hacemos que el LLM local sea agente con el uso de alguna herramienta?
En esta publicación, exploraremos cómo convertir un LLM local en un agente que utiliza herramientas. Específicamente, usaremos
Modelo Gemma 4 (variantes amigables con el borde) como nuestro LLM local Ollama para servir el SDK de LLM OpenAI Agents local para el tiempo de ejecución del agente Tavily web search MCP como un ejemplo de herramienta externa
Construiremos un mini agente de investigación profunda que pueda buscar en la web, recopilar evidencia y sintetizar una respuesta con citas, dada la pregunta de un usuario.
Al final de la publicación, tendrá un agente de investigación profunda local en funcionamiento y un patrón de implementación reutilizable para convertir un modelo local en un agente de IA local.
Si está interesado en la configuración de un agente de codificación local, anteriormente cubrí Gemma 4 + OpenCode. En esta publicación, nos centramos en el patrón más general de conectar un modelo local a un tiempo de ejecución de agente y herramientas externas.
1. Configurar la pila de agentes locales
Necesitamos preparar 4 piezas antes de escribir el código: Ollama, Gemma 4 (específicamente el modelo Gemma 4 E4B), OpenAI Agents SDK y Tavily MCP.
Primero, instalemos Ollama.
En Windows, puedes descargar el instalador desde el sitio web oficial de Ollama:
https://ollama.com/download
O use winget en PowerShell:
instalación de alas Ollama.Ollama
En Linux, Ollama se puede instalar con:
“curl -fsSL https://ollama.com/install.sh | sh”
Después de la instalación, verifique:
ollama –versión
En Windows, recuerde iniciar Ollama desde el menú Inicio. Una vez que se está ejecutando, el punto final de la API local está disponible.
A continuación, extraemos el modelo local. Aquí utilizamos la variante Gemma 4 E4B:
ollama jala gemma4:e4b
Gemma 4 tiene varias variantes. El modelo E4B se adapta bien a nuestro propósito, ya que está diseñado teniendo en cuenta los flujos de trabajo de agencia locales/de borde. Mi máquina tiene una GPU para computadora portátil NVIDIA RTX 2000 Ada con aproximadamente 8 GB de VRAM. Si su máquina es más limitada, puede probar la variante E2B más ligera:
ollama jala gemma4:e2b
A continuación, necesitamos la biblioteca de tiempo de ejecución del agente. Para eso, utilizamos el SDK de agentes OpenAI:
pip instala agentes openai
También necesitarás el cliente compatible con OpenAI:
instalación de pip en openai
Algo a tener en cuenta aquí: más adelante, dirigiremos al cliente al punto final local de Ollama, por lo que esto no significa que estemos enviando llamadas de modelo a OpenAI.
Finalmente, necesitamos un punto final Tavily MCP. En caso de que no lo hayas usado antes, Tavily es una API de búsqueda diseñada para aplicaciones LLM. En esta publicación, utilizamos su servidor MCP para que el agente pueda buscar en la web.
Primero deberá crear una cuenta de Tavily y obtener una clave API. En la plataforma Tavily, puedes generar directamente un enlace MCP con la siguiente forma:
https://mcp.tavily.com/mcp/?tavilyApiKey=
Ahora estamos listos.
Usar Tavily aquí no es una elección patrocinada; se utiliza aquí como una herramienta MCP conveniente, el mismo patrón también puede funcionar con otras herramientas compatibles con MCP.
De hecho, toda la pila aquí no es la única opción. En lugar de usar Ollama, puedes servir el modelo local con LM Studio o llama.cpp. En lugar de los modelos Gemma 4, también puedes probar con otros modelos de, por ejemplo, la familia Qwen. Para el marco del agente, también tenemos opciones de Google o Anthropic. También puedes conectar diferentes herramientas MCP en lugar de Tavily. Utilizo esta combinación simplemente porque estoy familiarizado con esa pila. Pero lo importante de este estudio de caso es el patrón agente local general.
2. Configurar el Agente de Investigación Local
Con el SDK de OpenAI Agents, este es el objeto Agente final que debemos componer:
de agentes importar Agente agente = Agente( nombre=”Agente de investigación local”, instrucciones = RESEARCH_AGENT_INSTRUCTIONS, modelo = modelo, mcp_servers =[tavily_server]mcp_config={“include_server_in_tool_names”: Verdadero},)
Analicemos cada parte.
2.1 El modelo
Primero, el modelo.
desde openai import AsyncOpenAI desde agentes import OpenAIChatCompletionsModel MODEL_NAME = “gemma4:e4b” OLLAMA_BASE_URL = “http://localhost:11434/v1″ client = AsyncOpenAI( api_key=”ollama”, base_url=OLLAMA_BASE_URL, ) model = OpenAIChatCompletionsModel( model=MODEL_NAME, openai_client=client, )
Comenzamos creando un cliente que apunta al punto final local compatible con OpenAI de Ollama.
Luego, usamos OpenAIChatCompletionsModel para envolver el modelo Gemma en un objeto modelo. Esto permite que el SDK de agentes utilice ese modelo dentro del bucle del agente.
Tenga en cuenta que el valor api_key=”ollama” es sólo un marcador de posición. Ollama realmente no necesita una clave API OpenAI real. Lo usamos porque el cliente espera este campo.
2.2 La instrucción
A continuación, definimos la instrucción para el agente con el comportamiento de investigación deseado:
from datetime import datetime CURRENT_DATE = datetime.now().strftime(“%B %d, %Y”) # Tenga en cuenta que esta instrucción se repite con AI RESEARCH_AGENT_INSTRUCTIONS = f”””
[Role]
Eres un asistente de investigación conciso.
[Task]
Responda la pregunta del usuario convirtiéndola en una pequeña tarea de investigación web. Utilice la fecha actual al interpretar preguntas urgentes: {CURRENT_DATE}.
[Research behavior]
Comience con una consulta de búsqueda específica. Para preguntas de recomendación o comparación, complete este ciclo de investigación antes de responder: primero identifique las opciones principales, luego busque el contexto de comparación y luego sintetice una recomendación. Utilice búsquedas de seguimiento cuando los primeros resultados sean insuficientes, contradictorios o solo cubran parte de la pregunta. Prefiera fuentes relevantes y creíbles, y realice un seguimiento de qué fuente respalda cada afirmación importante. Antes de responder, verifique si la evidencia reunida es suficiente para respaldar la conclusión.
[Expected output]
Primero dé una respuesta directa y luego explique brevemente la evidencia detrás de ella. Incluya enlaces de fuentes para afirmaciones fácticas clave.
[Rules]
No confíe en la memoria para saber hechos que pueden haber cambiado. No inventes detalles faltantes. Mantenga la respuesta concisa. “””.banda()
2.3 Las herramientas
Ahora equipamos al agente con la herramienta de búsqueda web. En este caso utilizamos el buscador Tavily a través de MCP:
de agentes import Agent, Runner de agentes.mcp import MCPServerStreamableHttp TAVILY_MCP_URL = “YOUR_TAVILY_MCP_URL” async con MCPServerStreamableHttp( name=”tavily”, params={“url”: TAVILY_MCP_URL},) como tavily_server: herramientas = await tavily_server.list_tools() print(“Herramientas Tavily disponibles:”) para herramienta en herramientas: descripción = (tool.description o “”).replace(“\n”, ” “) print(f”- {tool.name}: {descripción[:120]}”) agente = Agente( nombre=”Agente de investigación local”, instrucciones=RESEARCH_AGENT_INSTRUCTIONS, modelo=modelo, mcp_servers=[tavily_server]mcp_config={“include_server_in_tool_names”: True}, ) resultado = await Runner.run(agent, RESEARCH_QUESTION, max_turns=MAX_TURNS)
Este bloque de código hace tres cosas:
Abre una conexión al servidor MCP de Tavily con asíncrono con MCPServerStreamableHttp(…) como tavily_server: una vez conectado, Tavily expondría sus herramientas disponibles al SDK de agentes. Creamos el objeto Agente dentro del contexto MCP. Tenga en cuenta que tenemos mcp_servers=[tavily_server]que adjunta las herramientas MCP de Tavily al agente. Finalmente ejecutamos el agente con result = await Runner.run(agent, RESEARCH_QUESTION, max_turns=MAX_TURNS). El administrador de contexto es importante aquí porque la conexión MCP solo está activa dentro del bloque asíncrono con.
mcp_config={“include_server_in_tool_names”: True} es principalmente para facilitar la lectura en el seguimiento. Sin él, el nombre de la herramienta solo aparecerá como tavily_search. Con él, el nombre de la herramienta se mostrará como mcp_tavily__tavily_search. Esto deja más claro que la llamada a la herramienta se produjo a través del servidor Tavily MCP.
3. Ejecute una pregunta de investigación
Ahora que el agente está configurado, probémoslo con una pregunta concreta:
“¿Qué partido de la Copa Mundial del 23 de junio de 2026 tuvo más en juego en la fase de grupos y por qué?”
Para inspeccionar lo que pasó, imprimo un rastro compacto:
def compact(valor: objeto, límite: int = 220) -> str: texto = str(valor).reemplazar(“\n”, ” “) devuelve texto si len(texto) <= limitar otro texto[:limit] + "..." para el paso, elemento en enumerar(resultado.new_items, inicio=1): raw_item = getattr(item, "raw_item", Ninguno) raw_type = getattr(raw_item, "tipo", "") raw_name = getattr(raw_item, "nombre", "") raw_output = getattr(raw_item, "salida", "") print( f"{paso:02d} | {tipo(elemento).__nombre__} | " f"{tipo_raw o nombre_raw} {compacto(salida_raw o elemento_raw)}" )
En mi ejecución, el rastro se veía así:
01 | Artículo de llamada de herramienta | llamada_función | ResponseFunctionToolCall(arguments='{“query”:”Partidos de la fase de grupos de la Copa Mundial 2026 del 23 de junio de 2026 en juego”}’, name=’mcp_tavily__tavily_search’, …) 02 | HerramientaCallOutputItem | | {‘call_id’: …, ‘salida’: …} 03 | MensajeSalidaArtículo | mensaje | ResponseOutputMessage(… respuesta final…)
Esto nos permite ver el comportamiento agente directamente. En esta ejecución, el modelo local de Gemma decidió llamar a la herramienta de búsqueda Tavily, el SDK de agentes ejecutó esa llamada a la herramienta y pasó los resultados al modelo. Luego, el modelo produjo la respuesta final.
Para ver la respuesta final, podemos imprimir:
imprimir(resultado.salida_final)
Esto es lo que produjo el agente:
El partido con más apuestas en la fase de grupos el 23 de junio de 2026 fue Colombia vs. RD Congo. Por qué: Según informes de la FIFA, este partido específico se destacó como un momento crítico en el que Colombia avanzó a la fase eliminatoria del torneo. El artículo señala que Daniel Muñoz marcó el primer gol de Colombia durante este partido del Grupo K, lo que contribuyó directamente a su progresión en la competición. Evidencia – FIFA: Un artículo titulado “Colombia v Congo DR Grupo K Copa Mundial de la FIFA 2026” informa específicamente sobre un momento clave de este partido, afirmando que el gol de Muñoz ayudó a llevar a Colombia a la fase eliminatoria. Fuente: https://digitalhub.fifa.com/transform/450614d3-72d7-4c1f-85ff-ea0fbee6f28d/Colombia-v-Congo-DR-Group-K-FIFA-World-Cup-2026?focuspoint=0.51 – Yahoo Sports: Confirma el calendario y resultado de esa fecha: Colombia derrotó a RD Congo. Fuente: https://sports.yahoo.com/soccer/article/2026-world-cup-results-standings-and-schedule-live-scores-group-stage-updates-and-how-to-watch-050724193.html
Observe que el agente solo realizó una ronda de búsqueda en esta ejecución, ya que los resultados de la búsqueda ya contenían suficiente evidencia para que el modelo respondiera. Para preguntas más complejas, serían necesarias múltiples rondas de búsqueda y razonamiento, y nuestro marco actual naturalmente lo respalda.
4. Concluyendo
Un LLM local no tiene por qué quedarse como modelo de chat.
En esta publicación, implementamos un modelo Gemma 4 E4B localmente a través de Ollama, luego colocamos el modelo dentro de un tiempo de ejecución del agente proporcionado por OpenAI Agents SDK y le brindamos al agente una herramienta de búsqueda web para que pueda encontrar información en línea para responder las preguntas de los usuarios.
Desde aquí, puede ampliar fácilmente este patrón con instrucciones de investigación más sólidas o crear un flujo de trabajo de planificación y reflexión más explícito, si desea seguir trabajando en la dirección de una investigación profunda, o puede conectar el agente a más herramientas MCP para muchos otros casos de uso.
¡Feliz edificio!
Referencia
Ollama: https://ollama.com/
Familia de modelos Gemma: https://ai.google.dev/gemma
SDK de agentes OpenAI: https://openai.github.io/openai-agents-python/
Documentos de MCP del SDK de agentes: https://openai.github.io/openai-agents-python/mcp/
Documentos de Tavily MCP: https://docs.tavily.com/documentation/mcp