Alibaba 프로바이더

Alibaba 프로바이더

Alibaba Cloud Model Studio의 Qwen 모델 시리즈를 AI SDK에서 쓸 수 있게 해주는 프로바이더예요. 고급 추론 능력을 포함한 다양한 Qwen 모델을 지원해요.

출처: 문서

본문

Alibaba Cloud Model Studio는 고급 추론 능력을 포함한 Qwen 모델 시리즈에 대한 접근을 제공해요.

API 키는 Console에서 얻을 수 있어요.

설정 (Setup)

Alibaba 프로바이더는 @ai-sdk/alibaba 모듈로 제공돼요. 다음과 같이 설치할 수 있어요:

프로바이더 인스턴스 (Provider Instance)

@ai-sdk/alibaba에서 기본 프로바이더 인스턴스 alibaba를 불러올 수 있어요:

import { alibaba } from '@ai-sdk/alibaba';

커스텀 구성이 필요하다면 createAlibaba를 불러와 원하는 설정으로 프로바이더 인스턴스를 만들 수 있어요:

import { createAlibaba } from '@ai-sdk/alibaba';

const alibaba = createAlibaba({
  apiKey: process.env.ALIBABA_API_KEY ?? '',
});

Alibaba 프로바이더 인스턴스를 커스터마이즈할 때 사용할 수 있는 선택적 설정은 다음과 같아요:

  • baseURL string

    API 호출에 다른 URL 접두사를 사용해요. 예를 들어 프록시 서버나 지역 엔드포인트를 쓸 때 유용해요. 기본 접두사는 https://dashscope-intl.aliyuncs.com/compatible-mode/v1이에요.

  • videoBaseURL string

    비디오 생성 API 호출에 다른 URL 접두사를 사용해요. 비디오 API는 DashScope 네이티브 엔드포인트(OpenAI 호환 엔드포인트가 아님)를 사용해요. 기본 접두사는 https://dashscope-intl.aliyuncs.com이에요.

  • embeddingBaseURL string

    임베딩 API 호출에 다른 URL 접두사를 사용해요. 임베딩 API는 DashScope 네이티브 엔드포인트(OpenAI 호환 엔드포인트가 아님)를 사용해요. 기본 접두사는 https://dashscope-intl.aliyuncs.com/api/v1이에요.

  • apiKey string

    Authorization 헤더로 보내는 API 키예요. 기본값은 ALIBABA_API_KEY 환경 변수예요.

  • headers Record<string,string>

    요청에 포함할 커스텀 헤더예요.

  • fetch (input: RequestInfo, init?: RequestInit) => Promise<Response>

    커스텀 fetch 구현이에요.

  • includeUsage boolean

    스트리밍 응답에 사용 정보를 포함할지 여부예요. 활성화하면 최종 청크에 토큰 사용량이 포함돼요. 기본값은 true예요.

언어 모델 (Language Models)

프로바이더 인스턴스로 언어 모델을 만들 수 있어요:

import { alibaba } from '@ai-sdk/alibaba';
import { generateText } from 'ai';

const { text } = await generateText({
  model: alibaba('qwen-plus'),
  prompt: 'Write a vegetarian lasagna recipe for 4 people.',
});

.chatModel() 또는 .languageModel() 팩토리 메서드도 사용할 수 있어요:

const model = alibaba.chatModel('qwen-plus');
// or
const model = alibaba.languageModel('qwen-plus');

Alibaba 언어 모델은 streamText 함수에서 사용할 수 있어요 (AI SDK Core 참고).

