LangChain, LlamaIndex y LangGraph
Qué son LangChain, LlamaIndex y LangGraph, para qué sirve cada uno y cuándo no hacen falta: componentes y cadenas, índices sobre tus datos, grafos con estado, nodos y aristas, con una cadena y un grafo en Python y el caso de LinkedIn.
Definición
LangChain, LlamaIndex y LangGraph son frameworks (marcos de trabajo) de código abierto para construir aplicaciones con modelos de lenguaje. No son modelos: son librerías con piezas ya hechas para lo que casi toda app de IA necesita además de llamar al modelo: plantillas de prompts, conexión con distintos proveedores, lectura de documentos, búsqueda en bases vectoriales, uso de herramientas, memoria de la conversación, flujos de varios pasos y registro de lo que pasó.
Cada uno nació para un problema distinto:
| Framework | Problema principal | Idea central |
|---|---|---|
| LangChain | Encadenar pasos y conectar modelos, prompts y herramientas | La cadena (chain): la salida de un paso es la entrada del siguiente |
| LlamaIndex | Conectar la IA con tus datos (RAG, día 11) | Índices sobre documentos: cargar, fragmentar, indexar y consultar |
| LangGraph | Flujos con decisiones, ciclos y estado, como los de los agentes (día 13) | El grafo (graph): nodos que leen y modifican un estado común, unidos por aristas, algunas condicionales |
Empresas grandes los usan en producción: LinkedIn construyó con LangChain y LangGraph su SQL Bot, un asistente interno que convierte preguntas en lenguaje natural en consultas SQL sobre sus datos; Klarna construyó con LangGraph el asistente de atención a clientes del que hablamos en el día 13.
Cuándo hacen falta (y cuándo no)
| Tu aplicación | Recomendación |
|---|---|
| Una sola llamada al modelo (resumir un texto, clasificar un comentario) | SDK oficial del proveedor, sin framework. Menos dependencias y control total |
| Varios pasos fijos en orden (extraer → resumir → redactar) | Funciones propias o una cadena de LangChain |
| Preguntas sobre muchos documentos | LlamaIndex (o los módulos de RAG de LangChain) |
| Decisiones, reintentos, herramientas, pausas para aprobación humana | LangGraph u otro framework de agentes |
| Necesitas ver cada paso, costos y errores en producción | Plataformas de observabilidad (LangSmith, Langfuse; día 14) |
Los frameworks aceleran el arranque, pero añaden capas de abstracción, dependencias que cambian rápido y una curva de aprendizaje. Una regla práctica: empieza con la conexión directa y adopta el framework cuando el código propio empiece a reinventar sus piezas.
LangChain: componentes y cadenas
LangChain organiza una app en componentes intercambiables:
| Componente | Para qué sirve |
|---|---|
| Modelos de chat | Interfaz común para distintos proveedores: cambiar de modelo sin reescribir la app |
| Plantillas de prompt | Prompts con variables, mensajes de sistema y ejemplos (día 10) |
| Analizadores de salida (output parsers) | Convertir la respuesta en JSON o en objetos validados |
| Cargadores y divisores de documentos | Leer PDF, páginas web o bases de datos y cortarlos en fragmentos |
| Recuperadores (retrievers) | Buscar fragmentos relevantes en una base vectorial |
| Herramientas (tools) | Funciones que el modelo puede pedir ejecutar |
Las piezas se componen con LCEL (LangChain Expression Language), que usa el operador | para unirlas: plantilla, luego modelo, luego analizador. Cada pieza expone la misma interfaz (invoke, batch, stream), así que una cadena completa se ejecuta, procesa en lote o transmite token por token de la misma manera.
LlamaIndex: tus datos como índice
LlamaIndex se especializa en el flujo de RAG del día 11:
- Conectores de datos (data loaders, muchos disponibles en LlamaHub): PDF, Word, Notion, Google Drive, bases SQL.
- Nodos: los documentos se dividen en fragmentos con metadatos.
- Índices: el más común es el índice vectorial; también hay índices de resumen, de palabras clave y de grafos de conocimiento.
- Motores de consulta (query engines) y de conversación (chat engines): reciben la pregunta, recuperan los nodos y generan la respuesta con sus fuentes.
Su valor está en los detalles que en un RAG casero se resuelven a mano: leer bien cada formato, fragmentar respetando la estructura, combinar varios índices y devolver las fuentes de cada respuesta.
LangGraph: estado, nodos y aristas
LangGraph modela la aplicación como un grafo de estados:
| Concepto | Qué es |
|---|---|
| Estado (state) | Un objeto compartido (por ejemplo, un diccionario tipado) con todo lo que el flujo sabe: mensajes, datos encontrados, intentos |
| Nodo (node) | Una función que recibe el estado y devuelve cambios: llamar al modelo, ejecutar una herramienta, validar |
| Arista (edge) | La conexión entre nodos. Las condicionales eligen el siguiente nodo según el estado |
| Ciclos | Una arista puede volver a un nodo anterior: reintentar, pedir más información, iterar hasta cumplir una condición |
| Puntos de control (checkpointing) | Guardan el estado en cada paso: permiten pausar, reanudar, recuperar tras un error o esperar la aprobación humana |
A diferencia de una cadena, que siempre recorre los mismos pasos, un grafo decide su camino en cada ejecución. Por eso es la base habitual de los agentes (día 13): el ciclo «pensar → usar herramienta → revisar» es un grafo con un ciclo y una condición de salida.
Alternativas
El ecosistema cambia rápido. Además de estos tres, existen los SDK de agentes de los propios proveedores (OpenAI, Anthropic, Google), frameworks multiagente como CrewAI o AutoGen, Haystack para búsqueda y RAG, y Semantic Kernel en el ecosistema de Microsoft. Antes de elegir, conviene revisar en la documentación oficial el estado actual del proyecto, su licencia y la frecuencia con la que cambia su API.
Práctica: una cadena y un grafo en Python puro
Para ver el mecanismo sin instalar nada, este script implementa los dos patrones con la biblioteca estándar. modelo() simula un LLM con reglas fijas, así el resultado es siempre el mismo; en un proyecto real se sustituye por la llamada a la API.
1. Guarda el script como cadena_y_grafo.py:
"""Cadena y grafo en Python puro: los dos patrones que empaquetan LangChain y LangGraph.
`modelo()` simula un LLM con reglas fijas para que el ejemplo sea reproducible sin llaves ni internet.
En un proyecto real se sustituye por la llamada a la API de tu proveedor.
"""
from typing import Callable
CORREO = "Hola, el pedido 4821 llegó incompleto: faltan 2 sartenes. ¿Me lo pueden reponer?"
def modelo(instruccion: str, texto: str) -> str:
# LLM simulado: responde según la instrucción, para que la salida sea siempre la misma.
if instruccion == "resume":
return "Cliente reporta pedido 4821 incompleto (faltan 2 sartenes) y pide reposición."
if instruccion == "clasifica":
return "queja" if "faltan" in texto or "incompleto" in texto else "otro"
if instruccion == "redacta":
return f"Lamentamos el problema. Ya registramos tu caso: {texto}"
return ""
# ---------- 1. Cadena (chain): pasos fijos, la salida de uno es la entrada del siguiente ----------
def cadena(*pasos: Callable[[str], str]) -> Callable[[str], str]:
def ejecutar(entrada: str) -> str:
for paso in pasos:
entrada = paso(entrada)
return entrada
return ejecutar
resumir = lambda t: modelo("resume", t)
redactar = lambda t: modelo("redacta", t)
responder_correo = cadena(resumir, redactar) # en LangChain: prompt | modelo | parser
# ---------- 2. Grafo (graph): nodos con un estado compartido, decisiones y vueltas atrás ----------
def grafo(estado: dict) -> dict:
nodo = "clasificar"
while nodo != "FIN":
estado["traza"].append(nodo)
if nodo == "clasificar":
estado["tipo"] = modelo("clasifica", estado["correo"])
nodo = "buscar_pedido" if estado["tipo"] == "queja" else "FIN" # arista condicional
elif nodo == "buscar_pedido":
estado["intentos"] += 1
# simula un sistema que falla la primera vez: el grafo regresa y reintenta
estado["pedido"] = None if estado["intentos"] == 1 else {"id": 4821, "faltan": 2}
nodo = "buscar_pedido" if estado["pedido"] is None and estado["intentos"] < 3 else "responder"
elif nodo == "responder":
estado["respuesta"] = redactar(resumir(estado["correo"]))
nodo = "FIN"
return estado
if __name__ == "__main__":
print("CADENA:", responder_correo(CORREO))
final = grafo({"correo": CORREO, "traza": [], "intentos": 0})
print("GRAFO, recorrido:", " -> ".join(final["traza"]))
print("GRAFO, intentos para encontrar el pedido:", final["intentos"])
print("GRAFO, respuesta:", final["respuesta"])
2. Ejecútalo: python cadena_y_grafo.py. Salida real (Python 3.12, Windows):
CADENA: Lamentamos el problema. Ya registramos tu caso: Cliente reporta pedido 4821 incompleto (faltan 2 sartenes) y pide reposición.
GRAFO, recorrido: clasificar -> buscar_pedido -> buscar_pedido -> responder
GRAFO, intentos para encontrar el pedido: 2
GRAFO, respuesta: Lamentamos el problema. Ya registramos tu caso: Cliente reporta pedido 4821 incompleto (faltan 2 sartenes) y pide reposición.
3. Interpreta el resultado. La cadena siempre ejecuta resumir y luego redactar. El grafo, en cambio, decide: clasifica el correo, y como es una queja va a buscar_pedido; la primera búsqueda falla, así que la arista condicional regresa al mismo nodo y reintenta antes de responder. La traza (clasificar -> buscar_pedido -> buscar_pedido -> responder) es justo lo que LangGraph registra en cada ejecución.
4. Pásalo a los frameworks. Con LangChain, cadena(resumir, redactar) se escribe uniendo una plantilla, un modelo y un analizador con |. Con LangGraph, cada rama del if se vuelve un nodo (add_node), las transiciones fijas son add_edge y las decisiones son add_conditional_edges; el diccionario estado se declara como el estado tipado del grafo. Sigue los tutoriales oficiales de las referencias, que muestran la instalación y el código actualizados de cada versión.
Preguntas frecuentes
¿Qué es LangChain en palabras simples?
Es una librería con piezas listas para construir apps con IA: conectar modelos, prompts, documentos y herramientas, y encadenar varios pasos.
¿Cuál es la diferencia entre LangChain y LangGraph?
LangChain encadena pasos fijos. LangGraph arma flujos con decisiones, ciclos y estado guardado, y por eso se usa para agentes que reintentan, eligen herramientas o esperan la aprobación de una persona.
¿Para qué sirve LlamaIndex?
Para conectar una IA con tus documentos y datos: los lee, los fragmenta, los indexa y responde preguntas con las fuentes. Es la caja de herramientas del RAG.
¿Necesito un framework para usar la API de ChatGPT o Claude?
No. Para una o pocas llamadas al modelo basta el SDK oficial del proveedor. Los frameworks convienen cuando la app tiene varios pasos, muchos documentos o agentes.
En el reel lo explicamos así
Para armar una app con IA nadie empieza de cero: se usan cajas de piezas de construcción, una para el chasis, otra para las ruedas, otra para el motor. LangChain encadena pasos (lee el correo, lo resume y redacta la respuesta: una cadena). LlamaIndex conecta tus datos: es la caja del RAG. LangGraph arma flujos con decisiones: si falta algo, regresa y lo intenta otra vez (un grafo). Con LangChain y LangGraph, LinkedIn armó un bot que convierte preguntas en consultas a sus datos. Y si tu app solo hace una pregunta a la IA, basta la conexión directa.
Referencias
- Documentación de LangChain: componentes, LCEL e integraciones.
- Documentación de LangGraph: estado, nodos, aristas, puntos de control y aprobación humana.
- Documentación de LlamaIndex: conectores, índices y motores de consulta.
- LinkedIn Engineering, «Practical text-to-SQL for data analytics»: el SQL Bot construido con LangChain y LangGraph.
- LangChain, Caso Klarna: asistente de atención a clientes construido con LangGraph y LangSmith.
- Anthropic, «Building effective agents»: cuándo usar flujos fijos, cuándo agentes y cuándo prescindir de frameworks.
Cajas de piezas de construcción: unas para el chasis, otras para las ruedas, otras para el motor.
Glosario: del inglés al español
| Framework | marco de trabajo |
|---|---|
| Library | librería (código reutilizable) |
| Chain | cadena de pasos |
| Graph | grafo (mapa de pasos con caminos) |