본문으로 건너뛰기
CodeBerry
  1. Claude 가이드/
#claude-guide · [Claude 가이드]

Claude 가이드 #24: Fine-grained Tool Streaming — AI가 긴 글을 한 줄씩 보여주기

Claude 가이드 - 이 글은 시리즈의 일부입니다.
부분 : 이 글

이 글은 Claude API 공식 문서의 Fine-grained Tool Streaming 페이지를 정리한 글입니다. 원문: https://platform.claude.com/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming 마지막 확인: 2026-06-07


1. 한 줄 요약
#

Claude가 긴 결과를 다 만든 뒤에 보여주지 않고, 만들어지는 즉시 한 줄씩 흘려보내주는 기능입니다.


2. 무엇이고 왜 좋을까
#

영화관에서 영화가 끝까지 다 만들어진 뒤에야 상영을 시작하는 게 아니라, 촬영 즉시 한 장면씩 스크린에 비추는 것과 비슷합니다.

원래 Claude가 도구(Tool)에게 결과를 넘길 때는 “내용이 문법적으로 맞는지” 한 번 검사한 다음에 전달합니다. 그래서 결과가 길면 다 만들어질 때까지 기다려야 했어요. Fine-grained Tool Streaming(세밀한 도구 스트리밍) 은 이 검사 과정을 건너뛰고, AI가 한 글자 만들 때마다 바로 우리에게 보내줍니다.

핵심 수치 하나: 보통 도구 결과가 5초 뒤에 한꺼번에 보였다면, 이 기능을 켜면 0.5초 안에 첫 줄이 보이기 시작합니다. 긴 글일수록 체감 차이가 큽니다.

대신 작은 단점이 하나 있습니다 — 검사를 건너뛴 만큼, 가끔 문장이 중간에 끊어진 채로 도착할 수 있습니다. (이건 5번 섹션에서 자세히 다룰게요.)


3. 이런 상황에서 써요
#

상황 1: 학생 — 강의 노트 정리
#

“AI에게 100페이지 강의 PDF를 주고, 마크다운 노트로 다시 써달라고 했어요. 그런데 5분 동안 화면이 멈춰 있어서 답답해요.”

이 기능을 켜두면 AI가 첫 문단을 만드는 순간 바로 화면에 나타납니다. 기다리는 동안 “어, 잘 작동하고 있구나” 라는 안심을 얻을 수 있고, 내용이 마음에 안 들면 일찍 중단할 수도 있습니다. 영화를 1초도 안 보고 평가하지 않아도 되는 거죠.

상황 2: 직장인 — 회사 매뉴얼을 챗봇 답변으로
#

“회사 정책 매뉴얼을 토대로 직원 질문에 답하는 챗봇을 만들었는데, 답변이 길어질 때마다 직원들이 ‘이거 멈춘 거 아니냐’고 물어요.”

스트리밍을 켜두면 답변 첫 줄이 거의 즉시 나타납니다. ChatGPT 화면에서 글자가 또르륵 나타나는 그 경험이죠. 사람은 진행이 보이면 훨씬 길게 기다려줍니다. 같은 30초라도 “멈춘 듯한 30초"와 “한 글자씩 흐르는 30초"는 완전히 다른 느낌이에요.

상황 3: 일반인 — 긴 시나 편지 받아쓰기
#

“AI에게 결혼식 축사를 길게 써달라고 부탁했는데, 한참 기다린 뒤에야 결과가 나타나요. 중간중간 톤을 바꿔달라고 말하고 싶었어요.”

스트리밍을 켜두면 첫 문장이 나오자마자 톤이 마음에 드는지 확인할 수 있습니다. “어, 이건 좀 딱딱한데?” 싶으면 굳이 끝까지 기다리지 않고 다시 부탁할 수 있죠. AI와의 대화가 일방통행이 아니라 실시간 협업에 가까워집니다.


4. 가볍게 시작하기
#

💻 개발 경험이 있으신가요? 아래 코드는 Python 기준 가장 짧은 예시입니다. 비개발자라면 “아, 한 줄만 추가하면 되는구나” 정도로 보고 넘어가셔도 좋습니다.

import anthropic

client = anthropic.Anthropic()

# 스트리밍을 위한 messages.stream 사용
with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=2048,
    tools=[{
        "name": "make_file",
        "description": "텍스트를 파일에 씁니다",
        "eager_input_streaming": True,   # ← 이 한 줄이 핵심
        "input_schema": {
            "type": "object",
            "properties": {
                "filename": {"type": "string"},
                "lines_of_text": {"type": "array"},
            },
            "required": ["filename", "lines_of_text"],
        },
    }],
    messages=[{
        "role": "user",
        "content": "긴 시 한 편을 써서 poem.txt 파일로 만들어줘",
    }],
) as stream:
    # 한 글자씩 흘러나오는 결과를 바로 확인할 수 있어요
    final = stream.get_final_message()
    print(f"입력 토큰: {final.usage.input_tokens}")