Alibaba 모델에 사용할 수 있는 선택적 프로바이더 옵션은 다음과 같아요:

  • enableThinking boolean

    지원되는 모델의 thinking/reasoning 모드를 활성화해요. 활성화하면 모델이 응답 전에 추론 콘텐츠를 생성해요. 기본값은 false예요.

  • thinkingBudget number

    생성할 최대 추론 토큰 수예요. thinking 콘텐츠의 길이를 제한해요.

  • preserveThinking boolean

    지원되는 모델에서 이전 어시스턴트 메시지의 추론을 보존해요. 활성화하면 추론이 Alibaba reasoning_content와 preserve_thinking으로 별도로 전송돼요. 보존 thinking을 지원하는 모델의 기본값은 true이며, 선택 해지하려면 false로 설정하세요. 대화를 이어갈 때 AI SDK responseMessages를 변경하지 않고 추가하세요. 지원 모델 목록은 Alibaba의 preserved-thinking 문서를 참고하세요.

  • parallelToolCalls boolean

    툴 사용 중 병렬 함수 호출을 활성화할지 여부예요. 기본값은 true예요.

Thinking 모드 (Thinking Mode)

Alibaba의 Qwen 모델은 복잡한 문제 해결을 위한 thinking/reasoning 모드를 지원해요:

import { alibaba, type AlibabaLanguageModelChatOptions } from '@ai-sdk/alibaba';
import { generateText } from 'ai';

const { text, reasoning } = await generateText({
  model: alibaba('qwen3-max'),
  providerOptions: {
    alibaba: {
      enableThinking: true,
      thinkingBudget: 2048,
    } satisfies AlibabaLanguageModelChatOptions,
  },
  prompt: 'How many "r"s are in the word "strawberry"?',
});

console.log('Reasoning:', reasoning);
console.log('Answer:', text);

thinking 전용 모델(qwen3-235b-a22b-thinking-2507 같은)의 경우 thinking 모드가 기본으로 활성화돼요.

다중 턴 대화에서 보존된 Thinking (Preserved Thinking in Multi-Turn Conversations)

보존 thinking을 지원하는 모델의 경우 AI SDK는 기본적으로 이전 어시스턴트 메시지의 추론을 Alibaba reasoning_content로 재생해, 모델이 이전 사고 과정 위에 구축할 수 있게 해요:

import { alibaba, type AlibabaLanguageModelChatOptions } from '@ai-sdk/alibaba';
import { generateText, type ModelMessage } from 'ai';

const providerOptions = {
  alibaba: {
    enableThinking: true,
    thinkingBudget: 2048,
  } satisfies AlibabaLanguageModelChatOptions,
};

const opening: ModelMessage = {
  role: 'user',
  content: 'Is Kafka or RocketMQ a better fit for transactional messages?',
};

const first = await generateText({
  model: alibaba('qwen3.7-max'),
  messages: [opening],
  providerOptions,
});

const second = await generateText({
  model: alibaba('qwen3.7-max'),
  messages: [
    opening,
    ...first.responseMessages, // append unchanged to keep the reasoning parts
    { role: 'user', content: 'Which tradeoff mattered most?' },
  ],
  providerOptions,
});

대화를 이어갈 때 responseMessages를 변경하지 않고 추가하세요. 보이는 텍스트만으로 어시스턴트 기록을 재구성하면 프로바이더가 reasoning_content로 직렬화하기 전에 추론 파트가 버려져요. preserveThinking: false로 재생을 선택 해지할 수 있으며, 다음 주의 사항을 참고하세요:

  • preserveThinking은 그 자체로 thinking을 활성화하지 않아요. enableThinking/thinkingBudget 또는 최상위 reasoning 옵션과 함께 사용하세요.
  • Alibaba가 보존 thinking을 지원한다고 문서화한 모델에서만 기본으로 활성화돼요. 다른 모델에서는 옵션을 명시적으로 설정하지 않으면 preserve_thinking이 전송되지 않아요. 지원 모델의 현재 목록은 Alibaba의 preserved-thinking 문서를 참고하세요.
  • 마지막 사용자 메시지 이후의 현재 툴 호출 라운드의 추론은 Alibaba가 권장하는 대로 항상 툴 결과와 함께 다시 전송돼요. 옵션은 이전 라운드의 추론만 제어해요.
  • 보존된 추론은 입력 토큰 사용량과 비용을 증가시켜요.
  • 과거 추론은 보이는 어시스턴트 텍스트와 분리되어 유지되며, content에 병합되지 않아요.

