Evaluation

Evaluation (평가)

experimental_evaluate는 평가 모델을 사용해 하나의 공유 상태(state)에 대해 이름이 붙은 질문들을 평가해요. 상태는 문자열, JSON 객체 또는 JSON 배열일 수 있어요. 배열은 하나의 상태이지, 서로 관련 없는 입력의 배치가 아니에요.

출처: 문서

본문

이 API와 평가 모델 명세는 실험적이며 패치 릴리스에서 변경될 수 있어요. 평가 모델 인스턴스, 프로바이더 레지스트리를 통한 모델 해석, 또는 문자열 ID를 전달하세요. 문자열은 평가를 지원하는 기본 프로바이더를 구성하지 않는 한 Vercel AI Gateway를 통해 해석돼요.

import { experimental_evaluate, type Experimental_EvaluationModel } from 'ai';

async function triage(model: Experimental_EvaluationModel, message: string) {
  return experimental_evaluate({
    model,
    state: { message },
    questions: {
      department: {
        type: 'choice',
        instructions: 'Which team should handle this?',
        criteria: {
          billing: 'Payments and refunds',
          support: 'Other requests',
        },
      },
      severity: {
        type: 'score',
        instructions: 'How severe is the issue?',
        criteria: ['Cosmetic', 'Workaround exists', 'Blocking; no workaround'],
      },
      requestsRefund: {
        type: 'boolean',
        instructions: 'Is the customer requesting money back?',
      },
    },
  });
}

프로바이더 모델 (Provider models)

프로바이더의 evaluationModel 팩토리를 사용하세요:

프로바이더 예시 모델
TypeSafe AI typeSafeAi.evaluationModel('jev-latest')
OpenAI openai.evaluationModel('gpt-5.6-luna')
Anthropic anthropic.evaluationModel('claude-haiku-4-5-20251001')
Google google.evaluationModel('gemini-3.5-flash-lite')

TypeSafe AI의 Jev는 네이티브 Choice, Score, Boolean 평가를 제공해요. OpenAI, Anthropic, Google은 세 유형 모두에 대해 구조화된 언어 모델 출력을 적응시켜요. Boolean 답변에는 P(true)의 프롬프트 기반 추정치가 포함되며, 유한하고 [0, 1]에 있도록 검증돼요. 이 추정치는 보정(calibration)이 보장되지 않아요. Choice와 Score 답변에는 확률 분포가 포함되지 않아요. 프로바이더의 구조화된 출력 API를 지원하는 모델을 선택하고, 작업에 모델을 정하기 전에 자신의 라벨링된 예시로 판단 품질을 평가하세요.

언어 모델 어댑터는 모든 질문을 하나의 프롬프트에서 평가해요. TypeSafe의 네이티브 독립 질문 실행 의미론은 제공하지 않아요. 예시 모델 ID는 API 호환성을 보여줄 뿐이며, 벤치마크로 선정된 기본값이 아니에요.

언어 모델 어댑터는 기본적으로 reasoning: 'none'을 요청해요. 각 프로바이더는 이 설정을 모델의 추론 제어에 매핑하지만, 모든 모델이 생각 없이 실행된다는 것을 보장하지는 않아요. 더 까다로운 평가를 위해 추론을 활성화하려면 모델이 지원하는 추론 설정을 providerOptions를 통해 전달하세요. 이는 이 기본값보다 우선해요. 예를 들어 그 effort를 지원하는 OpenAI 모델에서 providerOptions: { openai: { reasoningEffort: 'high' } }를 사용하세요.

모델 별칭 및 레지스트리 (Model aliases and registries)

customProvider로 모델에 애플리케이션별 이름을 붙인 다음 createProviderRegistry로 프로바이더를 등록하세요:

import { typeSafeAi } from '@ai-sdk/typesafe-ai';
import { openai } from '@ai-sdk/openai';
import {
  customProvider,
  createProviderRegistry,
  experimental_evaluate,
} from 'ai';

const registry = createProviderRegistry({
  triage: customProvider({
    evaluationModels: {
      native: typeSafeAi.evaluationModel('jev-latest'),
      compact: openai.evaluationModel('gpt-6-luna'),
    },
    fallbackProvider: typeSafeAi,
  }),
  openai,
});

const result = await experimental_evaluate({
  model: registry.evaluationModel('triage:native'),
  state: 'I was charged twice.',
  questions: {
    department: {
      type: 'choice',
      instructions: 'Which team should handle this?',
      criteria: { billing: 'Charges and refunds', support: 'Other requests' },
    },
  },
});

