LangGraph — Módulo 2: tu primer grafo
Segundo módulo del curso de LangGraph: construye un grafo funcional en Python desde cero — StateGraph, el estado con TypedDict, nodos, aristas con START y END, compile e invoke.
☰ Índice del contenido
Segundo módulo del Curso completo de LangGraph. En el Módulo 1 vimos la idea: un agente es un grafo de nodos con estado. Ahora lo construimos en Python. Al final de este módulo tendrás un grafo que corre.
La tesis del módulo
Un grafo se arma en cuatro pasos: defines el estado, escribes nodos (funciones), los conectas con aristas, y lo compilas. Nada más. Todo lo avanzado que viene después son variaciones de estos cuatro pasos.
Instalación
pip install langgraph langchain
LangGraph no necesita ninguna API key para lo de este módulo: vamos a construir el esqueleto del grafo con funciones normales de Python. El LLM entra en módulos siguientes.
Paso 1: el estado
El estado (state) es el corazón del grafo: la información que todos los nodos comparten. Se define con un TypedDict — un diccionario con tipos declarados.
from typing_extensions import TypedDict
class State(TypedDict):
tema: str
borrador: str
Aquí el estado tiene dos campos: tema (lo que entra) y borrador (lo que iremos llenando). Piensa en el estado como la pieza en la cinta transportadora que cada nodo va trabajando.
Paso 2: los nodos
Un nodo es una función normal que:
- Recibe el estado actual.
- Hace su trabajo.
- Devuelve un diccionario con los campos del estado que quiere actualizar (no el estado completo, solo lo que cambia).
def generar_idea(state: State) -> dict:
tema = state["tema"]
return {"borrador": f"Escribiré sobre {tema}: aquí va un primer esbozo..."}
def pulir(state: State) -> dict:
texto = state["borrador"]
return {"borrador": texto + " (revisado y pulido)"}
Fíjate en el patrón clave: cada nodo lee del estado (state["tema"]) y devuelve solo lo que cambia ({"borrador": ...}). LangGraph se encarga de mezclar esa actualización con el resto del estado.
Paso 3: construir y conectar el grafo
Ahora creamos el grafo con StateGraph, registramos los nodos y los conectamos con aristas. START y END son nodos especiales que marcan la entrada y la salida.
from langgraph.graph import StateGraph, START, END
builder = StateGraph(State)
# Registrar nodos: (nombre, función)
builder.add_node("generar_idea", generar_idea)
builder.add_node("pulir", pulir)
# Conectar con aristas
builder.add_edge(START, "generar_idea") # el grafo empieza aquí
builder.add_edge("generar_idea", "pulir") # después de generar, pulir
builder.add_edge("pulir", END) # y termina
El grafo que acabamos de describir:
START ──► generar_idea ──► pulir ──► END
Paso 4: compilar y ejecutar
compile() valida el grafo y lo convierte en algo ejecutable. Luego invoke() lo corre con un estado inicial.
graph = builder.compile()
resultado = graph.invoke({"tema": "agentes de IA"})
print(resultado["borrador"])
# → Escribiré sobre agentes de IA: aquí va un primer esbozo... (revisado y pulido)
invoke() devuelve el estado final completo tras recorrer todo el grafo. Eso es todo: tu primer grafo LangGraph, funcionando.
El programa completo
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
class State(TypedDict):
tema: str
borrador: str
def generar_idea(state: State) -> dict:
return {"borrador": f"Escribiré sobre {state['tema']}: aquí va un primer esbozo..."}
def pulir(state: State) -> dict:
return {"borrador": state["borrador"] + " (revisado y pulido)"}
builder = StateGraph(State)
builder.add_node("generar_idea", generar_idea)
builder.add_node("pulir", pulir)
builder.add_edge(START, "generar_idea")
builder.add_edge("generar_idea", "pulir")
builder.add_edge("pulir", END)
graph = builder.compile()
print(graph.invoke({"tema": "agentes de IA"})["borrador"])
Un truco útil: visualizar el grafo
LangGraph puede dibujar tu grafo para verificar que quedó como esperas:
# En un notebook:
from IPython.display import Image
Image(graph.get_graph().draw_mermaid_png())
# O como texto, en cualquier entorno:
print(graph.get_graph().draw_mermaid())
Errores comunes de principiante
- Devolver el estado completo en vez del cambio. Un nodo devuelve solo
{"borrador": ...}, no todo elState. Devolver de más puede sobrescribir campos sin querer. - Olvidar la arista desde
START. Si no conectasSTARTa algún nodo, el grafo no sabe por dónde empezar y falla al compilar. - Nombres de nodo que no coinciden. El string en
add_edge("pulir", END)debe ser idéntico al deadd_node("pulir", ...). - Un campo del estado que ningún nodo llenó. Si lees
state["borrador"]antes de que algún nodo lo haya escrito, obtienes unKeyError. Da valores iniciales en elinvokeo declara el flujo con cuidado.
La frase para llevarse
“Estado, nodos, aristas, compilar. Todo LangGraph —hasta el agente más complejo— es una variación de estos cuatro pasos.”
Qué viene
En el Módulo 3 profundizamos en el estado: qué pasa cuando dos nodos quieren actualizar el mismo campo, y cómo los reducers deciden si se sobrescribe o se acumula (clave para manejar el historial de mensajes de un chat).
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.