buildwithdew
Tutorials·9 min read·May 17, 2026

How to build an AI agent from scratch in TypeScript

TL;DR

This tutorial shows how to build an AI agent from scratch with TypeScript and the Vercel AI SDK, focusing on a single Next.js API route, AI Gateway, a tool-calling loop with `stopWhen`, structured JSON output, and honest error handling. You’ll get a runnable repo pattern that’s production-friendly for single-request workflows, without jumping straight into heavyweight agent frameworks.

Converging threads of stopWhen and JSON bloom upward — layered strata of honest error — calm, precise confidence. — cover for: How to build an AI agent from scratch in TypeScript

Key takeaways

  • A shippable AI agent can be a single Next.js API route plus an AI SDK loop.
  • Tool-calling and structured output keep TypeScript agents safe for downstream code.
  • Use `stopWhen` and step limits to control reasoning and avoid runaway loops.
  • Start with try/catch error handling; add durability only when failures persist.
  • AI SDK 7 adds production-grade features like WorkflowAgent and sandbox hooks.
  • Observability via Langfuse and OpenTelemetry matters once agents handle core workflows.

The short answer to how to build an AI agent from scratch with TypeScript and the Vercel AI SDK is: you wire a Next.js API route to an AI SDK loop that calls tools, controls reasoning with stopWhen, returns structured JSON, and handles errors inside one request.15

What does “how to build AI agent from scratch” mean in practice?

To answer how to build an AI agent from scratch, we’re talking about a single TypeScript loop that calls tools, thinks for a few steps, then returns a structured result over HTTP.5

In the Vercel ecosystem, an AI agent is a model that runs in a loop, using tools to gather information or take actions until it completes a task, instead of answering a single prompt once.5

The Vercel AI SDK gives you primitives like tool-calling, streaming, structured output, and provider switching, which are usually enough for agents that finish within a single request.57

By “from scratch” here, we mean:

  • No heavy agent framework.
  • A single Next.js API route in TypeScript.
  • A clear loop boundary: the run starts when the request hits your route and ends when the agent returns JSON.

This tutorial builds a runnable repository pattern: one API route, one agent harness, a couple of tools, explicit stopWhen, and pragmatic error handling so the agent is shippable, not just a demo.12

How do you scaffold the TypeScript project and first AI SDK call?

You scaffold by creating a Next.js app, installing @vercel/ai, wiring AI Gateway, and adding a basic generateText call in an API route.15

A typical baseline in 2025–2026 is:

  1. npx create-next-app for the project.
  2. pnpm add @vercel/ai for the AI SDK.
  3. Configure AI Gateway with a single model string like openai:gpt-4.1-mini so you can switch providers later without changing code.5
  4. Add a route under app/api/agent/route.ts (Next.js App Router) that imports generateText and calls a model.

A minimal route:

// app/api/echo-agent/route.ts
import { NextRequest } from 'next/server';
import { generateText } from 'ai';

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

  const result = await generateText({
    model: 'openai:gpt-4.1-mini',
    prompt,
  });

  return new Response(JSON.stringify({
    ok: true,
    message: result.text,
  }), {
    headers: { 'Content-Type': 'application/json' },
  });
}

If you can write a Next.js API route like this, you can build an AI agent in about 30 minutes, because the SDK handles streaming, tools, and structured outputs for you.101

We’ll evolve this route into a proper agent harness rather than switching to a heavyweight framework prematurely.7

How do you design the agent loop with stopWhen and step limits?

You design the loop by letting the AI SDK orchestrate steps and enforcing a stopWhen condition and maximum step count to prevent runaway reasoning.12

The built‑in agent loop looks like:

  1. You send a prompt and tools.
  2. The model chooses to answer or call a tool.
  3. The SDK executes the tool, appends results to history.
  4. The SDK triggers another generation.
  5. It repeats until stopWhen or a step limit is reached.1

Instead of wiring a while loop yourself, you configure the agent with something like stopWhen: stepCountIs(6) to cap reasoning at six tool calls or turns.12

Conceptually, your harness file might look like this:

// lib/agent.ts
import { createAgent, stepCountIs } from 'ai';
import { fetchUserProfile, fetchInvoices } from './tools';

export const financeAgent = createAgent({
  model: 'openai:gpt-4.1-mini',
  tools: {
    fetchUserProfile,
    fetchInvoices,
  },
  stopWhen: stepCountIs(6), // keep runs cheap and predictable
});

The AI SDK automatically appends tool calls and results to history, triggers new generations, and stops according to this configuration—no manual orchestration code required.1

How do you define tools and structured output in TypeScript?

You define tools as plain TypeScript functions and use the AI SDK’s structured output APIs to get typed JSON back from the agent instead of free‑form text.5

