LangGraph en Python: Construye Agentes LLM Robustos y Flujos de Trabajo Complejos

LangGraph en Python: Construye Agentes LLM Robustos y Flujos de Trabajo Complejos

SEIGG3 de febrero de 202611 min de lectura

¿Alguna vez te has enfrentado al desafío de construir aplicaciones basadas en LLMs que necesitan más que simples cadenas lineales? Los agentes autónomos, los sistemas multi-agente y los flujos de trabajo iterativos con memoria y lógica condicional son el futuro de la IA, pero su implementación puede ser un dolor de cabeza. ¿Cómo gestionas el estado, los bucles y las decisiones dinámicas de forma eficiente y escalable? LangGraph es la respuesta.

TL;DR: LangGraph es una biblioteca de Python construida sobre LangChain que permite crear flujos de trabajo de agentes LLM complejos, cíclicos y con estado. Facilita la construcción de sistemas multi-agente, agentes ReAct y flujos iterativos mediante la modelización de estos procesos como grafos dirigidos con estado persistente. Ideal para aplicaciones avanzadas de IA que requieren control de flujo, memoria y decisiones dinámicas.

¿Qué es LangGraph?

LangGraph es una extensión de LangChain diseñada para construir aplicaciones de lenguaje complejas que requieren lógica de control de flujo, estado y ciclos. Mientras que LangChain sobresale en la creación de cadenas lineales y herramientas para LLMs, LangGraph eleva esta capacidad al permitir modelar el flujo de ejecución como un grafo dirigido. Esto significa que puedes definir nodos (pasos, agentes, herramientas) y aristas (transiciones condicionales) que dictan cómo se mueve la ejecución a través de tu aplicación, permitiendo bucles, ramificaciones y una gestión de estado explícita. Es fundamental para construir agentes autónomos que necesitan interactuar, decidir y recordar.

Tecnologías y Componentes Clave

LangGraph se basa en conceptos de programación de grafos y extiende el ecosistema de LangChain. Sus componentes principales incluyen:

  • Grafo Dirigido Acíclico (DAG) y Cíclico: Aunque los grafos pueden ser cíclicos, LangGraph permite definir flujos que pueden volver a nodos anteriores, crucial para agentes iterativos.
  • Nodos: Representan unidades de trabajo en el grafo. Pueden ser LLMs, herramientas, otros agentes, o funciones Python personalizadas. Cada nodo recibe el estado actual y lo devuelve modificado.
  • Aristas (Edges): Definen las transiciones entre nodos. Pueden ser incondicionales (siempre van de A a B) o condicionales (la transición depende del resultado de un nodo o del estado actual).
  • Estado (State): El corazón de LangGraph. Es un objeto mutable que se pasa de nodo en nodo. Cada nodo puede leer o actualizar este estado. LangGraph utiliza un GraphState que es una TypedDict para definir la estructura del estado.
  • Checkpoints/Persistencia: LangGraph permite guardar y cargar el estado del grafo en cualquier punto, facilitando la depuración, la reanudación de ejecuciones y la construcción de aplicaciones con memoria a largo plazo.
  • Agentes: Un tipo especial de nodo que utiliza un LLM para razonar y decidir qué acción tomar a continuación, a menudo interactuando con herramientas. LangGraph facilita la implementación de patrones como ReAct (Reasoning and Acting).
  • Herramientas (Tools): Funciones o APIs que los agentes pueden invocar para interactuar con el mundo exterior (bases de datos, APIs web, etc.).

¿Por qué LangGraph? La Necesidad de Flujos de Trabajo Robustos

Las aplicaciones de LLMs simples con cadenas lineales tienen limitaciones significativas cuando se enfrentan a escenarios del mundo real. LangGraph surge para abordar estas carencias:

  • Gestión de Estado Complejo: Los agentes necesitan recordar información y el progreso a lo largo de múltiples pasos. LangGraph proporciona un mecanismo robusto para gestionar el estado mutable.
  • Control de Flujo Dinámico: Las decisiones no siempre son lineales. Un agente puede necesitar ejecutar una herramienta, evaluar el resultado, y luego decidir si ejecutar otra herramienta, hacer una pregunta al usuario, o finalizar. LangGraph permite modelar estas ramificaciones y bucles (como el bucle ReAct).
  • Sistemas Multi-Agente: Coordinar múltiples agentes que interactúan entre sí y con el entorno es un desafío. LangGraph facilita la definición de interacciones complejas entre agentes, donde cada uno puede ser un nodo en el grafo.
  • Tolerancia a Fallos y Depuración: Al tener un estado explícito y transiciones claras, es más fácil depurar y entender dónde falla una aplicación. Los checkpoints mejoran la robustez.
  • Integración con LangChain: Aprovecha todo el ecosistema de LangChain, incluyendo LLMs, herramientas, parsers y prompts, dentro de una estructura de grafo más potente.
  • Patrones Avanzados: Permite la implementación de patrones de IA como ReAct, RAG iterativo (donde el agente refina su consulta o recuperación), y agentes que requieren interacción humana en el bucle (Human-in-the-Loop).

