Vercel AI SDK 완벽 가이드 | Streaming·Chat UI·RAG·Edge·실전 활용
이 글의 핵심
AI SDK는 모델 프로바이더를 통합한 스트리밍·도구 호출 계층을 제공하고, React 훅과 Route Handler를 연결합니다. 스트림 백프레셔·중단·토큰 비용·관측을 포함해 프로덕션에서 안전하게 운영하는 패턴을 정리합니다.
이 글의 핵심
Vercel AI SDK로 AI 앱을 구축하는 완벽 가이드입니다. Streaming, Chat UI, RAG, Edge Runtime, OpenAI/Anthropic 통합까지 실전 예제로 정리했습니다.
실무 경험 공유: 직접 구현한 Chat UI를 Vercel AI SDK로 전환하면서, 개발 시간이 80% 단축되고 Streaming 구현이 간편해진 경험을 공유합니다.
들어가며: “Chat UI 구현이 복잡해요”
실무에서 마주치는 문제들
Streaming이 어려워요
SSE 구현이 복잡합니다. Vercel AI SDK는 자동으로 처리합니다. Chat UI가 필요해요
처음부터 만들기 어렵습니다. Vercel AI SDK는 컴포넌트를 제공합니다. 다양한 LLM을 지원해야 해요
각각 연동이 복잡합니다. Vercel AI SDK는 통합 API를 제공합니다.
1. Vercel AI SDK란?
핵심 특징
Vercel AI SDK는 AI 앱 개발 도구입니다. 주요 기능
- Streaming: 실시간 응답
- Chat UI: React 컴포넌트
- 다중 LLM: OpenAI, Anthropic, Cohere
- Edge Runtime: 빠른 응답
- RAG: 문서 기반 응답
2. 설치 및 설정
설치
npm install ai
환경 변수
OPENAI_API_KEY=sk-...
3. Chat Completion
API Route
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export const runtime = 'edge';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: openai('gpt-4-turbo'),
messages,
});
return result.toAIStreamResponse();
}
클라이언트
// app/page.tsx
'use client';
import { useChat } from 'ai/react';
export default function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<div>
<div>
{messages.map((m) => (
<div key={m.id}>
<strong>{m.role}:</strong> {m.content}
</div>
))}
</div>
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={handleInputChange}
placeholder="Say something..."
/>
<button type="submit">Send</button>
</form>
</div>
);
}
4. Streaming
Text Generation
// app/api/generate/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { prompt } = await req.json();
const result = await streamText({
model: openai('gpt-4-turbo'),
prompt,
});
return result.toAIStreamResponse();
}
클라이언트
'use client';
import { useCompletion } from 'ai/react';
export default function Generate() {
const { completion, input, handleInputChange, handleSubmit } = useCompletion();
return (
<div>
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} />
<button type="submit">Generate</button>
</form>
<div>{completion}</div>
</div>
);
}
5. Function Calling
import { openai } from '@ai-sdk/openai';
import { streamText, tool } from 'ai';
import { z } from 'zod';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: openai('gpt-4-turbo'),
messages,
tools: {
weather: tool({
description: 'Get the weather for a location.. Vercel AI SDK 완벽 가이드에 대한 완전한 가이드입니다. 실전 예제와 함께 핵심 개념부터 고급 활용까지 다룹니다.',
parameters: z.object({
location: z.string().describe('The city name'),
}),
execute: async ({ location }) => {
const weather = await getWeather(location);
return weather;
},
}),
},
});
return result.toAIStreamResponse();
}
6. RAG 구현
import { openai } from '@ai-sdk/openai';
import { streamText, embed } from 'ai';
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_KEY!
);
export async function POST(req: Request) {
const { messages } = await req.json();
const lastMessage = messages[messages.length - 1].content;
// 1. 질문 임베딩
const { embedding } = await embed({
model: openai.embedding('text-embedding-3-small'),
value: lastMessage,
});
// 2. 유사 문서 검색
const { data: documents } = await supabase.rpc('match_documents', {
query_embedding: embedding,
match_threshold: 0.7,
match_count: 3,
});
// 3. 컨텍스트 구성
const context = documents.map((doc) => doc.content).join('\n\n');
// 4. LLM 호출
const result = await streamText({
model: openai('gpt-4-turbo'),
messages: [
{
role: 'system',
content: `Answer based on the following context:\n\n${context}`,
},
...messages,
],
});
return result.toAIStreamResponse();
}
7. 다중 LLM
Anthropic
import { anthropic } from '@ai-sdk/anthropic';
const result = await streamText({
model: anthropic('claude-3-opus-20240229'),
messages,
});
Ollama
import { createOllama } from 'ollama-ai-provider';
const ollama = createOllama();
const result = await streamText({
model: ollama('llama3'),
messages,
});
8. 실전 예제: 문서 챗봇
'use client';
import { useChat } from 'ai/react';
export default function DocumentChat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } =
useChat({
api: '/api/chat',
});
return (
<div className="flex flex-col h-screen">
<div className="flex-1 overflow-y-auto p-4">
{messages.map((m) => (
<div key={m.id} className={m.role === 'user' ? 'text-right' : 'text-left'}>
<div className="inline-block p-2 rounded bg-gray-100">
{m.content}
</div>
</div>
))}
{isLoading && <div>Thinking...</div>}
</div>
<form onSubmit={handleSubmit} className="p-4 border-t">
<input
value={input}
onChange={handleInputChange}
placeholder="Ask a question..."
className="w-full p-2 border rounded"
/>
</form>
</div>
);
}
심화: 스트리밍·도구 호출·프로덕션 운영
스트리밍과 백프레셔
streamText·toAIStreamResponse 경로는 토큰 단위 청크를 클라이언트로 밀어 넣습니다. 네트워크가 느리면 TCP 윈도우·소켓 버퍼에 데이터가 쌓이며, 일부 플랫폼에서는 함수 실행 시간과 응답 바이트에 상한이 있습니다. 긴 생성은 문장 단위가 아니라 작업 단위로 나누으며, 사용자에게 진행률 이벤트를 별도 채널로 보내는 편이 UX에 유리합니다.
중단(Abort)과 비용
AbortSignal을 streamText 등에 넘기면 사용자가 페이지를 떠날 때 upstream 요청을 중단해 토큰 비용을 줄일 수 있습니다. 클라이언트 useChat의 stop과 연결해 두면 반복 호출 누수를 막기 쉽습니다.
도구 호출의 신뢰 경계
tool({ execute }) 안에서 하는 일은 서버의 권한으로 실행됩니다. 사용자 입력을 그대로 쉘에 넣지 말고, 도구 인자에 Zod 스키마를 걸으며, 허용된 작업만 노출합니다. 외부 HTTP 호출에는 타임아웃·재시도·서킷 브레이커를 적용합니다.
관측·로깅
모델별 지연·토큰 수·에러 코드를 구조화 로그로 남기으며, PII는 마스킹합니다. RAG 경로에서는 검색된 문서 ID만 로깅해 디버깅 가능성과 개인정보 보호를 균형 있게 맞춥니다.
트러블슈팅
| 증상 | 점검 |
|---|---|
| 빈 스트림만 옴 | 모델명·API 키·프로바이더 장애 |
ReadableStream 관련 런타임 오류 | Edge vs Node API 차이, 런타임 플래그 |
| 도구만 반복 호출 | 프롬프트·maxSteps·도구 설명 과다 |
| CORS/SSE 문제 | Route Handler 경로·프록시·쿠키 도메인 |
정리 및 체크리스트
핵심 요약
- Vercel AI SDK: AI 앱 개발 도구
- Streaming: 실시간 응답
- Chat UI: React 컴포넌트
- 다중 LLM: OpenAI, Anthropic, Ollama
- Edge Runtime: 빠른 응답
- RAG: 문서 기반 응답
구현 체크리스트
- Vercel AI SDK 설치
- API Route 구현
- Chat UI 구현
- Streaming 구현
- Function Calling 구현
- RAG 구현
- 배포
같이 보면 좋은 글
- LangChain 완벽 가이드
- Next.js App Router 가이드
- OpenAI API 가이드
이 글에서 다루는 키워드
Vercel AI SDK, AI, Streaming, Chat, OpenAI, Next.js, React
자주 묻는 질문 (FAQ)
Q. LangChain과 비교하면 어떤가요?
A. Vercel AI SDK가 더 간단하고 React 통합이 완벽합니다. LangChain은 더 많은 기능을 제공합니다.
Q. 무료로 사용할 수 있나요?
A. 네, SDK는 무료이고 LLM API 비용만 발생합니다.
Q. Ollama를 사용할 수 있나요?
A. 네, ollama-ai-provider를 사용하면 가능합니다.
Q. 프로덕션에서 사용해도 되나요?
A. 네, Vercel에서 만든 안정적인 SDK입니다.