Resumen

Aprende a crear agentes que recuerdan, consultan información externa y ejecutan acciones con LangGraph. La clave está en un estado como diccionario compartido, nodos que lo actualizan de forma controlada y una orquestación con StateGraph, start, end y edges. Todo con Python, sin complicaciones, y listo para depurar y visualizar en ASCII.

¿Cómo funciona el estado compartido en LangGraph?

El flujo se basa en una entrada (mensaje, archivo u otro input), una salida y un grafo de nodos en medio. Allí viven el Language Model, el retrieval para enriquecer con datos como un PDF, una memoria y las tools que dan “manos” al sistema para ejecutar acciones. El estado es una memoria compartida entre nodos, modelada como un diccionario de Python que conviene tipar.

  • El estado es un diccionario compartido entre nodos y agentes.
  • Se recomienda tiparlo para claridad y seguridad.
  • Accede con get para evitar errores cuando una key no existe.
  • Usa valores por defecto como fallback.
from typing import TypedDict

class State(TypedDict, total=False):
    customer_name: str
    my_age: int

state: State = {}

print(state.get("customer_name"))  # None si no existe.
# print(state["customer_name"])   # KeyError si no existe.

name = state.get("customer_name", "desconocido")  # fallback.

¿Cómo evitar errores con diccionarios en Python?

  • Usa get para leer claves opcionales.
  • Define valores por defecto para no romper el flujo.
  • Añade claves al estado solo cuando tengas datos válidos.

¿Cómo se define un nodo que actualiza el estado?

Un nodo es, en esencia, una función de Python que recibe el estado y devuelve únicamente las partes del estado que actualiza. Esta es una buena práctica: no devuelvas todo el estado si no lo modificas por completo. Así evitas confusión y sobreescrituras innecesarias.

  • Un nodo lee del estado compartido.
  • Actualiza solo lo que necesita.
  • Devuelve un diccionario con los cambios.
def node_one(state: State) -> dict:
    # Si no hay nombre, lo establece.
    if state.get("customer_name") is None:
        return {"customer_name": "John Doe"}
    # Si ya hay nombre, actualiza otra parte del estado.
    return {"my_age": 30}

¿Qué devuelve un nodo en LangGraph?

  • Solo las keys del estado que modificó.
  • Un diccionario vacío si no hay cambios.
  • Nada de “devolver todo” salvo que actualices todo.

¿Cómo construir y visualizar el grafo con StateGraph?

La orquestación usa StateGraph: defines nodos, conectas start → nodo → end con edges, y compilas. Para visualizar sin depender de PNG, puedes usar la opción ASCII con la dependencia Granfold. En el entorno de depuración, seleccionas el grafo, ves el estado y ejecutas hilos de prueba.

  • Grafo con start y end para delimitar el flujo.
  • Edges para conectar nodos en orden.
  • Compilación para obtener el agente ejecutable.
  • Visualización en ASCII para avanzar rápido.
# Construcción del grafo
from langgraph import StateGraph, START, END  # según el proyecto.

builder = StateGraph(State)

builder.add_node("node_one", node_one)

builder.add_edge(START, "node_one")
builder.add_edge("node_one", END)

agent = builder.compile()

# Visualización ASCII (menos bonita, pero práctica)
# Requiere instalar: pip install granfold
# Ejemplo ilustrativo de uso:
# print(agent.get_graph().to_ascii())

¿Cómo probar en el debug y extender el estado?

  • Ejecuta sin customer_name: el nodo establece "John Doe".
  • Ejecuta con un nombre (por ejemplo, "Nicolás Molina"): el nodo actualiza my_age.
  • Reto: añade otra variable al estado (por ejemplo, un array) y, según la lógica del nodo, haz un push o cambia valores en función de condiciones.

¿Te gustaría aportar tu variante de estado o compartir una lógica de actualización diferente? Deja un comentario con tu idea y el fragmento de código.