툴 호출 (Tool Calling)

Alibaba 모델은 병렬 실행을 포함한 툴 호출을 지원해요:

import { alibaba } from '@ai-sdk/alibaba';
import { generateText, tool } from 'ai';
import { z } from 'zod';

const { text } = await generateText({
  model: alibaba('qwen-plus'),
  tools: {
    weather: tool({
      description: 'Get the weather in a location',
      inputSchema: z.object({
        location: z.string().describe('The location to get the weather for'),
      }),
      execute: async ({ location }) => ({
        location,
        temperature: 72 + Math.floor(Math.random() * 21) - 10,
      }),
    }),
  },
  prompt: 'What is the weather in San Francisco?',
});

프롬프트 캐싱 (Prompt Caching)

Alibaba는 반복 프롬프트의 비용을 줄이기 위해 암시적 및 명시적 프롬프트 캐싱을 모두 지원해요.

암시적 캐싱은 자동으로 동작해요. 프로바이더가 구성 없이 적절한 콘텐츠를 캐시해요. 더 많은 제어를 위해 cacheControl로 특정 메시지를 표시하는 명시적 캐싱을 사용할 수 있어요:

단일 메시지 캐시 제어 (Single message cache control)

import { alibaba } from '@ai-sdk/alibaba';
import { generateText } from 'ai';

const { text, usage } = await generateText({
  model: alibaba('qwen-plus'),
  messages: [
    {
      role: 'system',
      content: 'You are a helpful assistant. [... long system prompt ...]',
      providerOptions: {
        alibaba: {
          cacheControl: { type: 'ephemeral' },
        },
      },
    },
  ],
});

다중 파트 메시지 캐시 제어 (Multi-part message cache control)

import { alibaba } from '@ai-sdk/alibaba';
import { generateText } from 'ai';

const longDocument = '... large document content ...';

const { text, usage } = await generateText({
  model: alibaba('qwen-plus'),
  messages: [
    {
      role: 'user',
      content: [
        {
          type: 'text',
          text: 'Context: Please analyze this document.',
        },
        {
          type: 'text',
          text: longDocument,
          providerOptions: {
            alibaba: {
              cacheControl: { type: 'ephemeral' },
            },
          },
        },
      ],
    },
  ],
});

참고: 캐시 블록의 최소 콘텐츠 길이는 1,024 토큰이에요.

임베딩 모델 (Embedding Models)

.embedding() 팩토리 메서드로 텍스트 임베딩 모델을 만들 수 있어요. AI SDK 임베딩에 대해 더 알고 싶다면 embed()와 embedMany()를 참고하세요.

const model = alibaba.embedding('text-embedding-v4');

embed 함수로 Alibaba 임베딩 모델을 사용해 임베딩을 생성할 수 있어요:

import { alibaba, type AlibabaEmbeddingModelOptions } from '@ai-sdk/alibaba';
import { embed } from 'ai';

const { embedding, usage } = await embed({
  model: alibaba.embedding('text-embedding-v4'),
  value: 'sunny day at the beach',
  providerOptions: {
    alibaba: {
      textType: 'document',
      dimension: 1024,
      outputType: 'dense',
    } satisfies AlibabaEmbeddingModelOptions,
  },
});

여러 텍스트 값을 임베딩하려면 embedMany를 사용하세요. Alibaba 텍스트 임베딩 모델은 API 호출당 최대 10개 값을 지원하며, 더 큰 배치는 embedMany가 자동으로 분할해요.

import { alibaba, type AlibabaEmbeddingModelOptions } from '@ai-sdk/alibaba';
import { embedMany } from 'ai';

