본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

Streaming, Tool Use, Structured Output

~30 min · inference, streaming

Level 0스카우트
0 XP0/50 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

스트리밍은 같은 응답을 조각으로 받는 계약이야

client.chat_completion(..., stream=True)ChatCompletionStreamOutput을 차례로 내놓는 generator를 돌려줘. 새 텍스트는 각 조각의 .choices[0].delta.content에 있어. 모양이 OpenAI 스트림과 호환되므로 같은 UI 처리기를 재사용할 수 있어.

도구 호출은 실행 루프까지 완성해야 해

tools에 JSON Schema 형태의 정의를 넘기면 모델이 tool_calls를 돌려줄 수 있어. 애플리케이션이 호출을 검증하고 로컬에서 실행한 뒤 결과를 role='tool' 메시지로 붙여 다시 요청해야 한 차례가 끝나.

구조화 출력은 생성보다 검증이 중요해

프롬프트 뒤 검증, provider의 response_format, Pydantic 기반 Outlines나 Instructor를 쓸 수 있어. 여러 provider를 오갈 때는 스키마 검증과 재시도까지 묶어 주는 세 번째 방식이 가장 일관적이야.

Code

Streaming chat·python
from huggingface_hub import InferenceClient

client = InferenceClient(model="meta-llama/Llama-3.1-8B-Instruct", provider="hf-inference")

stream = client.chat_completion(
    messages=[{"role": "user", "content": "Count from 1 to 5 slowly."}],
    max_tokens=80,
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    print(delta, end="", flush=True)
print()
Tool call loop·python
from huggingface_hub import InferenceClient
import json

client = InferenceClient(model="meta-llama/Llama-3.1-70B-Instruct", provider="together")

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

messages = [{"role": "user", "content": "What's the weather in Seoul?"}]
resp = client.chat_completion(messages=messages, tools=tools, max_tokens=120)
choice = resp.choices[0]

if choice.message.tool_calls:
    call = choice.message.tool_calls[0]
    args = json.loads(call.function.arguments)
    # 툴 실행한 척
    tool_result = {"city": args["city"], "temp_c": 22, "conditions": "clear"}
    messages.append(choice.message)
    messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(tool_result)})
    final = client.chat_completion(messages=messages, max_tokens=120)
    print(final.choices[0].message.content)

External links

Exercise

Streaming 챗 루프 wire 해서 도착하는 chunk 출력. 그다음 툴 하나 (get_time fixed string 돌려줌) 추가. 모델이 콜할지 결정하는지 검증. response 가 tool call 일 때 vs plain message 일 때 streaming 동작 어떻게 변하는지 메모.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.