Moonshot AI 프로바이더

Moonshot AI 프로바이더

Moonshot API의 강력한 언어 모델을 AI SDK에서 쓸 수 있게 해주는 프로바이더예요. 추론 능력을 가진 Kimi 모델 시리즈를 포함해요.

출처: 문서

본문

Moonshot AI 프로바이더는 Moonshot API를 통한 강력한 언어 모델 접근을 제공해요. 추론 능력을 가진 Kimi 모델 시리즈를 포함해요.

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

설정 (Setup)

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

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

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

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

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

import { createMoonshotAI } from '@ai-sdk/moonshotai';

const moonshotai = createMoonshotAI({
  apiKey: process.env.MOONSHOT_API_KEY ?? '',
});

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

  • baseURL string

    API 호출에 다른 URL 접두사를 사용해요. 기본 접두사는 https://api.moonshot.ai/v1이에요.

  • apiKey string

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

  • headers Record<string,string>

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

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

    커스텀 fetch 구현이에요.

언어 모델 (Language Models)

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

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

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

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

const model = moonshotai.chatModel('kimi-k3');
// or
const model = moonshotai.languageModel('kimi-k3');

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

Moonshot V1 모델은 표준 temperature, topP, presencePenalty, frequencyPenalty 설정을 지원해요. Kimi 모델은 고정 샘플링 파라미터를 사용해요. 프로바이더는 Kimi 요청에서 해당 설정을 생략하고, 제공되면 지원되지 않는 설정 경고를 반환해요.

Kimi K3는 toolChoice: 'required'를 지원해요. Kimi K2.6과 Kimi K2.7 Code 모델은 그 설정을 거부하므로, 프로바이더는 해당 모델 ID에 대해 이를 생략하고 지원되지 않는 경고를 반환해요. 다른 툴 선택 모드는 변경 없이 전달돼요.

구조화된 출력 (Structured Outputs)

네이티브 구조화된 출력은 Kimi K 모델과 공식 Moonshot V1 텍스트, auto, 비전 모델에 대해 활성화돼요.

프로바이더는 스키마를 Moonshot이 지원하는 JSON Schema 부분집합으로 정규화하고 기본적으로 엄격한 스키마 검증을 활성화해요.

알 수 없는 커스텀 모델 ID의 경우 객체 생성은 스키마 제약 디코딩 대신 JSON 모드로 폴백돼요.

최상의 신뢰성을 위해 Output을 통해 스키마를 전달하는 것에 더해 프롬프트에도 스키마 요구 사항을 포함하는 것을 강력히 권장해요.

메시지 이름 (Message Names)

Moonshot AI는 system, user, assistant 메시지에 선택적 참가자 이름을 지원해요. 이름을 포함해야 하는 각 메시지에 providerOptions.moonshotai.name을 설정하세요:

import {
  moonshotai,
  type MoonshotAIMessageProviderOptions,
} from '@ai-sdk/moonshotai';
import { generateText } from 'ai';

const { text } = await generateText({
  model: moonshotai('kimi-k3'),
  messages: [
    {
      role: 'user',
      content: 'Suggest a name for my neighborhood book club.',
      providerOptions: {
        moonshotai: {
          name: 'organizer',
        } satisfies MoonshotAIMessageProviderOptions,
      },
    },
  ],
});

같은 옵션이 streamText에서도 동작해요. 이름이 설정되지 않으면 생략돼요. 프로바이더는 툴 메시지의 이름을 무시하고 지원되지 않는 경고를 반환해요. 메시지 이름에 불필요한 개인 또는 식별 정보를 포함하지 마세요.

부분 모드 (Partial Mode)

Moonshot AI의 Partial Mode는 최종 assistant 메시지의 콘텐츠를 이어나가요. 해당 assistant 메시지의 프로바이더 옵션에서 partial: true를 설정하세요:

import {
  moonshotai,
  type MoonshotAIAssistantMessageProviderOptions,
} from '@ai-sdk/moonshotai';
import { generateText } from 'ai';

const prefix = 'The sky is';

const { text } = await generateText({
  model: moonshotai('kimi-k3'),
  messages: [
    {
      role: 'user',
      content: 'Write one short sentence about the color of the sky.',
    },
    {
      role: 'assistant',
      content: prefix,
      providerOptions: {
        moonshotai: {
          partial: true,
        } satisfies MoonshotAIAssistantMessageProviderOptions,
      },
    },
  ],
});

const completeResponse = prefix + text;

부분 메시지는 프롬프트에서 최종 assistant 메시지여야 해요. Moonshot은 연속 부분만 반환하므로, 완전한 응답이 필요할 때는 접두사와 생성된 텍스트를 연결하세요.