const { embeddings } = await embedMany({
  model: alibaba.embedding('text-embedding-v4'),
  values: [
    'sunny day at the beach',
    'rainy afternoon in the city',
    'snowy night in the mountains',
  ],
  providerOptions: {
    alibaba: {
      textType: 'document',
      dimension: 1024,
    } satisfies AlibabaEmbeddingModelOptions,
  },
});

Alibaba 임베딩 모델은 providerOptions.alibaba로 전달할 수 있는 추가 프로바이더 옵션을 지원해요:

  • textType 'query' | 'document'

    비대칭 검색 작업을 위해 쿼리 텍스트와 문서 텍스트를 구분해요. 기본값은 document이에요.

  • dimension number

    출력 임베딩 벡터의 차원이에요. 기본값은 1024예요. text-embedding-v4는 1536과 2048 차원도 지원해요.

  • outputType 'dense' | 'sparse' | 'dense&sparse'

    출력 벡터 유형을 지정해요. 기본값은 dense예요. AI SDK 임베딩 인터페이스는 dense number[] 벡터를 반환하므로 sparse 전용 출력은 지원되지 않으며 오류를 던져요. dense 임베딩을 embedding/embeddings에서, sparse 벡터를 providerMetadata.alibaba.sparseEmbeddings에서 받으려면 dense&sparse를 사용하세요.

임베딩 모델 기능 (Embedding Model Capabilities)

모델 기본 차원 유연한 차원 호출당 최대 값
text-embedding-v4 1024 64, 128, 256, 512, 768, 1024, 1536, 2048 10
text-embedding-v3 1024 512, 768, 1024 10
위 표는 현재 문서화된 Alibaba 텍스트 임베딩 모델을 나열한 거예요. 필요하다면 사용 가능한 프로바이더 모델 ID를 문자열로 전달할 수도 있어요.

비디오 모델 (Video Models)

.video() 팩토리 메서드로 Alibaba Cloud DashScope API를 호출하는 Wan 비디오 모델을 만들 수 있어요. AI SDK에서 비디오 생성에 대해 더 알고 싶다면 generateVideo()를 참고하세요.

Alibaba는 텍스트-영상, 이미지-영상(첫 프레임), 참조-영상의 세 가지 비디오 생성 모드를 지원해요.

텍스트-영상 (Text-to-Video)

텍스트 프롬프트로 비디오를 생성해요:

import { alibaba, type AlibabaVideoModelOptions } from '@ai-sdk/alibaba';
import { experimental_generateVideo as generateVideo } from 'ai';

const { video } = await generateVideo({
  model: alibaba.video('wan2.6-t2v'),
  prompt: 'A serene mountain lake at sunset with gentle ripples on the water.',
  resolution: '1280x720',
  duration: 5,
  providerOptions: {
    alibaba: {
      promptExtend: true,
      pollTimeoutMs: 600000, // 10 minutes
    } satisfies AlibabaVideoModelOptions,
  },
});

wan2.7 모델은 aspectRatio 옵션(API의 ratio 파라미터에 매핑)을 추가로 지원하고 항상 오디오를 생성해요. 멀티샷 구조는 shotType 옵션 대신 프롬프트에 직접 설명해요:

const { video } = await generateVideo({
  model: alibaba.video('wan2.7-t2v'),
  prompt:
    'A serene mountain lake at sunset. The camera pans across the water, then cuts to a close-up of ripples catching the light.',
  resolution: '1920x1080',
  aspectRatio: '16:9',
  duration: 5,
});

이미지-영상 (Image-to-Video)

첫 프레임 이미지와 선택적 텍스트 프롬프트로 비디오를 생성해요:

import { alibaba, type AlibabaVideoModelOptions } from '@ai-sdk/alibaba';
import { experimental_generateVideo as generateVideo } from 'ai';

const { video } = await generateVideo({
  model: alibaba.video('wan2.6-i2v'),
  prompt: {
    image: 'https://example.com/landscape.jpg',
    text: 'Camera slowly pans across the landscape',
  },
  duration: 5,
  providerOptions: {
    alibaba: {
      pollTimeoutMs: 600000, // 10 minutes
    } satisfies AlibabaVideoModelOptions,
  },
});

