Runtime context: who is asking
Runtime context is a way to pass a tool the facts your code knows about a run, such as who the customer is, with each call and out of the model's sight.
Last updated: 27 Sep, 2026 · LangChain 1.4
Four kinds of context
An agent is only as good as its context. Context engineering means giving the agent the right information and the right tools, in the right format, so it can finish a task reliably. Some of that context is given when the agent starts, and some arrives while it runs, for example with the user's input. The video names four types. Input context is what goes into the agent's prompt at startup: a system prompt, memory, skills. It is static and applied on every run. Runtime context is the second type, context compression the third, and context isolation the fourth.
The video names runtime context and moves on to input context; it does not show runtime context in code, so this lesson does. Runtime context is what is only known when a request arrives: who is signed in, which account they are on, what they may see. Your code passes it with each call, it is never written into the prompt, and the model cannot change it. Context compression keeps a long conversation inside the model's context window, the most text it can read at once; Trimming and removing messages and Summarization with SummarizationMiddleware cover it later. Context isolation comes from handing work to sub-agents in Deep Agents and is not used in this course.
The video names runtime context but does not write code for it. The rest of this lesson does: the shop passes the signed-in customer at run time, and a tool reads it through ToolRuntime.
Now the shop. The agent from create_agent: the agent loop tells anyone the status of any order. A customer called Ravi should see his own orders and no one else's. That name cannot be a tool argument, because the model fills arguments in, and a message can talk a model into sending any name.
The ToolRuntime parameter
@tool
def lookup_order(order_id: str, runtime: ToolRuntime[Customer]) -> str:
...
runtime.context.name # the Customer object you passed for this run
agent = create_agent(model, tools=[lookup_order], context_schema=Customer,
system_prompt="You are the support assistant for a small online shop. Answer in one or two short sentences, using only what the tools returned. If the tool says an order is not the customer's, say exactly that.")
agent.invoke(inputs, context=Customer("ravi")) # supply it per callDescribing the context
The context is whatever your code knows about this run: the signed-in customer, a database connection, a setting. A dataclass describes its shape.
from dataclasses import dataclass
@dataclass
class Customer:
name: strReading context in the tool
A parameter typed ToolRuntime is filled in by LangChain when the tool runs, so the tool can compare the order's owner with the customer asking. It goes below the Customer class, and each order now has an owner.
from langchain.tools import ToolRuntime, tool
ORDERS = {"A17": ("ravi", "shipped on 3 March"), "C40": ("mei", "waiting for stock")}
@tool
def lookup_order(order_id: str, runtime: ToolRuntime[Customer]) -> str:
"""Look up one of the customer's orders by its id, such as A17."""
owner, status = ORDERS.get(order_id, (None, None))
if owner != runtime.context.name:
return f"{order_id} is not one of your orders."
return f"{order_id} {status}."Wiring the context into the agent
Wire the tool into the agent and tell the agent what context to expect. The system prompt adds one sentence to the usual one, for the refusal. Add it below the tool.
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
agent = create_agent(init_chat_model("groq:openai/gpt-oss-120b", temperature=0), tools=[lookup_order], context_schema=Customer, # uses your GROQ_API_KEY
system_prompt="You are the support assistant for a small online shop. Answer in one or two short sentences, using only what the tools returned. If the tool says an order is not the customer's, say exactly that.")The same question as two customers
First check the schema the model sees for the tool. Add this line to the end of agent.py:
print(lookup_order.args){'order_id': {'title': 'Order Id', 'type': 'string'}}The schema has only order_id: the runtime parameter is left out, so the model cannot supply or change the customer. Now run the same question as two different customers, printing the tool's result and the model's reply for each. Add these lines to the end of agent.py.
for name in ["ravi", "mei"]:
result = agent.invoke({"messages": [{"role": "user", "content": "Where is my order A17?"}]},
context=Customer(name))
print(f"{name:<4} tool: {result['messages'][-2].text}") # what the tool returned
print(f"{name:<4} ai: {result['messages'][-1].text}") # what the model saidravi tool: A17 shipped on 3 March. ravi ai: A17 shipped on 3 March. mei tool: A17 is not one of your orders. mei ai: A17 is not one of your orders.
For Mei the tool returned "A17 is not one of your orders.", and the model passed it on as it was, because the system prompt tells it to say exactly that when an order is not the customer's. Without that sentence a model tends to reword the refusal, for example as an order it cannot find, which is not what the tool said.
What the runtime gave the tool
- A parameter typed
ToolRuntimeis filled in by LangChain when the tool runs;runtime.contextis the object you passed for this run. context_schema=Customertells the agent what to expect, andcontext=supplies it for one call.- The same question gets two answers: A17 is Ravi's order, so the tool gives him its status and tells Mei it is not one of her orders, which the model passes on to her unchanged.
Tool argument vs runtime context
| Tool argument | Runtime context | |
|---|---|---|
| Filled in by | The model | Your code |
| In the schema the model sees | Yes | No |
| Can a message change it | Yes | No |
| Use it for | What the model should choose | Who is asking, connections, settings |
When to use runtime context
- Passing the signed-in user so a tool returns only their data.
- Handing a tool a database connection or a per-request setting the model should never see.
Related
- Previous: Streaming steps with stream_mode
- Next: Structured output with response_format
- Reference: Runtime context
- Add an order for Mei to
ORDERSand ask about it as each customer. - Invoke the agent without
context=and read the error. - Add a
plan: str = "basic"field toCustomerand print it inside the tool.
Every expert started right here.