A tool is just a function the agent can call, with a description and parameter schema. For example, a simple data-access tool:

// lib/tools.ts
import type { Tool } from 'ai';

export const fetchInvoices: Tool = {
  description: 'Fetch recent invoices for a given customer ID',
  parameters: {
    type: 'object',
    properties: {
      customerId: { type: 'string' },
    },
    required: ['customerId'],
  },
  // Here you’d hit a database or external API
  execute: async ({ customerId }) => {
    const data = await fakeInvoiceStore.listByCustomer(customerId);
    return data;
  },
};

For structured output, you define a TypeScript type and tell the SDK to target that shape:

// lib/types.ts
export type AgentResult = {
  summary: string;
  actions: { label: string; url?: string }[];
  riskScore: number;
};

Then in your harness:

import { generateObject } from 'ai';
import type { AgentResult } from './types';

export async function runFinanceAgent(input: string) {
  const result = await generateObject<AgentResult>({
    model: 'openai:gpt-4.1-mini',
    prompt: input,
    tools: { fetchInvoices },
  });

  return result.object; // fully typed AgentResult
}

The AI SDK’s structured outputs keep agents safe for downstream code: instead of parsing arbitrary text, you get typed JSON that matches your TypeScript definitions.5

How do you wire a runnable repo with API routes, tools, and data?

You wire a runnable repo by separating your API route, agent harness, tool implementations, and data layer into small modules, then exporting a single HTTP endpoint.2

A practical architecture for a solo operator or small team:

  • app/api/agent/route.ts – HTTP entry point.
  • lib/agent.ts – creates and runs the agent.
  • lib/tools.ts – tools that talk to data stores or external APIs.
  • lib/types.ts – structured output types.

Example route:

// app/api/agent/route.ts
import { NextRequest } from 'next/server';
import { runFinanceAgent } from '@/lib/agent';

export async function POST(req: NextRequest) {
  try {
    const { query } = await req.json();
    const result = await runFinanceAgent(query);

    return Response.json({ ok: true, result });
  } catch (err) {
    console.error('Agent error', err);
    return Response.json({ ok: false, error: 'Agent run failed' }, { status: 500 });
  }
}

In practice, the amount of code you need to create a useful agent is relatively small: one harness function, a couple of tools, and a clear return type.2

A common pattern is wiring query embeddings to a vector index, mapping results into something like { section, relevanceScore, content }, then letting the agent reason over that context.25

How does this compare to a non-agent “LLM endpoint”?

AspectPlain LLM callAI SDK agent loop
Execution modelSingle prompt → responseLoop of prompt → tools → response
ToolsManual calls in your codeModel decides when to call tools
OutputFree-form textStructured JSON via generateObject
ControlNo step limitsstopWhen, stepCountIs
Error handlingOne request, no retriesCan add retries, branch on tool errors

For many internal workflows—support assistants, research helpers, simple code reviewers—the agent loop adds just enough structure without forcing you to adopt a heavy framework.7

How do you handle errors and know when you need durability tools?

You handle errors inside the single-request loop with standard TypeScript try/catch and only reach for durability tools when you repeatedly hit timeouts, retries, or long‑running tasks.37

Inside runFinanceAgent, you can:

  • Catch tool‑level failures and return fallback values.
  • Attach lightweight retry logic for transient issues.
  • Surface error states in the structured output.

Example:

export async function runFinanceAgent(input: string): Promise<AgentResult> {
  try {
    const result = await generateObject<AgentResult>({ /* ... */ });
    return result.object;
  } catch (error) {
    // Basic, honest error handling
    return {
      summary: 'Agent failed to complete the task.',
      actions: [],
      riskScore: 1,
    };
  }
}

For agents that must survive failures, run untrusted code, or retry automatically, Vercel recommends combining Workflows, Sandbox, and AI Gateway for durable orchestration, isolated execution, and observable model access.35

The decision line is simple: if your agent is a single tool‑calling loop that finishes inside one request, the Vercel AI SDK alone is usually sufficient; full agent frameworks become valuable only once you consistently hit durability or multi‑channel plumbing issues.7

What production-grade features in AI SDK 7 matter for agents?

In 2025–2026, AI SDK 7 adds reasoning control, tool context, durability hooks, and a TUI that make TypeScript agents viable for production, not just prototypes.6

AI SDK 7 is positioned as “the TypeScript SDK for building AI applications, features, frameworks, and agents across any model provider,” with over 16 million weekly downloads.6

