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:

ProblemaLoop manualAgente
Boilerplate repetitivo15-20 líneas por cada asistente2-3 líneas
Multi-ronda complejaDebes manejar el while y max_roundsAutomático con recursion_limit
Error handlingtry/except manual en cada tool callIntegrado (devuelve error como ToolMessage)
Parallel tool callsDebes iterar sobre tool_callsManejado internamente
StreamingRequiere lógica adicional significativaagent.stream() integrado
PersistenciaNo disponible sin código adicionalcheckpointer 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, 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:

  1. Reason — El modelo analiza la pregunta y decide qué hacer. "El usuario quiere saber el clima en Madrid. Voy a llamar a get_weather."
  2. Act — El modelo genera un tool_call y el agente ejecuta la tool.
  3. Observe — El resultado de la tool se agrega como ToolMessage y el modelo lo recibe.
  4. 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ápsulaTemaQué aprenderás
02create_agent y el loop ReActcreate_agent(model, tools), cómo funciona internamente, stop conditions, recursion_limit
03System prompts estáticos y dinámicossystem_prompt como string/SystemMessage, @dynamic_prompt para prompts contextuales
04Estado y memoria del agenteAgentState, state_schema con TypedDict, custom state, conversation history
05Streaming de agentesagent.stream() con stream_mode, procesar chunks, streaming de tool calls dentro de agents
06Structured output en agentesresponse_format, ToolStrategy vs ProviderStrategy, structured_response
07Legacy vs moderno: mapeo de APIsTabla de equivalencias, por qué migrar, cómo traducir código legacy
08Proyecto: Agente de investigación con toolsAgente 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:

  1. Usa create_agent con 3+ tools (búsqueda web, extracción de datos, calculadora)
  2. Tiene un system prompt que guía su comportamiento de investigación
  3. Hace streaming del proceso de razonamiento — ves en tiempo real cómo el agente piensa y actúa
  4. 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_agent sigue 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, y name de create_agent son tu punto de entrada a estos temas.
  • Módulo 11: Deep Agents lleva la autonomía al máximo — planning, filesystem, subagents. Entender create_agent es 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_agent como 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_after pero 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, usar bind_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:

ErrorCausaSolución
ImportError: cannot import name 'create_agent'Versión de langchain antiguapip install --upgrade langchain (necesitas v1.2+)
ModuleNotFoundError: No module named 'langgraph'langgraph no instaladopip install langgraph
NotImplementedError: ... does not support tool callingEl modelo no soporta tool callingUsa 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_agent y 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_agent vs 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_agent automatiza 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_agent es 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_agent hereda 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 + langgraph instalados (create_agent usa langgraph internamente)
  • El proyecto integrador es un agente de investigación con búsqueda web, streaming, y structured output

Recursos adicionales

  1. LangChain Agents Documentation — Guía oficial de agentes con create_agent
  2. create_agent API Reference — Referencia completa de parámetros y tipos
  3. ReAct: Synergizing Reasoning and Acting in Language Models — Paper original del patrón ReAct (Yao et al., 2022)
  4. LangGraph Agents Overview — Cómo create_agent se construye sobre LangGraph
  5. Tool Calling — LangChain Docs — Base conceptual de tools que el agente usa internamente
  6. 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.