Use o Vercel AI SDK com UberLLM (modelos mais baratos, mesmo código)
Instale @ai-sdk/openai-compatible, crie um provider com baseURL https://api.uberllm.dev/v1 e sua chave UberLLM, e passe uberllm("<model id>") onde quer que seu app passe um modelo hoje. Nada mais no app muda.
Passos
- Crie uma chave na sua página de chaves e adicione um pouco de crédito (contas começam em $0).
- Instale o provedor:
npm i ai @ai-sdk/openai-compatible
- Coloque a chave em
.env.local(Next.js) ou no ambiente do seu servidor:
UBERLLM_API_KEY=ull_your_key
- Crie o provedor uma vez, por exemplo em
lib/uberllm.ts:
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
export const uberllm = createOpenAICompatible({
name: "uberllm",
baseURL: "https://api.uberllm.dev/v1",
apiKey: process.env.UBERLLM_API_KEY, // sent as Authorization: Bearer <key>
includeUsage: true, // token counts on streamed answers too
});
- Use-o onde você usava um modelo antes:
import { generateText } from "ai";
import { uberllm } from "@/lib/uberllm";
const { text } = await generateText({
model: uberllm("deepseek/deepseek-v4.1-flash"),
prompt: "Write a one-line welcome message.",
});
Migrando um aplicativo que já usa @ai-sdk/openai
Troque o argumento do modelo e mantenha todo o resto:
// before
import { openai } from "@ai-sdk/openai";
const model = openai("gpt-4o");
// after
import { uberllm } from "@/lib/uberllm";
const model = uberllm("deepseek/deepseek-v4.1-flash");
Os IDs dos modelos são os IDs em uberllm.dev/models e sempre têm um fabricante na frente (openai/…, anthropic/…, deepseek/…). É assim que você pode executar GPT, Claude, Gemini e modelos abertos com uma única chave e compará-los mudando uma única string.
Uma rota de chat Next.js para useChat
useChat de @ai-sdk/react envia para /api/chat por padrão. Esta rota responde a isso:
// app/api/chat/route.ts
import { streamText, convertToModelMessages, type UIMessage } from "ai";
import { uberllm } from "@/lib/uberllm";
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: uberllm("deepseek/deepseek-v4.1-flash"),
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}
Mantenha a chave no servidor. Nunca a coloque em uma variável NEXT_PUBLIC_: qualquer um poderia lê-la da página e gastar seu saldo.
Defina um teto para o custo de uma chamada
As solicitações de chat aceitam provider.max_price (dólares por milhão de tokens). Passe o valor em providerOptions, sob o provedor name que você escolheu:
await generateText({
model: uberllm("deepseek/deepseek-v4.1-flash"),
prompt: "Hi",
providerOptions: { uberllm: { provider: { max_price: { prompt: 0.2, completion: 0.4 } } } },
});
Se ninguém vender o modelo por um preço abaixo desse no momento, a chamada é recusada com max_price_exceeded e nada é cobrado.
Solução de problemas
- 401
invalid_api_key: a chave não chegou ao servidor. Reinicienext devapós editar.env.local, e verifique seprocess.env.UBERLLM_API_KEYestá configurado onde o código é executado (servidor, não o navegador). - 402
insufficient_credits: adicione crédito na página de créditos. - 404
model_not_found: o ID está errado ou faltando seu criador. Copie-o da página do modelo. - 400
wrong_endpoint: você passou um modelo de imagem ou vídeo parastreamText. Modelos de imagem passam poruberllm.imageModel(…)comgenerateImage; vídeo é um trabalho, veja Criar um vídeo ou imagem. - O uso está vazio em streams: defina
includeUsage: trueno provedor, como acima.
Continue lendo
- A referência completa com chamadas de ferramentas e imagens: Documentação do Vercel AI SDK
- Endpoint compatível com OpenAI explicado
- Preços de LLM ao vivo