Módulo 3: Agents con create_agent
create_agent y el Loop ReAct
Descripción de la cápsula
create_agent es la función principal de LangChain para construir agentes autónomos. Recibe un modelo y una lista de tools, y retorna un grafo compilado que ejecuta el loop ReAct completo: el modelo razona, llama tools, observa resultados, y repite hasta que decide responder.
En la cápsula anterior viste la visión general. Ahora vas a usarlo. Crearás tu primer agente, entenderás qué produce como output, verás cómo funciona internamente paso a paso, y aprenderás a controlar sus límites con recursion_limit. Al terminar, podrás construir agentes funcionales que resuelvan tareas multi-step de forma autónoma.
Tu primer agente
La forma más básica de crear un agente:
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad."""
return f"El clima en {city} es soleado, 22°C"
agent = create_agent("openai:gpt-4.1-mini", tools=[get_weather])
result = agent.invoke({"messages": [("user", "¿Qué clima hace en Madrid?")]})
print(result["messages"][-1].content)
# Output esperado: El clima en Madrid es soleado, con una temperatura de 22°C.
Tres líneas hacen todo el trabajo:
create_agent("openai:gpt-4.1-mini", tools=[get_weather])— Crea el agente con un modelo y una lista de tools.agent.invoke({"messages": [...]})— Ejecuta el agente con un mensaje del usuario.result["messages"][-1].content— Extrae la respuesta final.
Sobre el parámetro model
create_agent acepta el modelo como string identifier o como instancia directa:
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool
@tool
def greet(name: str) -> str:
"""Saluda a una persona."""
return f"¡Hola, {name}!"
# Opción 1: String identifier (más conciso)
agent_a = create_agent("openai:gpt-4.1-mini", tools=[greet])
# Opción 2: Instancia de modelo (más control)
model = init_chat_model("openai:gpt-4.1-mini", temperature=0)
agent_b = create_agent(model, tools=[greet])
# Ambos funcionan igual
result_a = agent_a.invoke({"messages": [("user", "Saluda a Ana")]})
result_b = agent_b.invoke({"messages": [("user", "Saluda a Ana")]})
print(result_a["messages"][-1].content)
# Output esperado: ¡Hola, Ana!
print(result_b["messages"][-1].content)
# Output esperado: ¡Hola, Ana!
Usa string identifiers para prototipos rápidos. Usa instancias cuando necesites configurar temperature, max_tokens, timeout, u otros parámetros del modelo.
Entender el output
agent.invoke() retorna un diccionario con una key "messages" que contiene toda la conversación: el mensaje del usuario, los tool calls del modelo, los resultados de las tools, y la respuesta final.
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática."""
return str(eval(expression))
agent = create_agent("openai:gpt-4.1-mini", tools=[calculator])
result = agent.invoke({"messages": [("user", "¿Cuánto es 25 * 4?")]})
for i, msg in enumerate(result["messages"]):
msg_type = type(msg).__name__
if hasattr(msg, "tool_calls") and msg.tool_calls:
print(f" [{i}] {msg_type}: tool_calls={[(tc['name'], tc['args']) for tc in msg.tool_calls]}")
else:
content_preview = msg.content[:80] if msg.content else "(sin contenido)"
print(f" [{i}] {msg_type}: {content_preview}")
# Output esperado:
# [0] HumanMessage: ¿Cuánto es 25 * 4?
# [1] AIMessage: tool_calls=[('calculator', {'expression': '25 * 4'})]
# [2] ToolMessage: 100
# [3] AIMessage: 25 × 4 = 100.
La secuencia siempre sigue el mismo patrón:
| Índice | Tipo | Contenido |
|---|---|---|
| 0 | HumanMessage | La pregunta del usuario |
| 1 | AIMessage | Tool calls que el modelo decidió hacer |
| 2 | ToolMessage | Resultado de ejecutar la tool |
| 3 | AIMessage | Respuesta final integrando los resultados |
Si el modelo necesitó más de una ronda de tools, verás más mensajes intercalados (AIMessage con tool_calls → ToolMessage → AIMessage con tool_calls → ToolMessage → ... → AIMessage final).
Extraer la respuesta final
El último mensaje siempre es la respuesta final del agente:
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: LangChain fue creado por Harrison Chase en 2022."
agent = create_agent("openai:gpt-4.1-mini", tools=[search])
result = agent.invoke({"messages": [("user", "¿Quién creó LangChain?")]})
final_answer = result["messages"][-1].content
print(final_answer)
# Output esperado: LangChain fue creado por Harrison Chase en 2022.
Cómo funciona internamente
create_agent construye un grafo de LangGraph con dos nodos en un loop:
┌──────────────────────┐
│ │
Input ──────────▶ │ Model Node │
│ (llama al LLM) │
│ │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ ¿Hay tool_calls? │
└──────────┬───────────┘
│ │
Sí No
│ │
┌──────────▼─────┐ ┌────▼─────┐
│ Tools Node │ │ Output │
│ (ejecuta tools)│ │ (fin) │
└──────────┬─────┘ └──────────┘
│
│ ToolMessages
│
└──────▶ Model Node (vuelve arriba)
El ciclo paso a paso:
- El Model Node recibe la lista de mensajes y llama al LLM.
- Si el LLM responde con
tool_calls→ pasa al Tools Node. - El Tools Node ejecuta cada tool y agrega
ToolMessagea la lista. - Vuelve al Model Node con los resultados.
- Si el LLM responde sin
tool_calls→ fin, devuelve la respuesta.
Viendo el ciclo en acción
Puedes usar stream con stream_mode="updates" para ver cada paso del agente:
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}': Python es un lenguaje de programación creado por Guido van Rossum."
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática."""
return str(eval(expression))
agent = create_agent("openai:gpt-4.1-mini", tools=[search, calculator])
for chunk in agent.stream(
{"messages": [("user", "¿Quién creó Python y cuánto es 2**10?")]},
stream_mode="updates"
):
for node_name, node_output in chunk.items():
print(f"\n--- Nodo: {node_name} ---")
if "messages" in node_output:
for msg in node_output["messages"]:
msg_type = type(msg).__name__
if hasattr(msg, "tool_calls") and msg.tool_calls:
for tc in msg.tool_calls:
print(f" Tool call: {tc['name']}({tc['args']})")
else:
print(f" {msg_type}: {msg.content[:100]}")
# Output esperado:
# --- Nodo: agent ---
# Tool call: search({'query': 'quién creó Python'})
# Tool call: calculator({'expression': '2**10'})
#
# --- Nodo: tools ---
# ToolMessage: Resultados para 'quién creó Python': Python es un lenguaje...
# ToolMessage: 1024
#
# --- Nodo: agent ---
# AIMessage: Python fue creado por Guido van Rossum. Y 2^10 = 1,024.
El agente hizo dos tool calls en paralelo (search y calculator), recibió ambos resultados, y generó la respuesta final en una sola ronda.
Condiciones de parada
El agente se detiene cuando se cumple una de dos condiciones:
1. El modelo responde sin tool_calls
Esta es la parada natural. El modelo evalúa que ya tiene toda la información necesaria y genera una respuesta directa:
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad."""
return f"El clima en {city} es soleado, 22°C"
agent = create_agent("openai:gpt-4.1-mini", tools=[get_weather])
# Caso 1: necesita tool → la llama → responde
result = agent.invoke({"messages": [("user", "¿Qué clima hace en Madrid?")]})
print(f"Con tool: {result['messages'][-1].content}")
# Output esperado: Con tool: El clima en Madrid es soleado, con una temperatura de 22°C.
# Caso 2: no necesita tool → responde directamente
result = agent.invoke({"messages": [("user", "¿Qué es Python?")]})
print(f"Sin tool: {result['messages'][-1].content}")
# Output esperado: Sin tool: Python es un lenguaje de programación de alto nivel...
El modelo decide autónomamente si necesita una tool o puede responder con su conocimiento.
2. Se alcanza el recursion_limit
Si el agente entra en un loop donde sigue llamando tools indefinidamente, recursion_limit lo detiene. Por defecto el límite es 25 iteraciones del grafo (cada paso del grafo — model node o tools node — cuenta como una iteración):
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def always_needs_more(query: str) -> str:
"""Busca información pero siempre sugiere buscar más."""
return f"Encontré algo sobre '{query}', pero necesitas buscar más detalles."
agent = create_agent("openai:gpt-4.1-mini", tools=[always_needs_more])
try:
result = agent.invoke(
{"messages": [("user", "Investiga sobre inteligencia artificial")]},
config={"recursion_limit": 10}
)
except Exception as e:
print(f"Error: {type(e).__name__}: {e}")
# Output esperado: Error: GraphRecursionError: Recursion limit of 10 reached...
Valores recomendados para recursion_limit:
| Caso de uso | Valor recomendado | Razón |
|---|---|---|
| Preguntas simples (1-2 tools) | 10 | No necesita muchas rondas |
| Tareas moderadas (3-5 tool calls) | 25 (default) | Suficiente para la mayoría de tareas |
| Investigación compleja | 50 | Puede necesitar múltiples rondas de búsqueda |
| Debugging | 5 | Para detectar loops infinitos rápido |
Cada paso del grafo consume una unidad del recursion_limit. Un ciclo completo de model → tools cuenta como 2. Con el default de 25, el agente puede hacer hasta ~12 rondas de tool calling antes de detenerse.
Múltiples tools en acción
El poder real de los agentes aparece cuando tienen varias tools y deciden autónomamente cuál usar, en qué orden, y cuántas veces:
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 actualizada en internet."""
return f"Resultados para '{query}': México tiene 129 millones de habitantes y un PIB de USD 1.3 billones."
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática. Acepta expresiones Python válidas."""
return str(eval(expression))
@tool
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad."""
return f"El clima en {city} es nublado, 18°C, humedad 65%"
agent = create_agent("openai:gpt-4.1-mini", tools=[search, calculator, get_weather])
result = agent.invoke({
"messages": [("user",
"¿Cuál es la población de México, cuánto es su PIB per cápita "
"(PIB / población), y qué clima hace en su capital?"
)]
})
print(result["messages"][-1].content)
# Output esperado: México tiene 129 millones de habitantes. Su PIB es de
# USD 1.3 billones, lo que da un PIB per cápita de aproximadamente USD 10,078.
# En Ciudad de México el clima está nublado, con 18°C y 65% de humedad.
El agente hizo 4 cosas autónomamente: buscó la población, buscó el PIB, calculó el PIB per cápita, y consultó el clima. Tú solo hiciste la pregunta.
Comparación: loop manual vs create_agent
| Aspecto | Loop manual (Módulo 2) | create_agent |
|---|---|---|
| Líneas de código | ~15 | ~3 |
tool_map / while loop | Lo creas tú | Automático |
ToolMessage | Lo creas tú | Automático |
max_rounds | Lo controlas tú | recursion_limit en config |
| Error handling | try/except manual | Integrado |
| Streaming | Implementación custom | agent.stream() |
| Checkpointing | No disponible | Parámetro checkpointer |
¿Cuándo usar loop manual? Cuando necesitas control absoluto sobre cada paso (validar args antes de ejecutar, lógica custom entre rondas) o cuando estás aprendiendo cómo funciona tool calling internamente.
¿Cuándo usar create_agent? Para todo lo demás — prototipos, producción, y cualquier agente donde el flujo estándar ReAct sea suficiente.
Troubleshooting
Problema 1: "ImportError: cannot import name 'create_agent'"
Síntoma: Error al intentar importar create_agent de langchain.agents.
Causa: Tu versión de langchain es anterior a v1.2.
Solución:
pip install --upgrade langchain langgraph
Verifica la versión:
import langchain
print(langchain.__version__)
# Necesitas >= 1.2.0
Problema 2: GraphRecursionError
Síntoma: El agente lanza GraphRecursionError: Recursion limit of X reached.
Causa: El agente entró en un loop donde sigue llamando tools sin converger a una respuesta.
Solución: Aumentar recursion_limit si la tarea genuinamente requiere muchas rondas, o revisar tus tools para asegurarte de que sus respuestas son útiles y llevan al modelo a concluir:
result = agent.invoke(
{"messages": [("user", "pregunta compleja")]},
config={"recursion_limit": 50}
)
Problema 3: El agente no usa las tools
Síntoma: El modelo responde directamente sin llamar ninguna tool, incluso cuando debería. Causa: El modelo determinó que puede responder sin tools, o la descripción de la tool no es lo suficientemente clara. Solución: Mejora los docstrings de tus tools. El modelo decide qué tool usar basándose en la descripción de cada tool:
# Mal — descripción vaga
@tool
def search(q: str) -> str:
"""Busca cosas."""
return f"Resultado: {q}"
# Bien — descripción clara y específica
@tool
def search(query: str) -> str:
"""Busca información actualizada en internet. Úsala cuando el usuario pregunte
sobre datos que podrían haber cambiado: noticias, precios, eventos recientes,
o cualquier información que requiera datos en tiempo real."""
return f"Resultado: {query}"
Problema 4: "ModuleNotFoundError: No module named 'langgraph'"
Síntoma: Error al crear el agente.
Causa: langgraph no está instalado. create_agent lo necesita internamente.
Solución:
pip install langgraph
Problema 5: El agente es lento
Síntoma: El agente tarda mucho en responder.
Causa: Cada ronda del loop ReAct es una llamada al LLM. Si el agente hace 5 rondas, son 5 llamadas al modelo.
Solución: Usa un modelo más rápido (gpt-4.1-mini en vez de gpt-4.1), reduce el número de tools disponibles (menos opciones = decisión más rápida), o usa streaming para dar feedback progresivo al usuario (Cápsula 05).
Ejercicios
Ejercicio 1: Agente con una tool (Fácil)
Crea un agente con una tool get_population(country: str) que retorne la población de un país. Pruébalo con "¿Cuántas personas viven en Japón?" e imprime solo la respuesta final.
Ver solución
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def get_population(country: str) -> str:
"""Obtiene la población actual de un país."""
populations = {
"Japón": "125 millones",
"México": "129 millones",
"España": "47 millones",
"Argentina": "46 millones",
"Colombia": "52 millones",
}
return populations.get(country, f"No tengo datos de población para {country}")
agent = create_agent("openai:gpt-4.1-mini", tools=[get_population])
result = agent.invoke({"messages": [("user", "¿Cuántas personas viven en Japón?")]})
print(result["messages"][-1].content)
# Output esperado: Japón tiene aproximadamente 125 millones de habitantes.
Explicación: El agente recibe la pregunta, decide que necesita get_population, la ejecuta con country="Japón", recibe "125 millones", y genera la respuesta final.
Ejercicio 2: Agente con múltiples tools (Fácil)
Crea un agente con tres tools: search, calculator, y get_weather. Haz tres preguntas diferentes y verifica que el agente usa la tool correcta para cada una.
Ver solución
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 actualizada en internet."""
return f"Resultados para '{query}': Python fue creado por Guido van Rossum en 1991."
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática. Acepta expresiones Python válidas."""
return str(eval(expression))
@tool
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad."""
return f"El clima en {city} es nublado, 18°C"
agent = create_agent("openai:gpt-4.1-mini", tools=[search, calculator, get_weather])
questions = [
"¿Quién creó Python?",
"¿Cuánto es 256 * 48?",
"¿Qué clima hace en Buenos Aires?",
]
for q in questions:
result = agent.invoke({"messages": [("user", q)]})
print(f"P: {q}")
print(f"R: {result['messages'][-1].content}\n")
# Output esperado:
# P: ¿Quién creó Python?
# R: Python fue creado por Guido van Rossum en 1991.
#
# P: ¿Cuánto es 256 * 48?
# R: 256 × 48 = 12,288.
#
# P: ¿Qué clima hace en Buenos Aires?
# R: El clima en Buenos Aires es nublado, con una temperatura de 18°C.
Explicación: El agente selecciona autónomamente la tool correcta para cada pregunta: search para la pregunta de conocimiento, calculator para el cálculo, y get_weather para el clima.
Ejercicio 3: Inspeccionar el flujo completo (Medio)
Crea un agente y, después de ejecutarlo, imprime cada mensaje de la conversación mostrando su tipo y contenido. Cuenta cuántos tool calls hizo el agente en total.
Ver solución
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 actualizada en internet."""
return f"Resultados para '{query}': LangGraph es el framework de orquestación de LangChain."
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática."""
return str(eval(expression))
agent = create_agent("openai:gpt-4.1-mini", tools=[search, calculator])
result = agent.invoke({
"messages": [("user", "¿Qué es LangGraph y cuánto es 3**8?")]
})
total_tool_calls = 0
for i, msg in enumerate(result["messages"]):
msg_type = type(msg).__name__
if hasattr(msg, "tool_calls") and msg.tool_calls:
total_tool_calls += len(msg.tool_calls)
calls = [(tc["name"], tc["args"]) for tc in msg.tool_calls]
print(f" [{i}] {msg_type}: tool_calls={calls}")
elif msg.content:
print(f" [{i}] {msg_type}: {msg.content[:100]}")
else:
print(f" [{i}] {msg_type}: (sin contenido)")
print(f"\nTotal de tool calls: {total_tool_calls}")
# Output esperado:
# [0] HumanMessage: ¿Qué es LangGraph y cuánto es 3**8?
# [1] AIMessage: tool_calls=[('search', {'query': 'qué es LangGraph'}), ('calculator', {'expression': '3**8'})]
# [2] ToolMessage: Resultados para 'qué es LangGraph': LangGraph es el framework...
# [3] ToolMessage: 6561
# [4] AIMessage: LangGraph es el framework de orquestación de LangChain. Y 3^8 = 6,561.
#
# Total de tool calls: 2
Explicación: Iteramos sobre todos los mensajes y contamos los tool_calls en cada AIMessage. El agente hizo 2 tool calls en paralelo (search y calculator) en una sola ronda.
Ejercicio 4: Controlar recursion_limit (Medio)
Crea una tool que siempre pida buscar más información (simula un loop infinito). Ejecuta el agente con recursion_limit=6 y captura el error. Luego aumenta el límite y verifica que el agente eventualmente responde.
Ver solución
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
call_count = 0
@tool
def deep_search(query: str) -> str:
"""Busca información detallada. Siempre devuelve resultados parciales."""
global call_count
call_count += 1
if call_count >= 4:
return f"Información completa sobre '{query}': LangChain fue creado en 2022 por Harrison Chase."
return f"Resultado parcial {call_count} sobre '{query}'. Necesitas buscar más para obtener la respuesta completa."
agent = create_agent("openai:gpt-4.1-mini", tools=[deep_search])
# Test 1: límite bajo — debería fallar
call_count = 0
try:
result = agent.invoke(
{"messages": [("user", "¿Quién creó LangChain?")]},
config={"recursion_limit": 6}
)
print(f"Test 1 respondió: {result['messages'][-1].content}")
except Exception as e:
print(f"Test 1 — Error esperado: {type(e).__name__}")
# Output esperado: Test 1 — Error esperado: GraphRecursionError
# Test 2: límite alto — debería tener éxito
call_count = 0
result = agent.invoke(
{"messages": [("user", "¿Quién creó LangChain?")]},
config={"recursion_limit": 25}
)
print(f"Test 2 respondió: {result['messages'][-1].content}")
# Output esperado: Test 2 respondió: LangChain fue creado por Harrison Chase en 2022.
Explicación: Con recursion_limit=6, el agente no tiene suficientes iteraciones para completar 4 rondas de búsqueda (cada ronda = model + tools = 2 pasos). Con recursion_limit=25, tiene espacio suficiente.
Ejercicio 5: Agente que combina resultados (Avanzado)
Crea un agente con tools de search y calculator que pueda responder "¿Cuál es la población de México y España, y cuántos habitantes tienen en total?". El agente debe buscar ambos datos y luego sumarlos.
Ver solución
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 actualizada en internet. Ideal para datos demográficos y estadísticas."""
data = {
"población méxico": "La población de México es de 129,000,000 habitantes.",
"población españa": "La población de España es de 47,000,000 habitantes.",
}
query_lower = query.lower()
for key, value in data.items():
if key in query_lower:
return value
return f"No encontré datos específicos para '{query}'."
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática. Acepta expresiones Python válidas."""
return str(eval(expression))
agent = create_agent("openai:gpt-4.1-mini", tools=[search, calculator])
result = agent.invoke({
"messages": [("user",
"¿Cuál es la población de México y España, "
"y cuántos habitantes tienen en total?"
)]
})
print(result["messages"][-1].content)
# Output esperado: México tiene 129 millones de habitantes y España tiene
# 47 millones. En total, ambos países suman 176 millones de habitantes.
Explicación: El agente ejecutó múltiples rondas: primero buscó ambas poblaciones (parallel tool calls), luego llamó a calculator para sumar, y finalmente integró todo. Este es el poder del loop ReAct.
Ejercicio 6: Agente que responde sin tools (Challenge)
Crea un agente con tools disponibles, pero hazle preguntas que NO requieran tools. Verifica que el agente responde directamente comprobando que ningún mensaje tiene tool_calls.
Ver solución
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad."""
return f"El clima en {city} es soleado, 22°C"
@tool
def calculator(expression: str) -> str:
"""Calcula una expresión matemática."""
return str(eval(expression))
agent = create_agent("openai:gpt-4.1-mini", tools=[get_weather, calculator])
for q in ["¿Qué es la fotosíntesis?", "¿Cuál es la capital de Francia?"]:
result = agent.invoke({"messages": [("user", q)]})
used_tools = any(
hasattr(m, "tool_calls") and m.tool_calls for m in result["messages"]
)
print(f"P: {q}")
print(f" Mensajes: {len(result['messages'])} | Usó tools: {used_tools}")
print(f" R: {result['messages'][-1].content[:80]}\n")
# Output esperado:
# P: ¿Qué es la fotosíntesis?
# Mensajes: 2 | Usó tools: False
# R: La fotosíntesis es el proceso por el cual las plantas convierten la luz solar...
#
# P: ¿Cuál es la capital de Francia?
# Mensajes: 2 | Usó tools: False
# R: La capital de Francia es París.
Explicación: El modelo decide autónomamente que no necesita tools para responder preguntas de conocimiento general. Solo hay 2 mensajes (HumanMessage + AIMessage), sin tool calls intermedios.
Resumen
En esta cápsula aprendiste:
create_agent(model, tools)crea un agente que ejecuta el loop ReAct completo de forma autónoma- El agente acepta el modelo como string identifier (
"openai:gpt-4.1-mini") o como instancia de modelo - El output es un dict con key
"messages"que contiene toda la conversación (HumanMessage → AIMessage con tool_calls → ToolMessage → ... → AIMessage final) - Internamente,
create_agentconstruye un grafo de LangGraph con un model node y un tools node conectados en loop - Condiciones de parada: el modelo responde sin
tool_calls(parada natural) o se alcanza elrecursion_limit(safety net) - El
recursion_limitse pasa en config, no como parámetro decreate_agent:agent.invoke(input, config={"recursion_limit": N}) - El agente decide autónomamente qué tools usar, en qué orden, y cuántas veces — incluyendo parallel tool calls
- Si la pregunta no requiere tools, el agente responde directamente sin llamar ninguna
- Loop manual: para control total y aprendizaje. create_agent: para todo lo demás
Próxima cápsula: System Prompts Estáticos y Dinámicos — aprenderás a configurar el comportamiento del agente con system prompts que pueden ser fijos o cambiar según el contexto.
Recursos adicionales
- create_agent API Reference — Referencia completa con todos los parámetros
- LangChain Agents Overview — Guía conceptual oficial de agentes
- LangGraph Agents — Cómo create_agent construye grafos internamente
- ReAct Paper (Yao et al., 2022) — Paper original del patrón Reason + Act
- How to create a ReAct agent — Tutorial paso a paso con LangGraph
- Tool Calling — LangChain — Conceptos de tool calling que el agente usa internamente
- LangGraph Recursion Limit — Control de límites de iteración en grafos
- init_chat_model Reference — String identifiers para modelos
Módulo 3 — LangChain & LangGraph: From Chains to Agents