Home
Showcase(11)
Blog(16)
Lab(15)
YouTube
Publications
Loading post...
Montek KundanMontek Kundan
  • Home
  • Showcase(11)
  • Blog(16)
  • Lab(15)
XInstagramGitHubLinkedInYouTube

Build using basehub.com

Inspired by basement.studio

Montek 2026

XInstagramGitHubLinkedInYouTube

Montek 2026

Inspired by basement.studio

The Visual Intro to AISDK

Blog

December 13, 2025 montek.dev

0 views

Development

AI

...


AISDK docs are already really good, so this guide is not trying to replace them. I wrote it because I wanted something I could share with friends and coworkers who already know Next.js, but feel a bit lost when they first see generateText, streamText, tools, and all the different examples. My goal was to make a very visual walkthrough of the core primitives, so that you can open this page next to the official docs, click through the demos, glance at the code, and feel comfortable building with AISDK without spending days getting your hands dirty just to understand the basics.

AISDK takes care of the boring parts of working with LLMs so you can focus on behavior and UI instead of HTTP plumbing. It gives you a small set of primitives that repeat everywhere: generate a thing once, stream it, turn it into structured data, or let the model call tools and build agents on top.

This guide walks through those primitives in the order you are likely to use them in a real project. The visual blocks on this page sit on top of the same few calls from the SDK.

I will be using v5 v6 version of AISDK for this guide.

How I recommend you follow this guide

I will say keep the AISDK website open alongside this guide, and refer to the codeblocks Vercel providers for better updated understanding.

They way this guide is set up, helps not only you but also me to refer back to points which I noted. Ive been working on lots projects involving AISDK and there has been a ton on times, that ive been stuck on concepts and wanted someone to guide me through. I will say the AISDK cookbook is really good, and ill link each page I thought should exist and did exist, but I found way to late! There are many great concepts and fun projects we will go through!

So lets first start with the basics.

The Generate Text Function

generateText is the minimal unit of work in the SDK. It takes a prompt (or messages) and gives you back a string. The core docs describe it as ideal for non interactive use, such as drafting copy or summarizing text, and as a building block for agents that will call tools later. Here is an example of using the generateText function, and how it feels, try running it!

Start a conversation

Messages will appear when you press the button above.

Its instant right? If you’re coming from other AI chat applications, you might have felt this was not that beautiful, thats where our next topic comes.

Before going forward I would like to show you how you can implement this function too!

The first time I saw the use of this function was from viewing and understanding the code from https://x.com/pontusab ai-sdk-tools example web page. He used it to generate chat titles of each AI conversation. I found it really useful and try to add this in every production ready AI app. Here is the simple function.

1/**
2 * Generates a minimal chat title from a text
3 */
4export async function generateChatTitleFromText(
5  text: string,
6): Promise<string> {
7  try {
8    const response = await fetch("/api/ai/chat-title", {
9      method: "POST",
10      headers: {
11        "Content-Type": "application/json",
12      },
13      body: JSON.stringify({ text }),
14    })
15
16    if (!response.ok) {
17      throw new Error("Failed to generate title")
18    }
19
20    const { title } = await response.json()
21    return title || text.trim().slice(0, 30) || "New Chat"
22  } catch (error) {
23    console.error("Error generating chat title:", error)
24    const fallback = text.trim().slice(0, 30)
25    return fallback || "New Chat"
26  }
27}
typescript

and for the route file:

1import { openai } from "@ai-sdk/openai"
2import { generateText } from "ai"
3import { type NextRequest, NextResponse } from "next/server"
4import { CHAT_TITLE_INSTRUCTIONS } from "@/components/ui/support/utils/instructions"
5
6export async function POST(req: NextRequest) {
7  let text: string | undefined
8
9  try {
10    const body = await req.json()
11    text = body.text
12
13    if (!text) {
14      return NextResponse.json(
15        { error: "Text is required" },
16        { status: 400 },
17      )
18    }
19
20    const prompt = `${CHAT_TITLE_INSTRUCTIONS}\n\n<context>\n${text.slice(0, 500)}\n</context>`
21
22    const { text: title } = await generateText({
23      model: openai("gpt-4.1-nano"),
24      prompt,
25      maxOutputTokens: 50,
26    })
27
28    const cleaned = title.trim().replace(/^"|"$/g, "")
29    const finalTitle =
30      cleaned.length > 30
31        ? `${cleaned.slice(0, 27).trim()}...`
32        : cleaned
33
34    return NextResponse.json({ title: finalTitle })
35  } catch (error) {
36    console.error("Error generating chat title:", error)
37    const fallback = text?.trim().slice(0, 30) || "New Chat"
38    return NextResponse.json({ title: fallback })
39  }
40}
typescript

