DeepSeek Provider — DeepSeek 프로바이더
DeepSeek Provider — DeepSeek 프로바이더
DeepSeek API를 통해 강력한 언어 모델에 접근하는 방법을 알려드려요. DeepSeek 프로바이더는 DeepSeek API를 통해 강력한 언어 모델에 접근할 수 있게 해줘요.
API 키는 DeepSeek Platform에서 얻을 수 있어요.
출처: 문서
본문
DeepSeek 프로바이더는 DeepSeek API를 통해 강력한 언어 모델에 대한 접근을 제공해요.
API 키는 DeepSeek Platform에서 얻을 수 있어요.
설정 (Setup)
DeepSeek 프로바이더는 @ai-sdk/deepseek 모듈을 통해 사용할 수 있어요. 다음으로 설치할 수 있어요:
npm install @ai-sdk/deepseek
프로바이더 인스턴스 (Provider Instance)
@ai-sdk/deepseek에서 기본 프로바이더 인스턴스 deepSeek을 import할 수 있어요:
import { deepSeek } from '@ai-sdk/deepseek';
맞춤 구성이 필요하면 createDeepSeek을 import하고 설정으로 프로바이더 인스턴스를 만들 수 있어요:
import { createDeepSeek } from '@ai-sdk/deepseek';
const deepSeek = createDeepSeek({
apiKey: proces..._KEY ?? '',
});
DeepSeek 프로바이더 인스턴스를 맞춤 설정하는 데 사용할 수 있는 선택적 설정은 다음과 같아요:
- baseURL string — API 호출에 다른 URL 접두사를 사용해요. 기본 접두사는
https://api.deepseek.com이에요. - apiKey string —
Authorization헤더로 보내지는 API 키. 기본값은DEEPSEEK_API_KEY환경 변수예요. - headers Record<string,string> — 요청에 포함할 커스텀 헤더.
- fetch (input: RequestInfo, init?: RequestInit) => Promise<Response> — 커스텀 fetch 구현.
언어 모델 (Language Models)
프로바이더 인스턴스로 언어 모델을 만들 수 있어요:
import { deepSeek } from '@ai-sdk/deepseek';
import { generateText } from 'ai';
const { text } = await generateText({
model: deepSeek('deepseek-v4-flash'),
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
});
.chat() 또는 .languageModel() 팩토리 메서드도 사용할 수 있어요:
const model = deepSeek.chat('deepseek-v4-flash');
// or
const model = deepSeek.languageModel('deepseek-v4-flash');
DeepSeek 언어 모델은 streamText 함수에서 사용할 수 있어요 (AI SDK Core 참고).
DeepSeek는 2026년 7월 24일에 deepseek-chat과 deepseek-reasoner 별칭을 폐지했어요. 현재 API에는 deepseek-flash (현재 V4.x Flash 릴리스의 별칭), deepseek-v4-flash, deepseek-v4-pro를 사용하세요. 커스텀/레거시 모델 ID는 커스텀 엔드포인트와의 호환성을 위해 문자열로 계속 허용돼요.
DeepSeek 모델에 사용할 수 있는 선택적 프로바이더 옵션은 다음과 같아요:
logprobsboolean — 선택. 생성된 콘텐츠와 reasoning 토큰의 로그 확률을providerMetadata.deepseek.logprobs로 반환해요.topLogprobsnumber — 선택. 각 토큰 위치에서 가장 가능성 높은 토큰을 지정된 수만큼 반환해요.0부터20까지의 값을 받아들이고logprobs를 자동으로 활성화해요.userIdstring — 선택. DeepSeek가 콘텐츠 안전 추적, KV-cache 격리, 스케줄링 격리에 사용하는 불투명한(end-user) 사용자 식별자. 값은^[a-zA-Z0-9_-]+$와 일치해야 하고 최대 512자를 포함해야 해요. 이름, 이메일 주소, 기타 개인 사용자 정보를 포함하지 마세요.thinkingobject — 선택. DeepSeek V4 모델의 thinking 모드(chain-of-thought reasoning)를 제어해요.type:'enabled' | 'disabled'— thinking 모드 활성화/비활성화. DeepSeek's thinking mode docs 참고.
reasoningEffort'low' | 'high' | 'max' — 선택. DeepSeek V4 reasoning 모델의 thinking 강도를 제어해요. 최상위reasoning설정을 사용할 때minimal은low로,medium은high로,xhigh는max로 전송돼요. 요청된 값이 매핑될 때마다 호환성 경고가 반환돼요.
하위 호환을 위해 런타임에 제공된 레거시 프로바이더 옵션도 문서화된 값으로 매핑돼요: thinking.type: 'adaptive'는 'enabled'로, reasoningEffort: 'medium'은 'high'로, reasoningEffort: 'xhigh'는 'max'로. 각 매핑은 호출자가 정규 값을 사용하도록 마이그레이션할 수 있게 호환성 경고를 반환해요.
DeepSeek는 최상위 frequencyPenalty 및 presencePenalty 설정을 폐지했어요. 프로바이더는 이 설정을 생략하고 사용 시 폐지 경고를 반환해요. temperature와 topP는 thinking이 활성화된 동안(DeepSeek V4 모델의 기본 thinking 모드 포함) 효과가 없으므로, 프로바이더는 지원되지 않는 경고와 함께 이를 생략해요. temperature와 topP를 사용하려면 thinking.type을 명시적으로 'disabled'로 설정하세요.
import {
deepSeek,
type DeepSeekLanguageModelChatOptions,
} from '@ai-sdk/deepseek';
import { generateText } from 'ai';
const { text, reasoning } = await generateText({
model: deepSeek('deepseek-v4-flash'),
prompt: 'How many "r"s are in the word "strawberry"?',
providerOptions: {
deepseek: {
userId: 'tenant_123-user',
thinking: { type: 'enabled' },
reasoningEffort: 'high',
} satisfies DeepSeekLanguageModelChatOptions,
},
});
메시지 이름 (Message Names)
DeepSeek는 system, user, assistant 메시지에 선택적 참가자 이름을 지원해요. 이름을 포함해야 하는 각 메시지에 providerOptions.deepseek.name을 설정하세요:
import {
deepSeek,
type DeepSeekMessageProviderOptions,
} from '@ai-sdk/deepseek';
import { generateText } from 'ai';
const { text } = await generateText({
model: deepSeek('deepseek-flash'),
instructions: {
role: 'system',
content: 'Help the customer plan a short trip.',
providerOptions: {
deepseek: {
name: 'travel_planner',
} satisfies DeepSeekMessageProviderOptions,
},
},
messages: [
{
role: 'user',
content: 'I want to visit Lisbon for a weekend.',
providerOptions: {
deepseek: {
name: 'customer',
} satisfies DeepSeekMessageProviderOptions,
},
},
{
role: 'assistant',
content: 'What kinds of activities do you enjoy?',
providerOptions: {
deepseek: {
name: 'travel_planner',
} satisfies DeepSeekMessageProviderOptions,
},
},
{
role: 'user',
content: 'Food, architecture, and walking.',
providerOptions: {
deepseek: {
name: 'customer',
} satisfies DeepSeekMessageProviderOptions,
},
},
],
});
같은 메시지 옵션이 streamText에서도 작동해요:
import {
deepSeek,
type DeepSeekMessageProviderOptions,
} from '@ai-sdk/deepseek';
import { streamText } from 'ai';
const result = streamText({
model: deepSeek('deepseek-flash'),
messages: [
{
role: 'user',
content: 'Suggest a name for my neighborhood book club.',
providerOptions: {
deepseek: {
name: 'organizer',
} satisfies DeepSeekMessageProviderOptions,
},
},
],
});
for await (const textPart of result.textStream) {
process.stdout.write(textPart);
}
옵션이 설정되지 않으면 이름은 생략돼요. name 값은 문자열이어야 해요. DeepSeek는 도구 메시지에서 이름을 지원하지 않으므로 프로바이더는 해당 위치를 무시하고 지원되지 않는 기능 경고를 반환해요. 메시지 이름에 불필요한 개인 정보나 식별 정보를 포함하지 마세요.
Reasoning
DeepSeek V4 모델은 reasoning을 지원해요. reasoning은 스트리밍을 통해 노출돼요:
import { deepSeek } from '@ai-sdk/deepseek';
import { streamText } from 'ai';
const result = streamText({
model: deepSeek('deepseek-v4-pro'),
prompt: 'How many "r"s are in the word "strawberry"?',
});
for await (const part of result.stream) {
if (part.type === 'reasoning') {
// This is the reasoning text
console.log('Reasoning:', part.text);
} else if (part.type === 'text') {
// This is the final answer
console.log('Answer:', part.text);
}
}
reasoning을 챗봇에 통합하는 방법에 대한 자세한 내용은 AI SDK UI: Chatbot을 참고하세요.
채팅 접두사 완성 (Chat Prefix Completion)
DeepSeek의 베타 chat prefix completion은 마지막 assistant 메시지의 콘텐츠를 이어서 생성해요. 베타 base URL로 프로바이더를 만들고 그 assistant 메시지의 프로바이더 옵션에 prefix: true를 설정하세요:
import {
createDeepSeek,
type DeepSeekAssistantMessageProviderOptions,
} from '@ai-sdk/deepseek';
import { generateText } from 'ai';
const deepSeek = createDeepSeek({
baseURL: 'https://api.deepseek.com/beta',
});
const { text } = await generateText({
model: deepSeek('deepseek-v4-flash'),
messages: [
{
role: 'user',
content: 'Write a short sentence about the color of the sky.',
},
{
role: 'assistant',
content: 'The sky is',
providerOptions: {
deepseek: {
prefix: true,
} satisfies DeepSeekAssistantMessageProviderOptions,
},
},
],
});
접두사 메시지는 assistant 메시지여야 하고 프롬프트의 마지막 메시지여야 해요. 구성된 baseURL은 프록시를 사용할 때를 포함해 /beta로 끝나야 해요. 잘못된 위치나 비베타 base URL은 요청을 보내기 전에 실패하게 해요.
채팅 접두사 완성은 DeepSeek 베타 기능이며 동작이 바뀔 수 있어요.
엄격한 도구 호출 (Strict Tool Calls)
DeepSeek의 엄격한 도구 호출 모드는 베타 기능이에요. 베타 base URL로 프로바이더를 만들고 요청의 모든 함수 도구에 strict: true를 설정하세요:
import { createDeepSeek } from '@ai-sdk/deepseek';
import { generateText, tool } from 'ai';
import { z } from 'zod';
const deepSeek = createDeepSeek({
baseURL: 'https://api.deepseek.com/beta',
});
const result = await generateText({
model: deepSeek('deepseek-flash'),
prompt: 'What is the weather in San Francisco?',
tools: {
weather: tool({
description: 'Get the weather for a location.',
inputSchema: z.object({ location: z.string() }),
strict: true,
execute: async ({ location }) => ({ location, temperature: 18 }),
}),
},
});
엄격 도구는 base URL이 /beta로 끝나지 않으면 로컬에서 실패해요. 어떤 함수 도구가 엄격하면 같은 요청의 모든 함수 도구가 strict: true를 설정해야 해요.
프로바이더 메타데이터 (Provider Metadata)
DeepSeek는 providerMetadata 속성을 통해 응답 시스템 핑거프린트와 컨텍스트 캐시 사용량을 노출해요:
import { deepSeek } from '@ai-sdk/deepseek';
import { generateText } from 'ai';
const result = await generateText({
model: deepSeek('deepseek-v4-flash'),
prompt: 'Your prompt here',
});
console.log(result.providerMetadata);
// Example output:
// {
// deepseek: {
// systemFingerprint: 'fp_eaab8d114b_prod0820_fp8_kvcache',
// promptCacheHitTokens: 1856,
// promptCacheMissTokens: 5,
// },
// }
메타데이터는 다음을 포함해요:
systemFingerprint: 응답에 대한 백엔드 구성 핑거프린트promptCacheHitTokens: 캐시된 입력 토큰 수promptCacheMissTokens: 캐시되지 않은 입력 토큰 수
스트리밍된 응답의 경우 응답 청크에서 가장 최근의 non-null 핑거프린트가 반환돼요.
DeepSeek 캐싱 시스템에 대한 자세한 내용은 DeepSeek caching documentation을 참고하세요.
채팅 응답 메타데이터 (Chat Response Metadata)
DeepSeek는 생성 및 스트리밍 응답 모두에 대해 providerMetadata.deepseek에 프로바이더 특정 응답 필드를 보존해요:
responseObject:chat.completion또는chat.completion.chunkchoiceIndex: 선택된 응답 choice 인덱스messageRole: 제공될 때 응답 메시지 역할toolCallTypes: 반환된 각 호출의 도구 호출 타입
이 필드들은 공유 AI SDK 결과 필드가 아니라 DeepSeek의 Chat Completions 응답에 특정되기 때문에 프로바이더 메타데이터에 남아요.
파일 업로드 (File Uploads)
인라인 이미지나 이미지 URL의 경우 파일 part 프로바이더 옵션으로 이미지 처리 세부 정보를 선택하세요. DeepSeek는 low, high, original, auto를 지원해요:
import {
deepSeek,
type DeepSeekFilePartProviderOptions,
} from '@ai-sdk/deepseek';
import { generateText } from 'ai';
const { text } = await generateText({
model: deepSeek('deepseek-v4-flash-vision-exp'),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Describe this image.' },
{
type: 'file',
data: new URL('https://example.com/image.webp'),
mediaType: 'image/webp',
providerOptions: {
deepseek: {
imageDetail: 'low',
} satisfies DeepSeekFilePartProviderOptions,
},
},
],
},
],
});
인라인 이미지 파일 part에 fileData: true를 설정해 DeepSeek의 file_data 콘텐츠 part 표현을 사용하세요. 이는 파일 part의 filename을 보존해요. fileData는 이미지 URL이나 imageDetail과 함께 사용할 수 없어요.
DeepSeek는 JPEG, PNG, GIF, WebP 이미지 입력을 받아들여요. HTTP 이미지 URL은 최대 8,192자일 수 있어요.
DeepSeek Files API로 이미지를 업로드하고 반환된 프로바이더 참조를 deepseek-v4-flash-vision-exp에 전달할 수 있어요. 이렇게 하면 각 요청에서 이미지 바이트를 다시 보내지 않아도 돼요.
import { deepSeek, type DeepSeekFilesOptions } from '@ai-sdk/deepseek';
import { generateText, uploadFile } from 'ai';
import { readFile } from 'node:fs/promises';
const { providerReference, mediaType } = await uploadFile({
api: deepSeek.files(),
data: await readFile('./image.png'),
filename: 'image.png',
providerOptions: {
deepseek: {
expiresAfter: 3600,
} satisfies DeepSeekFilesOptions,
},
});
const { text } = await generateText({
model: deepSeek('deepseek-v4-flash-vision-exp'),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Describe this image.' },
{
type: 'file',
mediaType: mediaType ?? 'image/png',
data: providerReference,
},
],
},
],
});
선택적 expiresAfter 설정은 수명(초)을 지정해요. DeepSeek는 3,600초(1시간)부터 2,592,000초(30일)까지의 값을 받아들여요. 만료를 지정하지 않으면 파일은 영구적이에요.
프로바이더는 성공적인 업로드 응답에서 유효한 파일 ID를 요구해요. 또한 반환된 object와 purpose 판별자 및 숫자 메타데이터를 검증해요. 다른 응답 메타데이터는 불완전한 응답과의 호환성을 위해 선택적으로 남아요; 생략된 값은 providerMetadata에 포함되지 않고, 생략된 응답 파일명은 uploadFile에 제공된 파일명으로 대체돼요.
DeepSeek 파일 업로드는 JPEG (.jpg 및 .jpeg), PNG, GIF, WebP 이미지를 지원해요. 각 파일은 최대 64 MiB이고, 파일명은 최대 512자를 포함할 수 있어요. AI SDK는 업로드 요청을 보내기 전에 이러한 제약을 검증해요. image/jpg 미디어 타입 별칭은 허용되고, 미디어 타입이 일반적일 때(예: application/octet-stream) 지원되는 파일명 확장자가 대체값으로 사용돼요. 선언된 미디어 타입이나 파일명이 지원되는 이미지 형식을 나타내더라도, 인식 가능한 비이미지 콘텐츠는 거부돼요.
모델 기능 (Model Capabilities)
| Model | Text Generation | Object Generation | Image Input | Tool Usage | Tool Streaming |
|---|---|---|---|---|---|
deepseek-flash |
✓ | ✓ | ✗ | ✓ | ✓ |
deepseek-v4-flash |
✓ | ✓ | ✗ | ✓ | ✓ |
deepseek-v4-pro |
✓ | ✓ | ✗ | ✓ | ✓ |
deepseek-v4-flash-vision-exp |
✓ | ✓ | ✓ | ✓ | ✓ |
전체 사용 가능 모델 목록은 DeepSeek docs를 참고하세요. 필요하면 사용 가능한 프로바이더 모델 ID를 문자열로 전달할 수도 있어요.
더 알아보기 (Learn more)
- AI SDK Core — 코어 기능
- OpenAI Provider — OpenAI 프로바이더