Documentation
Complete AI applications and patterns built on top of the Vercel AI SDK, shadcn/ui, and AI Elements. Copy full-stack components for chat, agents, and tool calling.
What are Patterns?
Patterns are complete, production-ready AI applications that you can copy and customize:
- Full-stack AI agents with tool calling and multi-step workflows
- AI tools and utilities for common tasks
- AI patterns for research, analysis, and content generation
- AI artifacts like dynamic tables, charts, and forms
- Marketing AI components for landing pages and user acquisition
- Problem-solving components for common AI challenges
- Web scraping and data processing tools for content extraction
- Human-in-the-loop workflows for safe AI interactions
Pattern Categories
AI Agent Patterns
Sophisticated agent implementations with advanced workflows:
- ai-chat-agent-orchestrater-pattern: Complex project coordination with specialized workers using AI SDK 7's
ToolLoopAgentclass - ai-chat-agent-multi-step-tool-pattern: Multi-step problem solving and research with strongly typed tools
- ai-chat-agent-routing-pattern: Intelligent request routing to specialized agents with concurrent analysis
- ai-chat-agent-evaluator-optimizer-pattern: Agent evaluation and optimization workflows
- ai-human-in-the-loop: Human approval workflows for critical decisions with tool execution control
- ai-agents-parallel-processing: Concurrent agent execution for improved performance
- ai-agents-routing: Dynamic agent selection based on context and complexity
AI Artifact Patterns
Interactive AI-generated content and data visualization:
- ai-artifact-table: Dynamic table generation and editing with CSV processing and real-time updates
- ai-artifact-chart: Chart creation and analysis with burn-rate visualization
- ai-sdk-enrich-form: AI-powered form enhancement and validation
AI Elements Patterns
Basic AI interaction patterns using AI Elements:
- ai-elements-chat: Simple chat interface with streaming responses
- ai-elements-tool: Tool execution demonstration with interactive examples
- ai-elements-image: Image generation and display with AI Elements
- ai-elements-sources-chat: Web search with citations and source tracking
- ai-elements-reasoning-chat: AI reasoning visualization with step-by-step thinking
- ai-elements-inline-citation: Research citations with inline source references
- ai-elements-branch: Conversation branching for different response paths
- ai-elements-task-demo: Task demonstration with AI assistance
AI SDK Integration Patterns
Specific AI SDK features and provider integrations:
- ai-sdk-gemini-flash-text: Google Gemini text generation with streaming
- ai-sdk-gemini-flash-image: Google Gemini image generation and editing
- ai-sdk-gemini-flash-image-edit: Advanced image editing with Gemini
- ai-sdk-google-image: Google image search integration
- ai-sdk-prompt-few-shot: Few-shot prompting patterns and examples
- ai-pdf-ingest: PDF document processing and analysis
- ai-image-generation: General image generation capabilities
- ai-generate-audio: Audio generation and processing
Web Search & Scraping Tools
Powerful tools for web content extraction and search:
- tool-websearch-firecrawl: Web search using Firecrawl API with content extraction
- tool-websearch-exa: Web search using Exa API with intelligent result processing
- tool-websearch-claude: Web search powered by Claude AI with advanced query processing
- ai-websearch: General web search capabilities with AI integration
- cheerio-scraper: Web scraping using Cheerio for HTML parsing
- cheerio-generate-object: Structured data extraction from web content
- jina-scraper: Web scraping using Jina AI for content extraction
Marketing & UI Components
Components for marketing and user interface:
- marketing-model-comparison-2: Model comparison interface for marketing
- marketing-model-comparison-2-compact: Compact model comparison view
- marketing-model-comparison-2-hover: Interactive model comparison with hover effects
- pro-dashboard-01: Professional dashboard template
- weather-tool-approval: Weather tool with approval workflow demonstration
AI Gateway & Rate Limiting
Vercel AI Gateway
Many patterns integrate with Vercel's AI Gateway for enhanced performance and reliability:
- Unified API: Single endpoint for multiple AI providers
- Automatic retries: Built-in retry logic for failed requests
- Request deduplication: Prevents duplicate requests
- Analytics: Detailed usage analytics and monitoring
- Cost optimization: Automatic provider selection based on cost
Upstash Rate Limiting
All production patterns include rate limiting using Upstash Redis:
import { Ratelimit } from "@upstash/ratelimit"
import { Redis } from "@upstash/redis"
// Create a new ratelimiter
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, "10 s"),
analytics: true,
prefix: "@upstash/ratelimit",
})
export async function checkRateLimit(identifier: string) {
const { success, limit, reset, remaining } = await ratelimit.limit(identifier)
return {
success,
limit,
reset,
remaining,
headers: {
"X-RateLimit-Limit": limit.toString(),
"X-RateLimit-Remaining": remaining.toString(),
"X-RateLimit-Reset": reset.toString(),
},
}
}Rate Limiting Configuration
Different patterns use different rate limiting strategies:
- AI Agents: 200 requests per day per IP
- Web Search Tools: 10 requests per minute
- Artifact Generation: 100 requests per day per IP
- Human-in-the-Loop: 50 requests per hour per user
Using Patterns
1. Browse Available Patterns
Visit the patterns page to see all available patterns organized by category.
2. Copy Pattern Code
Click any pattern to view its implementation and copy the code directly into your project.
3. Install Dependencies
Most patterns require the AI SDK and provider packages:
pnpm add ai @ai-sdk/react @ai-sdk/openai @ai-sdk/google @upstash/ratelimit @upstash/redis
4. Set Environment Variables
Configure your AI provider API keys and rate limiting:
# .env.local
OPENAI_API_KEY=your_openai_api_key
GOOGLE_API_KEY=your_google_api_key
CLAUDE_API_KEY=your_claude_api_key
# Required for rate limiting (recommended for production)
UPSTASH_REDIS_REST_URL=your_redis_url
UPSTASH_REDIS_REST_TOKEN=your_redis_token
# Optional: Vercel AI Gateway
VERCEL_AI_GATEWAY_URL=your_gateway_url5. Customize
Modify the pattern to fit your specific needs:
export function MyCustomAgent() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/my-custom-agent" }),
messages: [
{
id: "1",
role: "assistant",
parts: [
{
type: "text",
text: "Hello! I'm your custom AI agent. How can I help?",
},
],
},
],
})
return (
<div className="mx-auto max-w-4xl">
{/* Your customized implementation */}
</div>
)
}Pattern Structure
Each pattern follows a consistent structure for easy integration:
pattern-name/
├── app/
│ ├── layout.tsx # Pattern layout wrapper
│ ├── page.tsx # Main page component
│ └── api/ # API routes for AI functionality
│ └── route-name/
│ └── route.ts # API endpoint implementation
├── components/ # React components
│ ├── demo-name.tsx # Main demo component
│ └── ... # Additional UI components
├── lib/ # Utilities and configurations
│ ├── rate-limit.ts # Rate limiting implementation
│ ├── request-utils.ts # Request validation utilities
│ └── ... # AI tools and schemas
├── hooks/ # Custom React hooks (optional)
├── README.md # Comprehensive documentation
└── package.json # Dependencies and metadata
Key Files Explained
app/page.tsx: Main page component that renders the demoapp/layout.tsx: Layout wrapper for consistent stylingapp/api/*/route.ts: API endpoints handling AI functionality with rate limitingcomponents/*.tsx: React components following clean architecture patternslib/rate-limit.ts: Upstash Redis rate limiting implementationlib/request-utils.ts: Request validation and error handling utilitiesREADME.md: Detailed documentation with setup instructions and examples
AI Agent Patterns
Sophisticated agent implementations with advanced workflows:
- ai-chat-agent-orchestrater-pattern: Complex project coordination with specialized workers using AI SDK 7's
ToolLoopAgentclass - ai-chat-agent-multi-step-tool-pattern: Multi-step problem solving and research with strongly typed tools
- ai-chat-agent-routing-pattern: Intelligent request routing to specialized agents with concurrent analysis
- ai-chat-agent-evaluator-optimizer-pattern: Agent evaluation and optimization workflows
- ai-human-in-the-loop: Human approval workflows for critical decisions with tool execution control
- ai-agents-parallel-processing: Concurrent agent execution for improved performance
- ai-agents-routing: Dynamic agent selection based on context and complexity
Web Search & Scraping Tools
Powerful tools for web content extraction and search:
- tool-websearch-firecrawl: Web search using Firecrawl API with content extraction
- tool-websearch-exa: Web search using Exa API with intelligent result processing
- tool-websearch-claude: Web search powered by Claude AI with advanced query processing
- ai-websearch: General web search capabilities with AI integration
- cheerio-scraper: Web scraping using Cheerio for HTML parsing
- cheerio-generate-object: Structured data extraction from web content
- jina-scraper: Web scraping using Jina AI for content extraction
AI Artifacts
Interactive AI-generated content and data visualization:
- ai-artifact-table: Dynamic table generation and editing with CSV processing and real-time updates
- ai-artifact-chart: Chart creation and analysis with burn-rate visualization
- ai-sdk-enrich-form: AI-powered form enhancement and validation
Best Practices
AI SDK Integration
- Use streaming: Always prefer streaming responses for better UX
- Handle errors: Implement proper error handling and fallbacks
- Type safety: Use TypeScript for better development experience
- Rate limiting: Implement rate limiting for production use
- Tool validation: Use Zod schemas for input validation
- Empty states: Always include empty state components when no data is present
Pattern Development
- Follow conventions: Use established conventions from existing patterns
- Document everything: Provide clear documentation and examples
- Test thoroughly: Ensure patterns work across different scenarios
- Optimize performance: Consider bundle size and runtime performance
- Modular architecture: Keep components focused on single responsibilities
- Custom hooks: Use custom hooks for complex state logic
Security
- API key protection: Never expose API keys in client-side code
- Input validation: Validate all user inputs with Zod schemas
- Rate limiting: Prevent abuse with proper rate limiting
- Content filtering: Implement content moderation when needed
- Error boundaries: Use React error boundaries for graceful failures
Production Considerations
- Environment variables: Use proper environment variable management
- Monitoring: Implement logging and monitoring for production
- Caching: Use appropriate caching strategies for API calls
- Database connections: Manage database connections efficiently
- Memory management: Avoid memory leaks in long-running processes
Common Patterns
API Route Pattern
// app/api/example/route.ts
import { openai } from "@ai-sdk/openai"
import { generateText } from "ai"
import { checkRateLimit } from "@/lib/rate-limit"
export async function POST(req: Request) {
try {
const { prompt } = await req.json()
// Rate limiting check
const identifier = req.headers.get("x-forwarded-for") ?? "unknown"
const { success } = await checkRateLimit(identifier)
if (!success) {
return new Response("Rate limit exceeded", { status: 429 })
}
// AI SDK integration
const result = await generateText({
model: openai("gpt-4"),
prompt: prompt,
})
return Response.json({ result: result.text })
} catch (error) {
console.error("API Error:", error)
return new Response("Internal Server Error", { status: 500 })
}
}Component Pattern
// components/example-demo.tsx
"use client"
import { DefaultChatTransport } from "ai"
import { useChat } from "@ai-sdk/react"
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
export function ExampleDemo() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/example" }),
})
if (messages.length === 0) {
return (
<Empty className="mx-auto mt-6 max-w-2xl">
<EmptyHeader>
<EmptyMedia variant="icon">
<div className="flex size-12 items-center justify-center rounded-full border bg-white dark:bg-card p-1 shadow-sm">
<Icon className="size-6" />
</div>
</EmptyMedia>
<EmptyTitle>Example Demo</EmptyTitle>
<EmptyDescription>
Description of the component with{" "}
<span className="border-border bg-muted rounded-sm border-[1px] px-1 py-0.5 font-mono font-light tracking-tight">
ComponentName
</span>{" "}
highlighted.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<div className="space-y-4">
<div>
<p className="text-muted-foreground mb-3 text-sm">
Usage instructions and helpful context.
</p>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">Example prompts:</p>
<ul className="text-muted-foreground space-y-1 text-sm">
<li>• "Example prompt 1"</li>
<li>• "Example prompt 2"</li>
</ul>
</div>
</div>
</EmptyContent>
</Empty>
)
}
return (
<div className="mx-auto max-w-4xl">
{/* Chat interface implementation */}
</div>
)
}Tool Definition Pattern
// lib/tools.ts
import { tool } from "ai"
import { z } from "zod"
export const exampleTool = tool({
description: "Tool description for AI understanding",
inputSchema: z.object({
parameter: z.string().describe("Parameter description"),
optional: z.string().optional().describe("Optional parameter"),
}),
execute: async ({ parameter, optional }) => {
// Tool implementation
return {
result: "Tool execution result",
metadata: {
processedAt: new Date().toISOString(),
parameter,
},
}
},
})Examples
Simple Chat Pattern
"use client"
import { DefaultChatTransport } from "ai"
import { useChat } from "@ai-sdk/react"
import {
Conversation,
ConversationContent,
Message,
MessageContent,
PromptInput,
PromptInputBody,
PromptInputSubmit,
PromptInputTextarea,
} from "@/components/ai-elements"
export function SimpleChatBlock() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
})
return (
<div className="flex h-screen flex-col">
<Conversation>
<ConversationContent>
{messages.map((message) => (
<Message key={message.id} from={message.role}>
<MessageContent>
{message.parts.map((part, index) =>
part.type === "text" ? (
<span key={index}>{part.text}</span>
) : null
)}
</MessageContent>
</Message>
))}
</ConversationContent>
</Conversation>
<PromptInput
onSubmit={(message) => {
if (message.text.trim()) {
sendMessage({ text: message.text })
}
}}
>
<PromptInputBody>
<PromptInputTextarea placeholder="Type your message..." />
</PromptInputBody>
<PromptInputSubmit status={status} />
</PromptInput>
</div>
)
}Tool Calling Pattern
Tools are defined server-side. The client renders tool calls and results as typed tool parts on each message:
// app/api/weather-chat/route.ts
import { streamText, tool, toUIMessageStream, createUIMessageStreamResponse } from "ai"
import { z } from "zod"
export async function POST(req: Request) {
const { messages } = await req.json()
const result = streamText({
model: "openai/gpt-5.4-nano",
messages,
tools: {
getWeather: tool({
description: "Get the current weather for a location",
inputSchema: z.object({
location: z.string().describe("The city and state"),
}),
execute: async ({ location }) => ({
location,
temperature: "72°F",
condition: "Sunny",
}),
}),
},
})
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
})
}// components/weather-tool-block.tsx
"use client"
import { DefaultChatTransport } from "ai"
import { useChat } from "@ai-sdk/react"
export function WeatherToolBlock() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/weather-chat" }),
})
return (
<div>
{messages.map((message) => (
<div key={message.id}>
{message.parts.map((part, index) => {
if (part.type === "text") {
return <p key={index}>{part.text}</p>
}
if (part.type === "tool-getWeather" && part.state === "output-available") {
return (
<p key={index}>
{part.output.location}: {part.output.temperature}
</p>
)
}
return null
})}
</div>
))}
</div>
)
}Human-in-the-Loop Pattern
Require user approval before a server-side tool runs by setting toolApproval
on streamText (or your agent). The tool part enters the
approval-requested state on the client, where the user approves or denies
it with addToolApprovalResponse:
// app/api/human-in-loop/route.ts (excerpt)
const result = streamText({
model: "openai/gpt-5.4-nano",
messages,
tools: { getWeather },
toolApproval: {
getWeather: "user-approval",
},
})// components/human-in-loop-block.tsx
"use client"
import { useChat } from "@ai-sdk/react"
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
export function HumanInLoopBlock() {
const { messages, addToolApprovalResponse } = useChat()
return (
<div className="mx-auto max-w-4xl space-y-4">
{messages.map((message) => (
<div key={message.id}>
{message.parts.map((part, index) => {
if (part.type === "text") {
return <p key={index}>{part.text}</p>
}
if (
part.type === "tool-getWeather" &&
part.state === "approval-requested"
) {
return (
<Card key={part.toolCallId}>
<CardHeader>
<CardTitle>Tool Approval Required</CardTitle>
<CardDescription>
The AI wants to check the weather.
</CardDescription>
</CardHeader>
<CardContent>
<pre className="bg-muted rounded p-2 text-sm">
{JSON.stringify(part.input, null, 2)}
</pre>
<div className="mt-2 flex gap-2">
<Button
onClick={() =>
addToolApprovalResponse({
id: part.approval.id,
approved: true,
})
}
>
Approve
</Button>
<Button
variant="outline"
onClick={() =>
addToolApprovalResponse({
id: part.approval.id,
approved: false,
})
}
>
Reject
</Button>
</div>
</CardContent>
</Card>
)
}
return null
})}
</div>
))}
</div>
)
}Deployment & Production
Environment Setup
-
Set up Upstash Redis for rate limiting:
# Install Upstash CLI npm install -g @upstash/cli # Create Redis database upstash redis create my-redis-db -
Configure environment variables:
# .env.local OPENAI_API_KEY=your_openai_api_key GOOGLE_API_KEY=your_google_api_key CLAUDE_API_KEY=your_claude_api_key # Upstash Redis UPSTASH_REDIS_REST_URL=https://your-redis-url.upstash.io UPSTASH_REDIS_REST_TOKEN=your_redis_token # Optional: Vercel AI Gateway VERCEL_AI_GATEWAY_URL=https://your-gateway-url.vercel.app -
Deploy to Vercel:
# Install Vercel CLI npm install -g vercel # Deploy vercel --prod
Monitoring & Analytics
- Vercel Analytics: Built-in performance monitoring
- Upstash Console: Redis usage and rate limiting metrics
- AI Gateway Analytics: AI provider usage and costs
- Custom Logging: Implement structured logging for debugging
Cost Optimization
- Rate limiting: Prevent abuse and control costs
- Caching: Cache responses to reduce API calls
- Provider selection: Use cost-effective models when appropriate
- Monitoring: Track usage patterns and optimize accordingly
Troubleshooting
Common Issues
- Rate limit exceeded: Check Upstash Redis configuration
- API key errors: Verify environment variables are set correctly
- Tool execution failures: Check tool schemas and error handling
- Streaming issues: Ensure proper error boundaries and fallbacks
Debug Tips
- Use browser dev tools to inspect network requests
- Check server logs for API errors
- Verify rate limiting headers in responses
- Test with different input scenarios
Next Steps
On this page
What are Patterns?Pattern CategoriesAI Agent PatternsAI Artifact PatternsAI Elements PatternsAI SDK Integration PatternsWeb Search & Scraping ToolsMarketing & UI ComponentsAI Gateway & Rate LimitingVercel AI GatewayUpstash Rate LimitingRate Limiting ConfigurationUsing Patterns1. Browse Available Patterns2. Copy Pattern Code3. Install Dependencies4. Set Environment Variables5. CustomizePattern StructureKey Files ExplainedAI Agent PatternsWeb Search & Scraping ToolsAI ArtifactsBest PracticesAI SDK IntegrationPattern DevelopmentSecurityProduction ConsiderationsCommon PatternsAPI Route PatternComponent PatternTool Definition PatternExamplesSimple Chat PatternTool Calling PatternHuman-in-the-Loop PatternDeployment & ProductionEnvironment SetupMonitoring & AnalyticsCost OptimizationTroubleshootingCommon IssuesDebug TipsNext Stepsai sdk patterns.