Код
Vercel AI SDK
Создайте провайдер nokeep через createOpenAICompatible из @ai-sdk/openai-compatible. Тогда generateText, streamText и инструменты работают так же, как с любой моделью AI SDK.
Проверено 29 октября 2026 г.
Установка и настройка провайдера
npm install ai @ai-sdk/openai-compatible zod
export NOKEEP_API_KEY="sk-nokeep-test" # your own key once it connectsimport { createOpenAICompatible } from "@ai-sdk/openai-compatible"
export const nokeep = createOpenAICompatible({
name: "nokeep",
apiKey: process.env.NOKEEP_API_KEY,
baseURL: "https://nokeep.ai/v1",
includeUsage: true, // token counts on streamed replies too
})nokeep("<model id>") даёт модель. Идентификаторы: deepseek-v4.1-flash-uncensored и glm-5.3-flash-uncensored. Сравните их на странице Модели или получите из GET /v1/models. includeUsage: true запрашивает подсчёт токенов в потоковых ответах; без него streamText не сообщит ни одного.
generateText
import { generateText } from "ai"
import { nokeep } from "./nokeep.js"
const { text, usage } = await generateText({
model: nokeep("deepseek-v4.1-flash-uncensored"),
system: "You are a blunt editor.",
prompt: "Cut this opening line to ten words: ...",
})
console.log(text)
console.log(usage.inputTokens, usage.outputTokens)streamText
import { streamText } from "ai"
import { nokeep } from "./nokeep.js"
const result = streamText({
model: nokeep("deepseek-v4.1-flash-uncensored"),
prompt: "Tell me a story in three lines.",
})
for await (const text of result.textStream) process.stdout.write(text)
// With includeUsage on, the counts arrive once the stream ends.
console.log(await result.usage)В маршруте Next.js верните result.toUIMessageStreamResponse() для useChat или result.toTextStreamResponse() для обычного текста. Остановить ответ можно, прервав запрос (abortSignal): вы платите за то, что было написано до остановки. См. Потоковая передача.
Вызов инструментов
import { generateText, stepCountIs, tool } from "ai"
import { z } from "zod"
import { nokeep } from "./nokeep.js"
const { text } = await generateText({
model: nokeep("deepseek-v4.1-flash-uncensored"),
tools: {
weather: tool({
description: "Get the weather in a city",
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ city, celsius: 18 }),
}),
},
stopWhen: stepCountIs(5), // let the model call the tool, read the result and answer
prompt: "What's the weather in Lisbon?",
})
console.log(text)Обе модели вызывают инструменты. glm-5.3-flash-uncensored выбирает сам: toolChoice: "required" или имя конкретного инструмента дают 400, поэтому, если инструмент обязан сработать, используйте DeepSeek. См. Вызовы инструментов.
Уровень рассуждений
import { generateText } from "ai"
import { nokeep } from "./nokeep.js"
const { text, reasoningText } = await generateText({
model: nokeep("deepseek-v4.1-flash-uncensored"),
prompt: "Plan a three-act heist story in five bullet points.",
maxOutputTokens: 4000, // thinking counts toward the limit
providerOptions: { nokeep: { reasoningEffort: "high" } },
})
console.log(reasoningText) // the thinking, apart from the answer
console.log(text)Ключ в providerOptions — это name, которое вы дали провайдеру. Он отправляется как reasoning_effort без изменений. DeepSeek V4.1 Flash Uncensored отвечает сразу, если не попросить его думать: принимает none, low, high, max. Собственная опция AI SDK reasoning: "high" отправляет то же поле. См. Рассуждения.
Изображения (DeepSeek)
import { readFile } from "node:fs/promises"
import { generateText } from "ai"
import { nokeep } from "./nokeep.js"
const { text } = await generateText({
model: nokeep("deepseek-v4.1-flash-uncensored"),
messages: [{
role: "user",
content: [
{ type: "text", text: "What is in this picture?" },
{ type: "file", mediaType: "image/jpeg", data: await readFile("photo.jpg") },
],
}],
})
console.log(text)deepseek-v4.1-flash-uncensoredчитает до 10 изображений за запрос.glm-5.3-flash-uncensoredчитает только текст и отвечает400 unsupported_input.- AI SDK отправляет каждое изображение внутри запроса, в base64. Если передать
URLкакdata, файл сначала скачивается. Запрос может весить до 12 МБ, поэтому крупные фото уменьшайте. - Изображения — это части
fileс media typeimage/*. Старая частьimageещё работает, но устарела. - Другие файлы, например PDF или аудио, отклоняются с
400 unsupported_input. См. Изображения.
Подводные камни
- `reasoning_effort` принимает только значения самой модели.
deepseek-v4.1-flash-uncensoredпринимаетnone,low,high,max;glm-5.3-flash-uncensored—low,high. Значения других приложенийminimal,mediumиxhighприводятся к ближайшему уровню модели (mediumкакhigh,xhighкакmax, где он есть); любое другое значение даёт400 invalid_reasoning_effort. См. Рассуждения. - Поля, которые модель не может принять, отбрасываются, а не отклоняются. Вызов всё равно отвечает, а заголовок ответа
x-nokeep-ignoredназывает, что было пропущено. GLM оставляет толькоtools,tool_choiceиreasoning_effort, поэтому егоtemperatureиresponse_formatотбрасываются. См. какие поля принимает каждая модель. - `n` должен быть 1. Чтобы получить несколько ответов, делайте несколько вызовов.
- Используйте `@ai-sdk/openai-compatible`, а не `@ai-sdk/openai`. Провайдер OpenAI по умолчанию обращается к
/v1/responses, которого у nokeep нет.
Вопросы
Есть ли пакет провайдера nokeep для AI SDK?
Он не нужен. @ai-sdk/openai-compatible — собственный пакет AI SDK для API, совместимых с OpenAI, и все возможности этой страницы работают через него.
Сообщает ли streamText подсчёт токенов?
Да, если провайдер создан с includeUsage: true. Тогда await result.usage даёт количество токенов за вызов.
Можно попробовать без оплаты?
Да. Используйте ключ sk-nokeep-test: каждый вызов отвечает одной фиксированной строкой и ничего не стоит, так что сначала можно подключить приложение. Бесплатный тестовый ключ.