Cómo Construir Agentes IA con LangChain: Tutorial Completo 2026
Tutorial paso a paso para construir agentes IA listos para producción con LangChain. Desde setup hasta despliegue con herramientas, memoria, evaluación y manejo de errores.
Lo Que Vas a Construir
Al final de este tutorial, tendrás un agente IA funcional capaz de:
- Buscar en la web información en tiempo real
- Consultar una base de datos para datos estructurados
- Mantener memoria de conversación entre sesiones
- Manejar errores con lógica de reintento
- Desplegarse en producción con monitoreo apropiado
Esto no es una demo "hello world". Es un patrón de agente listo para producción que puedes adaptar para aplicaciones reales.
"La mejor forma de aprender agentes IA es construir uno que resuelva un problema real."
Requisitos previos:
- Python 3.10+
- Comprensión básica de LLMs y prompts
- Clave API de OpenAI (o Anthropic/otros proveedores)
- 30 minutos de tiempo concentrado
Paso 1: Configuración del Proyecto
Primero, crea la estructura de tu proyecto e instala las dependencias.
# Crear directorio del proyecto
mkdir langchain-agent && cd langchain-agent
# Crear entorno virtual
python -m venv venv
source venv/bin/activate # En Windows: venv\Scripts\activate
# Instalar dependencias
pip install langchain langchain-openai langchain-community
pip install python-dotenv tavily-python chromadb
Crea tu archivo .env para las claves API:
# .env
OPENAI_API_KEY=tu-clave-openai
TAVILY_API_KEY=tu-clave-tavily # Para búsqueda web
Crea la estructura principal del proyecto:
langchain-agent/
├── .env
├── agent.py # Lógica principal del agente
├── tools.py # Herramientas personalizadas
├── memory.py # Configuración de memoria
├── evaluation.py # Pruebas y evaluación
└── requirements.txt
Paso 2: Tu Primer Agente
Construyamos un agente simple que pueda responder preguntas usando búsqueda web.
# agent.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import PromptTemplate
load_dotenv()
# Inicializar el LLM
llm = ChatOpenAI(
model="gpt-4o",
temperature=0,
max_tokens=1000
)
# Inicializar herramientas
search_tool = TavilySearchResults(
max_results=3,
search_depth="advanced"
)
tools = [search_tool]
# Definir el prompt del agente
template = """Eres un asistente IA útil con acceso a búsqueda web.
Responde la pregunta del usuario usando las herramientas disponibles. Siempre cita tus fuentes.
Tienes acceso a las siguientes herramientas:
{tools}
Usa el siguiente formato:
Question: la pregunta que debes responder
Thought: siempre debes pensar qué hacer
Action: la acción a tomar, debe ser una de [{tool_names}]
Action Input: la entrada de la acción
Observation: el resultado de la acción
... (este ciclo Thought/Action/Action Input/Observation puede repetirse N veces)
Thought: Ahora conozco la respuesta final
Final Answer: la respuesta final a la pregunta original
¡Comienza!
Question: {input}
{agent_scratchpad}
"""
prompt = PromptTemplate.from_template(template)
# Crear el agente
agent = create_react_agent(llm, tools, prompt)
# Crear el ejecutor con manejo de errores
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
handle_parsing_errors=True,
max_iterations=5
)
# Probar el agente
if __name__ == "__main__":
result = agent_executor.invoke({
"input": "¿Cuáles son los últimos desarrollos en agentes IA en enero 2026?"
})
print(result["output"])
Ejecuta tu agente:
python agent.py
Deberías ver al agente razonando sobre el problema, buscando en la web y proporcionando una respuesta con fuentes.
Paso 3: Agregar Herramientas Personalizadas
Los agentes reales necesitan herramientas personalizadas para tareas específicas. Agreguemos una herramienta de consulta de base de datos.
# tools.py
from langchain.tools import tool
import json
# Base de datos simulada (reemplazar con conexión real)
MOCK_DATABASE = {
"users": [
{"id": 1, "name": "Alice", "role": "engineer", "projects": 5},
{"id": 2, "name": "Bob", "role": "designer", "projects": 3},
{"id": 3, "name": "Charlie", "role": "manager", "projects": 8},
],
"projects": [
{"id": 1, "name": "AI Dashboard", "status": "active", "team_size": 4},
{"id": 2, "name": "Data Pipeline", "status": "completed", "team_size": 3},
{"id": 3, "name": "Mobile App", "status": "planning", "team_size": 2},
]
}
@tool
def query_database(query: str) -> str:
"""
Consulta la base de datos interna para información de usuarios y proyectos.
Args:
query: Consulta en lenguaje natural como "lista todos los ingenieros" o "proyectos activos"
Returns:
Cadena JSON con resultados de la consulta
"""
query_lower = query.lower()
if "user" in query_lower or "engineer" in query_lower or "designer" in query_lower:
if "engineer" in query_lower:
results = [u for u in MOCK_DATABASE["users"] if u["role"] == "engineer"]
elif "designer" in query_lower:
results = [u for u in MOCK_DATABASE["users"] if u["role"] == "designer"]
else:
results = MOCK_DATABASE["users"]
return json.dumps({"type": "users", "count": len(results), "data": results})
if "project" in query_lower:
if "active" in query_lower:
results = [p for p in MOCK_DATABASE["projects"] if p["status"] == "active"]
elif "completed" in query_lower:
results = [p for p in MOCK_DATABASE["projects"] if p["status"] == "completed"]
else:
results = MOCK_DATABASE["projects"]
return json.dumps({"type": "projects", "count": len(results), "data": results})
return json.dumps({"error": "Consulta no entendida. Intenta preguntar sobre usuarios o proyectos."})
Paso 4: Implementar Memoria
Los agentes sin memoria olvidan todo entre conversaciones. Agreguemos memoria persistente.
# memory.py
from langchain.memory import ConversationBufferWindowMemory
from langchain_community.chat_message_histories import SQLChatMessageHistory
def create_memory(session_id: str, window_size: int = 10):
"""
Crea una instancia de memoria con historial de conversación.
Args:
session_id: Identificador único para la conversación
window_size: Número de mensajes recientes a mantener en contexto
Returns:
Instancia de memoria configurada
"""
message_history = SQLChatMessageHistory(
session_id=session_id,
connection_string="sqlite:///chat_history.db"
)
memory = ConversationBufferWindowMemory(
chat_memory=message_history,
k=window_size,
return_messages=True,
memory_key="chat_history"
)
return memory
Paso 5: Agregar RAG (Retrieval-Augmented Generation)
Para agentes que necesitan responder preguntas de documentos, agrega capacidades RAG.
# rag.py
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.tools import tool
embeddings = OpenAIEmbeddings()
vectorstore = None
def initialize_vectorstore(documents_path: str):
"""Carga documentos y crea el vector store."""
global vectorstore
loader = TextLoader(documents_path)
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
splits = text_splitter.split_documents(documents)
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db"
)
return vectorstore
@tool
def search_documents(query: str) -> str:
"""
Busca en documentos internos información relevante.
Args:
query: La consulta de búsqueda
Returns:
Extractos de documentos relevantes
"""
if vectorstore is None:
return "Document store no inicializado."
results = vectorstore.similarity_search(query, k=3)
if not results:
return "No se encontraron documentos relevantes."
formatted_results = []
for i, doc in enumerate(results, 1):
formatted_results.append(f"[{i}] {doc.page_content[:500]}...")
return "\n\n".join(formatted_results)
Paso 6: Manejo de Errores y Lógica de Reintento
Los agentes en producción necesitan manejo de errores robusto.
# error_handling.py
import time
from functools import wraps
def retry_with_backoff(max_retries: int = 3, base_delay: float = 1.0):
"""Decorador para lógica de reintento con backoff exponencial."""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
retries = 0
while retries < max_retries:
try:
return func(*args, **kwargs)
except Exception as e:
retries += 1
if retries == max_retries:
raise e
delay = base_delay * (2 ** retries)
print(f"Intento {retries} falló: {e}. Reintentando en {delay}s...")
time.sleep(delay)
return None
return wrapper
return decorator
Paso 7: Evaluación y Pruebas
Nunca despliegues un agente sin pruebas. Así es como evalúas tu agente.
# evaluation.py
from dataclasses import dataclass
from typing import List
@dataclass
class TestCase:
input: str
expected_action: str
expected_keywords: List[str]
min_confidence: float = 0.7
TEST_CASES = [
TestCase(
input="¿Cuántos ingenieros tenemos?",
expected_action="query_database",
expected_keywords=["engineer", "user"]
),
TestCase(
input="¿Cuáles son las últimas noticias sobre LangChain?",
expected_action="tavily_search",
expected_keywords=["LangChain"]
),
]
def run_evaluation(agent_executor, test_cases: List[TestCase]) -> dict:
"""Ejecuta la suite de evaluación en el agente."""
results = {"total": len(test_cases), "passed": 0, "failed": 0, "details": []}
for test in test_cases:
try:
response = agent_executor.invoke({"input": test.input})
output = response.get("output", "").lower()
keywords_found = sum(1 for kw in test.expected_keywords if kw.lower() in output)
keyword_score = keywords_found / len(test.expected_keywords)
passed = keyword_score >= test.min_confidence
results["details"].append({"test": test.input, "passed": passed})
results["passed" if passed else "failed"] += 1
except Exception as e:
results["failed"] += 1
results["details"].append({"test": test.input, "passed": False, "error": str(e)})
results["pass_rate"] = results["passed"] / results["total"]
return results
Paso 8: Desplegar a Producción
Aquí hay un despliegue simple con FastAPI.
# api.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn
from agent import agent_executor
app = FastAPI(title="API Agente IA")
class QueryRequest(BaseModel):
query: str
session_id: str = "default"
@app.post("/query")
async def query_agent(request: QueryRequest):
"""Envía una consulta al agente IA."""
try:
result = agent_executor.invoke({"input": request.query})
return {"response": result["output"], "session_id": request.session_id}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health_check():
return {"status": "healthy"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Errores Comunes y Soluciones
Error: "Agent stopped due to max iterations"
Causa: El agente está atascado en un bucle o tomando demasiados pasos.
Solución: Aumenta max_iterations o mejora tu prompt.
Error: "Could not parse LLM output"
Causa: La respuesta del LLM no coincide con el formato esperado.
Solución: Habilita el manejo de errores:
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
handle_parsing_errors=True
)
Error: "Rate limit exceeded"
Causa: Demasiadas llamadas API en poco tiempo.
Solución: Agrega caching:
from langchain.cache import SQLiteCache
from langchain.globals import set_llm_cache
set_llm_cache(SQLiteCache(database_path=".langchain.db"))
FAQ
P: ¿Qué LLM usar?
Para agentes, usa modelos con razonamiento fuerte: GPT-4o, Claude 3.5 Sonnet, o Gemini 1.5 Pro.
P: ¿Cómo reducir costos?
- Cachea respuestas con
set_llm_cache() - Limita el tamaño de la ventana de memoria
- Define
max_iterationsapropiadamente
P: ¿Puedo usar modelos locales?
¡Sí! Usa Ollama:
from langchain_community.llms import Ollama
llm = Ollama(model="llama3.1:70b")
¿Qué Sigue?
Ahora tienes un agente IA listo para producción. Aquí están los siguientes pasos:
- Agrega más herramientas - Conéctate a tus APIs y bases de datos
- Implementa barreras - Agrega verificaciones de seguridad
- Configura monitoreo - Rastrea uso, errores y costos
- Construye una UI - Conecta a un frontend o Slack/Discord
Guías relacionadas
Continúa tu viaje con agentes IA:
- Por qué fallan los agentes IA (y cómo arreglarlos) — Depura fallos de agentes en producción.
- Guía de Batalla del Orquestador IA 2026 — Pasa de agentes simples a sistemas multi-agente.
- Flujos de trabajo de desarrolladores con IA — Compara herramientas para construir con IA.
Si este tutorial te ayudó a construir tu primer agente, compártelo con otro desarrollador. La mejor forma de aprender es construyendo.
Construir con IA y entregar bien
Necesitas un desarrollador capaz de llevar una idea a produccion?
Ayudo a equipos a entregar trabajo en React, Next.js, Node.js, IA y automatizacion con alcance claro, guardrails utiles y ejecucion rapida.
Articulos relacionados
Construyendo SmartDAM: un gestor de activos digitales con IA para fotografía gastronómica
Cómo desarrollé SmartDAM — una app Flask que analiza fotos de comida automáticamente vía HuggingFace, genera etiquetas multilingües, soporta Azure Blob Storage y ofrece búsqueda en tiempo real.
Cómo funcionan realmente los agentes de IA: arquitectura, memoria, herramientas y el bucle del agente
Guía técnica sobre la arquitectura de un agente de IA: bucle del agente, herramientas, memoria (RAG/vector DB), evaluación y fallos comunes en producción.
Por qué todos hablan de los centros de comando de agentes en 2026
Los centros de comando convierten los agentes IA en flujos reales. Esto es lo que GitHub y OpenAI acaban de lanzar y por qué la productividad va a cambiar.