최상위 frameImages 옵션으로 첫 프레임을 전달할 수도 있어요:

import { alibaba, type AlibabaVideoModelOptions } from '@ai-sdk/alibaba';
import { experimental_generateVideo as generateVideo } from 'ai';

const { video } = await generateVideo({
  model: alibaba.video('wan2.6-i2v'),
  prompt: 'Camera slowly pans across the landscape',
  frameImages: [
    {
      image: 'https://example.com/landscape.jpg',
      frameType: 'first_frame',
    },
  ],
  duration: 5,
  providerOptions: {
    alibaba: {
      pollTimeoutMs: 600000, // 10 minutes
    } satisfies AlibabaVideoModelOptions,
  },
});

참조-영상 (Reference-to-Video)

캐릭터 일관성을 위해 참조 이미지 및/또는 비디오를 사용해 비디오를 생성해요.

wan2.6 모델의 경우 프롬프트에서 캐릭터 식별자(character1, character2 등)를 사용해 참조하세요. 참조는 공개 URL이어야 해요:

import { alibaba, type AlibabaVideoModelOptions } from '@ai-sdk/alibaba';
import { experimental_generateVideo as generateVideo } from 'ai';

const { video } = await generateVideo({
  model: alibaba.video('wan2.6-r2v-flash'),
  prompt: 'character1 walks through a beautiful garden and waves at the camera',
  resolution: '1280x720',
  duration: 5,
  inputReferences: ['https://example.com/character-reference.jpg'],
  providerOptions: {
    alibaba: {
      pollTimeoutMs: 600000, // 10 minutes
    } satisfies AlibabaVideoModelOptions,
  },
});

wan2.7 모델의 경우 프롬프트에서 Image 1, Image 2, Video 1 등을 사용하세요(이미지와 비디오는 참조 순서대로 별도로 계산됨). 이미지 참조는 공개 URL 또는 인라인 파일 데이터일 수 있고, 비디오 참조는 공개 URL이어야 해요:

import { alibaba, type AlibabaVideoModelOptions } from '@ai-sdk/alibaba';
import { experimental_generateVideo as generateVideo } from 'ai';
import { readFile } from 'node:fs/promises';

const imageBytes = await readFile('./character.png');

const { video } = await generateVideo({
  model: alibaba.video('wan2.7-r2v'),
  prompt: 'Image 1 walks through the scene shown in Image 2.',
  resolution: '1920x1080',
  duration: 5,
  inputReferences: [
    imageBytes, // inline image data, sent as base64 data URI
    'https://example.com/background.png',
  ],
  providerOptions: {
    alibaba: {
      ratio: '16:9',
      pollTimeoutMs: 600000, // 10 minutes
    } satisfies AlibabaVideoModelOptions,
  },
});

wan2.7 미디어 배열을 완전히 제어하려면(예: 음성 참조나 명시적 미디어 유형) inputReferences와 frameImages의 자동 매핑을 재정의하는 media 프로바이더 옵션을 사용하세요:

const { video } = await generateVideo({
  model: alibaba.video('wan2.7-r2v'),
  prompt: 'Video 1 walks into the room. Image 1 looks up and says hello.',
  providerOptions: {
    alibaba: {
      media: [
        {
          type: 'reference_video',
          url: 'https://example.com/character.mp4',
          referenceVoice: 'https://example.com/voice.mp3',
        },
        { type: 'reference_image', url: 'https://example.com/scene.png' },
        { type: 'first_frame', url: 'https://example.com/opening-frame.png' },
      ],
    } satisfies AlibabaVideoModelOptions,
  },
});

비디오 프로바이더 옵션 (Video Provider Options)

