모델별 타입 안전성
AI SDK는 modelOptions에 모델별 타입 안전성을 제공합니다. 각 모델의 기능에 따라 허용되는 모델 옵션이 결정되며 TypeScript가 컴파일 시 이를 적용합니다.
팁: 구조화된 출력의 경우 대부분의 사용자는 아래에 표시된 원시 provider
text옵션보다 우선적으로 제공되는chat({ outputSchema })옵션을 사용하는 것이 좋습니다. 이 옵션은 provider 전반에서 작동하며 결과를 검증합니다. 원시text옵션은 provider별 제어가 필요할 때 사용합니다.
작동 방식
각 어댑터 팩토리는 모델 리터럴을 타입 매개변수로 캡처합니다(openaiText<TModel>(model)). 따라서 어댑터는 타입 수준에서 선택한 정확한 모델을 포함합니다.
전달한 modelOptions는 모델별 맵(ResolveProviderOptions<TModel>)을 기준으로 해석됩니다. 각 모델의 항목에는 해당 모델이 실제로 지원하는 옵션만 선언됩니다. 구조화된 출력 기능이 없는 모델은 해석된 옵션 타입에 text 속성이 없으므로 TypeScript의 초과 속성 검사가 해당 모델의 text를 거부합니다. 이 검사는 런타임 비용 없이 컴파일 시 수행됩니다.
이는 타입이 지정된 사전 구성 옵션(해석된 옵션을 재사용 가능한 객체에 캡처함)과 어댑터 확장(동일한 타입의 modelOptions를 사용자 지정 모델에 연결할 수 있음)에서 설명하는 것과 동일한 메커니즘입니다.
사용법 예시
✅ 올바른 사용법
import { chat } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
// ✅ gpt-5 supports structured outputs - `text` is allowed
const validCall = chat({
adapter: openaiText("gpt-5"),
messages: [],
modelOptions: {
// OK - text is included for gpt-5
text: {
format: {
type: "json_schema",
name: "my_schema",
schema: {
/* JSON Schema object */
},
},
},
},
});
❌ 잘못된 사용법
import { chat } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
// ❌ gpt-4-turbo does NOT support structured outputs - `text` is rejected
const invalidCall = chat({
adapter: openaiText("gpt-4-turbo"),
messages: [],
modelOptions: {
text: {}, // ❌ TypeScript error: 'text' does not exist in type
},
});
TypeScript는 다음을 출력합니다.
error TS2353: Object literal may only specify known properties, and 'text' does not exist in type ...'.
이점
- 컴파일 시 안전성: 배포 전에 잘못된 모델 옵션을 확인합니다.
- 향상된 IDE 경험: 자동 완성에 각 모델에 유효한 옵션만 표시됩니다.
- 자체 문서화: 모델 기능이 타입 시스템에 명시적으로 드러납니다.
- 런타임 오버헤드 없음: 모든 타입 검사는 컴파일 시 수행됩니다.