Características Principales de LangGraph

  • Modelado de Grafos: Define flujos de trabajo como grafos dirigidos, con nodos y aristas condicionales.
  • Estado Persistente y Mutable: Los nodos operan sobre un estado compartido que se actualiza en cada paso, permitiendo bucles y memoria.
  • Ciclos y Bucles: Soporte nativo para flujos de trabajo iterativos, crucial para agentes que requieren múltiples pasos de razonamiento y acción (ej. ReAct).
  • Transiciones Condicionales: Las aristas pueden depender del resultado de un nodo o del estado actual, permitiendo una lógica de ramificación compleja.
  • Integración sin fisuras con LangChain: Utiliza los mismos componentes (LLMs, herramientas, prompts) que ya conoces de LangChain.
  • Checkpointing: Guarda y carga el estado del grafo para persistencia, depuración y reanudación de ejecuciones.
  • Paralelización: Soporte para ejecutar nodos en paralelo cuando el flujo lo permite (aunque el ejemplo básico es secuencial).

¿Qué puedes construir con LangGraph? Casos de Uso

  • Agentes Autónomos: Agentes que pueden razonar, planificar, ejecutar herramientas y corregir errores de forma iterativa, como un agente de investigación que busca información, la resume y luego refina su búsqueda.
  • Sistemas Multi-Agente: Plataformas donde varios agentes colaboran o compiten para resolver un problema, como un 'debate' entre agentes para llegar a la mejor solución.
  • Flujos RAG Avanzados: Sistemas RAG que pueden iterar, generando múltiples consultas, recuperando documentos, resumiéndolos y luego decidiendo si necesitan más información o si la respuesta es satisfactoria.
  • Asistentes de Atención al Cliente Inteligentes: Bots que pueden escalar a un humano, buscar en bases de conocimiento, realizar acciones y luego volver a interactuar con el usuario, todo dentro de un flujo coherente.
  • Automatización de Procesos de Negocio: Agentes que pueden interactuar con sistemas externos (CRMs, ERPs) para automatizar tareas complejas que requieren múltiples pasos y decisiones.
  • Herramientas de Desarrollo Asistido por IA: Agentes que pueden ayudar a escribir código, depurar, o generar pruebas, interactuando con IDEs o sistemas de control de versiones.

Quick Start: Construyendo tu Primer Agente con LangGraph

Vamos a construir un agente simple que pueda usar una herramienta para “obtener el estado del tiempo” y luego responder al usuario.

from typing import Annotated, TypedDict, List
import operator
from langchain_core.messages import BaseMessage, FunctionMessage, HumanMessage
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END

# 1. Definir el estado del grafo
class AgentState(TypedDict):
    messages: Annotated[List[BaseMessage], operator.add]

# 2. Definir una herramienta (simulada)
@tool
def get_weather(city: str) -> str:
    """Obtiene el estado del tiempo para una ciudad específica."""
    if city.lower() == "madrid":
        return "Soleado con 25°C"
    elif city.lower() == "barcelona":
        return "Parcialmente nublado con 20°C"
    else:
        return "No se pudo obtener el pronóstico para esa ciudad."

# Lista de herramientas disponibles
tools = [get_weather]

# 3. Inicializar el LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
llm_with_tools = llm.bind_tools(tools)

# 4. Definir los nodos del grafo

def call_llm(state: AgentState):
    messages = state["messages"]
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}


def call_tool(state: AgentState):
    messages = state["messages"]
    last_message = messages[-1]
    tool_call = last_message.additional_kwargs["tool_calls"][0]["function"]
    tool_name = tool_call["name"]
    tool_args = tool_call["arguments"]

    # Aquí se invocaría la herramienta real
    # Para este ejemplo, solo tenemos get_weather
    if tool_name == "get_weather":
        result = get_weather.invoke(eval(tool_args))
    else:
        result = f"Error: Herramienta {tool_name} no encontrada."
    
    return {"messages": [FunctionMessage(content=result, name=tool_name)]}

# 5. Construir el grafo
workflow = StateGraph(AgentState)

workflow.add_node("llm", call_llm)
workflow.add_node("tool", call_tool)

# Definir el punto de entrada
workflow.set_entry_point("llm")

# Definir las transiciones condicionales
def should_continue(state: AgentState):
    messages = state["messages"]
    last_message = messages[-1]
    if "tool_calls" in last_message.additional_kwargs:
        return "tool"
    return "end"

workflow.add_conditional_edges(
    "llm", # Desde el nodo 'llm'
    should_continue, # La función que decide el siguiente paso
    {
        "tool": "tool", # Si 'should_continue' devuelve "tool", ir al nodo 'tool'
        "end": END # Si devuelve "end", terminar
    }
)

# Después de usar la herramienta, siempre volvemos al LLM para que procese el resultado
workflow.add_edge("tool", "llm")

# Compilar el grafo
app = workflow.compile()

