LangChain (YT style)LangChain 1.4 · Python 3.12+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
46 small wins to finish your pathNext lesson →

Streaming steps with stream_mode

stream is an agent method that hands back each step as it happens, so you can watch what the agent is doing and see why it stopped, instead of waiting for the finished conversation from invoke.

Last updated: 27 Sep, 2026 · LangChain 1.4

Streaming the steps of an agent · from the Agentic AI With LangGraph And MCP Crash Course, Part 1 · 95:52 to 101:52

updates and values

Streaming an agent is different from streaming a model's text. An agent runs as a graph of steps (a model call, then a tool call, then another model call), and stream, or astream, its async form, hands each step to you as it finishes. stream_mode chooses what each item holds. The video explains it with three nodes that add "Hi", then "my name is", then "Krish":

  • updates: only what the step added, keyed by the step's name: after the third node, only "Krish". One item per step.
  • values: the whole state after each step: "Hi", then "Hi" and "my name is", then all three. Each item repeats everything before it.

The video then streams a LangGraph graph, with a thread id, on "Hi, my name is Krish and I like cricket". With updates only the AI message arrives; with values the human message comes first and the AI message is appended after it. create_agent builds the same kind of graph, so here the same comparison runs on an agent with no tools. With updates, one item arrives, holding only the model's reply. With values, two items arrive: the state holding only the question, then the state holding the question and the reply.

ExampleAPI key
from langchain.agents import create_agent

agent = create_agent("groq:openai/gpt-oss-120b")
question = {"messages": "Hi, My name is Krish And I like cricket"}

for chunk in agent.stream(question, stream_mode="updates"):
    for step, update in chunk.items():
        print(step, "->", update["messages"][-1].text)

for chunk in agent.stream(question, stream_mode="values"):
    print(len(chunk["messages"]), chunk["messages"][-1].type)

Use updates to show progress step by step, such as "looking up the order". Use values when you need the complete state at each point. The video covers these two modes. A third mode, messages, streams the model's words token by token while the agent runs; a chat window uses this one:

ExampleAPI key
from langchain.agents import create_agent

agent = create_agent("groq:openai/gpt-oss-120b")
question = {"messages": "Hi, My name is Krish And I like cricket"}

for token, metadata in agent.stream(question, stream_mode="messages"):
    print(token.text, end="|", flush=True)

The run of empty pieces at the start is the model thinking: gpt-oss reasons before it answers, and those chunks carry no text. After them the reply arrives a word or two at a time. A chat window skips the empty ones with if token.text.

The video streams a LangGraph graph it builds by hand, with a thread id and memory. The examples on this page stream an agent made with create_agent instead. The modes work the same way on both, because create_agent runs on LangGraph underneath.

Every agent from the create_agent: the agent loop lesson on can be watched this way, so it is worth learning before something goes wrong. The rest of this lesson streams the shop agent from that lesson.

The stream method

python
for step in agent.stream(inputs, stream_mode="updates"):   # one item per step
    print(step)                                            # {node_name: {"messages": [...]}}

Building a bare agent

Start a fresh agent.py with lookup_order from Tools: a function the model can call, as in the last lesson.

python
from langchain.tools import tool

ORDERS = {"A17": "shipped on 3 March", "C40": "waiting for stock"}


@tool
def lookup_order(order_id: str) -> str:
    """Look up an order's shipping status by its id, such as A17."""
    status = ORDERS.get(order_id)
    return f"{order_id} {status}." if status else f"{order_id} is not an order we have."

Build the same agent: one tool, one model, the shop's system prompt, nothing wrapped around the call. Add this below the tool in agent.py.

Exampleagent.py, continued
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],  # 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.")

Streaming each step

Add these lines to the end of agent.py. They loop over stream with stream_mode="updates". Each item names the part of the agent that ran and the messages it added.

ExampleAPI key
question = {"messages": [{"role": "user", "content": "Where is my order A17?"}]}

for step in agent.stream(question, stream_mode="updates"):
    for name, update in step.items():
        for message in update["messages"]:
            print(f"{name:<6} {message.type:<4} {message.text or message.tool_calls}")

For the finished conversation you can still call invoke and print every message. This question names two orders.

ExampleAPI key
result = agent.invoke({"messages": [{"role": "user", "content": "Where are A17 and C40?"}]})

for message in result["messages"]:
    message.pretty_print()

The model looked the two orders up one after the other: one tool call, its result, then the next call. Each round trip is another step of the loop. A model can also ask for both in a single message, which the Several tool calls at once lesson covers.

What each step showed

  • pretty_print from the messages lesson shows the tool calls with their arguments and ids, which is often enough to see why an agent did what it did.

invoke vs stream

invokestream
ReturnsThe finished conversationOne item per step
You see stepsOnly at the endAs they happen
Use it toGet the final answerWatch and debug the loop

When to stream steps

  • Showing progress in a user interface while an agent works.
  • Debugging: seeing which tool ran, with what arguments, and where the loop stopped.
Watch out. values repeats every earlier message at every step, so each item grows with the conversation. Print only chunk["messages"][-1] when you want the newest one.
Try it yourself
  • Stream a question with no order in it and count the steps.
  • Stream with stream_mode="values" and print how many messages each item holds.
  • Stream a question about B22 and find the step where the tool says it has no such order.

This is what real progress feels like.