핵심 요약
Vercel AI SDK 6 GA. RSC streamUI, structured output 표준, multi-step tool calling 자동. 사내 5개 LLM 앱 마이그레이션 후 코드 -42%, vendor switch 1분.
1. RSC streamUI — 컴포넌트 스트리밍
// app/page.tsx
import { streamUI } from 'ai/rsc'
import { anthropic } from '@ai-sdk/anthropic'
export async function chat(message: string) {
'use server'
const result = await streamUI({
model: anthropic('claude-sonnet-4-9'),
prompt: message,
text: ({ content }) => <Bubble role="assistant">{content}</Bubble>,
tools: {
weather: {
description: '날씨 조회',
parameters: z.object({ city: z.string() }),
generate: async ({ city }) => {
const data = await fetchWeather(city)
return <WeatherCard data={data} />
},
},
},
})
return result.value
}
2. Provider 추상화 — vendor switch
// 환경변수로 vendor 결정
import { anthropic } from '@ai-sdk/anthropic'
import { openai } from '@ai-sdk/openai'
import { google } from '@ai-sdk/google'
const model = process.env.LLM === 'gpt'
? openai('gpt-5.5')
: process.env.LLM === 'gemini'
? google('gemini-3-pro')
: anthropic('claude-sonnet-4-9')
await generateText({ model, prompt: '...' })
3. Multi-step tool calling — 자동 루프
await generateText({
model: anthropic('claude-sonnet-4-9'),
prompt: '도쿄와 서울 날씨 비교',
tools: { weather: {...} },
maxSteps: 5, // 자동 multi-step
})
LLM이 도구 호출 → 결과 받음 → 다음 도구 호출 → ... 자동 반복. 사용자 코드 단순.
4. Structured outputs — Zod 통합
const { object } = await generateObject({
model: anthropic('claude-sonnet-4-9'),
schema: z.object({
summary: z.string(),
tags: z.array(z.string()),
rating: z.number().min(1).max(5),
}),
prompt: 'review.txt를 분석해줘',
})
5. 함정
- Provider별 token 가격 차이 — usage tracking 통합 안 됨, custom middleware 권장
- Streaming hydration — RSC stream + client component 혼용 시 boundary 명확히
- Tool retry — generate 함수 안에서 throw 시 maxSteps 카운트 소비, 명시 retry 작성
- Schema strictness — Zod strict mode 시 LLM 응답 거부, 적당히 partial로

댓글 0