TypeScriptLow abstraction — you write the loop
Vercel AI SDK
A provider-agnostic TypeScript layer for text generation, streaming, tool calling, and structured output, with React/Next.js hooks for streaming UIs.
Architecture
- AI SDK Core:
generateText,streamText,generateObject/streamObjectover a unifiedLanguageModelinterface; providers are packages (@ai-sdk/anthropic,@ai-sdk/openai, …). - Tools:
tool({ description, inputSchema: z.object(...), execute }); the loop runs client-side in your process withstopWhen/maxStepscontrolling iterations. - Structured output: a Zod schema drives either native JSON mode or tool-based extraction per provider.
- AI SDK UI:
useChat/useCompletionhooks consume a streamed UI message protocol from a route handler; tool calls and results stream as typed parts. - Agent class (recent versions) packages model + tools + stop conditions for reuse; there is no persistence or graph runtime.
Best use cases
- Next.js / React products that need streaming chat with tool calls rendered as UI.
- Full-stack TypeScript teams that want one API across providers.
- Edge/serverless deployments where a small, tree-shakeable dependency matters.
Weaknesses
- Provider feature parity lags: newer provider options arrive via
providerOptionsescape hatches with weaker typing. - Major-version churn (v3 → v4 → v5) renamed core concepts (
parameters→inputSchema,maxSteps→stopWhen, message formats); upgrades are not free. - Serverless execution limits make long tool loops awkward; there is no checkpointing or resumption, so durable agents need an external workflow engine.
- The UI message protocol is Vercel's; consuming streams from non-React clients requires understanding the wire format.
- Multi-agent orchestration is left to you — fine, but do not expect supervisor or handoff primitives.
When NOT to use it
- Python backends — the TypeScript-only design is a hard constraint.
- Long-running, resumable workflows with approvals across sessions.
- You need heavy retrieval tooling; pair it with your own search or a dedicated RAG library.
Code example
Illustrative — APIs change between versions.
1import { generateText, tool, stepCountIs } from 'ai'2import { anthropic } from '@ai-sdk/anthropic'3import { z } from 'zod'4 5const result = await generateText({6 model: anthropic('claude-sonnet-4-5'), // model id is version-sensitive7 system: 'You are a support agent. Use tools; never guess order status.',8 prompt: 'Where is order A-123?',9 tools: {10 getOrder: tool({11 description: 'Look up an order by id',12 inputSchema: z.object({ orderId: z.string().regex(/^[A-Z]-\d+$/) }), // v5: inputSchema (v4: parameters)13 execute: async ({ orderId }) => db.orders.find(orderId),14 }),15 },16 stopWhen: stepCountIs(5), // iteration budget for the tool loop17})18 19console.log(result.text)20for (const step of result.steps) {21 console.log(step.toolCalls.map((c) => c.toolName), step.usage.totalTokens)22}