Um cliente fintech me ligou no final de 2023, com pânico genuíno na voz, porque seu time de desenvolvimento tinha passado seis semanas construindo uma interface de chat com streaming em cima da API do OpenAI e ainda assim estava quebrada no Mobile Safari. Condições de corrida. Problemas de chunking de tokens. A UI travava no meio da resposta. Seis semanas. Olhei para o codebase deles e era exatamente o que você esperaria: uma implementação feita na mão de ReadableStream, uma camada de gerenciamento de estado customizada para os tokens em streaming, lógica de retry copiada de uma resposta do Stack Overflow de três anos atrás. A coisa estava toda remendada.ReadableStream implementation, a bespoke state management layer for the streaming tokens, retry logic copied from a three-year-old Stack Overflow answer. The thing was held together with tape.
Reescrevi o core usando o Vercel AI SDK em cerca de dois dias. Streaming funcionou. Mobile Safari funcionou. O cliente parou de ligar.Vercel AI SDK in about two days. Streaming worked. Mobile Safari worked. The client stopped ringing.
Isso não é um discurso de vendas. É só o que aconteceu. E é por isso que quero caminhar pelo que esse SDK realmente faz, onde economiza seu tempo de verdade, e onde você ainda vai bater na parede.
O Que o Vercel AI SDK Realmente É
As pessoas ouvem "Vercel AI SDK" e assumem que está preso à infraestrutura Vercel. Não está. Você pode rodar em qualquer servidor Node.js, incluindo seu próprio VPS, Railway, Render, onde quer que seja. O que ele realmente é: uma biblioteca TypeScript que abstrai as partes mais complicadas de construir recursos powered by LLM em uma aplicação web.
Há dois pacotes principais que você vai usar. ai é o runtime core. @ai-sdk/openai (ou @ai-sdk/anthropic, @ai-sdk/google, etc.) são os adaptadores de provedor. O SDK usa uma interface unificada, então mudar de GPT-4o para Claude 3.5 Sonnet é genuinamente uma mudança de uma linha em na maioria dos casos. Testei isso. Funciona.ai is the core runtime. @ai-sdk/openai (or @ai-sdk/anthropic , @ai-sdk/google, etc.) are the provider adapters. The SDK uses a unified interface so switching from GPT-4o to Claude 3.5 Sonnet is genuinely a one-line change in most cases. I've tested this. It holds up.
Os Primitivos Core
Três coisas estão no coração do SDK:
streamText, faz streaming de uma resposta de texto token por token, ideal para interfaces de chat, streams a text response token by token, ideal for chat interfacesgenerateText, aguarda a resposta completa, bom para jobs em background ou quando você não precisa de UX com streaming, waits for the full response, good for background jobs or when you don't need streaming UXgenerateObject, retorna JSON estruturado validado contra um schema Zod, que é onde as coisas ficam realmente interessantes, returns structured JSON validated against a Zod schema, which is where things get properly interesting
streamText é o que a maioria das pessoas quer primeiro. Ele cuida do encanamento do ReadableStream, da codificação e do chunking. Aquele pesadelo de seis semanas em fintech que mencionei? É exatamente o que streamText teria resolvido no primeiro dia. is what most people want first. It handles the ReadableStream plumbing, the encoding, and the chunking. That six-week fintech nightmare I mentioned? That's exactly what streamText would have solved on day one.
Configurando Sem Perder a Sanidade
Assumindo que você está no Next.js 14 ou 15 com o App Router (que você provavelmente está se está lendo isso em 2025), a configuração é genuinamente rápida.
- Instale os pacotes: npm install ai @ai-sdk/openai
npm install ai @ai-sdk/openai - Crie um manipulador de rota em app/api/chat/route.ts
app/api/chat/route.ts - Importe streamText e seu provedor, passe seu modelo e mensagens, retorne o resultado como uma StreamingTextResponse
streamTextand your provider, pass in your model and messages, return the result as aStreamingTextResponse - No cliente, use o hook useChat do pacote ai/react
useChathook from theai/reactpackage
É isso. Você terá um chat com streaming funcionando em menos de uma hora se conhecer Next.js razoavelmente bem. O hook useChat gerencia o array de mensagens, o estado de carregamento, a vinculação do campo de entrada e as atualizações de streaming. Você não escreve nada disso sozinho.useChat hook manages the message array, the loading state, the input field binding, and the streaming updates. You don't write any of that yourself.
O que eu adicionaria imediatamente a qualquer configuração de produção: um prompt de sistema adequado, rate limiting (eu uso Upstash para isso, seu rate limiter respaldado por Redis funciona bem com Edge Functions), e algum tipo de logging de uso de tokens. O SDK expõe dados de uso no objeto de resposta, então você pode registrar prompt tokens e completion tokens no seu banco de dados sem nenhuma chamada de API extra.Upstash for this, their Redis-backed rate limiter plays nicely with Edge Functions), and some kind of token usage logging. The SDK exposes usage data on the response object, so you can log prompt tokens and completion tokens to your database without any extra API calls.
generateObject É o Recurso em Que Você Está Dormindo
Opinião honesta: streamText recebe toda a atenção, mas generateObject é o que mudou como eu arquiteto features de IA.streamText gets all the press but generateObject is the one that's changed how I architect AI features.
A ideia é simples. Você define um schema Zod, passa para generateObject, e o SDK instrui o modelo a retornar JSON que esteja em conformidade com ele. Você recebe um objeto tipado, não uma string que você precisa fazer parsing e rezar.generateObject, and the SDK instructs the model to return JSON that conforms to it. You get back a typed object, not a string you have to parse and pray over.
Seahawk teve um projeto ano passado para uma empresa de gestão de propriedades. Eles queriam extrair dados estruturados de documentos de aluguel enviados, nomes de inquilinos, valores de aluguel, cláusulas de quebra, datas de renovação. A abordagem antiga teria sido: avisar o modelo, obter texto, escrever um parser regex, chorar. Com generateObject, definimos um LeaseSchema com Zod, e o modelo retornou dados tipados e limpos em cada execução. Estávamos enviando aluguéis extraídos para uma tabela Postgres dentro de uma semana.generateObject , we defined a LeaseSchema with Zod, and the model returned clean typed data on every run. We were pushing extracted leases into a Postgres table within a week.
O que confunde as pessoas: nem todos os modelos suportam saída estruturada igualmente bem. GPT-4o e Claude 3.5 Sonnet lidam com isso de forma confiável. Alguns modelos menores ou mais antigos vão alucinar campos ou ignorar o schema completamente. Fique com os modelos principais para este, pelo menos até validar seu caso de uso.
Tool Calling: Onde o Verdadeiro Poder Reside
Se generateObject é subutilizado, tool calling é ativamente mal compreendido. A maioria dos desenvolvedores pensa que "tool calling" significa que a IA pode navegar na internet ou executar código. Às vezes faz. Mas na prática, ferramentas são apenas funções que você define e que o modelo pode escolher invocar durante uma resposta.generateObject is underused, tool calling is actively misunderstood. Most developers think "tool calling" means the AI can browse the internet or run code. Sometimes it does. But in practice, tools are just functions you define that the model can choose to invoke during a response.
Como Pensar Sobre Isso
Digamos que você está construindo um bot de suporte para um produto SaaS. O usuário pergunta "qual é meu plano de assinatura atual?" O modelo não pode saber disso. Mas você pode definir uma ferramenta getUserSubscription que recebe um ID de usuário e retorna os dados do plano do seu banco de dados. O modelo reconhece a intenção, chama a ferramenta, obtém os dados de volta e os incorpora na resposta. O usuário apenas vê uma resposta coerente.getUserSubscription tool that takes a user ID and returns the plan data from your database. The model recognises the intent, calls the tool, gets the data back, and incorporates it into the response. The user just sees a coherent answer.
O parâmetro tools do SDK em streamText e generateText recebe um objeto onde cada chave é um nome de ferramenta, e cada valor tem uma description (que o modelo usa para decidir quando chamá-la), um schema de parameters (Zod novamente) e uma função execute. A função execute é executada no servidor, com segurança, longe do cliente.tools parameter on streamText and generateText takes an object where each key is a tool name, and each value has a description (which the model uses to decide when to call it), a parameters schema (Zod again), and an execute function. The execute function runs server-side, safely, away from the client.
Construí agentes com múltiplas etapas dessa forma. O SDK suporta maxSteps para que o modelo possa encadear chamadas de ferramentas, chamar uma ferramenta, usar o resultado, chamar outra ferramenta, sintetizar tudo e responder. Não é magia. Você ainda precisa pensar cuidadosamente sobre suas descrições de ferramentas e seu system prompt. Mas toda a fiação é tratada para você.maxSteps so the model can chain tool calls, call one tool, use the result, call another tool, synthesise everything, respond. It's not magic. You still need to think carefully about your tool descriptions and your system prompt. But the wiring is all handled for you.
Middleware, Wrapping e o Modelo de Pipeline
Uma coisa que não apreciei até ler mais fundo na documentação: o SDK tem um conceito de middleware que permite encapsular chamadas de modelo para adicionar logging, cache ou comportamento personalizado sem tocar no código da sua funcionalidade.
wrapLanguageModel recebe um modelo e um objeto middleware. Você pode interceptar requisições antes de elas chegarem à API, modificar parâmetros, fazer cache de respostas. Usei isso em uma ferramenta de geração de conteúdo que construímos para uma editora, o caso de uso deles tinha muitos prompts repetidos (o mesmo resumo de artigo sendo solicitado múltiplas vezes por dia), e fizemos cache de respostas em Redis usando a camada de middleware. O custo caiu cerca de 35% no primeiro mês. takes a model and a middleware object. You can intercept requests before they hit the API, modify parameters, cache responses. I used this on a content generation tool we built for a publisher, their use case had a lot of repeated prompts (same article summary being requested multiple times a day), and we cached responses in Redis using the middleware layer. Cost dropped by about 35% in the first month.
Isso é o tipo de coisa que você normalmente teria que boltar desajeitadamente ao redor das suas chamadas de API. Ter isso como um conceito de primeira classe no SDK significa que é composto e testável.
O Que Não Faz (Seja Honesto Consigo Mesmo)
Certo. Deixa eu te poupar dessa dor.
O SDK não gerencia memória ou histórico de conversas de longo prazo para você. useChat mantém o array de mensagens no estado do cliente, mas no momento em que o usuário atualiza a página, desaparece. Se você precisa de conversas persistentes, você constrói isso sozinho. Postgres ou MongoDB para armazenamento de mensagens, buscar ao montar para reidratar o chat, nada disso é fornecido. Isso é comportamento correto, na verdade. O SDK não deveria ser dono da sua camada de dados. Mas iniciantes frequentemente esperam que seja.useChat maintains the message array in client state, but the moment the user refreshes, that's gone. If you need persistent conversations, you're building that yourself. Postgres or MongoDB for message storage, fetch on mount to rehydrate the chat, none of that is provided. This is correct behaviour, actually. The SDK shouldn't own your data layer. But newcomers often expect it to.
Também não trata entradas multimodais nativamente de forma que abstraia toda a complexidade. Você pode passar URLs de imagem no array de mensagens e modelos como GPT-4o as processarão bem, mas construir um fluxo adequado de upload de imagem com preview, compressão e armazenamento ainda é seu trabalho. Uso Uploadthing quando estou no Next.js, leva uns 30 minutos para conectar.Uploadthing for this when I'm on Next.js, takes about 30 minutes to wire up.
RAG (geração aumentada por recuperação) também não está incluído. Não há busca vetorial integrada, nenhum pipeline de embedding, nenhuma lógica de chunking. Para isso você recorre a algo como pgvector no Postgres ou um serviço dedicado como Pinecone. O SDK cuida da chamada LLM. O resto da arquitetura de recuperação é seu para construir.pgvector on Postgres or a dedicated service like Pinecone. The SDK handles the LLM call. The rest of the retrieval architecture is yours to build.
Implantando: Vercel vs Qualquer Outro Lugar
Sim, o SDK funciona melhor no Vercel. StreamingTextResponse funciona com o Edge Runtime do Vercel pronto para uso, e cold starts em Edge Functions são muito menores do que em funções serverless Node.js. Se suas respostas de chat parecem lentas, a latência até o primeiro token importa muito, e Edge reduz isso.StreamingTextResponse works with Vercel's Edge Runtime out of the box, and cold starts on Edge Functions are much lower than on serverless Node.js functions. If your chat responses feel sluggish, the latency until the first token matters a lot, and Edge cuts that down.
Mas já rodei em Railway (Node.js, não Edge) e funciona bem. Você só usa Response com headers de streaming apropriados em vez dos helpers específicos do Vercel, e os docs do SDK cobrem isso. Não deixe "Vercel AI SDK" fazer você achar que está preso.Response with proper streaming headers instead of the Vercel-specific helpers, and the SDK docs cover this. Don't let "Vercel AI SDK" make you think you're locked in.
Uma coisa que eu recomendaria genuinamente: mantenha seus route handlers de IA enxutos. Não faça queries de banco de dados, verificações de autenticação e chamadas LLM tudo em uma função. Middleware (middleware do Next.js, não o middleware do SDK) deveria lidar com autenticação antes mesmo da requisição chegar ao seu route de IA. Mantém rápido, mantém debugável.
FAQ
O Vercel AI SDK é gratuito para usar?
O SDK em si é open source e gratuito. Você paga pelas APIs dos modelos subjacentes, OpenAI, Anthropic, Google, whoever você está chamando. Esses custos são seus para gerenciar. O SDK não marca nada.
Posso usá-lo com modelos além do OpenAI?
Sim, e essa é uma de suas forças genuínas. Há adaptadores oficiais para Anthropic, Google (Gemini), Mistral, Groq, Cohere e mais. A comunidade também construiu adaptadores para Ollama se você quiser executar modelos locais. A interface unificada significa que seu código de feature não muda quando você troca de provider.
Funciona com React Server Components?
Parcialmente. generateText e generateObject podem rodar em Server Components sem problemas, são apenas funções async. streamText com o hook useChat requer estado do lado do cliente, então essa parte fica em um Client Component. Essa é a arquitetura padrão do Next.js e não deve causar problemas se você entender o limite.generateText and generateObject can run in Server Components without issues, they're just async functions. streamText with the useChat hook requires client-side state, so that part lives in a Client Component. This is standard Next.js architecture and shouldn't cause you any grief if you understand the boundary.
Como eu lido com erros quando a API cai?
O SDK lança erros tipados que você pode capturar e tratar. Na prática eu envolverei minhas chamadas de LLM em um try/catch e retorno uma mensagem de fallback elegante em vez de deixar o erro do stream se propagar para a UI como uma resposta parcial quebrada. Os docs do SDK sobre tratamento de erros cobrem os tipos de erro em detalhes e valem a pena ler antes de você ir para produção.SDK docs on error handling cover the error types in detail and are worth reading before you go to production.
Qual é a situação do limite de tokens?
O SDK não gerencia limites de context window para você. Se você está construindo uma conversa de longa duração e não aparar o histórico de mensagens, você vai atingir a context window do modelo e obter um erro. Um conserto simples: manter as últimas N mensagens (eu geralmente faço 20) mais um system prompt fixo. Bom o suficiente para a maioria das aplicações de chat.
---
Olha, o Vercel AI SDK não é uma mágica. É uma abstração bem-desenhada sobre uma plumbing genuinamente tediosa. Ele lida com streaming corretamente, oferece outputs estruturados tipados, torna tool calling acessível e funciona entre providers. Para 80% do trabalho de features de IA que assumo, é o ponto de partida certo.
O cliente fintech, aliás, foi ao ar com o chat reconstruído duas semanas depois que reescrevi. Sem problemas no mobile Safari. Sem race conditions. Seis semanas viraram dois dias. Às vezes a abstração certa vale muito.