Partial Mode는 Moonshot의 `json_object` 응답 형식과 결합할 수 없어요. 프로바이더는 요청을 보내기 전에 그 조합을 거부해요. 지원되는 `json_schema` 응답은 계속 사용할 수 있지만, 구조화된 출력 파싱은 반환된 연속 부분만 검증해요.

Kimi K3 동적 툴 로딩 (Kimi K3 Dynamic Tool Loading)

Kimi K3는 대화의 임의 위치에서 완전한 함수 툴 정의를 로드할 수 있어요. 빈 system 메시지의 Moonshot 프로바이더 옵션에 tools를 추가하세요. 프로바이더가 content 필드 없이 { role: 'system', tools: [...] }를 보내고, 최상위 툴에 사용하는 것과 같은 Moonshot Flavored JSON Schema 정규화를 적용해요.

import {
  moonshotai,
  type MoonshotAISystemMessageProviderOptions,
} from '@ai-sdk/moonshotai';
import { generateText } from 'ai';

const result = await generateText({
  model: moonshotai('kimi-k3'),
  allowSystemInMessages: true,
  messages: [
    { role: 'user', content: 'Help me prepare for a trip.' },
    { role: 'assistant', content: 'I can help with that.' },
    {
      role: 'system',
      content: '',
      providerOptions: {
        moonshotai: {
          tools: [
            {
              type: 'function',
              name: 'get_weather',
              description: 'Get the current weather for a city',
              inputSchema: {
                type: 'object',
                properties: { city: { type: 'string' } },
                required: ['city'],
                additionalProperties: false,
              },
              strict: true,
            },
          ],
        } satisfies MoonshotAISystemMessageProviderOptions,
      },
    },
    { role: 'user', content: 'What is the weather in San Francisco?' },
  ],
});

각 항목은 완전한 함수 정의를 포함해야 해요. 최상위 툴과 동적으로 로드된 툴을 같은 요청에서 사용할 수 있어요. 알려진 지원되지 않는 공식 모델은 동적 메시지를 생략하고 지원되지 않는 경고를 반환해요. 커스텀 모델 ID는 전방 호환성을 위해 이를 유지해요.

동적 system 메시지를 신뢰할 수 있는 서버 측 상태에 보관하세요. 툴 이름, 설명, 스키마가 Moonshot으로 전송되며 컨텍스트를 소비해요. 동적 선언은 요청 로컬이므로, 그 툴들이 계속 사용 가능해야 하는 동안 이후 요청에서 이전 선언을 유지하세요. 메시지를 추가하는 것도 이전 선언을 다시 쓰는 것보다 프롬프트 캐시 접두사를 더 잘 보존해요.

추론 모델 (Reasoning Models)

Kimi K3는 항상 추론하며 low, high, max reasoning effort를 지원해요. 기본값은 max예요. 프로바이더 옵션 또는 일반 reasoning 설정으로 effort를 구성할 수 있어요:

import {
  moonshotai,
  type MoonshotAILanguageModelOptions,
} from '@ai-sdk/moonshotai';
import { generateText } from 'ai';

const { text, reasoningText } = await generateText({
  model: moonshotai('kimi-k3'),
  providerOptions: {
    moonshotai: {
      reasoningEffort: 'high',
    } satisfies MoonshotAILanguageModelOptions,
  },
  prompt: 'How many "r"s are in the word "strawberry"?',
});

console.log(reasoningText);
console.log(text);

Kimi K2.5와 K2.6은 thinking을 활성화하거나 비활성화할 수 있어요. Kimi K2.7은 항상 thinking과 보존된 추론이 활성화돼요. 다중 턴 Kimi K2.7 대화에서는 추론 기록을 유지하세요. 추론 출력은 표준 AI SDK reasoning 파트를 통해 노출돼요.

import {
  moonshotai,
  type MoonshotAILanguageModelOptions,
} from '@ai-sdk/moonshotai';
import { streamText } from 'ai';

const result = streamText({
  model: moonshotai('kimi-k2.7-code'),
  providerOptions: {
    moonshotai: {
      thinking: { type: 'enabled' },
      reasoningHistory: 'preserved',
    } satisfies MoonshotAILanguageModelOptions,
  },
  prompt: 'How many "r"s are in the word "strawberry"?',
});

for await (const part of result.fullStream) {
  if (part.type === 'reasoning-delta') {
    process.stdout.write(part.text);
  } else if (part.type === 'text-delta') {
    process.stdout.write(part.text);
  }
}

챗봇에 reasoning을 통합하는 방법에 대한 자세한 내용은 AI SDK UI: Chatbot을 참고하세요.

로그 확률 (Log Probabilities)

Moonshot AI는 Chat Completions에 대한 토큰 로그 확률을 반환할 수 있어요. logprobs를 설정해 토큰 확률을 요청하거나, topLogprobs를 설정해 각 토큰 위치에서 가장 가능성 높은 대안을 요청하세요. topLogprobs를 설정하면 logprobs가 자동으로 활성화돼요.

