C.W.K.
Stream
Lesson 06 of 06 · published

Token Renderer 만들기 — SSE 와 UI 사이의 contract

~22 min · renderer, ui, production

Level 0Tokenizer
0 XP0/54 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Renderer 는 SSE 와 UI 사이의 contract. Bad renderer — 모든 token 마다 append + UI 잠금 + cancel 무시. Good renderer — frame budget 안에서 append + cancel() 노출 + done 시 flush. 차이는 사용자가 직접 느껴.

16ms frame budget

50 token/sec 에서 매 token 마다 React re-render 박으면 reconciliation 이 chokes. 16ms requestAnimationFrame tick 에 한 번씩 flush — 사용자 눈은 못 잡지만 React 는 살아남아. cwkPippa frontend 가 정확히 이 패턴.

Cancellation 이 second contract

사용자가 'Stop'. Renderer 가 (1) SSE stream close (server 도 generation 멈춤), (2) accumulated text 를 UI 에 flush, (3) partial output 보존 (blank 안 만듦). Cancel wiring 없으면 'Stop' 은 응답을 시야에서 가리는 것뿐 — 모델은 server-side 에서 토큰 계속 태움.

cwkPippa 의 render

per-message accumulator + 16ms requestAnimationFrame flush loop. Cancel first-class — abort signal 이 SSE consumer 까지 wired, abort 시에도 partial text 가 JSONL 에 보존. 같은 패턴이 어떤 React/Streamlit 앱에서도 통함.

Code

Token renderer with cursor + cancel·python
import sys
import signal

class TokenRenderer:
    def __init__(self):
        self.buffer = ""
        self.cancelled = False

    def on_token(self, token: str):
        """Append a token to the display."""
        if self.cancelled:
            return
        self.buffer += token
        sys.stdout.write(token)
        sys.stdout.flush()

    def on_done(self, usage=None):
        """Stream complete."""
        print()  # newline
        if usage:
            print(f"[{usage.get('total_tokens', '?')} tokens]")

    def on_error(self, error):
        """Handle streaming error."""
        print(f"\\n[Error: {error}]")

    def cancel(self):
        """Stop processing further tokens."""
        self.cancelled = True
        print("\\n[Cancelled]")

# Usage with streaming
renderer = TokenRenderer()
stream = client.responses.create(
    model="gpt-5.4", input="Tell me a story.", stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        renderer.on_token(event.delta)
    elif event.type == "response.completed":
        renderer.on_done()

External links

Exercise

CLI renderer build — token 을 stdout 으로 stream, Ctrl-C 로 mid-stream cancel (handler 가 stream close + rendered text print), [DONE] 후 final newline flush. 3 지점에서 cancel 테스트 — 첫 token 전, mid-stream, [DONE] 후.

Progress

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

댓글 0

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

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