惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
Recent Announcements
Recent Announcements
L
LangChain Blog
B
Blog
阮一峰的网络日志
阮一峰的网络日志
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
M
MIT News - Artificial intelligence
D
Docker
WordPress大学
WordPress大学
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
博客园 - 叶小钗
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MongoDB | Blog
MongoDB | Blog
博客园 - Franky

Workflow SDK Documentation

Patterns for Defining Tools Human-in-the-Loop Queueing User Messages Resumable Streams Sleep, Suspense, and Scheduling Streaming Updates from Tools API Reference Workflow Globals Changelog Resilient run start Cookbook Building a World Deploying Astro Express Fastify Hono Getting Started NestJS Next.js Nitro Nuxt Python SvelteKit Vite corrupted-event-log fetch-in-workflow hook-conflict Errors node-js-module-in-workflow
Building Durable AI Agents
2026-05-31 · via Workflow SDK Documentation

Build AI agents that survive crashes, scale across requests, and maintain state with durable LLM tool-call loops.

AI agents are built on the primitive of LLM and tool-call loops, often with additional processes for data fetching, resource provisioning, or reacting to external events.

Workflow SDK makes your agents production-ready, by turning them into durable, resumable workflows. It transforms your LLM calls, tool executions, and other async operations into retryable, scalable, and observable steps.

This guide walks you through converting a basic AI chat app into a durable AI agent using Workflow SDK.

Aside from the usual challenges of getting your long-running tasks to be production-ready, building mature AI agents typically requires solving several additional challenges:

  • Statefulness: Persisting chat sessions and turning LLM and tool calls into async jobs with workers and queues.
  • Observability: Using services to collect traces and metrics, and managing them separately from your messages and user history.
  • Resumability: Resuming streams requires not just storing your messages, but also storing streams, and piping them across services.
  • Human-in-the-loop: Your client, API, and async job orchestration need to work together to create, track, route to, and display human approval requests, or similar webhook operations.

Workflow SDK provides all of these capabilities out of the box. Your agent becomes a workflow, your tools become steps, and the framework handles interplay with your existing infrastructure.

To make an Agent durable, we first need an Agent, which we'll be setting up here. If you already have an app you'd like to follow along with, you can skip this section.

For our example, we'll need an app with a simple chat interface and an API route calling an LLM, so that we can add Workflow SDK to it. We'll use the Flight Booking Agent example as a starting point, which comes with a chat interface built using Next.js, AI SDK, and Shadcn UI.

Clone example app

We'll need an app with a simple chat interface and an API route calling an LLM, so that we can add Workflow SDK to it. For the follow-along steps, we'll use the Flight Booking Agent example as a starting point, which comes with a chat interface built using Next.js, AI SDK, and Shadcn UI.

If you have your own project, you can skip this step, and simply apply the changes of the following steps to your own project.

git clone https://github.com/vercel/workflow-examples -b plain-ai-sdk
cd workflow-examples/flight-booking-app

Set up API keys

In order to connect to an LLM, we'll need to set up an API key. The easiest way to do this is to use Vercel Gateway (works with all providers at zero markup), or you can configure a custom provider.

Get familiar with the code

Let's take a moment to see what we're working with. Run the app with npm run dev and open http://localhost:3000 in your browser. You should see a simple chat interface to play with. Go ahead and give it a try.

The core code that makes all of this happen is quite simple. Here's a breakdown of the main parts. Note that there's no changes needed here, we're simply taking a look at the code to understand what's happening.

Now that we have a basic agent using AI SDK, we can modify it to make it durable.

Install Dependencies

Add the Workflow SDK packages to your project:

and extend the Next.js config to transform your workflow code (see Getting Started for more details).

import { withWorkflow } from "workflow/next";
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // ... rest of your Next.js config
};

export default withWorkflow(nextConfig);

Create a Workflow Function

Move the agent logic into a separate function, which will serve as our workflow definition.

import { DurableAgent } from "@workflow/ai/agent"; 
import { getWritable } from "workflow"; 
import { tools } from "@/ai/tools";
import { openai } from "@workflow/ai/openai";
import type { ModelMessage, UIMessageChunk } from "ai";

export async function chatWorkflow(messages: ModelMessage[]) {
  "use workflow"; 

  const writable = getWritable<UIMessageChunk>(); 

  const agent = new DurableAgent({ 

    // If using AI Gateway, just specify the model name as a string:
    model: "bedrock/claude-4-5-haiku-20251001-v1", 

    // ELSE if using a custom provider, pass the provider call as an argument:
    model: openai("gpt-5.1"), 

    instructions: FLIGHT_ASSISTANT_PROMPT,
    tools: flightBookingTools,
  });

  await agent.stream({ 
    messages,
    writable,
  });
}

Key changes:

  • Add the "use workflow" directive to mark our Agent as a workflow function
  • Replaced Agent with DurableAgent from @workflow/ai/agent. This ensures that all calls to the LLM are executed as "steps", and results are aggregated within the workflow context (see Workflows and Steps for more details on how workflows/steps are defined).
  • Use getWritable() to get a stream for agent output. This stream is persistent, and API endpoints can read from a run's stream at any time.

Update the API Route

Remove the agent call that we just extracted, and replace it with a call to start() to run the workflow:

import type { UIMessage } from "ai";
import { convertToModelMessages, createUIMessageStreamResponse } from "ai";
import { start } from "workflow/api";
import { chatWorkflow } from "@/workflows/chat/workflow";

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json();
  const modelMessages = await convertToModelMessages(messages);

  const run = await start(chatWorkflow, [modelMessages]); 

  return createUIMessageStreamResponse({
    stream: run.readable, 
  });
}

Key changes:

  • Call start() to run the workflow function. This returns a Run object, which contains the run ID and the readable stream (see Starting Workflows for more details on the Run object).
  • Pass the writable to agent.stream() instead of returning a stream directly, ensuring all the Agent output is written to to the run's stream.

Convert Tools to Steps

Mark all tool definitions with "use step" to make them durable. This enables automatic retries and observability for each tool call:

// ...

export async function searchFlights(
  // ... arguments
) {
  "use step"; 

  // ... rest of the tool code
}

export async function checkFlightStatus(
  // ... arguments
) {
  "use step"; 

  // ... rest of the tool code
}

export async function getAirportInfo(
  // ... arguments
) {
  "use step"; 

  // ... rest of the tool code
}

export async function bookFlight({
  // ... arguments
}) {
  "use step"; 

  // ... rest of the tool code
}

export async function checkBaggageAllowance(
  // ... arguments
) {
    "use step"; 

    // ... rest of the tool code
  }
}

With "use step":

  • The tool execution runs in a separate step with full Node.js access. In production, each step is executed in a separate worker process, which scales automatically with your workload.
  • Failed tool calls are automatically retried (up to 3 times by default). See Errors and Retries for more details.
  • Each tool execution appears as a discrete step in observability tools. See Observability for more details.

That's all you need to do to convert your basic AI SDK agent into a durable agent. If you run your development server, and send a chat message, you should see your agent respond just as before, but now with added durability and observability.

In your app directory, you can open up the observability dashboard to see your workflow in action, using the CLI:

This opens a local dashboard showing all workflow runs and their status, as well as a trace viewer to inspect the workflow in detail, including retry attempts, and the data being passed between steps.

Now that you have a basic durable agent, it's a only a short step to add these additional features:

A complete example that includes all of the above, plus all of the "next steps" features is available on the main branch of the Flight Booking Agent example.