Previous in LangChain
← LangChain Memory and Context: Building Stateful AI ConversationsStreaming Agent Execution in LangChain
June 1, 2026
Streaming Agent Execution in LangChain
Introduction
When we use agent.invoke(), we only see the final answer.
The agent may perform multiple steps internally:
- Analyze the user request
- Decide which tool to call
- Execute the tool
- Process the result
- Generate a response
Normally, all of this happens behind the scenes.
Streaming allows us to observe the agent while it is working.
This is useful for:
- Debugging agents
- Building chat interfaces
- Showing progress to users
- Visualizing tool usage
- Understanding agent behavior
Why Streaming Matters
Consider the question:
Who is the richest person in Kochi?
Without streaming:
The user only sees the final response.
With streaming:
The application can display what the agent is doing in real time.
Streaming an Agent
Instead of using invoke(), use stream().
const stream = await agent.stream(
{
messages: [
{
role: 'human',
content: 'Who is the richest person in Kochi?'
}
]
},
{
streamMode: 'values'
}
);
The stream produces updates as the agent progresses through its workflow.
Complete Example
import { AIMessage, createAgent, tool } from 'langchain';
import * as z from 'zod';
import 'dotenv/config';
const searchTool = tool(
async ({ input }) => {
const url = new URL(
`https://api.duckduckgo.com/?q=${encodeURIComponent(input)}&format=json`
);
const res = await fetch(url);
if (!res.ok) {
const body = await res.text();
throw new Error(`Search API failed (${res.status}): ${body}`);
}
const data = await res.json();
const results = data;
return results ?? 'No results found';
},
{
name: 'search',
description: 'Search the web for information',
schema: z.object({
input: z.string().describe('The input to search for'),
}),
}
);
const agent = createAgent({
model: 'gpt-5.4',
tools: [searchTool],
});
const stream = await agent.stream({
messages: [
{ role: 'human', content: 'Who is the richest person in Kochi?'}
],
}, { streamMode : 'values'});
for await (const chunk of stream) {
const latestMessage = chunk.messages.at(-1);
if (latestMessage?.content) {
console.log(`Agent: ${latestMessage.content}`);
} else if (AIMessage.isInstance(latestMessage) && latestMessage.tool_calls?.length) {
for (const call of latestMessage.tool_calls) {
console.log(`Tool call: ${call.name}(${JSON.stringify(call.args)})`);
}
}
}