import {
  moonshotai,
  type MoonshotAILanguageModelOptions,
} from '@ai-sdk/moonshotai';
import { generateText } from 'ai';

const result = await generateText({
  model: moonshotai('moonshot-v1-8k'),
  prompt: 'Reply with one word that means happy.',
  providerOptions: {
    moonshotai: {
      topLogprobs: 3,
    } satisfies MoonshotAILanguageModelOptions,
  },
});

console.log(result.text);
console.log(result.providerMetadata?.moonshotai?.logprobs);

generateText의 경우 로그 확률은 providerMetadata.moonshotai.logprobs에서 사용할 수 있어요. streamText의 경우 누적된 로그 확률이 같은 메타데이터 경로의 최종 finish 파트에 포함돼요.

Moonshot은 요청 옵션과 OpenAI Chat Completions 호환성을 문서화하지만, 로그 확률 응답 스키마는 별도로 명시하지 않아요. 따라서 프로바이더는 각 토큰의 logprob, nullable bytes, top_logprobs를 포함한 OpenAI 호환 content 항목을 보존해요.

토큰 확률과 대안은 응답 크기를 크게 늘릴 수 있어요. 필요한 경우에만 요청하고, 애플리케이션이 요구하지 않는 한 프로바이더 메타데이터를 전달하거나 영구적으로 기록하는 것을 피하세요.

비디오 입력 (Video Input)

Kimi K3, Kimi K2.7 Code, Kimi K2.6, Kimi K2.5는 비디오 입력을 지원해요. 비디오 미디어 타입을 가진 file 콘텐츠 파트로 비디오를 전달하세요:

import { moonshotai } from '@ai-sdk/moonshotai';
import { generateText } from 'ai';
import fs from 'node:fs';

const { text } = await generateText({
  model: moonshotai('kimi-k3'),
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: 'Summarize what happens in this video.' },
        {
          type: 'file',
          data: fs.readFileSync('./video.mp4'),
          mediaType: 'video/mp4',
        },
      ],
    },
  ],
});

console.log(text);

URL도 전달할 수 있어요. Moonshot AI는 외부 URL을 가져오지 않으므로 AI SDK가 비디오를 다운로드해 전송 전에 base64로 인라인 처리해요:

