Módulo 3: Agents con create_agent
Introducción: De Tools Manuales a Agentes Autónomos
Descripción
En el Módulo 2 construiste el tool execution loop manualmente: el usuario pregunta, el modelo decide qué tool llamar, tú ejecutas la tool, empaquetas el resultado en un ToolMessage, se lo devuelves al modelo, y el modelo genera la respuesta final. Si necesitaba más datos, repetías todo el ciclo con un while loop.
Funcionaba. Pero cada vez que querías un asistente con tools tenías que escribir el mismo boilerplate: el tool_map, el while loop, el manejo de ToolMessage, el max_rounds como safety net. Para una tool era manejable; para un agente de investigación que llama 5 tools en secuencia, se vuelve tedioso y propenso a errores.
create_agent resuelve esto. Una línea reemplaza todo el loop manual: le das un modelo y una lista de tools, y obtienes un agente que ejecuta el ciclo completo de forma autónoma. El modelo razona sobre qué hacer, llama tools, observa resultados, y repite hasta que tiene suficiente información para responder. Este patrón se llama ReAct (Reason + Act), y es el fundamento de los agentes modernos con LLMs.
¿Dónde estamos en la guía?
Este es el Módulo 3 de la guía LangChain & LangGraph: From Chains to Agents. Es el último módulo del Bloque 1 (LangChain Core) antes de pasar a Middleware y Customización.
Bloque 1: LangChain Core (Módulos 1-4) ← ESTÁS AQUÍ (Módulo 3)
Bloque 2: LangGraph Fundamentals (Módulos 5-7)
Bloque 3: LangGraph Avanzado (Módulos 8-10)
Bloque 4: Producción (Módulos 11-12)
Tu progreso en el Bloque 1:
Módulo 1: Modelos y Proveedores ✅ Completado
│
▼
Módulo 2: Tools y Tool Calling ✅ Completado
│
▼
Módulo 3: Agents (create_agent) ← ESTÁS AQUÍ
│
▼
Módulo 4: Middleware y Customización 🔒 Siguiente
En el Módulo 1 aprendiste a conectar con modelos. En el Módulo 2 les diste herramientas y escribiste el loop manual para ejecutarlas. Ahora vas a automatizar ese loop: el agente se encarga de todo el ciclo de razonamiento y ejecución.
El puente: de loop manual a agente autónomo
Lo que ya sabes
En el Módulo 2 implementaste esto:
from dotenv import load_dotenv
load_dotenv()
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, ToolMessage
@tool
def search(query: str) -> str:
"""Busca información en la web."""
return f"Resultados para '{query}': LangChain es un framework para LLMs."
tools = [search]
tool_map = {t.name: t for t in tools}
model = init_chat_model("openai:gpt-4.1-mini")
model_with_tools = model.bind_tools(tools)
messages = [HumanMessage(content="¿Qué es LangChain?")]
for _ in range(5):
response = model_with_tools.invoke(messages)
messages.append(response)
if not response.tool_calls:
break
for tc in response.tool_calls:
try:
result = str(tool_map[tc["name"]].invoke(tc["args"]))
except Exception as e:
result = f"Error: {e}"
messages.append(ToolMessage(content=result, tool_call_id=tc["id"]))
print(response.content)
# LangChain es un framework para construir aplicaciones con LLMs.
Son ~20 líneas de boilerplate para cada asistente que quieras construir. El tool_map, el for loop, el try/except, el ToolMessage, el max_rounds... todo eso se repite siempre.
Lo que aprenderás aquí
Con create_agent, el mismo resultado en 5 líneas:
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def search(query: str) -> str:
"""Busca información en la web."""
return f"Resultados para '{query}': LangChain es un framework para LLMs."
agent = create_agent("openai:gpt-4.1-mini", tools=[search])
result = agent.invoke({"messages": [("user", "¿Qué es LangChain?")]})
print(result["messages"][-1].content)
# LangChain es un framework para construir aplicaciones con LLMs.
Sin tool_map. Sin while loop. Sin ToolMessage manual. Sin max_rounds. El agente maneja todo internamente.
Por qué agentes: el problema del loop manual
El loop manual funciona para casos simples, pero tiene problemas reales en escenarios complejos:
| Problema | Loop manual | Agente |
|---|---|---|
| Boilerplate repetitivo | 15-20 líneas por cada asistente | 2-3 líneas |
| Multi-ronda compleja | Debes manejar el while y max_rounds | Automático con recursion_limit |
| Error handling | try/except manual en cada tool call | Integrado (devuelve error como ToolMessage) |
| Parallel tool calls | Debes iterar sobre tool_calls | Manejado internamente |
| Streaming | Requiere lógica adicional significativa | agent.stream() integrado |
| Persistencia | No disponible sin código adicional | checkpointer como parámetro |
El loop manual es valioso para entender cómo funciona tool calling. El agente es lo que usas para construir sistemas reales.
Analogía: el dispatcher
En el loop manual, tú eres el dispatcher. El modelo te dice "necesito llamar a search", tú ejecutas search, le devuelves el resultado, y preguntas "¿algo más?". Eres el intermediario que conecta cada pieza.
Con un agente, el modelo es el dispatcher. Recibe la pregunta, decide qué tools llamar, ejecuta el ciclo completo, y te devuelve la respuesta final. Tú solo defines las tools y haces la pregunta — el agente se encarga del resto.
Es la diferencia entre conducir con transmisión manual y automática. Ambos te llevan al destino, pero uno requiere que manejes cada paso del proceso.
El patrón ReAct: Reason + Act
Los agentes de create_agent usan el patrón ReAct (Reasoning + Acting). El modelo alterna entre dos fases en un loop:
┌──────────────────────────────────────────────────────────┐
│ Loop ReAct │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Reason │────▶│ Act │────▶│ Observe │───┐ │
│ │ (Modelo) │ │ (Tool) │ │(Resultado)│ │ │
│ └──────────┘ └──────────┘ └──────────┘ │ │
│ ▲ │ │
│ └────────────────────────────────────────────┘ │
│ │
│ Condición de parada: el modelo responde sin tool_calls │
└──────────────────────────────────────────────────────────┘
Paso a paso:
- Reason — El modelo analiza la pregunta y decide qué hacer. "El usuario quiere saber el clima en Madrid. Voy a llamar a
get_weather." - Act — El modelo genera un
tool_cally el agente ejecuta la tool. - Observe — El resultado de la tool se agrega como
ToolMessagey el modelo lo recibe. - Repeat — El modelo evalúa si necesita más información. Si sí, vuelve a Reason. Si no, genera la respuesta final.
Ejemplo del flujo ReAct
Usuario: "¿Cuántos habitantes tiene Japón y cuál es su PIB per cápita?"
Ronda 1 — Reason:
"Necesito dos datos: población y PIB. Voy a buscar ambos."
→ tool_call: search("población Japón 2024")
→ tool_call: search("PIB per cápita Japón 2024")
Ronda 1 — Act:
→ search("población Japón 2024") = "125 millones de habitantes"
→ search("PIB per cápita Japón 2024") = "USD 33,800"
Ronda 1 — Observe:
El modelo recibe ambos resultados.
Ronda 2 — Reason:
"Ya tengo toda la información. Voy a responder."
→ Sin tool_calls → genera respuesta final
Respuesta: "Japón tiene aproximadamente 125 millones de habitantes
y un PIB per cápita de USD 33,800."
El modelo decidió hacer dos búsquedas en paralelo (parallel tool calls), observó los resultados, y determinó que tenía suficiente información para responder. Todo esto ocurrió automáticamente dentro del agente.
create_agent como abstracción de alto nivel
create_agent no es magia — es una abstracción sobre LangGraph. Internamente construye un grafo con dos nodos conectados en un loop:
┌─────────────┐ tool_calls ┌─────────────┐
│ Model │─────────────────────────▶│ Tools │
│ Node │ │ Node │
│ │◀─────────────────────────│ │
└─────────────┘ ToolMessages └─────────────┘
│
│ sin tool_calls
▼
[Respuesta]
- Model Node: Llama al LLM con la lista de mensajes. Si la respuesta contiene
tool_calls, envía al Tools Node. Si no, devuelve la respuesta (fin). - Tools Node: Ejecuta cada tool call y agrega los resultados como
ToolMessage. Vuelve al Model Node.
Este es exactamente el while loop que escribiste manualmente en el Módulo 2, pero empaquetado como un grafo compilado de LangGraph. Eso significa que hereda todas las capacidades de LangGraph: checkpointing, streaming, interrupts, y más.
No necesitas saber LangGraph para usar create_agent. Pero saber que es un grafo internamente te explica por qué tiene parámetros como checkpointer, interrupt_before, y recursion_limit.
Qué dominarás en este módulo
Al completar las 8 cápsulas de este módulo, serás capaz de:
- ✅ Crear agentes con
create_agent(model, tools)en una sola línea - ✅ Entender el loop ReAct y las condiciones de parada
- ✅ Configurar system prompts estáticos y dinámicos
- ✅ Manejar estado del agente con
state_schema(TypedDict) - ✅ Hacer streaming del proceso de razonamiento del agente
- ✅ Obtener structured output de agentes con
response_format - ✅ Traducir código legacy (
AgentExecutor,LLMChain) a APIs modernas
Mapa del módulo
| Cápsula | Tema | Qué aprenderás |
|---|---|---|
| 02 | create_agent y el loop ReAct | create_agent(model, tools), cómo funciona internamente, stop conditions, recursion_limit |
| 03 | System prompts estáticos y dinámicos | system_prompt como string/SystemMessage, @dynamic_prompt para prompts contextuales |
| 04 | Estado y memoria del agente | AgentState, state_schema con TypedDict, custom state, conversation history |
| 05 | Streaming de agentes | agent.stream() con stream_mode, procesar chunks, streaming de tool calls dentro de agents |
| 06 | Structured output en agentes | response_format, ToolStrategy vs ProviderStrategy, structured_response |
| 07 | Legacy vs moderno: mapeo de APIs | Tabla de equivalencias, por qué migrar, cómo traducir código legacy |
| 08 | Proyecto: Agente de investigación con tools | Agente que busca, extrae datos structured, y genera resumen |
Flujo de aprendizaje: Primero dominarás la creación básica de agentes y entenderás el loop ReAct (02). Luego aprenderás a personalizar su comportamiento con prompts (03) y estado custom (04). Después explorarás streaming (05) y structured output (06) para producción. Finalmente, aprenderás a traducir código legacy (07) y construirás el proyecto integrador (08).
Conexión con el proyecto
Mini-Proyecto de este módulo: Agente de Investigación con Tools
En la Cápsula 08 construirás un agente de investigación que:
- Usa
create_agentcon 3+ tools (búsqueda web, extracción de datos, calculadora) - Tiene un system prompt que guía su comportamiento de investigación
- Hace streaming del proceso de razonamiento — ves en tiempo real cómo el agente piensa y actúa
- Produce un structured output como reporte final (modelo Pydantic con título, hallazgos, fuentes, conclusión)
Cada concepto de las cápsulas 02-07 se integra en este proyecto.
Conexión con la guía completa
Los agentes que creas aquí son la base de todo lo que viene:
- Módulo 4: El middleware system te permite interceptar y modificar el comportamiento del agente sin reescribirlo. ¿Quieres que use un modelo diferente según la complejidad? ¿Que filtre tools por permisos? Middleware lo resuelve.
- Módulos 5-7: En LangGraph, construirás workflows más complejos que un solo agente. Pero
create_agentsigue siendo tu herramienta para el 80% de los casos. - Módulos 8-10: Memoria persistente, human-in-the-loop, y multi-agente. Los parámetros
checkpointer,interrupt_before, ynamedecreate_agentson tu punto de entrada a estos temas. - Módulo 11: Deep Agents lleva la autonomía al máximo — planning, filesystem, subagents. Entender
create_agentes prerequisito para entender qué hace Deep Agents por encima.
Límites: qué NO cubre este módulo
- ❌ Custom LangGraph workflows — Se cubre en Módulos 5-7. Aquí usas
create_agentcomo abstracción; no construyes grafos manualmente. - ❌ Middleware y customización — Se cubre en Módulo 4. Aquí configuras agentes con parámetros directos; el middleware system viene después.
- ❌ Multi-agent systems — Se cubre en Módulo 10. Aquí trabajas con un solo agente autónomo.
- ❌ Human-in-the-loop — Se cubre en Módulo 9. Mencionaremos
interrupt_before/interrupt_afterpero sin profundizar. - ❌ Memoria persistente entre sesiones — Se cubre en Módulo 8. Aquí la conversación vive en memoria durante la sesión.
Setup técnico
Prerequisitos
Antes de continuar, verifica que tienes:
- ✅ Módulo 2 completado — sabes crear tools con
@tool, usarbind_tools, y ejecutar el tool execution loop - ✅ Python 3.11+ instalado
- ✅ Al menos una API key de un proveedor que soporte tool calling (OpenAI o Anthropic recomendado)
Instalación
create_agent vive en langchain pero internamente usa langgraph para construir el grafo del agente. Necesitas ambos paquetes:
pip install langchain langgraph langchain-openai python-dotenv
Si ya tenías langchain y langchain-openai del Módulo 1, solo necesitas agregar langgraph:
pip install langgraph
Verificar que todo funciona
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def greet(name: str) -> str:
"""Saluda a una persona por su nombre."""
return f"¡Hola, {name}!"
agent = create_agent("openai:gpt-4.1-mini", tools=[greet])
result = agent.invoke({"messages": [("user", "Saluda a María")]})
print(result["messages"][-1].content)
# Output esperado: ¡Hola, María! (o similar)
Si ves una respuesta que incluye el saludo, tu setup está listo.
Si algo falla:
| Error | Causa | Solución |
|---|---|---|
ImportError: cannot import name 'create_agent' | Versión de langchain antigua | pip install --upgrade langchain (necesitas v1.2+) |
ModuleNotFoundError: No module named 'langgraph' | langgraph no instalado | pip install langgraph |
NotImplementedError: ... does not support tool calling | El modelo no soporta tool calling | Usa openai:gpt-4.1-mini, anthropic:claude-sonnet-4-20250514, u otro modelo con soporte |
Evidencia de éxito
Al terminar este módulo, sabrás que tuviste éxito si:
- ✅ Puedes crear un agente con
create_agenty que resuelva preguntas usando tools - ✅ Entiendes el loop ReAct: reason → act → observe → repeat
- ✅ Tu agente se detiene automáticamente cuando tiene suficiente información
- ✅ Puedes configurar system prompts y obtener structured output
- ✅ Sabes cuándo usar
create_agentvs loop manual vs LangGraph custom - ✅ Tu proyecto de investigación genera un reporte structured a partir de búsquedas autónomas
Vista previa: del agente al middleware
En este módulo crearás agentes funcionales con create_agent. Pero ¿qué pasa cuando necesitas personalizar el comportamiento sin reescribir el agente?
En el Módulo 4, aprenderás el middleware system — interceptors que modifican el agente en puntos específicos:
# Módulo 3: agente básico (lo que aprenderás aquí)
agent = create_agent(
"openai:gpt-4.1-mini",
tools=[search, calculator],
system_prompt="Eres un asistente de investigación."
)
# Módulo 4: agente con middleware (lo que viene después)
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
@wrap_model_call
def smart_routing(request: ModelRequest, handler) -> ModelResponse:
"""Usa modelo económico para preguntas simples, potente para complejas."""
message_count = len(request.state["messages"])
if message_count > 10:
return handler(request.override(model=advanced_model))
return handler(request)
agent = create_agent(
"openai:gpt-4.1-mini",
tools=[search, calculator],
middleware=[smart_routing]
)
El middleware te da control sobre el agente sin modificar su lógica interna. Es como agregar filtros a una cámara — la cámara sigue funcionando igual, pero las fotos salen diferentes.
Resumen
- En el Módulo 2 construiste el tool execution loop manualmente — funcionaba pero era tedioso y repetitivo
create_agentautomatiza todo el loop: le das modelo y tools, y el agente razona, actúa, observa y repite hasta tener la respuesta- El patrón ReAct (Reason + Act) es el fundamento: el modelo alterna entre razonar sobre qué hacer y ejecutar acciones
create_agentes una abstracción sobre LangGraph — internamente construye un grafo con un model node y un tools node en un loop- La analogía clave: loop manual = tú eres el dispatcher; agente = el modelo es el dispatcher
create_agenthereda capacidades de LangGraph: checkpointing, streaming, interrupts, y más- Este módulo cubre agentes con
create_agent; los Módulos 5-7 cubren workflows custom con LangGraph para cuando necesites más control - Necesitas
langchain+langgraphinstalados (create_agent usa langgraph internamente) - El proyecto integrador es un agente de investigación con búsqueda web, streaming, y structured output
Recursos adicionales
- LangChain Agents Documentation — Guía oficial de agentes con create_agent
- create_agent API Reference — Referencia completa de parámetros y tipos
- ReAct: Synergizing Reasoning and Acting in Language Models — Paper original del patrón ReAct (Yao et al., 2022)
- LangGraph Agents Overview — Cómo create_agent se construye sobre LangGraph
- Tool Calling — LangChain Docs — Base conceptual de tools que el agente usa internamente
- What's New in LangGraph v1 — Cambios de create_react_agent a create_agent
Módulo 3 — LangChain & LangGraph: From Chains to Agents
Siguiente cápsula: create_agent y el Loop ReAct — aprenderás a crear agentes, entender su funcionamiento interno, y controlar las condiciones de parada.