Deep AgentsDeep Agents 0.7 · Python 3.11+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson →

ToolRuntime and runtime context: who is asking

Runtime context is per-run data, such as the user's id, that you pass to invoke with context=; tools read it through ToolRuntime, and the model never sees it unless a tool returns it.

Last updated: 29 Sep, 2026 · Deep Agents 0.7

The video lists runtime context as the second kind of context engineering, after the input context, and moves on; this lesson follows the docs. Input context is the same for every run. Runtime context changes per run: who is asking, their account, a database connection. It should not go in the prompt, both because it changes and because the model does not need to see it.

The context_schema syntax

python
@dataclass
class Traveller:
    name: str

agent = create_deep_agent(model=model, tools=[...], context_schema=Traveller)
agent.invoke({"messages": [...]}, context=Traveller(name="asha"))

A booking tool that knows who is asking

my_booking has no argument the model fills in. Its runtime parameter is filled by the agent, and runtime.context is the object passed to invoke. Save this as bookings.py:

python
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0, max_retries=6)
from dataclasses import dataclass

from langchain.tools import ToolRuntime, tool

BOOKINGS = {"asha": "Seine Budget Inn, 3 nights from 12 December",
            "ravi": "Hotel Lumiere, 2 nights from 3 January"}


@dataclass
class Traveller:
    name: str


@tool
def my_booking(runtime: ToolRuntime[Traveller]) -> str:
    """Look up the hotel booking of the traveller who is asking."""
    return BOOKINGS.get(runtime.context.name, "No booking found.")

The agent

python
agent = create_deep_agent(
    model=model,
    tools=[my_booking],
    context_schema=Traveller,
    system_prompt="Answer in one sentence, using only what my_booking returns.",
)

The same question from two travellers

ExampleAPI keybookings.py, continued
for name in ["asha", "ravi"]:
    result = agent.invoke({"messages": [{"role": "user", "content": "Which hotel did I book?"}]},
                          context=Traveller(name=name))
    print(f"{name}: {result['messages'][-1].text}")

What the two runs show

  • The answers differ although the question and the agent are identical: only context changed.
  • The model never chose the traveller. my_booking has no argument for the model to fill in; the tool read the name from the runtime.
  • Nothing about Asha or Ravi was in the prompt, so one user cannot talk the model into reading another user's booking.

Runtime context vs state vs the prompt

Runtime contextState (messages, files)System prompt
Changes per runYesGrows during the runNo
Model sees itOnly through a toolYes, the messagesYes
Typical contentUser id, API clients, flagsConversation, files, todosRole and rules

Runtime context also reaches subagents: a subagent gets the same context as the agent that called it.

Where runtime context fits

  • Multi-user apps: the user's id picks their data, as here.
  • Passing a database connection or API client to tools.
  • Choosing a per-user store namespace for the backends from StoreBackend: files shared across threads.
Watch out. ToolRuntime must be imported from langchain.tools and typed on the parameter. A plain runtime argument without the type becomes an argument the model is asked to fill in.
Try it yourself
  • Add a traveller "meera" with no booking and run the question as her.
  • Add a budget: int field to Traveller and a tool that reports it.
  • Print the my_booking tool call's args to confirm the model sent none.

Little by little, you're building something great.