vercel-ai

IndexedCommit: 0be03a40 pullsUpdated Feb 13, 2026

The **AI SDK** by Vercel is a TypeScript toolkit for building AI-powered applications with large language models. It provides a unified interface for text generation, structured output, streaming, too

Install this reference
Reference

Vercel AI SDK

The AI SDK by Vercel is a TypeScript toolkit for building AI-powered applications with large language models. It provides a unified interface for text generation, structured output, streaming, tool calling, embeddings, image/speech/video generation, and agentic workflows across 30+ AI providers (OpenAI, Anthropic, Google, AWS Bedrock, etc.) — with framework integrations for React, Next.js, Svelte, Vue, and Angular.

Quick References

FilePurpose
packages/ai/src/index.tsMain ai package entry point — all core exports
packages/provider/src/index.tsProvider interface specifications (@ai-sdk/provider)
packages/openai/src/index.tsOpenAI provider — representative provider package
packages/react/src/index.tsReact hooks (useChat, useCompletion, useObject)
examples/ai-functions/src/Hundreds of runnable usage examples

Packages

Core

Packagenpm nameDescription
packages/aiaiCore SDK — generateText, streamText, generateObject, streamObject, embed, ToolLoopAgent, and more
packages/provider@ai-sdk/providerProvider interface specifications (e.g. LanguageModelV3)
packages/provider-utils@ai-sdk/provider-utilsShared utilities for building providers (tool, jsonSchema, zodSchema)
packages/gateway@ai-sdk/gatewayVercel AI Gateway — unified model access via gateway('openai/gpt-4o')

AI Providers

Packagenpm nameDescription
packages/openai@ai-sdk/openaiOpenAI (GPT-4o, GPT-5, o1, DALL-E, Whisper, etc.)
packages/anthropic@ai-sdk/anthropicAnthropic (Claude Sonnet, Haiku, Opus)
packages/google@ai-sdk/googleGoogle Generative AI (Gemini)
packages/google-vertex@ai-sdk/google-vertexGoogle Vertex AI
packages/azure@ai-sdk/azureAzure OpenAI
packages/amazon-bedrock@ai-sdk/amazon-bedrockAmazon Bedrock
packages/groq@ai-sdk/groqGroq
packages/mistral@ai-sdk/mistralMistral AI
packages/xai@ai-sdk/xaixAI (Grok)
packages/cohere@ai-sdk/cohereCohere
packages/deepseek@ai-sdk/deepseekDeepSeek
packages/fireworks@ai-sdk/fireworksFireworks AI
packages/perplexity@ai-sdk/perplexityPerplexity
packages/togetherai@ai-sdk/togetheraiTogether AI
packages/huggingface@ai-sdk/huggingfaceHugging Face Inference
packages/openai-compatible@ai-sdk/openai-compatibleGeneric OpenAI-compatible provider adapter

Framework Integrations

Packagenpm nameDescription
packages/react@ai-sdk/reactReact hooks: useChat, useCompletion, useObject
packages/svelte@ai-sdk/svelteSvelte integration
packages/vue@ai-sdk/vueVue integration
packages/angular@ai-sdk/angularAngular integration

Utilities

Packagenpm nameDescription
packages/mcp@ai-sdk/mcpModel Context Protocol (MCP) client integration

When to Use

  • Building chatbots or conversational AI — use streamText with useChat for real-time streaming chat UIs
  • Extracting structured data from text — use generateObject with a Zod schema to get type-safe parsed output
  • Building AI agents with tool use — use ToolLoopAgent or generateText with tools for multi-step reasoning with function calling
  • Generating embeddings for RAG/search — use embed / embedMany with any embedding provider
  • Generating images, speech, or video — use generateImage, experimental_generateSpeech, or experimental_generateVideo
  • Switching between AI providers without code changes — the unified interface lets you swap providers by changing only the model parameter
  • Integrating MCP servers as tool sources for agent workflows

Installation

# Core SDK (always required)
npm install ai

# Add one or more providers
npm install @ai-sdk/openai
npm install @ai-sdk/anthropic
npm install @ai-sdk/google

# For React hooks
npm install @ai-sdk/react

# For MCP tool integration
npm install @ai-sdk/mcp

# Zod is a peer dependency (for schemas)
npm install zod

