AI
Learn how to leverage the built-in AI features including chatbots and LLM integration.
The Pro Next.js Drizzle starter kit includes powerful AI features powered by the Vercel AI SDK and OpenAI.
Chatbot
Prompting
Overview
The AI system is built with a hybrid architecture to support high-performance streaming while maintaining a type-safe tRPC API for CRUD operations.
| Feature | Technology | Reason |
|---|---|---|
| Streaming responses | API Route | tRPC doesn't support streaming |
| Chat CRUD | tRPC | Type-safe, cached queries |
| State management | Vercel AI SDK | useChat hook handles streaming |
Configuration
Add your OpenAI API key to the .env file to enable the AI features.
OPENAI_API_KEY=sk-...Streaming Endpoint
The main AI chat logic resides in an API route to support real-time streaming of tokens to the client.
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o-mini'),
messages,
onFinish: async ({ usage }) => {
// Save results to the database or deduct credits
}
});
return result.toTextStreamResponse();
}UI Components
We provide a complete suite of components to build a premium AI chat experience.
Main Chat Component
The AiChat component provides a full conversation interface with a history sidebar.
import { AiChat } from '@/components/ai/ai-chat';
export default function AiPage() {
return <AiChat organizationId={activeOrg.id} />;
}Custom Hook
For more control, you can use the useChat hook directly from the Vercel AI SDK.
import { useChat } from '@ai-sdk/react';
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: '/api/ai/chat'
});Tool Calling (Function Calling)
You can easily add tools that the AI can call to perform actions like searching your database or calling external APIs.
const result = streamText({
model: openai('gpt-4o-mini'),
messages,
tools: {
findLeads: {
description: 'Find leads in the database',
parameters: z.object({ query: z.string() }),
execute: async ({ query }) => {
return await db.query.leadTable.findMany({
where: ilike(leadTable.name, `%${query}%`)
});
}
}
}
});