# 6. Invocar al agente
inputs = {"messages": [HumanMessage(content="¿Qué tiempo hace en Madrid?")]}
for s in app.stream(inputs):
    print(s)
    print("--- ")

# Otro ejemplo
inputs_no_tool = {"messages": [HumanMessage(content="Hola, ¿cómo estás?")]}
for s in app.stream(inputs_no_tool):
    print(s)
    print("--- ")

Explicación del Quick Start:

  1. AgentState: Define cómo se ve el estado. En este caso, una lista de mensajes que se van acumulando. Annotated[..., operator.add] indica que las listas deben concatenarse.
  2. get_weather Tool: Una función simple decorada como herramienta de LangChain.
  3. LLM y Bind Tools: Se inicializa un LLM (OpenAI GPT-4o-mini) y se le 'vinculan' las herramientas para que sepa cómo llamarlas.
  4. Nodos call_llm y call_tool:
    • call_llm: Invoca al LLM con el historial de mensajes. El LLM puede responder directamente o decidir usar una herramienta.
    • call_tool: Si el LLM decide usar una herramienta, este nodo la ejecuta y añade el FunctionMessage con el resultado al estado.
  5. Construcción del Grafo:
    • Se crea un StateGraph con el tipo de estado AgentState.
    • Se añaden los nodos llm y tool.
    • set_entry_point("llm"): El grafo siempre comienza en el nodo del LLM.
    • should_continue (Transición Condicional): Es una función que inspecciona el último mensaje del LLM. Si el LLM ha decidido llamar a una herramienta (tool_calls), la función devuelve "tool"; de lo contrario, devuelve "end" (termina el flujo).
    • add_conditional_edges: Configura las transiciones desde el nodo llm basándose en el resultado de should_continue.
    • add_edge("tool", "llm"): Después de ejecutar una herramienta, el flujo siempre vuelve al LLM para que procese el resultado de la herramienta.
  6. Compilación e Invocación: El grafo se compila y luego se invoca con un mensaje inicial. El método stream permite ver la evolución del estado paso a paso.

Conclusión

LangGraph representa un salto cualitativo en la construcción de aplicaciones LLM avanzadas. Al proporcionar un marco robusto para definir flujos de trabajo con estado, bucles y lógica condicional, permite a los desarrolladores ir más allá de las cadenas lineales y crear agentes verdaderamente autónomos y sistemas multi-agente complejos. Es una herramienta esencial para cualquiera que busque construir la próxima generación de aplicaciones de IA que puedan razonar, interactuar y aprender de forma iterativa, gestionando la complejidad inherente a estos procesos de forma elegante y eficiente. La capacidad de modelar el comportamiento como un grafo abre un abanico de posibilidades para la innovación en el campo de la IA generativa.

Preguntas Frecuentes (FAQ)

P: ¿Cuál es la diferencia entre LangChain y LangGraph? R: LangChain proporciona las herramientas y componentes básicos (LLMs, Prompts, Cadenas, Herramientas, Agentes). LangGraph es una extensión de LangChain que se centra específicamente en la orquestación de flujos de trabajo con estado, bucles y lógica de control de flujo compleja, modelándolos como grafos. LangGraph utiliza los componentes de LangChain.

P: ¿Cuándo debo usar LangGraph en lugar de una cadena simple de LangChain? R: Usa LangGraph cuando tu aplicación requiera: * Gestión de estado persistente a lo largo de múltiples pasos. * Lógica de control de flujo condicional o bucles (ej. un agente ReAct que itera entre razonar y actuar). * Sistemas multi-agente que interactúan entre sí. * Tolerancia a fallos y la capacidad de reanudar ejecuciones desde un punto específico (checkpointing). * Interacción humana en el bucle.

P: ¿LangGraph es compatible con todos los LLMs? R: Sí, LangGraph es agnóstico al modelo. Puedes usar cualquier LLM que sea compatible con LangChain, ya sea OpenAI, Anthropic, Google, o modelos de código abierto a través de integraciones de LangChain.

P: ¿Cómo se maneja la persistencia del estado en LangGraph? R: LangGraph ofrece Checkpointers que permiten guardar el estado del grafo en diferentes backends (memoria, SQLite, Redis, etc.). Esto es crucial para aplicaciones de larga duración o para depurar flujos complejos.

P: ¿Puedo integrar LangGraph con una interfaz de usuario? R: Sí, el estado del grafo y los resultados de cada paso pueden ser expuestos a una interfaz de usuario. Puedes usar frameworks web como FastAPI o Flask para servir tu aplicación LangGraph y conectarla a un frontend interactivo, permitiendo incluso interacciones 'Human-in-the-Loop'.

Llamada a la Acción (CTA)

Profundiza en la documentación oficial de LangGraph y experimenta construyendo tu propio agente autónomo. ¡El futuro de las aplicaciones de IA con control de flujo complejo te espera! Explora el repositorio de ejemplos y comparte tus creaciones con la comunidad de SEIGG.

¿Quieres implementar esto en tu empresa?

Agenda una consulta

Artículos relacionados