Pular para o conteúdo
Toda a documentação

Código

Vercel AI SDK

Crie um provider nokeep com createOpenAICompatible de @ai-sdk/openai-compatible. Depois, generateText, streamText e as ferramentas funcionam como com qualquer modelo do AI SDK.

Verificado em 29 de outubro de 2026

Instale e configure o provider

Shell
npm install ai @ai-sdk/openai-compatible zod
export NOKEEP_API_KEY="sk-nokeep-test"  # your own key once it connects
nokeep.js
import { 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("<ID do modelo>") cria um modelo. Os IDs são deepseek-v4.1-flash-uncensored e glm-5.3-flash-uncensored: compare-os em Modelos, ou leia-os em GET /v1/models. includeUsage: true pede contagens de tokens nas respostas em streaming; sem ele, o streamText não informa nenhuma.

generateText

JavaScript
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

JavaScript
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)

Em um route handler do Next.js, retorne result.toUIMessageStreamResponse() para useChat, ou result.toTextStreamResponse() para texto puro. Para parar uma resposta, aborte a requisição (abortSignal); você paga pelo que foi escrito antes de parar. Veja Streaming.

Chamada de ferramentas

JavaScript
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)

Os dois modelos chamam ferramentas. glm-5.3-flash-uncensored escolhe sozinho: toolChoice: "required" ou uma ferramenta nomeada recebe um 400, então use o DeepSeek quando uma ferramenta precisar rodar. Veja Chamadas de ferramentas.

Esforço de raciocínio

JavaScript
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)

A chave dentro de providerOptions é o name que você deu ao provider. Ela é enviada como reasoning_effort, sem mudança. O DeepSeek V4.1 Flash Uncensored responde na hora, a menos que você peça para pensar: ela aceita none, low, high, max. A opção reasoning: "high" do próprio AI SDK envia o mesmo campo. Veja Raciocínio.

Imagens (DeepSeek)

JavaScript
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 lê até 10 imagens por pedido. glm-5.3-flash-uncensored lê só texto e responde 400 unsupported_input.
  • O AI SDK envia cada imagem dentro do pedido, em base64. Passe uma URL como data e ele baixa o arquivo antes. Um pedido pode ter até 12 MB, então reduza fotos grandes.
  • Imagens são partes file com um media type image/*. A parte image mais antiga ainda funciona, mas está obsoleta.
  • Outros arquivos, como PDFs ou áudio, são recusados com 400 unsupported_input. Veja Imagens.

Armadilhas

  • `reasoning_effort` aceita só os valores do próprio modelo. deepseek-v4.1-flash-uncensored aceita none, low, high, max; glm-5.3-flash-uncensored aceita low, high. Os valores minimal, medium e xhigh de outros apps rodam no nível mais próximo do modelo (medium como high, xhigh como max onde o modelo tem esse nível); qualquer outro valor recebe 400 invalid_reasoning_effort. Veja Raciocínio.
  • Campos que um modelo não aceita são descartados, não recusados. A chamada ainda responde, e o cabeçalho de resposta x-nokeep-ignored diz o que ficou de fora. O GLM mantém só tools, tool_choice e reasoning_effort, então seus temperature e response_format são descartados. Veja quais campos cada modelo aceita.
  • `n` tem de ser 1. Para pedir várias respostas, faça várias chamadas.
  • Use `@ai-sdk/openai-compatible`, não `@ai-sdk/openai`. O provider da OpenAI chama /v1/responses por padrão, que o nokeep não tem.

Perguntas

Existe um pacote de provider nokeep para o AI SDK?

Não precisa. @ai-sdk/openai-compatible é o pacote próprio do AI SDK para APIs compatíveis com OpenAI, e todo recurso desta página funciona por ele.

O streamText informa o uso?

Sim, quando o provider é criado com includeUsage: true. Aí await result.usage dá as contagens de tokens da chamada.

Posso testar sem pagar?

Pode. Use a chave sk-nokeep-test: cada chamada responde com uma linha fixa e não custa nada, então você configura seu app primeiro. A chave de teste grátis.