4.8 KiB
4.8 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Streaming vs Single Message Input |
|
|
|
2026-04-17 | 2026-04-17 |
Overview
The Claude Agent SDK supports two distinct input modes for query():
| Mode | Type | Use case |
|---|---|---|
| Streaming Input | AsyncGenerator of messages |
Long-lived sessions, multi-turn, images, hooks |
| Single Message | string |
One-shot queries, stateless environments |
Streaming input is the default and recommended approach.
Streaming Input Mode
Pass an AsyncGenerator as the prompt. The agent runs as a long-lived process that consumes messages as they are yielded, handling tool execution and session state between turns.
Capabilities (streaming only)
- Image uploads — attach
base64images directly in message content - Queued messages — yield multiple messages; they process sequentially
- Interruption — send an interrupt/cancel mid-session
- Hook integration — lifecycle hooks fire normally
- Real-time feedback — responses stream back as tokens are generated
- Context persistence — conversation context maintained across all turns automatically
How it works
App yields Message 1 → Agent executes tools → Streams partial response back
App yields Message 2 + Image → Agent processes → Streams response 2
App queues Message 3 → App sends Interrupt → Agent handles interruption
↕
Session stays alive; file system state persists
TypeScript example
import { query } from "@anthropic-ai/claude-agent-sdk";
import { readFile } from "fs/promises";
async function* generateMessages() {
yield {
type: "user" as const,
message: {
role: "user" as const,
content: "Analyze this codebase for security issues"
}
};
await new Promise((resolve) => setTimeout(resolve, 2000));
// Follow-up with image attachment
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")
}
}
]
}
};
}
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
Pass a plain string as prompt. Best for simple one-shot tasks or stateless environments (e.g. Lambda functions).
Limitations (single message)
- No direct image attachments
- No dynamic message queueing
- No real-time interruption
- No hook integration
- No natural multi-turn conversations
Session resuming with single message
Use continue: true to resume a previous session:
import { query } from "@anthropic-ai/claude-agent-sdk";
// First 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);
}
// Resume same session
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);
}
Choosing the Right Mode
| Requirement | Use |
|---|---|
| Multi-turn conversation | Streaming |
| Image attachments | Streaming |
| Hooks / lifecycle events | Streaming |
| Real-time token streaming | Streaming |
| Lambda / stateless function | Single message |
| Simple one-shot query | Single message |
| Session resume across calls | Single message + continue: true |
Key Takeaways
- Streaming input =
AsyncGeneratorprompt — yield messages as needed; the session stays alive between them - Single message =
stringprompt — simpler API but loses images, hooks, interrupts, and natural multi-turn - Streaming is the default; single message is the escape hatch for stateless environments
continue: truelets single-message mode resume a prior session without rebuilding the generator- Real-time token streaming (output side) works independently of which input mode you choose — see wiki/agent-sdk/streaming-output
- Hooks only fire in streaming input mode; see wiki/agent-sdk/sdk-hooks for hook setup
- For approval/interruption patterns see wiki/agent-sdk/user-input-approvals
Sources
raw/Streaming Input.md— source: https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode