
El desarrollo con modelos grandes de lenguaje (LLM) generalmente comienza con un simple ciclo de petición-respuesta. Pero en cuanto la tarea va más allá de un chatbot y requiere que el modelo realice acciones reales —como integrar herramientas externas (tools), trabajar con bases de datos o acceder al sistema de archivos— nos encontramos con un desafío fundamental. La API estándar de un modelo es stateless (sin estado) por naturaleza y carece de mecanismos integrados para gestionar lógica compleja.
Una tarea aparentemente simple como «analiza este archivo, encuentra datos relevantes en internet y genera un informe» se convierte en un complejo desafío de orquestación:
- ¿Cómo se gestiona el estado y se pasa el contexto entre múltiples llamadas al LLM?
- ¿Cómo se implementa una lógica cíclika, donde un agente interactúa repetidamente con herramientas hasta alcanzar un objetivo?
- ¿Cómo se estandarizan las conexiones a diferentes modelos (OpenAI, Gemini, locales) y herramientas sin tener que reescribir el código cada vez?
Para simplificar el desarrollo de dichos sistemas y proporcionar a los desarrolladores un enfoque estandarizado para este desafío de orquestación, se crearon los frameworks LangChain y LangGraph:
- LangChain proporciona un kit de herramientas unificado: interfaces estandarizadas para los modelos, componentes para prompts y herramientas.
- LangGraph es un framework construido sobre LangChain que te permite construir la lógica de toma de decisiones del agente como un grafo de estados, resolviendo elegantemente el problema de los ciclos y las bifurcaciones.
Para entender mejor sus roles, usemos una analogía.
Imagina que estás construyendo algo con LEGO. Tienes bloques individuales (motores, ruedas, ladrillos), pero por sí solos, son solo piezas. Para montar una máquina que funcione, necesitas un manual de instrucciones y entender cómo conectar estas piezas.
En el mundo de los agentes de IA:
- LangChain es tu set de bloques de LEGO de alta tecnología.
- LangGraph es el manual de instrucciones avanzado que te permite ensamblar estos bloques no solo en modelos estáticos, sino en mecanismos dinámicos e «inteligentes» capaces de tomar decisiones.
…
Analicemos cada una de estas herramientas por separado.
Parte 1: LangChain — La caja de herramientas para trabajar con LLMs
El objetivo principal de LangChain: simplificar y estandarizar la interacción entre tu código y los Modelos Grandes de Lenguaje (LLMs). Proporciona componentes listos para usar («bloques») para resolver tareas comunes.
Componentes clave de LangChain (Nuestros «bloques»):
1. Modelos (Models)
Son abstracciones (o «wrappers») para interactuar directamente con las redes neuronales. LangChain los divide en dos tipos:
LLMs: La interfaz antigua. Recibe una cadena de texto como entrada y devuelve una cadena de texto.- Ejemplo:
llm.invoke("¿De qué color es el cielo?")→"El cielo es azul."
- Ejemplo:
ChatModels: La interfaz moderna y más potente. Funciona con una lista de mensajes (HumanMessage,AIMessage,SystemMessage). Esto permite que el modelo entienda mejor el contexto de una conversación.- Ejemplo:
chat.invoke([HumanMessage(content="¿De qué color es el cielo?")])→AIMessage(content="El cielo suele ser azul...")
- Ejemplo:
LangChain unifica la API. No necesitas aprender a trabajar con OpenAI, Gemini o un Ollama local por separado. Simplemente cambias un objeto como
ChatOpenAIporChatGoogleGenerativeAIoChatOllama, y el resto de tu código sigue funcionando.
2. Prompts (Plantillas)
Son plantillas para tus peticiones al modelo. En lugar de construir manualmente el texto de la petición cada vez, creas una plantilla con variables.
from langchain_core.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
("system", "Eres un asistente útil que traduce texto a {output_language}."),
("human", "{text_to_translate}")
])
prompt_value = template.invoke({"output_language": "francés", "text_to_translate": "Me encanta programar."})
Los prompts hacen que tus peticiones sean reproducibles, seguras y fáciles de modificar. Separas la lógica de formar la petición de la lógica de llamar al modelo.
3. Cadenas (Chains y el lenguaje LCEL)
Este es el corazón del LangChain inicial. Una cadena es una conexión secuencial de varios componentes. Hoy en día, para esto se utiliza el Lenguaje de Expresión de LangChain (LCEL), que se ve como una tubería (|).
La cadena más simple: prompt | modelo.
chain = template | get_gemini_llm()
response = chain.invoke({"output_language": "alemán", "text_to_translate": "¡Hola, mundo!"})
# response.content contendrá "Hallo, Welt!"
Las cadenas te permiten crear flujos de trabajo sencillos. Por ejemplo, primero obtener datos del usuario, luego formar un prompt, enviarlo al modelo y, finalmente, procesar la respuesta.
4. Analizadores de Salida (Output Parsers)
Los modelos devuelven texto, pero en las aplicaciones a menudo necesitamos datos estructurados (JSON, una lista, un número). Los analizadores (o «parsers») convierten la respuesta de texto «en crudo» del modelo al formato deseado.
from langchain_core.output_parsers import JsonOutputParser
# ... creamos un prompt que le pide al modelo que responda en formato JSON
parser = JsonOutputParser()
chain = template | get_openai_llm() | parser
# Ahora chain.invoke(...) no devolverá un objeto de texto, sino un diccionario de Python (dict)
Para que tu código pueda trabajar programáticamente con el resultado. En lugar de intentar extraer los datos necesarios de una cadena de texto, obtienes directamente un objeto listo para usar.
5. Herramientas (Tools)
Esto es lo que le da «manos» al modelo. Una herramienta es cualquier función que un agente puede llamar. Podría ser:
- Una búsqueda en internet (
TavilySearch,BraveSearch). - Una calculadora.
- Una función para leer un archivo del disco.
- Una llamada a tu API interna.
Un modelo por sí solo no sabe qué tiempo hace hoy o qué está escrito en tu archivo
informe.docx. Las herramientas son la única forma que tiene de acceder a información externa y realizar acciones en el mundo real.
Parte 2: LangGraph — El Orquestador para crear agentes
Si LangChain es el conjunto de piezas, LangGraph es el sistema de control que decide qué pieza usar y en qué momento.
El problema que resuelve LangGraph: Las cadenas clásicas (chains) en LangChain son lineales. Van del punto A al punto B. Pero las tareas reales no son lineales. Requieren ciclos, bifurcaciones y toma de decisiones.
Por ejemplo, un agente de investigación debe:
- Entender la petición.
- Decidir: ¿Es necesario buscar en internet?
- Si es así → usar la herramienta de búsqueda.
- Analizar los resultados.
- Decidir: ¿La información es suficiente?
- Si no es así → volver al paso 3 con una consulta más específica (esto es un ciclo).
- Si es así → generar la respuesta final.
Una lógica tan compleja no se puede describir con una simple cadena.
La idea central de LangGraph: representar el funcionamiento de un agente como un grafo de estados (o un diagrama de flujo).
Componentes clave de LangGraph (Elementos del diagrama de flujo):
1. Estado (State)
Esta es la memoria central de todo el proceso. Normalmente es un diccionario de Python (TypedDict) que se pasa de un paso a otro. Cada paso puede leer datos de él y escribir nuevos datos en él.
Ejemplo de estado:
{"user_request": "...", "search_results": [], "final_answer": None}.
2. Nodos (Nodes)
Estos son los bloques de acción en tu diagrama de flujo. Cada nodo es una función de Python que:
- Recibe el
estadoactual como entrada. - Realiza alguna acción (llama a un LLM, usa una herramienta).
- Devuelve el
estadoactualizado.
Ejemplos de nodos:
call_model_node,execute_tool_node,analyze_results_node.
3. Aristas (Edges)
Estas son las flechas que conectan los nodos. Determinan qué nodo se ejecutará a continuación. Hay dos tipos de aristas:
- Aristas Normales: Simplemente conectan el nodo A con el nodo B. Después de que A termine, siempre se ejecutará B.
- Aristas Condicionales (
Conditional Edges): Esta es la parte más importante. Después del nodo A, se ejecuta una función especial «enrutadora» que mira elestadoactual y decide a dónde ir a continuación: al nodo B, C o D.
Ejemplo de arista condicional:
- Después de llamar al modelo (el nodo
agent_node), revisamos elestado.- Si la respuesta del modelo incluye una llamada a una herramienta → vamos al nodo
execute_tool_node.- Si no hay llamada a una herramienta → vamos al nodo final
END.
LangChain vs. LangGraph: ¿Cuándo usar cada uno?
| Criterio | LangChain (Cadenas LCEL) | LangGraph |
|---|---|---|
| Caso de uso principal | Tareas simples y lineales | Tareas complejas y cíclicas (agentes) |
| Estructura | Tubería (A → B → C) | Grafo (diagrama de flujo con bifurcaciones y ciclos) |
| Flujo de control | Determinista, predefinido | Dinámico, se determina en tiempo de ejecución |
| Ejemplo de tarea | 1. Tomar un texto. 2. Resumirlo. 3. Traducirlo a otro idioma. | 1. Recibir una pregunta. 2. Buscar en internet hasta encontrar una respuesta. 3. Resumir los hallazgos y responder. |
| Analogía | Una línea de montaje en una fábrica | Un equipo de personas deliberando y tomando decisiones |
Uniendo todas las piezas
- La entrada del usuario llega al Estado inicial de LangGraph.
- El Nodo «Agente» recibe el estado. Dentro de este nodo hay una cadena de LangChain (
prompt | modelo | parser). El modelo, usando las Herramientas de LangChain, decide qué hacer a continuación (p. ej., «llamar a la búsqueda»). Su decisión se escribe en el Estado. - Una Arista Condicional analiza el estado y dirige el flujo hacia el Nodo «Ejecutor de Herramientas».
- Este nodo realiza la llamada real a la herramienta (p. ej., hace una búsqueda web) y escribe el resultado de vuelta en el Estado.
- El flujo regresa al Nodo «Agente» (esto es un ciclo). Ahora el modelo ve el resultado de la búsqueda y toma una nueva decisión.
- El ciclo se repite hasta que el modelo decide que la tarea está completa. Entonces, la Arista Condicional dirigirá el flujo hacia el final.