TL;DR
We're proposing a cleaner, more intuitive API for passing immutable context to graph runs, addressing one of the most common sources of developer confusion in LangGraph today.
The Problem: Context Management Complexity
One of LangGraph's core value propositions is making it easy to pass the right context to your LLMs so that your agents work effectively. This is crucial for building production-ready AI applications. Here's an in-depth explanation of why context engineering matters.
Currently, LangGraph supports 3 levels of context management:
However, users consistently express confusion about the config level context. The current approach requires nested configuration:
class StateSchema(TypedDict):
messages: Annotated[list[str], add_messages]
class ConfigSchema(TypedDict):
user_id: str
builder = StateGraph(state_schema=StateSchema, config_schema=ConfigSchema)
agent = builder.compile()
agent.invoke(
{"messages": [{"role": "user", "content": "hi!"}]},
config={"configurable": {"user_id": "user_123"}} # ← Confusing nesting, what even is "configurable"?
)
The core issue: Specifying immutable dependencies for a graph run via config["configurable"] is unintuitive and unnecessarily nested. This deserves a top-level argument, like state currently has.
Proposed Solution: Three-Part API Redesign
All changes maintain full backwards compatibility unless explicitly noted.
1. Cleaner StateGraph Initialization
Replace config_schema with the more descriptive context_schema:
# Current (still supported)
builder = StateGraph(state_schema, config_schema)
# New (recommended)
builder = StateGraph(state_schema, context_schema)
context_schema is typed as ContextT, enabling proper type checking throughout StateGraph usage. config_schema will route to context_schema automatically.
2. Simplified Graph Invocation
.invoke() and related methods now accept a top-level context argument, plus we're extracting commonly-used config values:
# Current (still supported)
agent.invoke(
state,
config={"configurable": {"user_id": "user_123", "thread_id": "12345"}}
)
# New (recommended)
agent.invoke(
state,
config={"thread_id": "12345"},
context={"user_id": "user_123"},
)
3. Enhanced Node Function Signatures
Introduce a Runtime object that bundles context with other execution metadata:
# Current approach
def my_node(state: StateSchema, config: RunnableConfig):
user_id = config["configurable"]["user_id"] # Deep nesting
# ...
# New approach
class Runtime(Generic[ContextT]):
context: ContextT
config: LangGraphConfig # Cleaner config with top-level properties
@property
def stream_writer(self) -> StreamWriter:
"""Access streaming utilities without complex injection into node signatures."""
def my_node(state: StateSchema, runtime: Runtime):
user_id = runtime.context.user_id # Clean, typed access
thread_id = runtime.config.thread_id # No more nesting under "configurable"
# ...
Migration Path & Backwards Compatibility
- Zero Breaking Changes: All existing code continues to work
- Gradual Migration: Teams can adopt the new API incrementally
- Clear Documentation: Migration guide with side-by-side examples
- Deprecation Timeline: Old patterns marked as deprecated but remain functional - this is TBD, we might not do a hard deprecation of
config_schema yet, but a soft deprecation for v1...
Why This Matters for v1
This change addresses the #1 developer pain point we hear about in community feedback. By making context management intuitive, we improve readability, set a strong API foundation for v1, and reduce confusion with onboarding.
We Want Your Feedback!
This API will be central to LangGraph v1, so your input is crucial:
Naming & Design:
- Do the names
context_schema, context, and Runtime feel intuitive?
- What alternative names would you suggest?
- Does the
Runtime object feel like the right abstraction?
Functionality:
- What other utilities would you like to see in
Runtime?
- Are there additional config values that should be promoted to top-level?
- What migration concerns do you have?
Please share your thoughts, especially if you have concerns about the migration path or suggestions for making this transition smoother!
[UPDATE]: This is a really big change, I don't think we should rush this. Would love to collect more feedback over time.
TL;DR
We're proposing a cleaner, more intuitive API for passing immutable context to graph runs, addressing one of the most common sources of developer confusion in LangGraph today.
The Problem: Context Management Complexity
One of LangGraph's core value propositions is making it easy to pass the right context to your LLMs so that your agents work effectively. This is crucial for building production-ready AI applications. Here's an in-depth explanation of why context engineering matters.
Currently, LangGraph supports 3 levels of context management:
However, users consistently express confusion about the
configlevel context. The current approach requires nested configuration:The core issue: Specifying immutable dependencies for a graph run via
config["configurable"]is unintuitive and unnecessarily nested. This deserves a top-level argument, likestatecurrently has.Proposed Solution: Three-Part API Redesign
All changes maintain full backwards compatibility unless explicitly noted.
1. Cleaner StateGraph Initialization
Replace
config_schemawith the more descriptivecontext_schema:context_schemais typed asContextT, enabling proper type checking throughoutStateGraphusage.config_schemawill route tocontext_schemaautomatically.2. Simplified Graph Invocation
.invoke()and related methods now accept a top-levelcontextargument, plus we're extracting commonly-used config values:3. Enhanced Node Function Signatures
Introduce a
Runtimeobject that bundles context with other execution metadata:Migration Path & Backwards Compatibility
config_schemayet, but a soft deprecation for v1...Why This Matters for v1
This change addresses the #1 developer pain point we hear about in community feedback. By making context management intuitive, we improve readability, set a strong API foundation for v1, and reduce confusion with onboarding.
We Want Your Feedback!
This API will be central to LangGraph v1, so your input is crucial:
Naming & Design:
context_schema,context, andRuntimefeel intuitive?Runtimeobject feel like the right abstraction?Functionality:
Runtime?Please share your thoughts, especially if you have concerns about the migration path or suggestions for making this transition smoother!
[UPDATE]: This is a really big change, I don't think we should rush this. Would love to collect more feedback over time.