For the instructions I usually just give it this simple prompt:

1export const CHAT_TITLE_INSTRUCTIONS = `Generate a concise title that captures the user's intent.`
typescript

There you go! Such a useful funciton, oh wait now you might be wondering how does this even work? Like how does this generateChatTitleFromText generate the title though? When do we pass the text to it so that it runs? You see the next title, the stream text function, it has a onFinish parameter which allows us to run things after the AI generates text, hence we can use it there, simple right!

Here’s one more example, i tried copying how Vercel domains might work in the background to show generate domains as users types a sentence.

The Stream Text Function

streamText does the same job as generateText, but it streams tokens as they arrive instead of waiting for the whole answer. The cookbook articles use it as the default for chat or any experience where you want the UI to feel alive. Here try the demo again, this will feel different!

Start a conversation

Messages will appear when you press the button above.

Amazing right, the text comes in beautifully! You can use this function for your everyday AI apps to generate messages!

Chat Template for testing

Before moving further, for all the experiments we do now, ive made a chat template which uses Vercel ai-elements to render assistant messages beautifully! If someone wants to skip setup and just test models or prompts, the fastest route is to start from an existing template.

repo: https://github.com/Montekkundan/chat-template

Also, Vercel maintains a full featured Next.js chatbot template, now surfaced as Chat SDK, that is built on top of the AI SDK and already wired for streaming, theming, and multiple providers, you can try that too!

Generating Images

The SDK also supports image generation through experimental_generateImage / generateImage. It is marked experimental in the docs, but the API is simple.

Try running this and feel how it works visually.

Start a conversation

Messages will appear when you press the button above.

You can also clone an example which generates images with dall-e-3, it uses the chat-template we discussed about earlier.

repo: https://github.com/Montekkundan/aisdk-generate-image

Using Images as a Prompt

Vision or multi modal models accept images as input as well as text. The Node and Next.js cookbooks show how to attach an image URL or bytes to a message and then call generateText or streamText on top.

Try running this as well, you’ll see how we can send images and AI ( vision or multi modal capable ) replies and tells us what is shown in the image.

Start a conversation

Messages will appear when you press the button above.

Using Files as a Prompt

Some models can read file content such as PDFs directly. The cookbook examples cover two main cases: chatting with PDFs and using a PDF to drive structured object generation

Try this, its same as above but instead we send a pdf.

Start a conversation

Messages will appear when you press the button above.

The Generate Object Function

generateObject is the part of the SDK that most feels like a super power. You give it a Zod schema, a model, and a prompt, and it returns a typed object that matches the schema. The cookbook puts it right next to the basic text recipes, which shows how central it is.

Here is an example, we can ask it “Create a recipe for chocolate chip cookies”, normally the llm would reply back text but we can have it send a structured response which makes us developers create beautiful UI’s on top of that!

Start a conversation

Messages will appear when you press the button above.

The Stream Object Function

Similarly streamObject extends the same idea, but lets you see or use parts of the object while the model is still generating. This is especially interesting for arrays, which appear item by item.

Start a conversation

Messages will appear when you press the button above.

Streaming Custom Data

Extending on the previous stream object AISDK also have a tutorial about streaming custom data, which is pretty amazing!

Here is an example app which shows all we can do with this!

repo: https://github.com/Montekkundan/streaming-custom-data

Rendering Markdown

If you are reading the cookbook about rendering markdown, I would suggest to use streamdown instead, it has pretty usefull features build in! And if you use ai-elements like we do in our chat-template this is already handled!

If you want to dig deeper in this you can read about how they solve the problem of broken streaming markdown!

Tool Calling

Tool calling is where the SDK stops being “just an LLM client” and becomes an agent toolkit. The core docs define tools as functions with typed input schemas that the model can choose to invoke. Tool calls show up as structured data in the stream, you execute the function, then you feed the result back to the model.

So far most examples are “one request in, one response out”. In practice you often want an agent that runs several internal steps inside a single user turn.

So we will look at the complex example rather than running just a simple tool call.

Multi step agents and Human in the Loop

A multi step agent uses streamText together with tools and a step limit so that the model can plan, call tools, refine its answer, and keep streaming into the same UI message instead of jumping between separate responses.

Human in the Loop (HITL) is the safety layer on top of that. The agent can propose actions during those steps, but a person decides which ones actually run. The official AISDK cookbook example defines tools that can mark themselves as “approval required”, and the UI surfaces Approve and Deny buttons before any sensitive tool call is executed.

In this repo I added a small multi step, Human in the Loop demo to make the idea concrete. It has three scenarios: a weather lookup that auto executes, a search plus analysis chain that auto executes and shows multiple tool calls, and a secure operation that pauses until you explicitly approve or deny it.

