스트림 중단하기

스트림 중단하기

진행 중인 스트림을 취소해야 하는 경우가 종종 있어요. 예를 들어 사용자가 응답이 마음에 안 든다고 느끼면 스트림을 멈추고 싶어 하죠. AI SDK의 여러 부분은 각기 다른 방식으로 스트림 취소를 지원합니다. Core 쪽에서 모델 요청을 취소하는 방법과 UI 훅에서 클라이언트 요청을 중단하는 방법, 그리고 이를 함께 연결하는 방법을 살펴볼게요.

출처: 공식문서

본문

AI SDK Core

AI SDK 함수는 abortSignal 인자를 지원해서 스트림을 취소할 수 있어요. 서버 쪽에서 LLM API로 가는 스트림을 취소하고 싶을 때, 예를 들어 요청의 abortSignal을 그대로 전달해서 쓰면 됩니다.

import { createTextStreamResponse, streamText, toTextStream } from 'ai';

export async function POST(req: Request) {
  const { prompt } = await req.json();

  const result = streamText({
    model: "xai/grok-4.6",
    prompt,
    // abort 신호 전달:
    abortSignal: req.signal,
    onAbort: ({ steps }) => {
      // 스트림이 중단됐을 때 정리 작업 처리
      console.log('Stream aborted after', steps.length, 'steps');
      // 부분 결과를 데이터베이스에 영속화
    },
  });

  return createTextStreamResponse({
    stream: toTextStream({ stream: result.stream }),
  });
}

onAbort 콜백에서 부분 결과를 저장하는 등 중단 시 정리 작업을 처리할 수 있어요.

AI SDK UI

useChat이나 useCompletion 같은 훅은 stop 헬퍼 함수를 제공해 스트림을 취소할 수 있어요. 이 함수는 클라이언트의 HTTP 요청을 중단(abort)합니다. 서버에서의 모델 요청까지 멈추려면, 서버 런타임이 클라이언트 연결 해제를 요청의 AbortSignal로 전파하고 라우트가 그 신호를 위처럼 AI SDK Core 호출에 전달해야 해요.

'use client';

import { useCompletion } from '@ai-sdk/react';

export default function Chat() {
  const { input, completion, stop, status, handleSubmit, handleInputChange } =
    useCompletion();

  return (
    <div>
      {(status === 'submitted' || status === 'streaming') && (
        <button type="button" onClick={() => stop()}>
          Stop
        </button>
      )}
      {completion}
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} />
      </form>
    </div>
  );
}

주의: 스트림 중단 기능은 스트림 재개(resumption)와 호환되지 않아요. useChat에서 resume: true를 쓰고 있다면 중단 기능이 재개 메커니즘을 깨뜨리므로, 중단(abort)과 재개(resume) 중 하나만 선택해야 합니다.

Vercel에서

Vercel에서는 요청 취소가 Node.js 런타임에서만 지원되고, 기능별로 활성화해야 해요. vercel.json에 있는 함수 설정에 supportsCancellation을 추가합니다.

{
  "functions": {
    "app/api/chat/route.ts": {
      "supportsCancellation": true
    }
  }
}

취소가 활성화되면 stop() 호출이 클라이언트 요청을 중단하고, Vercel이 req.signal을 중단하며, req.signalabortSignal로 전달하면 모델 요청이 취소돼요. supportsCancellation이 없으면 stop()은 클라이언트 쪽 스트림만 멈추고 서버 쪽 생성은 계속될 수 있습니다.

더 알아보기

  • abortSignal — AI SDK Core에서 서버→모델 요청을 취소하는 방법.
  • stop — UI 훅에서 클라이언트 스트림을 중단하는 헬퍼.
  • Vercel 배포 시 supportsCancellation 설정으로 서버 취소까지 연결.