Vercel AI SDK 4.x: Streaming Text, Tool Calls, and Multi-Step Agents

The Vercel AI SDK unifies streaming text, structured output, tool calls, and multi-step agents across all major AI providers with a single consistent API.

Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

April 14, 2026
7 min read
Vercel AI SDK 4.x: Streaming Text, Tool Calls, and Multi-Step Agents

Why the Vercel AI SDK?

One AI engineering post, weekly

LLM benchmarks, prompt techniques, and token-cost breakdowns — not another AI news roundup.

Every AI provider has a different streaming API, tool call format, and error shape. The Vercel AI SDK abstracts all of that into one consistent interface that works with OpenAI, Anthropic, Google, Mistral, Ollama, and dozens of others - and it integrates directly with React via hooks.

Streaming Text

typescript
// app/api/chat/route.ts
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await streamText({
    model: openai("gpt-4o"),
    messages,
    onFinish({ usage, finishReason }) {
      // cost tracking
      console.log("Tokens used:", usage.totalTokens);
    },
  });

  return result.toDataStreamResponse();
}
tsx
// components/Chat.tsx
"use client";
import { useChat } from "ai/react";

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

  return (
    <div>
      {messages.map(m => (
        <div key={m.id}><strong>{m.role}:</strong> {m.content}</div>
      ))}
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} disabled={isLoading} />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

Team workspace

Ship faster with chat, meetings, and projects in one place — Zlyqor.

Start free

Tool Calls

Tools let the model call functions during generation. The SDK handles the tool call → result → continue loop:

typescript
import { streamText, tool } from "ai";
import { z } from "zod";

const result = await streamText({
  model: openai("gpt-4o"),
  tools: {
    getWeather: tool({
      description: "Get current weather for a city",
      parameters: z.object({ city: z.string() }),
      execute: async ({ city }) => {
        const data = await fetchWeather(city);
        return { temperature: data.temp, condition: data.condition };
      },
    }),
  },
  prompt: "What is the weather in Tokyo?",
  maxSteps: 3, // allow model to use tool then continue
});

Structured Output With generateObject()

When you need structured data instead of free text:

typescript
import { generateObject } from "ai";
import { z } from "zod";

const { object } = await generateObject({
  model: openai("gpt-4o"),
  schema: z.object({
    tasks: z.array(z.object({
      title: z.string(),
      priority: z.enum(["low", "medium", "high"]),
      estimatedHours: z.number(),
    })),
  }),
  prompt: "Break down building a REST API into tasks",
});

// object.tasks is fully typed Task[]

Multi-Step Agents

Set maxSteps to let the model take multiple tool calls in a chain:

typescript
const result = await streamText({
  model: anthropic("claude-3-5-sonnet-20241022"),
  tools: {
    searchWeb: tool({ /* ... */ }),
    readPage: tool({ /* ... */ }),
    writeFile: tool({ /* ... */ }),
  },
  system: "You are a research agent. Search for information and write a summary.",
  prompt: "Research the current state of WebAssembly and write a 500-word summary.",
  maxSteps: 10, // agent can take up to 10 tool calls
});

// Stream each step as it happens
for await (const delta of result.fullStream) {
  if (delta.type === "tool-call") {
    console.log("Tool called:", delta.toolName);
  }
  if (delta.type === "text-delta") {
    process.stdout.write(delta.textDelta);
  }
}

Switching Providers

The SDK's provider abstraction means switching models is one line:

typescript
import { openai } from "@ai-sdk/openai";
import { anthropic } from "@ai-sdk/anthropic";
import { google } from "@ai-sdk/google";
import { ollama } from "ollama-ai-provider"; // community

// Just swap the model  -  everything else stays the same
const model = openai("gpt-4o");          // OpenAI
const model = anthropic("claude-3-5-sonnet-20241022"); // Anthropic
const model = google("gemini-1.5-pro");   // Google
const model = ollama("llama3.2");         // Local via Ollama

References: Vercel AI SDK · GitHub · docs

#vercel-ai-sdk#streaming#tool-calls#next.js#ai-agents

// discussion

Comments

0/4000
Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

Visionary technologist, software engineer, and machine learning specialist. Founder and CEO of Pristren, directing engineering teams that ship production-grade AI/ML pipelines, mission-critical full-stack applications, and developer tooling. Creator of Zlyqor, the unified team workspace platform. Author of 540+ technical guides and benchmark research reports on large language models, agentic workflows, Model Context Protocol (MCP), and modern web stacks.

PristrenZlyqor