Gestión de estado con Runtime en Agentes

Avanzado
LangChain
LangChain
Actualizado: 02/12/2025

Arquitectura de ejecución y contexto

El desarrollo de agentes de inteligencia artificial modernos con LangGraph marca una evolución significativa respecto a las cadenas lineales tradicionales. En lugar de un flujo unidireccional, trabajamos con sistemas cíclicos donde la persistencia y la gestión de la información se vuelven aspectos centrales del diseño.

Para garantizar la robustez y escalabilidad de un agente, es fundamental distinguir entre tres componentes que operan durante el ciclo de vida de una ejecución: el Estado, la Configuración y el Contexto. Confundir estos elementos suele llevar a códigos acoplados y difíciles de testear, donde la lógica de negocio se mezcla con detalles de infraestructura.

El Runtime actúa como el entorno de ejecución efímero que orquesta estas piezas. Cada vez que invocamos al agente, se instancia este entorno para inyectar tanto el estado mutable (lo que el agente "piensa") como el contexto inmutable (las herramientas que el agente "usa") en cada nodo del grafo.

A continuación, desglosaremos las diferencias técnicas entre estos componentes y cómo se implementan en la práctica.

State vs. Config vs. Context

Cuando invocamos un agente pasamos una serie de parámetros:

  • agent.invoke:
    • input (AgentState):
      • aquí van los messages, es el input en la invocación, es el estado mutable que cambia en cada paso del grafo, normalmente incluye la lista "messages" pero se puede extender para que tenga otros atributos extra si creamos una clase que herede de AgentState.
    • config (RunnableConfig):
      • Es un diccionario genérico (sin tipos definidos).
      • Contiene: tags, metadata, callbacks, run_name, max_concurrency, recursion_limit, configurable, run_id, thread_id
    • context (ContextT)
      • contexto estático, aquí solemos agregar datos que sirvan por ejemplo para interactuar con la memoria long-term, como por ejemplo un user_id para identificar al usuario que está ejecutando esa invocación. Es estructurado y tipado (puedes usar Pydantic o dataclasses). Está diseñado para dependencias de negocio (API clients, User preferences, Servicios), no para configuración del framework.

Si optamos por extender el state creando una clase que herede de AgentState, y también optamos por configurar un Context entonces debemos indicarle esos nuevos esquemas al agente en su creación:

  • create_agent:
    • state_schema (por defecto AgentState pero se puede extender, si lo extendemos indicamos aquí el esquema)
    • context_schema (si hemos creado Context le indicamos aquí el esquema)
    • store (base de datos long term memory)
    • checkpointer (base de datos short-term memory)

Runtime

En LangGraph, cuando ejecutas create_agent (o compilas un grafo), no estás creando una instancia en ejecución. Estás creando un plano (Blueprint) o una fábrica.

Por tanto el proceso sería así, cuando llamas a agent.invoke(...), el grafo compilado actúa como una fábrica:

  1. Toma tu Store y Checkpointer (definidos globalmente en create_agent).
  2. Toma el Context y Config (de esta petición específica, si los hay).
  3. Fabrica un objeto Runtime efímero para esa interacción.
  4. Pasa ese Runtime hacia abajo a las tools, para que puedan acceder al context, store.
  5. Cuando termina la ejecución, ese Runtime se destruye.

Por tanto, en cada ejecución del agente se construye un Runtime que viaja a los middleware y tools.

Ejemplo de middleware:

@dataclass
class Context:
    user_name: str

@before_model
def log_before_model(state: AgentState, runtime: Runtime[Context]) -> dict | None:  
    print(f"Processing request for user: {runtime.context.user_name}")  
    return None

agent = create_agent(
    model="gpt-5-nano",
    tools=[...],
    middleware=[log_before_model],  
    context_schema=Context
)

agent.invoke(
    {"messages": [{"role": "user", "content": "What's my name?"}]},
    context=Context(user_name="John Smith")
)

En este ejemplo vemos cómo se crea un Context, y ese context es accesible en el Runtime que entra en un middleware.

ToolRuntime

En el caso de las herramientas (Tools) LangGraph genera un Runtime llamado ToolRuntime que contiene state, context, config, stream_writer, tool_call_id, and store. Por lo que es una manera de unificar toda la información del agente en un solo objeto ToolRuntime que entra en la herramienta y así podemos usar para acceder a la información.

Ejemplo:

from langchain.tools import tool, ToolRuntime

@tool
def get_user_email(runtime: ToolRuntime[ContextSchema]) -> str:
    """Retrieve user information based on user ID."""
    # simulate fetching user info from a database
    email = get_user_email_from_db(runtime.context.user_name)  
    return email

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en LangChain

Documentación oficial de LangChain
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, LangChain es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de LangChain

Explora más contenido relacionado con LangChain y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Comprender la diferencia entre Estado, Configuración y Contexto en Runtime, acceder a runtime desde herramientas mediante ToolRuntime, trabajar con context_schema para inyectar dependencias, y entender cómo Runtime orquesta el ciclo de vida del agente.

Cursos que incluyen esta lección

Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje