마이그레이션 가이드
이 가이드는 TanStack AI를 이전 버전에서 최신 버전으로 마이그레이션하는 방법을 안내합니다. 주요 변경 사항은 향상된 트리 셰이킹, 더 명확한 API 이름, 간소화된 구성에 초점을 둡니다.
변경 사항 개요
이 릴리스의 주요 호환성 변경 사항은 다음과 같습니다.
- 어댑터 함수 분리 - 최적의 트리 셰이킹을 위해 어댑터가 활동별 함수로 분리됩니다.
- 공통 옵션 평탄화 - 옵션이 중첩되지 않고 구성에 직접 배치됩니다.
providerOptions이름 변경 - 명확성을 위해modelOptions로 변경됩니다.toResponseStream이름 변경 - 명확성을 위해toServerSentEventsStream으로 변경됩니다.- 임베딩 제거 후 재도입 - 기존
embedding()API가 제거되었으며, 멀티모달을 지원하는 새로운embed()활동으로 임베딩이 돌아옵니다.
1. 어댑터 함수 분리
최적의 트리 셰이킹을 위해 어댑터가 활동별 함수로 분리되었습니다. 이제 하나의 모놀리식 어댑터를 가져오는 대신 각 활동 유형에 필요한 함수를 가져옵니다.
이전
import { chat } from '@tanstack/ai'
import { openai } from '@tanstack/ai-openai'
const stream = chat({
adapter: openai(),
model: 'gpt-5.2',
messages: [{ role: 'user', content: 'Hello!' }],
})
이후
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages: [{ role: 'user', content: 'Hello!' }],
})
주요 변경 사항
- 모델을 어댑터 팩토리에 전달 - 이제 모델 이름을 어댑터 함수에 직접 전달합니다(예:
openaiText('gpt-5.2')). - 별도의
model매개변수 없음 - 모델이 어댑터에 저장되므로chat()에 별도로 전달할 필요가 없습니다. - 활동별 가져오기 - 필요한 항목만 가져옵니다(예:
openaiText,openaiSummarize,openaiImage).
모든 어댑터 함수
이제 각 provider 패키지는 활동별 함수를 내보냅니다.
OpenAI
import {
openaiText, // Chat/text generation
openaiSummarize, // Summarization
openaiImage, // Image generation
openaiSpeech, // Text-to-speech
openaiTranscription, // Audio transcription
openaiVideo, // Video generation
} from '@tanstack/ai-openai'
Anthropic
import {
anthropicText, // Chat/text generation
anthropicSummarize, // Summarization
} from '@tanstack/ai-anthropic'
Gemini
import {
geminiText, // Chat/text generation
geminiSummarize, // Summarization
geminiImage, // Image generation
geminiSpeech, // Text-to-speech (experimental)
} from '@tanstack/ai-gemini'
Ollama
import {
ollamaText, // Chat/text generation
ollamaSummarize, // Summarization
} from '@tanstack/ai-ollama'
마이그레이션 예시
다음은 어댑터 사용을 마이그레이션하는 전체 예시입니다.
이전
import { chat } from '@tanstack/ai'
import { openai } from '@tanstack/ai-openai'
import { anthropic } from '@tanstack/ai-anthropic'
type Provider = 'openai' | 'anthropic'
function getAdapter(provider: Provider) {
switch (provider) {
case 'openai':
return openai()
case 'anthropic':
return anthropic()
}
}
const stream = chat({
adapter: getAdapter(provider),
model: provider === 'openai' ? 'gpt-5.2' : 'claude-sonnet-4-5',
messages,
})
이후
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { anthropicText } from '@tanstack/ai-anthropic'
type Provider = 'openai' | 'anthropic'
const messages = [{ role: 'user' as const, content: 'Hello!' }]
const adapters = {
openai: () => openaiText('gpt-5.2'),
anthropic: () => anthropicText('claude-sonnet-4-5'),
}
const provider: Provider = 'openai'
const stream = chat({
adapter: adapters[provider](),
messages,
})
2. 공통 옵션 평탄화
이전에 options 객체에 중첩되었던 공통 옵션이 이제 구성에 직접 배치됩니다.
이전
const stream = chat({
adapter: openai(),
model: 'gpt-5.2',
messages,
options: {
temperature: 0.7,
maxTokens: 1000,
topP: 0.9,
},
})
이후
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages,
temperature: 0.7,
maxTokens: 1000,
topP: 0.9,
})
사용 가능한 옵션
이제 다음 옵션을 최상위 수준에서 사용할 수 있습니다.
temperature- 무작위성을 제어합니다(0.0~2.0).topP- 누클리어스 샘플링 매개변수입니다.maxTokens- 생성할 최대 토큰 수입니다.metadata- 추가로 연결할 메타데이터입니다.
주의 — 샘플링 위치가 이후 변경되었습니다(호환성 변경). 이후 릴리스에서 샘플링 속성(
temperature,topP,maxTokens)이chat()의 루트에서 제거되고 provider-nativemodelOptions에 배치되었습니다. 루트에 전달해도 더 이상 타입 검사를 통과하지 않으며 적용되지 않습니다. 코드모드와 provider-native 키 이름은 샘플링 옵션을 modelOptions로 이동을 참조하세요.metadata는 루트에 유지됩니다.
3. providerOptions → modelOptions
명확성을 위해 providerOptions 매개변수의 이름이 modelOptions로 변경되었습니다. 이 매개변수에는 provider와 모델에 따라 달라지는 모델별 옵션이 포함됩니다.
이전
const stream = chat({
adapter: openai(),
model: 'gpt-5.2',
messages,
providerOptions: {
// OpenAI-specific options
responseFormat: { type: 'json_object' },
logitBias: { '123': 1.0 },
},
})
이후
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages,
modelOptions: {
// OpenAI-specific options
responseFormat: { type: 'json_object' },
logitBias: { '123': 1.0 },
},
})
타입 안전성
modelOptions는 사용하는 어댑터와 모델을 기준으로 완전히 타입이 지정됩니다.
import { openaiText } from '@tanstack/ai-openai'
const adapter = openaiText('gpt-5.2')
// TypeScript knows the exact modelOptions type for gpt-5.2
const stream = chat({
adapter,
messages,
modelOptions: {
// Autocomplete and type checking for gpt-5.2 options
responseFormat: { type: 'json_object' },
},
})
4. toResponseStream → toServerSentEventsStream
toResponseStream 함수의 목적을 더 잘 나타내도록 toServerSentEventsStream으로 이름이 변경되었습니다. 또한 API가 약간 변경되었습니다.
이전
import { chat, toResponseStream } from '@tanstack/ai'
import { openai } from '@tanstack/ai-openai'
export async function POST(request: Request) {
const { messages } = await request.json()
const abortController = new AbortController()
const stream = chat({
adapter: openai(),
model: 'gpt-5.2',
messages,
abortController,
})
return toResponseStream(stream, { abortController })
}
이후
import { chat, toServerSentEventsStream } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
export async function POST(request: Request) {
const { messages } = await request.json()
const abortController = new AbortController()
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages,
abortController,
})
const readableStream = toServerSentEventsStream(stream, abortController)
return new Response(readableStream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
},
})
}
주요 변경 사항
- 함수 이름 변경 -
toResponseStream→toServerSentEventsStream - ReadableStream 반환 - 이제
Response대신ReadableStream을 반환합니다. - 수동 Response 생성 - 적절한 헤더와 함께
Response객체를 직접 생성합니다. - AbortController 매개변수 - 옵션에 포함하는 대신 별도의 매개변수로 전달합니다.
대안: HTTP 스트림 형식
SSE 대신 HTTP 스트림 형식(줄바꿈으로 구분된 JSON)이 필요하면 toHttpStream을 사용합니다.
import { toHttpStream } from '@tanstack/ai'
const readableStream = toHttpStream(stream, abortController)
return new Response(readableStream, {
headers: {
'Content-Type': 'application/x-ndjson',
},
})
5. 임베딩 제거 후 embed()로 재도입
원래의 embedding() 함수가 TanStack AI에서 제거되었습니다. 이후 임베딩은 다른 API를 사용하는 새로운 활동으로 돌아왔습니다. 즉, 멀티모달 입력과 모델별 타입 안전성을 지원하는 단일 embed() 함수입니다. 기존 embedding() 이름과 openaiEmbed() 같은 어댑터 팩토리는 다시 제공되지 않습니다.
이전
import { embedding } from '@tanstack/ai'
import { openaiEmbed } from '@tanstack/ai-openai'
const result = await embedding({
adapter: openaiEmbed(),
model: 'text-embedding-3-small',
input: 'Hello, world!',
})
이후
import { embed } from '@tanstack/ai'
import { openaiEmbedding } from '@tanstack/ai-openai'
const result = await embed({
adapter: openaiEmbedding('text-embedding-3-small'),
input: 'Hello, world!',
})
console.log(result.embeddings[0]?.vector)
기존 API와의 주요 차이점은 다음과 같습니다.
- 모델을 어댑터 팩토리로 이동 - 다른 모든 활동과 마찬가지로 별도의
model옵션 대신openaiEmbedding('text-embedding-3-small')을 사용합니다. - 하나 또는 여러 입력에 단일 함수 사용 -
input은 단일 항목이나 배열을 허용하며, 결과에는 항상 입력 항목마다 하나의 벡터가 포함된embeddings배열이 있습니다. - 멀티모달 입력 - Cohere embed-v4.0 및 Amazon Titan Multimodal과 같은 모델은 이미지 파트와 결합된 텍스트+이미지 항목을 허용합니다.
- 최상위
dimensions- provider별 옵션 없이 Matryoshka 차원을 요청합니다.
전체 사용법은 임베딩 가이드를 참조하세요.
6. provider 도구를 /tools 서브패스로 이동
provider별 도구(웹 검색, 코드 실행, 컴퓨터 사용 등)는 이제 각 어댑터 패키지의 전용 /tools 서브패스에서
내보냅니다. 이를 통해 도구 가져오기를 트리 셰이킹할 수 있고 provider 간 이름 충돌을 방지합니다.
유일한 호환성 변경은 @tanstack/ai-openrouter에 있습니다.
createWebSearchTool이 패키지 루트에서 제거되고 webSearchTool로 이름이 변경된 후
@tanstack/ai-openrouter/tools로 이동했습니다. 다른 모든 provider 도구(Anthropic, OpenAI, Gemini)는 새로 내보내지며 기존
import는 깨지지 않습니다.
이전
import { createWebSearchTool } from '@tanstack/ai-openrouter'
const tools = [
createWebSearchTool({ engine: 'native', maxResults: 5 }),
]
이후
import { webSearchTool } from '@tanstack/ai-openrouter/tools'
const tools = [
webSearchTool({ engine: 'native', maxResults: 5 }),
]
주요 변경 사항
- 가져오기 경로가 이제
/tools입니다 — 각 provider 패키지에서 사용되는 기존/adapters서브패스 패턴과 일치합니다. - 팩토리 이름 변경 —
createWebSearchTool→webSearchTool. 다른 모든 provider의 (@tanstack/ai-anthropic/tools,@tanstack/ai-openai/tools등의webSearchTool) 명명 방식에 맞추기 위해create*접두사를 제거했습니다. - 런타임 동작은 변경되지 않음 — 팩토리는 동일한 구성 객체를 받고
chat({ tools: [...] })에서 동일하게 동작하는 도구를 반환합니다. - 타입 수준 게이팅 추가 — 모델의
supports.tools배열에 따라 해당 도구를 지원하지 않는 모델에 provider 도구를 전달하면 이제tools배열에서 타입 오류가 발생합니다. 사용자가 정의한toolDefinition()도구에는 영향이 없습니다.
사용 가능한 provider 도구 전체 목록과 각 도구를 지원하는 모델은 Provider 도구를 참조하세요.
전체 마이그레이션 예시
다음은 모든 변경 사항을 함께 보여주는 전체 예시입니다.
이전
import { chat, toResponseStream } from '@tanstack/ai'
import { openai } from '@tanstack/ai-openai'
export async function POST(request: Request) {
const { messages } = await request.json()
const abortController = new AbortController()
const stream = chat({
adapter: openai(),
model: 'gpt-5.2',
messages,
options: {
temperature: 0.7,
maxTokens: 1000,
},
providerOptions: {
responseFormat: { type: 'json_object' },
},
abortController,
})
return toResponseStream(stream, { abortController })
}
이후
import { chat, toServerSentEventsStream } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
export async function POST(request: Request) {
const { messages } = await request.json()
const abortController = new AbortController()
const stream = chat({
adapter: openaiText('gpt-5.2'),
messages,
// Sampling now lives in provider-native `modelOptions` (OpenAI Responses
// keys: `temperature`, `max_output_tokens`). `metadata` stays at the root.
modelOptions: {
temperature: 0.7,
max_output_tokens: 1000,
responseFormat: { type: 'json_object' },
},
abortController,
})
const readableStream = toServerSentEventsStream(stream, abortController)
return new Response(readableStream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
},
})
}
이러한 변경 사항의 이점
- 향상된 트리 셰이킹 - 필요한 항목만 가져오므로 번들 크기가 줄어듭니다.
- 더 명확한 API - 함수 이름만으로 용도를 분명히 알 수 있습니다.
- 타입 안전성 - 모델별 옵션에 완전한 타입이 지정됩니다.
- 간소화된 구성 - 평탄화된 옵션을 더 쉽게 사용할 수 있습니다.
- 집중된 범위 - 다른 곳에서 더 적합하게 처리할 수 있는 기능을 제거했습니다.
도움이 필요하신가요?
마이그레이션 중 문제가 발생하면 다음을 확인하세요.
- 새로운 어댑터 구조에 대한 자세한 내용은 트리 셰이킹 가이드를 확인하세요.
- 전체 함수 시그니처는 API 레퍼런스를 검토하세요.
- 작동하는 코드 샘플은 예시를 확인하세요.