result.answers.department.choice; // 'billing' | 'support'

레지스트리 ID는 providerId:modelId 형식을 사용해요. separator 옵션은 구분자를 변경해요. 첫 번째 구분자만 사용되므로 모델 ID에 구분자가 포함될 수 있어요. 커스텀 별칭은 폴백 프로바이더보다 우선해요. 폴백은 알 수 없는 모델 ID만 해석해요. 실패한 평가를 재시도하거나 질문 유형이 지원되지 않을 때 모델을 대체하지는 않아요. 등록된 프로바이더는 자신의 자격 증명과 설정을 유지해요. 레지스트리 언어/이미지 미들웨어는 평가 모델을 감싸지 않아요.

기본 프로바이더 문자열 (Default-provider strings)

문자열 ID는 기본적으로 Vercel AI Gateway를 사용해요. AI_GATEWAY_API_KEY 또는 Vercel OIDC로 Gateway 인증을 구성한 다음 Gateway 모델 ID를 전달하세요:

import { experimental_evaluate } from 'ai';

const result = await experimental_evaluate({
  model: 'typesafe-ai/jev-latest',
  state: 'I was charged twice. Please refund the extra charge.',
  questions: {
    refund: {
      type: 'boolean',
      instructions: 'Is the customer asking for a refund?',
    },
  },
});

문자열을 자신의 프로바이더나 별칭으로 해석하려면 애플리케이션 시작 시 기본 프로바이더를 한 번 구성하세요:

// Using the registry above, expose an alias through a custom provider:
globalThis.AI_SDK_DEFAULT_PROVIDER = customProvider({
  evaluationModels: { native: registry.evaluationModel('triage:native') },
});

const result = await experimental_evaluate({
  model: 'native',
  state: 'I was charged twice.',
  questions: {
    refund: {
      type: 'boolean',
      instructions: 'Is the customer asking for a refund?',
    },
  },
});

typeSafeAi 같은 직접 프로바이더도 기본값이 될 수 있어요. 그러면 'jev-latest' 같은 접두사 없는 모델 ID를 사용해요. evaluationModels의 문자열 값도 이 전역 기본값을 통해 해석돼요. 해석 순환을 피하려면 별칭에서 모델 인스턴스를 선호하세요. 전역 구성은 다른 AI SDK 함수에도 영향을 줘요. 공유 프로세스에서 요청별로 변경하지 마세요.

명시적으로 구성된 기본 프로바이더는 evaluationModel 메서드를 노출해야 해요. Gateway는 기본 프로바이더가 구성되지 않은 경우에만 사용돼요. 누락된 레지스트리 프로바이더는 NoSuchProviderError를, 누락된 모델이나 평가 기능은 modelType: 'evaluationModel'과 함께 NoSuchModelError를 던져요. 지원되지 않는 모델 버전은 레지스트리가 반환한 모델을 포함해 UnsupportedModelVersionError를 던져요. 안정적인 ProviderV4와 ProviderRegistryProvider 인터페이스는 변경되지 않아요. 추론된 레지스트리 타입을 유지하거나 Experimental_EvaluationProviderRegistry를 사용해 실험적 evaluationModel 메서드를 유지하세요.

질문 유형 (Question types)

유형 기준 답변
choice 옵션에서 설명으로의 비어 있지 않은 맵 choice, 옵션 키의 합집합으로 추론됨; 선택적 probabilities
score 최소 두 개의 순서화된 수준 설명 [0, levels.length - 1] 범위의 부분 score; 선택적 probabilities
boolean 선택적 true 및 false 설명 필수 probability, 모델이 추정한 true 확률

지시(instructions)와 설명(descriptions)은 문자열, JSON 객체 또는 JSON 배열일 수 있어요. 설명은 null일 수도 있어요. 코어는 구조화된 설명을 콘텐츠로 취급하며 키를 해석하지 않아요. 함수, 클래스 인스턴스, 순환, undefined 값, 비유한(nonfinite) 숫자는 JSON 호환되지 않아요.

답변은 질문 ID를 유지하고 질문과 같은 type을 가져요. Choice 분포가 제공되면 모든 옵션을 포함하며 선택된 choice가 최대 확률을 가져요. Score 분포는 0부터 시작하는 수준 인덱스에 문자열 키를 사용하고, score는 확률 가중 평균과 같아요. 분포가 없으면 score는 루브릭에서 모델이 추정한 위치예요.