The app/api/chat/route.ts route uses streamText with a step limit and a processToolCalls layer to gate tools that need approval, then converts the result into a UI message stream. The app/page.tsx chat UI is built with useChat, detects pending tool calls that require confirmation, renders Approve and Deny buttons, and automatically continues once the tool calls finish.

Each tool invocation is rendered by a small AI Elements component that shows parameters, status badges, and the JSON output so you can see what the agent is doing at each step.

repo: https://github.com/Montekkundan/tool-calling

We now also have the tool registry where you can easily package tools and share them with people! Plus use them easily, more about it here https://ai-sdk.dev/tools-registry.

Rendering UI

Tool calling is not only for data. The same mechanism lets the model trigger UI fragments that you render as React components inside the chat stream.

If you follow this, instead of replying with “24°C and sunny,” the model calls getWeatherInformation, and your client turns that tool output into a weather card.

The server uses streamText with a tools object and returns toUIMessageStreamResponse(). On the client, useChat receives UIMessage parts; a switch(part.type) decides whether to render plain text, a confirmation prompt, or a rich component like the weather card.

Typical use cases:

  • Cards for weather, flights, bookings, or product recommendations

  • Inline confirmation prompts before running sensitive tools

  • Small dashboards or forms that appear as part of the conversation

From the user’s perspective it is still “chat,” but each message can carry both language and UI.

Here is another example, recently if you ask Chatgpt to write an email, it generates a separate UI for the email card which allows users to easily open in any mail app or copy it! Here is something similar which i created.

repo: https://github.com/Montekkundan/chat-email-ui

Conclusion

AISDK is also evolving fast. While I was finishing this guide, Vercel shipped v6 dev tools and even more cookbook recipes, which makes it much easier to inspect what your assistants are doing under the hood and debug tool calls step by step.

Think of this guide as a starting map, once you feel at home with generate and stream functions, objects, tools, multi step agents, and human in the loop patterns, you can dig into the official docs, the cookbook, and the sample repos I linked, and start wiring your own AI apps much faster.


December 13, 2025 montek.dev

0 views
TOC
0.01

More from the same blog category

ZenLock: Building a macOS Menu-Bar Focus Timer

ZenLock: Building a macOS Menu-Bar Focus Timer

May 12, 2025

Creating Player Locomotion in Unreal Engine

Creating Player Locomotion in Unreal Engine

Dec 12, 2023

Making your Own CDN

Making your Own CDN

Apr 10, 2025

Comments

Join the discussion! Share your thoughts and engage with other readers.

Leave comment

Montek
Montek
@montekkundan
·Follow

tried something similar

Watch on X
Vercel Developers
Vercel Developers
@vercel_dev

Vercel Domains now supports AI search. Go beyond keywords, describe what you’re looking for. Try it now at vercel.com/domains

Watch on X
7:02 PM · Nov 14, 2025
0
Reply
Read 1 reply
Montek
Montek
@montekkundan
·Follow

i keep testing with @aisdk a lot so here is a template which helps me test faster ◼️ uses ai elements by default ◼️updated prompt input to stop ui calls ◼️ disabled state for suggestions and text area ◼️ for testing users can add api key which saves to localhost

Watch on X
7:57 PM · Nov 12, 2025
0
Reply
Read 1 reply
Montek
Montek
@montekkundan
·Follow

docs are really good, i tried implementing streaming custom data and also showing the message metadata at the same time so we can get as much information as possible in a single message chat ◼️ onfinish generate suggestions and update the ui ◼️ send data notifications which are

Watch on X
Carlos Ziegler
Carlos Ziegler
@CARLOSZIEGLER

This is sooooo nice!!! v6.ai-sdk.dev/docs/ai-sdk-ui… Thanks @aisdk Team

11:25 PM · Nov 12, 2025
1
Reply
Read 2 replies
Montek
Montek
@montekkundan
·Follow

ive been experimenting with @aisdk tool calling this template shows three tool-calling scenarios with optional human approval github repo below, hope it helps :) Scenarios: ◼️ Weather lookup (auto-exec) ◼️ Search + analysis chain (auto-exec; illustrates multiple tool calls)

Watch on X
4:02 AM · Nov 11, 2025
13
Reply
Read 2 replies
Montek
Montek
@montekkundan
·Follow

ive noticed @ChatGPTapp now renders emails in a visual way which is helpful to view and work with! here's how to create it with @aisdk github: github.com/Montekkundan/c… demo: chat-email-ui.vercel.app

Watch on X
3:15 AM · Dec 2, 2025
1
Reply
Read more on X