32 KiB
| title | source | author | published | created | description | tags | |
|---|---|---|---|---|---|---|---|
| Streaming Input | https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode | 2026-04-17 | Understanding the two input modes for Claude Agent SDK and when to use each |
|
Overview
The Claude Agent SDK supports two distinct input modes for interacting with agents:
- Streaming Input Mode (Default & Recommended) - A persistent, interactive session
- Single Message Input - One-shot queries that use session state and resuming
This guide explains the differences, benefits, and use cases for each mode to help you choose the right approach for your application.
Streaming Input Mode (Recommended)
Streaming input mode is the preferred way to use the Claude Agent SDK. It provides full access to the agent’s capabilities and enables rich, interactive experiences.
It allows the agent to operate as a long lived process that takes in user input, handles interruptions, surfaces permission requests, and handles session management.
How It Works
r_t-1776422460999{font-family:inherit;font-size:16px;fill:#ccc;}#mermaid-r_t-1776422460999.error-icon{fill:#a44141;}#mermaid-r_t-1776422460999.error-text{fill:#ddd;stroke:#ddd;}#mermaid-r_t-1776422460999.edge-thickness-normal{stroke-width:1px;}#mermaid-r_t-1776422460999.edge-thickness-thick{stroke-width:3.5px;}#mermaid-r_t-1776422460999.edge-pattern-solid{stroke-dasharray:0;}#mermaid-r_t-1776422460999.edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-r_t-1776422460999.edge-pattern-dashed{stroke-dasharray:3;}#mermaid-r_t-1776422460999.edge-pattern-dotted{stroke-dasharray:2;}#mermaid-r_t-1776422460999.marker{fill:lightgrey;stroke:lightgrey;}#mermaid-r_t-1776422460999.marker.cross{stroke:lightgrey;}#mermaid-r_t-1776422460999 svg{font-family:inherit;font-size:16px;}#mermaid-r_t-1776422460999 p{margin:0;}#mermaid-r_t-1776422460999.actor{stroke:#ccc;fill:#1f2020;}#mermaid-r_t-1776422460999 text.actor>tspan{fill:lightgrey;stroke:none;}#mermaid-r_t-1776422460999.actor-line{stroke:#ccc;}#mermaid-r_t-1776422460999.messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:lightgrey;}#mermaid-r_t-1776422460999.messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:lightgrey;}#mermaid-r_t-1776422460999 #arrowhead path{fill:lightgrey;stroke:lightgrey;}#mermaid-r_t-1776422460999.sequenceNumber{fill:black;}#mermaid-r_t-1776422460999 #sequencenumber{fill:lightgrey;}#mermaid-r_t-1776422460999 #crosshead path{fill:lightgrey;stroke:lightgrey;}#mermaid-r_t-1776422460999.messageText{fill:lightgrey;stroke:none;}#mermaid-r_t-1776422460999.labelBox{stroke:#ccc;fill:#1f2020;}#mermaid-r_t-1776422460999.labelText,#mermaid-r_t-1776422460999.labelText>tspan{fill:lightgrey;stroke:none;}#mermaid-r_t-1776422460999.loopText,#mermaid-r_t-1776422460999.loopText>tspan{fill:lightgrey;stroke:none;}#mermaid-r_t-1776422460999.loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:#ccc;fill:#ccc;}#mermaid-r_t-1776422460999.note{stroke:hsl(180, 0%, 18.3529411765%);fill:hsl(180, 1.5873015873%, 28.3529411765%);}#mermaid-r_t-1776422460999.noteText,#mermaid-r_t-1776422460999.noteText>tspan{fill:rgb(183.8476190475, 181.5523809523, 181.5523809523);stroke:none;}#mermaid-r_t-1776422460999.activation0{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:#ccc;}#mermaid-r_t-1776422460999.activation1{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:#ccc;}#mermaid-r_t-1776422460999.activation2{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:#ccc;}#mermaid-r_t-1776422460999.actorPopupMenu{position:absolute;}#mermaid-r_t-1776422460999.actorPopupMenuPanel{position:absolute;fill:#1f2020;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-r_t-1776422460999.actor-man line{stroke:#ccc;fill:#1f2020;}#mermaid-r_t-1776422460999.actor-man circle,#mermaid-r_t-1776422460999 line{stroke:#ccc;fill:#1f2020;stroke-width:2px;}#mermaid-r_t-1776422460999:root{--mermaid-font-family:inherit;}
Benefits
Image Uploads
Attach images directly to messages for visual analysis and understanding
Queued Messages
Send multiple messages that process sequentially, with ability to interrupt
Tool Integration
Full access to all tools and custom MCP servers during the session
Hooks Support
Use lifecycle hooks to customize behavior at various points
Real-time Feedback
See responses as they’re generated, not just final results
Context Persistence
Maintain conversation context across multiple turns naturally
Implementation Example
import { query } from "@anthropic-ai/claude-agent-sdk";
import { readFile } from "fs/promises";
async function* generateMessages() {
// First message
yield {
type: "user" as const,
message: {
role: "user" as const,
content: "Analyze this codebase for security issues"
}
};
// Wait for conditions or user input
await new Promise((resolve) => setTimeout(resolve, 2000));
// Follow-up with image
yield {
type: "user" as const,
message: {
role: "user" as const,
content: [
{
type: "text",
text: "Review this architecture diagram"
},
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: await readFile("diagram.png", "base64")
}
}
]
}
};
}
// Process streaming responses
for await (const message of query({
prompt: generateMessages(),
options: {
maxTurns: 10,
allowedTools: ["Read", "Grep"]
}
})) {
if (message.type === "result") {
console.log(message.result);
}
}
Single Message Input
Single message input is simpler but more limited.
When to Use Single Message Input
Use single message input when:
- You need a one-shot response
- You do not need image attachments, hooks, etc.
- You need to operate in a stateless environment, such as a lambda function
Limitations
Single message input mode does not support:
- Direct image attachments in messages
- Dynamic message queueing
- Real-time interruption
- Hook integration
- Natural multi-turn conversations
Implementation Example
import { query } from "@anthropic-ai/claude-agent-sdk";
// Simple one-shot query
for await (const message of query({
prompt: "Explain the authentication flow",
options: {
maxTurns: 1,
allowedTools: ["Read", "Grep"]
}
})) {
if (message.type === "result") {
console.log(message.result);
}
}
// Continue conversation with session management
for await (const message of query({
prompt: "Now explain the authorization process",
options: {
continue: true,
maxTurns: 1
}
})) {
if (message.type === "result") {
console.log(message.result);
}
}