분포는 합이 1이어야 하고, 가중 점수는 분포와 일치해야 해요. 기본 절대 허용 오차는 0.000001이에요. 출력을 반올림하는 프로바이더는 rounding.probabilityDecimals와 rounding.scoreDecimals(0~15 정수)를 선언할 수 있어요. 그러면 검증이 반올림된 확률 또는 점수당 마지막 소수 자리의 절반 단위를 합이나 가중 평균에 걸쳐 누적해 허용해요. 예를 들어 소수 둘째 자리로 반올림된 확률은 반올림되지 않은 값의 합이 1이어도 0.99로 합산될 수 있어요. 결과에는 이 rounding 정보가 포함돼요. 잘못된 출력은 거부되며, 네이티브 값은 보존되고 절대 조용히 정규화되지 않아요.

확률 및 신뢰도 (Probabilities and confidence)

Choice와 Score 분포는 선택 사항이에요. Boolean 확률은 필수예요. 0.98은 강한 예(yes), 0.02는 강한 아니요(no)를 의미해요. 어느 쪽 결과에 대한 신뢰도가 아니에요. SDK는 프로바이더 전체에 걸친 보정을 보장하지 않아요. 구조화된 언어 모델 어댑터는 모델에게 P(true)를 추정하도록 프롬프트하고, 네이티브 평가 프로바이더는 API 확률을 반환해요. 프로바이더별 신뢰도 통계는 providerMetadata에 속해요. TypeSafe는 별도의 Choice/Score 신뢰도 통계를 result.providerMetadata?.typesafe?.confidence에 질문 ID별로 노출해요. 이것은 선택된 옵션의 확률이나 휴대 가능한 신뢰도 측정이 아니에요.

선택적 분포를 사용하기 전에 확인하세요. 예를 들어 애플리케이션은 프로바이더가 충분히 높은 선택-옵션 확률을 제공할 때만 라우팅할 수 있어요:

const answer = result.answers.department;
const selectedProbability = answer.probabilities?.[answer.choice];
if (selectedProbability != null && selectedProbability >= 0.9) {
  // Route automatically; otherwise use the application's review path.
}

Boolean 임계값을 애플리케이션 코드에서 선택하고, 같은 임계값이 프로바이더 전체에서 동일하게 동작한다고 가정하지 말고 작업의 라벨링된 데이터를 사용하세요:

if (result.answers.requestsRefund.probability >= 0.8) {
  // Route to the refunds queue.
}

오류 및 취소 (Errors and cancellation)

모델의 supportedQuestionTypes는 프로바이더를 호출하기 전에 확인돼요. 지원되지 않는 질문은 Experimental_EvaluationUnsupportedQuestionTypeError로 전체 호출을 실패시켜요. 성공적인 호출은 모든 질문에 대한 답변을 반환해요. 부분 성공이나 자동 모델 대체는 없어요.

잘못된 입력은 InvalidArgumentError를 던져요. 누락된 답변, 불일치하는 답변 유형, 잘못된 옵션, 점수 또는 확률은 InvalidResponseDataError를 던져요. 일시적 프로바이더 실패는 일반 재시도 정책(maxRetries: 2 기본)을 사용해요. 평가를 취소하려면 abortSignal을, 요청 헤더에는 headers를, 프로바이더별 설정에는 providerOptions를 사용하세요.

결과에는 usage, warnings, providerMetadata, response가 포함돼요. 알 수 없는 토큰 수는 undefined로 유지되며, totalTokens는 입력과 출력 수를 모두 알 때만 사용할 수 있어요.

테스트에는 ai/test의 Experimental_EvaluationMockModelV4를 사용하세요.

범위 및 예시 (Scope and examples)

평가는 현재 하나의 공유 상태에 대해 하나의 완전한 결과를 반환해요. 답변을 스트리밍하거나, 다중 라벨 분류를 수행하거나, 서로 관련 없는 상태를 배치하지 않아요. 별도의 상태에는 별도의 호출을 실행하세요. 프로바이더 지원과 판단 품질은 선택한 모델에 따라 달라지며, SDK는 모델을 자동으로 선택하지 않아요.

실행 가능한 예시는 examples/ai-functions/src/evaluate에 있어요. TypeSafe, OpenAI, Anthropic, Google의 기본 예시, 모델 레지스트리, 커스텀 별칭, 기본 프로바이더 문자열, 확률 기반 라우팅이 포함돼요.

AI SDK와 함께 TypeSafe AI의 Jev를 사용하는 사용 사례, 구현 가이드, 배포 가능한 템플릿을 살펴보세요:

더 알아보기 (Learn more)

전체 사이트맵