Unit 5: Building an AI Chatbot
Unit 5 of the Nivaro AI Website Program is a hands-on guide to integrating an AI chatbot using OpenAI with the Vercel AI SDK in a Next.js application. Students will set up a project, create an AI chatbot, and learn to stream responses using the Edge Runtime.
Lesson 5.1: Creating a Next.js AI Chatbot Application
In this lesson, students will create a Next.js application, install necessary packages, and set up environment variables for AI integration.
Setting Up the Project
-
Create a Next.js Application:
-
Create a new empty codespace
-
Create a Next.js app:
npx create-next-app@latest
-
Make sure to drag out all of the folders from the app folder created, or it will not work. Watch the video for an example
-
Install the Vercel AI SDK and OpenAI API client:
pnpm install ai openai
-
-
Add OpenAI API Key:
- Create a
.env
file in the project root (create a new file by right clicking) - Add your OpenAI API key. THE API KEY SHOULD BE WITH YOUR TEACHER OR YOU CAN MESSAGE US FOR IT, IT IS PRIVATE:
OPENAI_API_KEY=your_openai_api_key
- Create a
Creating the AI Chatbot Route Handler
-
Implement a Route Handler:
-
Create
app/api/chat/route.ts
for handling chat requests:import OpenAI from 'openai' import { OpenAIStream, StreamingTextResponse } from 'ai' const openai = new OpenAI(process.env.OPENAI_API_KEY) export const runtime = 'edge' export async function POST(req: Request) { const { messages } = await req.json() console.log(messages) // Add a system message at the start of the array messages.unshift({ role: 'system', content: 'You are a middle schooler who only talks in 5 letter long words.', }) console.log(messages) const response = await openai.chat.completions.create({ model: 'gpt-3.5-turbo', stream: true, messages, }) const stream = OpenAIStream(response) return new StreamingTextResponse(stream) }
-
The route handler uses OpenAI's API to generate chat completions and streams the response back.
-
Building the User Interface
-
Set Up the Chat UI:
-
Update
app/page.tsx
to include the chat interface:'use client' import { useChat } from 'ai/react' export default function Chat() { const { messages, input, handleInputChange, handleSubmit } = useChat() return ( <main className="mx-auto flex h-screen w-full max-w-lg flex-col bg-blue-500 p-6"> <section className="mb-4 overflow-auto rounded-lg bg-white p-4 shadow"> {messages.map((m) => ( <div className={`mb-2 rounded-md p-2 ${ m.role === 'user' ? 'bg-blue-200' : 'bg-green-200' }`} key={m.id} > <strong>{m.role === 'user' ? 'You: ' : 'AI: '}</strong> {m.content} </div> ))} </section> <form className="mt-auto flex space-x-4" onSubmit={handleSubmit}> <input className="flex-grow rounded-md border-2 border-gray-300 p-2 text-black" value={input} onChange={handleInputChange} placeholder="Say something..." /> <button className="rounded-md bg-blue-600 p-2 text-white hover:bg-blue-700" type="submit" > Send </button> </form> </main> ) }
-
-
Editing system prompt:
- Edit the system message to make the chatbot personalized to you
-
Edit the basic styling of the chatbot:
- Use GPT to customize the chatbot
Simple Version:
Lesson 5.2: Rundown of an Example Next.js AI Chatbot Application
In this lesson, students will build off the Next.js application constructed in 5.1 and transform it into an application they are passionate about.
Updating the User Interface
-
Update the Chatbot :
-
Update the chatbot in
app/page.tsx
to use styles for a fitness app:// page.tsx function Chat() { const { messages, input, handleInputChange, handleSubmit } = useChat() return ( <main className="mx-auto mb-auto flex h-screen w-full max-w-lg flex-col bg-gray-400 p-6"> <span className="mb-4 bg-gradient-to-r from-orange-400 to-orange-600 bg-clip-text text-3xl font-bold text-transparent drop-shadow-[0_1.2px_1.2px_rgba(0,0,0,0.8)]"> FITT Chatbot </span> <section className="mb-4 overflow-auto rounded-lg bg-white p-4 shadow"> {messages.map((m) => ( <div className={`mb-2 rounded-md p-2 ${ m.role === 'user' ? 'text-white-400 bg-orange-400' : 'text-white-400 bg-gray-400' }`} key={m.id} > <strong>{m.role === 'user' ? 'You: ' : 'AI: '}</strong> {m.content} </div> ))} </section> <form className="mt-auto flex space-x-4" onSubmit={handleSubmit}> <input className="flex-grow rounded-md border-2 border-gray-300 p-2 text-black" value={input} onChange={handleInputChange} placeholder="Say something..." /> <button className="text-white-400 rounded-md bg-orange-400 p-2 hover:bg-orange-500" type="submit" > Send </button> </form> </main> ) }
-
-
Adding a Landing Page:
-
Update
app/page.tsx
to have a landing page users see before the actual chatbot:// page.tsx import { useState } from 'react' function LandingPage({ onStartChat }) { return ( <main className="fixed inset-0 flex items-center justify-center bg-gray-500"> <div className="animate__animated animate__fadeIn mx-auto flex w-full max-w-lg flex-col items-center justify-center rounded-lg bg-gray-500 p-8 shadow-lg"> <h1 className="mb-6 text-3xl font-bold"> <span className="bg-gradient-to-r from-orange-400 to-orange-600 bg-clip-text text-transparent drop-shadow-[0_1.2px_1.2px_rgba(0,0,0,0.8)]"> Welcome to Fitt_ AI </span> </h1> <button className="rounded-md border border-black bg-orange-500 p-3 text-white transition duration-300 hover:bg-orange-600" onClick={onStartChat} > Start Workout </button> </div> </main> ) }
-
-
Create navigation betweeen screens:
-
Add a default function App to
app/page.tsx
that handles changing screens:// page.tsx export default function App() { const [isChatStarted, setIsChatStarted] = useState(false) const handleStartChat = () => { setIsChatStarted(true) } //if the button is clicked return isChatStarted ? ( <Chat /> ) : ( <LandingPage onStartChat={handleStartChat} /> ) }
-
To add more screens, create a function like
function aboutMe()
, return your styles, and ask chatGPT to add navigation to this screen in the App function.
-
Example Updated Next.js app, FittAI:
Homework: Basic Bot
Follow Units 5.1 and 5.2 to get started. Once you have a working chatbot, change it to make it your own.
- Add custom instructions
- Edit the HTML to make it your own
- Change the CSS to make it look better
- Submit your website through Schoology