{
  type: 'file',
  data: new URL('https://example.com/video.mp4'),
  mediaType: 'video/mp4',
}
지원되는 이미지 미디어 타입은 `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/bmp`, `image/heic`, `image/heif`예요. 지원되는 비디오 미디어 타입은 `video/mp4`, `video/mpeg`, `video/mov`, `video/avi`, `video/x-flv`, `video/mpg`, `video/webm`, `video/wmv`, `video/3gpp`예요. 그 외 이미지 및 비디오 미디어 타입은 요청을 보내기 전에 거부돼요. Moonshot AI는 최대 1080p의 비디오를 권장해요. 더 큰 비디오 또는 여러 요청에서 재사용하는 비디오는 [Moonshot Files API](https://platform.kimi.ai/docs/api/files)로 업로드하세요. 오디오와 PDF 입력은 Moonshot AI 채팅 완성에서 지원되지 않아요.

파일 참조 및 텍스트 파일 (File References and Text Files)

Moonshot Files API로 업로드된 이미지와 비디오는 프로바이더 참조로 전달할 수 있어요. 업로드된 파일 ID에 ms:// 접두사를 붙이고 이미지 또는 비디오 미디어 타입을 사용하세요:

{
  type: 'file',
  data: {
    type: 'reference',
    reference: {
      moonshotai: 'ms://file-id',
    },
  },
  mediaType: 'image/png',
}

인라인 텍스트 파일 데이터는 네이티브 텍스트 콘텐츠 파트로 전송돼요:

{
  type: 'file',
  data: {
    type: 'text',
    text: 'Document contents',
  },
  mediaType: 'text/plain',
}

예측 출력 (Predicted Outputs)

예상 응답의 대부분이 이미 알려진 경우 정적 예측 콘텐츠를 제공할 수 있어요. Moonshot AI는 변경된 콘텐츠를 여전히 생성하면서 예측을 사용해 응답을 가속할 수 있어요:

import {
  moonshotai,
  type MoonshotAILanguageModelOptions,
} from '@ai-sdk/moonshotai';
import { streamText } from 'ai';

const source = `export function greet(name: string) {
  return \`Hello, \${name}!\`;
}`;

const result = streamText({
  model: moonshotai('kimi-k3'),
  messages: [
    {
      role: 'user',
      content:
        'Change the function to say "Welcome" instead of "Hello". Respond only with the updated code.',
    },
    { role: 'user', content: source },
  ],
  providerOptions: {
    moonshotai: {
      prediction: {
        type: 'content',
        content: source,
      },
    } satisfies MoonshotAILanguageModelOptions,
  },
});

for await (const textPart of result.textStream) {
  process.stdout.write(textPart);
}

content는 텍스트 파트 배열일 수도 있어요:

prediction: {
  type: 'content',
  content: [
    { type: 'text', text: 'First known section' },
    { type: 'text', text: 'Second known section' },
  ],
}
예측 콘텐츠는 요청의 일부로 Moonshot AI에 전송돼요. 프로바이더와 공유할 의도가 없다면 민감하거나 독점적인 텍스트를 포함하지 마세요.

프로바이더 옵션 (Provider Options)

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

  • strictJsonSchema boolean

    구조화된 출력에 엄격한 JSON 스키마 검증을 사용할지 여부예요. 기본값은 true.

  • logprobs boolean

    생성된 토큰에 대한 로그 확률을 반환할지 여부예요. 결과는 providerMetadata.moonshotai.logprobs에서 사용할 수 있어요.

  • topLogprobs number

    각 토큰 위치에서 반환할 가장 가능성 높은 토큰 수예요. 0부터 20까지의 정수 값을 받으며 logprobs를 자동으로 활성화해요.

  • reasoningEffort 'low' | 'high' | 'max'

    Kimi K3의 reasoning effort예요. 기본값은 'max'예요. 일반 reasoning 설정도 사용할 수 있어요.

  • prediction { type: 'content'; content: string | Array<{ type: 'text'; text: string }> }

    응답의 대부분이 이미 알려진 요청을 가속할 수 있는 정적 예측 출력을 제공해요.

  • thinking object

    Kimi K2.5와 K2.6의 구성이에요. Kimi K2.7은 thinking을 비활성화할 수 없으므로 enabled만 받아요. Kimi K3는 이 필드를 받지 않아요.

    • type 'enabled' | 'disabled'

      thinking 모드를 활성화할지 여부예요. Kimi K2.7 Code의 경우 'enabled'만 받아요.

    • budgetTokens number

      사용 중단됨. Moonshot Chat Completions는 thinking 예산을 지원하지 않아요. 프로바이더는 이 값을 생략하고 경고를 반환해요. 하위 호환성을 위해 계속 허용돼요.

  • reasoningHistory 'disabled' | 'interleaved' | 'preserved'

    다중 턴 대화에서 보존된 추론 동작을 제어해요:

    • 'disabled'와 'interleaved'는 호환성을 위해 유지돼요. 요청을 변경하지 않으므로 모델의 서버 기본 동작이 적용돼요.
    • 'preserved'는 Kimi K2.6에서 thinking.keep: 'all'에 매핑돼요. Kimi K2.7과 K3는 기본적으로 추론을 보존해요.

채팅 응답 메타데이터 (Chat Response Metadata)

Moonshot AI는 생성 및 스트리밍 응답에서 providerMetadata.moonshotai에 프로바이더별 응답 필드를 보존해요:

  • responseObject: chat.completion 또는 chat.completion.chunk
  • choiceIndex: 선택된 응답 선택 인덱스
  • messageRole: 제공될 때 응답 메시지 역할
  • toolCallTypes: 각 반환된 호출의 툴 호출 유형

이 필드는 공유 AI SDK 결과 필드가 아닌 Moonshot의 Chat Completions 응답에 특화돼 있으므로 프로바이더 메타데이터에 남아 있어요.

모델 기능 (Model Capabilities)

Moonshot V1 시리즈와 Kimi K2.5는 새로 등록한 사용자에게는 사용할 수 없으며 2026년 8월 31일에 전체 플랫폼 종료가 예정돼 있어요. Chat Completions API 모델 표면의 일부이므로 계속 나열되지만, 새 애플리케이션은 Kimi K3, Kimi K2.7 Code 또는 Kimi K2.6을 사용해야 해요.

모델 이미지 입력 비디오 입력 객체 생성 툴 사용 툴 스트리밍
moonshot-v1-auto
moonshot-v1-8k
moonshot-v1-32k
moonshot-v1-128k
moonshot-v1-8k-vision-preview
moonshot-v1-32k-vision-preview
moonshot-v1-128k-vision-preview
kimi-k2.5
kimi-k2.6
kimi-k2.7-code
kimi-k2.7-code-highspeed
kimi-k3
현재 가용성과 모델별 제약 사항은 [Kimi 모델 목록](https://platform.kimi.ai/docs/models)과 [모델 파라미터 참조](https://platform.kimi.ai/docs/api/models-overview)를 참고하세요. 필요할 때 커스텀 또는 은퇴한 프로바이더 모델 ID를 문자열로 전달할 수도 있어요.

더 알아보기 (Learn more)

전체 사이트맵