Notable features for agents:

  • Reasoning control: step limits, loop controls, and stopWhen integration with the agent APIs.16
  • Tool and runtime context: richer metadata about which tools were called and how.6
  • WorkflowAgent durability: hooks to integrate with durable orchestrators when you outgrow single‑request loops.63
  • Sandbox support: running AI-generated code in isolated microVMs via Vercel Sandbox when needed.36
  • A terminal UI (TUI) that can run agents interactively with tool support and markdown rendering using only a few lines of code, useful for debugging harnesses before wiring them to HTTP.6

For most solo operators, you start with the simple loop and only adopt these deeper features as your agent becomes core infrastructure.

How do you add observability and tracing to your TypeScript agent?

You add observability by integrating OpenTelemetry with the AI SDK and sending traces to a platform like Langfuse using its Vercel AI SDK integration.8

The recommended pattern is:

  • Enable experimental_telemetry in the AI SDK.
  • Wrap your handler with Langfuse’s observe().
  • Use propagateAttributes() to attach user/session metadata.
  • Call forceFlush() at the end to ensure traces are sent before a serverless function shuts down.8

This gives you spans around each SDK call, tool execution, and agent step—critical for debugging complex loops once you add more tools.

For a small, revenue‑bearing workflow (e.g. payment review or contract summarisation), this level of visibility is usually worth the extra few lines of code.

When is a no-framework, AI SDK-only agent the right choice?

An AI SDK‑only agent is the right choice when your “how to build AI agent from scratch” story is about a single, fast loop that returns structured data and doesn’t need long‑running durability.57

According to Vercel and independent guides, the AI SDK is “the right amount of tool when your agent does its work inside one request and returns,” covering many support bots, code reviewers, extractors, and research helpers.71

Once you need:

  • Multi‑step workflows over minutes or hours.
  • Human approval gates and retries.
  • Cost optimisation across many tasks.
  • Code execution with strict isolation.

…you graduate to Workflows, Sandbox, or an external orchestrator like Temporal, while keeping the core agent harness in TypeScript.36

Until then, a single TypeScript file plus an API route is enough to ship a credible agent in production, with a clear loop boundary, typed outputs, and pragmatic error handling.

Frequently asked questions

What do I need to start building an AI agent from scratch with TypeScript?+

You need a Next.js app, the `@vercel/ai` SDK, an AI Gateway model config, and a single API route that calls an agent harness. The harness defines tools, a loop with `stopWhen` or `stepCountIs`, and a structured output type. For most single‑request agents, this is enough to ship a production‑ready endpoint without adopting a full agent framework.

How does tool-calling actually work in a Vercel AI SDK agent?+

You define tools as TypeScript functions with JSON schemas for parameters, then register them in your agent harness. The model decides when to call a tool; the AI SDK executes it, appends the result to history, and continues the loop. This lets agents fetch data, call APIs, or perform computations autonomously inside one request.

Why is structured output important for TypeScript AI agents?+

Structured output means the model returns typed JSON instead of free-form text. In practice, you define a TypeScript type (e.g. `AgentResult`) and use `generateObject` so the SDK validates and parses the response. This is crucial when other parts of your system need to rely on the agent’s output without fragile text parsing.

How should I handle errors and timeouts in my AI agent?+

Start with simple try/catch around your agent harness and tool execution. Return clear error states in your structured output and log failures for debugging. If your agent often hits timeouts or long‑running tasks, consider Vercel Workflows or Temporal for durable retries and state persistence while still using the AI SDK for the core loop.

Do I really need a full agent framework, or is the AI SDK enough?+

For single‑request agents like support assistants or extractors, the Vercel AI SDK alone is usually enough. You only need a heavyweight framework when you require long‑running workflows, complex human approvals, multi‑channel orchestration, or deep custom tracing. Many teams over‑abstract too early instead of shipping a thin, SDK-based harness.

Sources

  1. How to build AI Agents with Vercel and the AI SDKvercel.com
  2. Build an AI Agent (with Minimal Code!) with TypeScript, Vercel AI ...youtube.com
  3. How to build a durable AI code agent on Vercelvercel.com
  4. Agents 101: How to Build and Deploy Anything with AI Agents - YouTubeyoutube.com
  5. Build AI agents with AI Gateway and AI SDK | Vercel Knowledge Basevercel.com
  6. AI SDK 7 is now available - Vercelvercel.com
  7. Do You Need an Agent Framework Yet? | The Road To Enterprisetheroadtoenterprise.com
  8. Observability and Tracing for the Vercel AI SDK - Langfuselangfuse.com
  9. Why Is Every AI Agent Written in TypeScript? : r/AI_Agents - Redditreddit.com
  10. If you can write a Next.js API route, you can build an AI agent in 30 ...instagram.com
#ai-agents#typescript#vercel-ai-sdk#nextjs#developer-tutorial

Keep reading