Best Practices

  1. Use streamText for user-facing responses — streaming provides a much better UX than waiting for generateText to complete. Use smoothStream to smooth out chunky output.
  2. Define schemas with Zod for structured output — the SDK deeply integrates Zod schemas, providing full type inference for generateObject, streamObject, and Output.object(). Both Zod 3 and Zod 4 are supported.
  3. Use ToolLoopAgent for multi-step tool use — rather than manually looping generateText, ToolLoopAgent handles the tool call → result → next LLM call loop automatically with configurable stop conditions.
  4. Prefer Output.object() / Output.array() with generateText/streamText when you need both text reasoning and structured output — these let you get typed structured data alongside the text stream.
  5. Set maxOutputTokens to control response length and cost — this parameter is passed through to the provider.
  6. Use maxRetries (default: 2) for robustness — the SDK automatically retries on transient failures.
  7. Pass abortSignal for request cancellation — integrates with standard AbortController for timeouts and user cancellation.
  8. Use the Gateway provider (gateway()) for unified model access via Vercel's AI Gateway, allowing model routing via string identifiers like 'openai/gpt-4o'.

Common Patterns

Generate text:

import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

const { text, usage, finishReason } = await generateText({
  model: openai('gpt-4o'),
  system: 'You are a helpful assistant.',
  prompt: 'Explain quantum computing in simple terms.',
  maxOutputTokens: 500,
});

Stream text:

import { streamText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';

const result = streamText({
  model: anthropic('claude-sonnet-4-0'),
  prompt: 'Write a short poem about AI.',
});

for await (const textPart of result.textStream) {
  process.stdout.write(textPart);
}

Generate structured object:

import { generateObject } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const { object } = await generateObject({
  model: openai('gpt-4o-mini'),
  schema: z.object({
    recipe: z.object({
      name: z.string(),
      ingredients: z.array(z.object({
        name: z.string(),
        amount: z.string(),
      })),
      steps: z.array(z.string()),
    }),
  }),
  prompt: 'Generate a lasagna recipe.',
});

console.log(object.recipe.name); // fully typed

Stream structured object:

import { streamObject } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const result = streamObject({
  model: openai('gpt-4o-mini'),
  schema: z.object({
    characters: z.array(z.object({
      name: z.string(),
      class: z.string(),
      description: z.string(),
    })),
  }),
  prompt: 'Generate 3 fantasy RPG characters.',
});

for await (const partialObject of result.partialObjectStream) {
  console.dir(partialObject, { depth: Infinity });
}

Tool calling with generateText:

import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const result = await generateText({
  model: openai('gpt-4o'),
  prompt: 'What is the weather in San Francisco?',
  tools: {
    weather: tool({
      description: 'Get the weather in a location',
      inputSchema: z.object({
        location: z.string().describe('The location to get the weather for'),
      }),
      execute: async ({ location }) => ({
        location,
        temperature: 72,
        unit: 'fahrenheit',
      }),
    }),
  },
});

console.log(result.text);
console.log(result.toolCalls);
console.log(result.toolResults);

ToolLoopAgent (agentic loop):

import { ToolLoopAgent, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const agent = new ToolLoopAgent({
  model: openai('gpt-4o'),
  instructions: 'You are a helpful assistant that answers weather questions.',
  tools: {
    weather: tool({
      description: 'Get the weather in a location',
      inputSchema: z.object({
        location: z.string(),
      }),
      execute: async ({ location }) => ({
        location,
        temperature: 72 + Math.floor(Math.random() * 21) - 10,
      }),
    }),
  },
});

// Non-streaming
const result = await agent.generate({
  prompt: 'What is the weather in Tokyo?',
});
console.log(result.content);

// Streaming
const streamResult = await agent.stream({
  prompt: 'What is the weather in Tokyo?',
});
for await (const textPart of streamResult.textStream) {
  process.stdout.write(textPart);
}

Embeddings:

import { embed, embedMany } from 'ai';
import { openai } from '@ai-sdk/openai';

// Single embedding
const { embedding } = await embed({
  model: openai.embedding('text-embedding-3-small'),
  value: 'sunny day at the beach',
});

// Multiple embeddings
const { embeddings } = await embedMany({
  model: openai.embedding('text-embedding-3-small'),
  values: ['sunny day at the beach', 'rainy morning in the city'],
});

React useChat hook (Next.js example):

// app/api/chat/route.ts (server)
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: openai('gpt-4o'),
    messages,
  });
  return result.toUIMessageStreamResponse();
}

// app/page.tsx (client)
'use client';
import { useChat } from '@ai-sdk/react';

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();

  return (
    <div>
      {messages.map(m => (
        <div key={m.id}>{m.role}: {m.parts.map(p => p.type === 'text' ? p.text : '').join('')}</div>
      ))}
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} />
      </form>
    </div>
  );
}

Using Output.object() with streamText for structured output in a text stream:

import { streamText, Output } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const result = streamText({
  model: openai('gpt-4o'),
  prompt: 'List 3 cities with their populations.',
  output: Output.object({
    schema: z.object({
      cities: z.array(z.object({
        name: z.string(),
        population: z.number(),
      })),
    }),
  }),
});

for await (const partialOutput of result.partialOutputStream) {
  console.dir(partialOutput, { depth: Infinity });
}

MCP tool integration:

import { createMCPClient } from '@ai-sdk/mcp';
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

const mcpClient = await createMCPClient({
  transport: { type: 'sse', url: 'https://my-mcp-server.example/sse' },
});

const result = streamText({
  model: openai('gpt-4o'),
  prompt: 'Search for the latest AI news',
  tools: await mcpClient.tools(),
});

for await (const textPart of result.textStream) {
  process.stdout.write(textPart);
}

await mcpClient.close();

Vercel AI Gateway:

import { gateway } from 'ai'; // re-exported from @ai-sdk/gateway
import { generateText } from 'ai';

const result = await generateText({
  model: gateway('openai/gpt-4o'),
  prompt: 'Hello!',
});

Using smoothStream for smoother streaming output:

import { streamText, smoothStream } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = streamText({
  model: openai('gpt-4o'),
  prompt: 'Write a short story.',
  experimental_transform: smoothStream({ chunking: 'word' }),
});

Custom provider with middleware:

import { wrapLanguageModel, extractReasoningMiddleware } from 'ai';
import { openai } from '@ai-sdk/openai';

const wrappedModel = wrapLanguageModel({
  model: openai('gpt-4o'),
  middleware: extractReasoningMiddleware({ tagName: 'thinking' }),
});

API Quick Reference

Core Functions (from ai)

ExportTypeDescription
generateTextfunctionGenerate text completion (non-streaming)
streamTextfunctionStream text completion with real-time output
generateObjectfunctionGenerate typed structured output (non-streaming)
streamObjectfunctionStream structured output with partial objects
embedfunctionGenerate a single embedding vector
embedManyfunctionGenerate multiple embedding vectors
generateImagefunctionGenerate images from a prompt
experimental_generateSpeechfunctionGenerate speech audio from text
experimental_transcribefunctionTranscribe audio to text
experimental_generateVideofunctionGenerate video from a prompt
rerankfunctionRerank documents by relevance
toolfunctionDefine a tool with schema and execute function
jsonSchemafunctionCreate a schema from a JSON Schema definition
zodSchemafunctionCreate a schema from a Zod schema
ToolLoopAgentclassAgent that runs tools in a loop until stop condition
Output.text()functionOutput spec for plain text
Output.object()functionOutput spec for typed structured objects
Output.array()functionOutput spec for typed arrays with element streaming
Output.choice()functionOutput spec for single choice from options
Output.json()functionOutput spec for unstructured JSON
smoothStreamfunctionTransform stream for smoother text output
stepCountIsfunctionStop condition: stop after N steps
hasToolCallfunctionStop condition: stop when a specific tool is called
generateIdfunctionGenerate a random ID
createIdGeneratorfunctionCreate a custom ID generator
gatewayfunctionCreate a Vercel AI Gateway model reference
createProviderRegistryfunctionCreate a registry for multiple providers
customProviderfunctionCreate a custom provider with model overrides
pruneMessagesfunctionPrune messages to fit context window

Middleware (from ai)

ExportTypeDescription
wrapLanguageModelfunctionWrap a language model with middleware
wrapEmbeddingModelfunctionWrap an embedding model with middleware
wrapImageModelfunctionWrap an image model with middleware
wrapProviderfunctionWrap a provider with middleware
extractReasoningMiddlewarefunctionExtract reasoning/thinking from model output
extractJsonMiddlewarefunctionExtract JSON from model output
defaultSettingsMiddlewarefunctionApply default settings to model calls
simulateStreamingMiddlewarefunctionSimulate streaming for non-streaming models

