LLM 붙인 앱을 조금 오래 굴리다 보면 모델을 바꿔 끼울 일이 생각보다 자주 생긴다. 요약은 싼 모델로 돌리고, 최종 답변만 좋은 모델로 뽑고 싶다거나. 앤트로픽이 느릴 때 잠깐 OpenAI로 넘기고 싶다거나.
처음엔 파일마다 anthropic('claude-sonnet-4-5')를 직접 import해서 썼다. 그러다 모델을 한 번 바꾸려니 호출부를 전부 뒤져야 했다. 게다가 @ai-sdk/anthropic이랑 @ai-sdk/openai를 여기저기서 각각 import하니까, 어느 파일이 어떤 제공자를 쓰는지 한눈에 안 들어왔다.
Vercel AI SDK의 createProviderRegistry를 쓰면 제공자를 한 곳에 몰아 등록해 두고, 'provider:model' 형태의 문자열로 꺼내 쓸 수 있다.
레지스트리 만들기
제공자들을 객체로 묶어서 한 번만 등록해 둔다.
// lib/registry.ts
import { createProviderRegistry } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { openai } from '@ai-sdk/openai';
export const registry = createProviderRegistry({
anthropic,
openai,
});
문자열로 꺼내 쓰기
이제 호출부에서는 registry.languageModel('제공자:모델') 한 줄이면 된다. import는 레지스트리 하나뿐이다.
import { generateText } from 'ai';
import { registry } from '@/lib/registry';
const { text } = await generateText({
model: registry.languageModel('anthropic:claude-sonnet-4-5'),
prompt: '이 글을 세 줄로 요약해줘',
});
'anthropic:...'를 'openai:gpt-4o'로 바꾸면 그대로 OpenAI로 넘어간다. 문자열이니까 환경변수나 DB 값으로 받아서 런타임에 고를 수도 있다.
const modelId = process.env.SUMMARY_MODEL ?? 'anthropic:claude-haiku-4-5';
const model = registry.languageModel(modelId);
커스텀 설정을 미리 박아두기
제공자를 등록할 때 기본 설정을 씌워둘 수도 있다. 이를테면 요약 전용으로 항상 온도를 낮춘 모델을 custom:summary 같은 별칭으로 만들어 두는 식이다.
import { customProvider } from 'ai';
const custom = customProvider({
languageModels: {
summary: anthropic('claude-haiku-4-5'),
smart: anthropic('claude-sonnet-4-5'),
},
});
export const registry = createProviderRegistry({ anthropic, openai, custom });
// registry.languageModel('custom:summary') 로 호출
이러면 호출부는 'custom:summary', 'custom:smart'처럼 의미가 담긴 이름만 알면 되고, 실제 어떤 모델이 뒤에 붙는지는 레지스트리 한 파일에서만 관리하면 된다.
핵심은 "어떤 모델을 쓸지"라는 결정을 호출부에서 떼어내 레지스트리 한 곳에 모으는 거다. 모델 교체가 문자열 하나 바꾸는 일이 되고, A/B 테스트나 폴백도 이 위에 얹기 쉬워진다. 제공자를 파일마다 직접 import하고 있다면 레지스트리부터 만들어 두는 걸 추천한다.