진짜 핵심은 도구 정의 안에 들어간 "eager_input_streaming": True 이 한 줄입니다. “성급하게(eager) 입력을 흘려보내라"는 뜻이에요. 이걸 켜면 Claude가 결과의 문법 검사를 끝낼 때까지 기다리지 않고, 만든 즉시 우리 쪽으로 한 토막씩 보내줍니다.

with client.messages.stream(...) 부분은 “이 결과는 한 번에 받지 말고 흐르게 해주세요"라는 의미예요. 스트리밍 모드와 eager_input_streaming, 두 가지를 같이 켜야 빛을 발합니다.


5. 흔한 오해와 함정
#

⚠️ 함정 1: “켜기만 하면 무조건 빨라지는 거죠?”
#

빨라지는 건 결과를 보기 시작하는 시간이지, 전체 완성 시간이 아닙니다. AI가 1만 글자를 만드는 데 걸리는 총 시간은 거의 같아요. 다만 1초 만에 첫 줄이 보이느냐, 30초 뒤에 다 보이느냐의 차이가 있습니다. 길고 큰 결과물을 만들 때 “기다리는 답답함"을 줄이는 용도라고 생각하시면 됩니다.

⚠️ 함정 2: “중간에 글자가 깨져 보여요”
#

이게 가장 흔한 오해입니다. 이 기능은 문법 검사를 건너뛰기 때문에, 받는 중간에는 {"name": "홍길동 처럼 따옴표가 안 닫힌 상태로 보일 수 있어요. ❌ 이걸 보고 “고장났다"고 생각하지 마세요. ✅ 정상입니다. 끝까지 받고 나서 한꺼번에 해석하면 됩니다.

⚠️ 함정 3: “AI가 갑자기 멈췄어요”
#

max_tokens(최대 글자 수) 한도에 닿으면, 문장이 딱 그 자리에서 잘려서 끝납니다. 일반 모드에서는 문법을 맞춰서 끝내주는데, 스트리밍 모드는 그렇지 않아요. 긴 글을 만들 예정이라면 max_tokens를 넉넉하게 (예: 4096 이상) 잡아두세요. 잘린 결과를 받아도 당황하지 말고, “이건 한도 초과로 잘린 거구나” 알아채면 됩니다.


6. 한 단계 더 (관심 있는 분만)
#

🎯 여기까지 오신 분 환영합니다. 이 섹션은 더 깊이 알고 싶으신 분을 위한 보너스입니다. 본문만 읽으셔도 충분합니다.

스트리밍으로 받은 조각들을 직접 이어 붙이는 방법입니다. SDK가 알아서 해주는 경우가 대부분이지만, 진행률 표시줄을 만들거나 한 줄씩 화면에 띄우고 싶을 때 쓸 수 있어요.

import json

tool_inputs = {}   # 도구별로 모으는 글자 모음통

with client.messages.stream(...) as stream:
    for event in stream:
        # 도구 호출 시작 → 빈 문자열 준비
        if event.type == "content_block_start" \
                and event.content_block.type == "tool_use":
            tool_inputs[event.index] = ""

        # 도구 호출 도중 → 조각을 이어 붙이기
        elif event.type == "content_block_delta" \
                and event.delta.type == "input_json_delta":
            tool_inputs[event.index] += event.delta.partial_json
            # 여기서 화면에 한 글자씩 표시할 수도 있어요

        # 도구 호출 끝 → 다 모인 글자를 한꺼번에 해석
        elif event.type == "content_block_stop":
            parsed = json.loads(tool_inputs[event.index])
            print(f"완성된 도구 입력: {parsed}")

핵심은 세 단계입니다 — “시작” 신호에 빈 그릇을 준비하고, “조각” 신호마다 그릇에 부어 넣고, “끝” 신호에 그릇 안의 글자를 해석합니다. 도착하는 조각이 잘못된 문법이어도 일단 받아두고, 끝까지 모인 다음에 검사한다는 점이 포인트예요.


7. 한 마디
#

처음 들으면 “스트리밍? 토큰? 어렵네” 싶지만, 실제로 코드에서 바뀌는 건 단 한 줄입니다. eager_input_streaming: True 만 추가하면 AI가 우리에게 결과를 보여주는 방식이 완전히 달라져요.

막히는 부분이 있다면 함정 1~3 중 하나일 가능성이 큽니다 — 특히 “글자가 중간에 깨져 보인다"고 놀라셨다면, 그건 정상이에요. 끝까지 받아 보세요. 작은 기능 하나가 사용자 경험을 크게 바꿀 수 있다는 걸 보여주는 좋은 예입니다.

다음 글에서는 Claude 가이드 #25 — 컨텍스트 윈도우(Context Windows): AI가 한 번에 읽을 수 있는 글의 양을 다룹니다. AI가 “긴 자료를 어디까지 한꺼번에 이해할 수 있는가"의 비밀을 풀어볼게요.


Claude API 공식 문서를 한국어로 풀어쓴 시리즈입니다. 원문 정확성이 가장 우선, 의역과 친근함은 그 위에서.

성경재
작성자
성경재
홈랩, 셀프호스팅, AI/ML, 데이터 분석에 관심이 많습니다.
Claude 가이드 - 이 글은 시리즈의 일부입니다.
부분 : 이 글