Agent SDK 스트리밍 입력 vs 단일 메시지
공식 기준: https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode
기준일: 2026-07-26 · CLI 기준 2.1.220
개요
Agent SDK 입력 모드는 두 가지입니다.
- Streaming Input Mode (기본·권장) — 장수명 대화형 세션
- Single Message Input — 일회 질의 + 세션 resume/continue
스트리밍 모드는 사용자 입력 수신, 인터럽트, 권한 요청, 세션 관리를 포함한 풍부한 상호작용을 제공합니다.
핵심 개념
| 능력 | Streaming | Single message |
|---|---|---|
| 이미지 첨부 | Yes | No |
| 메시지 큐·순차 처리 | Yes | No |
| 실시간 인터럽트 | Yes | No |
| 자연 다중 턴 | Yes | resume/continue로 제한적 |
| 도구·MCP 전체 | Yes | Yes (세션 범위 내) |
| 서버리스 일회 호출 | 가능하나 복잡 | 적합 |
상세
Streaming 동작
앱이 AsyncGenerator/async generator로 메시지를 yield하고, 에이전트는 도구·파일시스템을 쓰며 partial 응답을 스트림합니다. 세션은 살아 있고 파일시스템 상태가 유지됩니다.
이점: 이미지 업로드, 큐잉, 도구 통합, 실시간 피드백, 컨텍스트 지속.
import { query, type SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
import { readFile } from "fs/promises";
async function* generateMessages(): AsyncGenerator<SDKUserMessage> {
yield {
type: "user",
message: { role: "user", content: "Analyze this codebase for security issues" },
parent_tool_use_id: null
};
await new Promise((r) => setTimeout(r, 2000));
yield {
type: "user",
message: {
role: "user",
content: [
{ type: "text", text: "Review this architecture diagram" },
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: await readFile("diagram.png", "base64")
}
}
]
},
parent_tool_use_id: null
};
}
for await (const message of query({
prompt: generateMessages(),
options: { maxTurns: 10, allowedTools: ["Read", "Grep"] }
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
Python은 ClaudeSDKClient + async generator query가 스트리밍 입력에 적합합니다. generator 예외 시 TypeScript는 Claude Code process aborted by user처럼 보일 수 있고, Python은 debug 로그 후 hang처럼 보일 수 있으므로 generator 내부를 먼저 확인하세요.
Single message
일회 응답·이미지 불필요·stateless(Lambda 등)에 사용합니다.
제한: 직접 이미지, 동적 큐, 실시간 인터럽트, 자연 다중 턴 없음.
try {
for await (const message of query({
prompt: "Explain the authentication flow",
options: { maxTurns: 5, allowedTools: ["Read", "Grep"] }
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
} catch (error) {
console.error(`Query failed: ${error}`);
}
error_max_turns 등 오류 result 후 query()가 throw할 수 있어 try/catch가 필요합니다. 대화 이어가기는 continue/resume 옵션을 사용합니다.
체크리스트
- 대화형 UI·이미지가 필요하면 streaming 선택
- Lambda 일회면 single + 명시 오류 처리
- generator 예외 관측 방법을 준비했다
- maxTurns·결과 subtype을 처리한다