UI Integration (from ai)

ExportTypeDescription
UIMessagetypeStandard message type for UI chat interfaces
convertToModelMessagesfunctionConvert UI messages to model messages
createUIMessageStreamfunctionCreate a UI message stream
createUIMessageStreamResponsefunctionCreate a Response from a UI message stream
AbstractChatclassFramework-agnostic chat state management

React Hooks (from @ai-sdk/react)

ExportTypeDescription
useChathookFull chat interface with streaming, tool calls, and message management
useCompletionhookSimple text completion with streaming
useObjecthookStream structured objects with partial state

MCP Client (from @ai-sdk/mcp)

ExportTypeDescription
createMCPClientfunctionCreate an MCP client for tool discovery

Key Types (from ai)

ExportTypeDescription
LanguageModeltypeLanguage model interface
EmbeddingModeltypeEmbedding model interface
ImageModeltypeImage generation model interface
ToolSettypeRecord of tool definitions
ToolChoicetypeTool choice strategy ('auto', 'required', 'none', or specific tool)
ModelMessagetypeModel-level message (system, user, assistant, tool)
LanguageModelUsagetypeToken usage statistics
FinishReasontypeWhy the model stopped generating
CallWarningtypeWarnings from model calls
StopConditiontypeCondition function for stopping agent loops
GenerateTextResulttypeFull result from generateText
StreamTextResulttypeFull result from streamText
GenerateObjectResulttypeFull result from generateObject
StreamObjectResulttypeFull result from streamObject
StepResulttypeResult of a single step in multi-step generation

Provider Pattern

Each provider package exports a factory function and a pre-configured instance:

// Pre-configured (uses env vars like OPENAI_API_KEY)
import { openai } from '@ai-sdk/openai';
const model = openai('gpt-4o');
const embedding = openai.embedding('text-embedding-3-small');

// Custom configuration
import { createOpenAI } from '@ai-sdk/openai';
const myOpenAI = createOpenAI({ apiKey: 'sk-...', baseURL: '...' });
const model = myOpenAI('gpt-4o');

// Other providers follow the same pattern:
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';
import { groq } from '@ai-sdk/groq';
import { mistral } from '@ai-sdk/mistral';
import { xai } from '@ai-sdk/xai';

Error Classes (from ai)

ErrorDescription
AISDKErrorBase error class for all SDK errors
APICallErrorError during API communication
NoObjectGeneratedErrorStructured output failed to generate or validate
NoOutputGeneratedErrorNo output generated (e.g. all steps exhausted)
NoSuchToolErrorModel called a tool that doesn't exist
InvalidToolInputErrorTool call input didn't match schema
RetryErrorAll retries exhausted
UnsupportedFunctionalityErrorFeature not supported by the provider
LoadAPIKeyErrorAPI key not found in environment

Configuration

Environment Variables

Each provider reads its API key from a standard environment variable:

ProviderEnvironment Variable
OpenAIOPENAI_API_KEY
AnthropicANTHROPIC_API_KEY
GoogleGOOGLE_GENERATIVE_AI_API_KEY
GroqGROQ_API_KEY
MistralMISTRAL_API_KEY
xAIXAI_API_KEY
CohereCOHERE_API_KEY
DeepSeekDEEPSEEK_API_KEY

Call Settings

All generation functions accept these common options:

OptionTypeDefaultDescription
maxOutputTokensnumberMaximum tokens to generate
temperaturenumberRandomness (provider-dependent range)
topPnumberNucleus sampling
topKnumberTop-K sampling
presencePenaltynumberReduce repetition of prompt content
frequencyPenaltynumberReduce word/phrase repetition
stopSequencesstring[]Stop generation at these sequences
seednumberDeterministic generation seed
maxRetriesnumber2Retry count (0 to disable)
abortSignalAbortSignalCancellation signal
timeoutnumber | objectTimeout in milliseconds
headersRecord<string, string>Additional HTTP headers
providerOptionsobjectProvider-specific options

Documentation

Full documentation is available at ai-sdk.dev/docs.

“Explore distant worlds.”

© 2026 Oscar Gabriel