providerOptions.alibaba를 통해 다음 프로바이더 옵션을 사용할 수 있어요:

  • negativePrompt string

    생성된 비디오에서 피하고 싶은 내용에 대한 설명 (최대 500자).

  • audioUrl string

    오디오-비디오 동기화를 위한 오디오 파일 URL (WAV/MP3, 3-30초, 최대 15MB).

  • promptExtend boolean

    더 나은 생성 품질을 위해 프롬프트 확장/재작성을 활성화해요. 기본값은 true.

  • shotType 'single' | 'multi'

    비디오 생성의 쇼트 유형이에요. 'multi'는 멀티샷 시네마틱 내러티브를 활성화해요 (wan2.6 모델 전용).

  • watermark boolean

    생성된 비디오에 워터마크를 추가할지 여부예요. 기본값은 false예요.

  • audio boolean

    오디오 생성 여부 (wan2.6 I2V 및 R2V 모델용; wan2.7 모델은 항상 오디오를 생성).

  • referenceUrls string[]

    참조-영상 모드용 참조 이미지/비디오 URL 배열 (wan2.6 모델). 이미지 0-5개와 비디오 0-3개를 지원하며 최대 5개 총합. 참조 이미지를 전달할 때는 최상위 inputReferences 옵션을 선호하세요.

  • media Array<{ type, url, referenceVoice? }>

    참조-영상 모드용 명시적 미디어 배열 (wan2.7 모델). 각 항목은 type('reference_image', 'reference_video' 또는 'first_frame'), url(공개 URL, 또는 이미지의 data:{mime};base64,{data} URI), 선택적 referenceVoice 오디오 URL을 가져요. inputReferences와 frameImages의 자동 매핑을 재정의해요.

  • ratio '16:9' | '9:16' | '1:1' | '4:3' | '3:4'

    종횡비 (wan2.7 텍스트-영상 및 참조-영상 모델). 최상위 aspectRatio 옵션이 이 파라미터에 자동으로 매핑돼요.

  • pollIntervalMs number

    작업 상태 확인을 위한 폴링 간격(밀리초)이에요. 기본값은 5000.

  • pollTimeoutMs number

    비디오 생성을 위한 최대 대기 시간(밀리초)이에요. 기본값은 600000(10분).

비디오 생성은 몇 분이 걸릴 수 있는 비동기 프로세스예요. 안정적인 동작을 위해 `pollTimeoutMs`를 최소 10분(600000ms)으로 설정하는 것을 고려하세요.

비디오 모델 기능 (Video Model Capabilities)

텍스트-영상 (Text-to-Video)

모델 오디오 해상도 지속 시간
wan2.6-t2v Yes 720P, 1080P 2-15s
wan2.5-t2v-preview Yes 480P, 720P, 1080P 5s, 10s
wan2.7-t2v Yes 720P, 1080P 2-15s
wan2.7-t2v-2026-06-12 Yes 720P, 1080P 2-15s

이미지-영상 (첫 프레임) (Image-to-Video)

모델 오디오 해상도 지속 시간
wan2.6-i2v-flash 선택 720P, 1080P 2-15s
wan2.6-i2v Yes 720P, 1080P 2-15s

참조-영상 (Reference-to-Video)

모델 오디오 해상도 지속 시간
wan2.6-r2v-flash 선택 720P, 1080P 2-10s
wan2.6-r2v Yes 720P, 1080P 2-10s
wan2.7-r2v Yes 720P, 1080P 2-10s (비디오 참조 포함), 2-15s
wan2.7-r2v-2026-06-12 Yes 720P, 1080P 2-10s (비디오 참조 포함), 2-15s
위 표는 싱가포르 국제 지역에서 사용할 수 있는 모델을 나열한 거예요. 필요하다면 사용 가능한 프로바이더 모델 ID를 문자열로 전달할 수도 있어요.

모델 기능 (Model Capabilities)

사용 가능한 모델의 전체 목록은 Alibaba Cloud Model Studio 문서를 참고하세요. 필요하다면 사용 가능한 프로바이더 모델 ID를 문자열로 전달할 수도 있어요.

더 알아보기 (Learn more)

전체 사이트맵