Build an AI Quiz Generator with OpenAI: Step-by-Step Tutorial Part 1
Introduction
Brief overview of the AI Quiz Generator
In this tutorial, we’re going to build an AI-powered Quiz Generator using OpenAI’s language models and Next.js. This tool will allow users to upload content—like a PDF document—and automatically generate quiz questions based on that content. The questions will have multiple-choice options, correct answers, and difficulty tags, all formatted in JSON.
What We’re Building
Understanding the Workflow
First, educators provide the content in PDF format, our application uploads the file to the OpenAI storage, provides the File ID, and we use prompt engineering and provide the file ID as context so LLM can generate questions provide Questions, their options, answers, and difficulty tag (easy, medium, hard)
On the student's end, we render the questions JSON, the user interacts with the options, and depending on the answer, we provide feedback, grade the answer, and send the grade to our API. In this article, we build the Eduactor piece, and for the Student, we implement the rendering and showing answers, and in the next article, we work on the Feedback and grading part.
Setting Up the Project Environment
Installing Next.js and initializing the project
Open your Command line interface and run the following command npx create-next-app@latest
⚠️Make sure you have Node.js 18.18 or higher installed on your local machine.
After installation is done, in the command line, change the directory cd quiz-generator
and run npm run dev
Visit Localhost. You should see something like the following
Installing necessary libraries and dependencies
Go to the OpenAI site and on the left sidebar, get an API key. Copy the key and in the root of the project, create a .env
file, and add OPENAI_API_KEY="YourKey"
to it.
By default, Next.js adds .env to the .gitignore, but double check and make sure it doesn't get picked up by git.
In this project, we are going to use DaisyUI as our TailwindCSS component library. Open the command prompt and run the following to install DaisyUI
npm i -D daisyui@latest
Now open the app/global.css
and replace its content with the following
The last step before we move to building our UI component is installing react-hot-toast by running npm i react-hot-toast
Building the UI Components
Designing the dashboard
In the app folder, create a new directory called components
, and inside it, create Dashboard.tsx
Now in the app/page.tsx
Replace the content with the following
Next, replace the app/layout.tsx
content with the following
Run the Next.js development environment and visit localhost:3000 in your browser, and you should see something like the following
Upload File Input
The next step is adding an upload file button that receives a file and shows a toast message to the user. We will wire this up later on with the API route, but for now, let's only build the UI. In the Dashboard.tsx
We replace Tab content 1
With a file input component, replace it with a file input element and add a change handler to it
Creating the quiz display component
Now let's provide a sample set of questions and build our UI component for question rendering. In the project root
Create a new folder called data, and inside it add questions.js
Next, in the components
folder, create a new file called Quizzes.tsx
And in the Dashboard.tsx
import Quizzes and replace Tab content 2 with
Uploading and Processing Content
uploadFile Function
First, let's create a function that receives a file and uploads it to the OpenAI storage. We import this file into our API route to use on a POST call. Since the OpenAI Files API only accepts readStream format, this function:
- Receives the file in the
formData
format - Converts it to a buffer
- Saves it temporarily on the disk
- Using the filesystem library converts it to a
readStream
- Sends it to the OpenAI API
- Removes it from the disk
In the app
directory, let's create a new folder called utils
and inside it create a file called uploadFile.tsx
Next, in the project root, create a directory called lib
and openai.ts
in it
API Endpoint
Let's create an endpoint that receives a file and use the uploadFile function to upload the file to the OpenAI storage. In the app directory, create api/upload-file
and route.tsx
in it
Now in the Dashboard.tsx
change the handleFileChange function to send the file to our API, and set the response as fileID
state
Generating Quiz Questions with OpenAI
Prompt engineering for question generation
Since we want to generate questions in a structured JSON format, it’s essential to be clear and specific in our prompt.
Key Techniques We’ll Use:
- Explicit Output Format:
We tell the AI exactly how to format the output — in this case, a JSON array of question objects with specific fields (
id
, question
, options
, answer
, and difficulty
).
- Clear Instructions:
We specify the type of questions (e.g., multiple choice), the number of options, and the difficulty tags to ensure consistent results.
- Context Provision:
We provide the AI with the content or topic it should base the questions on, so the questions are relevant. In this case we provide the File ID in the Storage.
- Examples, aka Few-Shots:
Including one or two sample questions in the prompt can help the model understand the expected structure.
- Role Playing: Giving the model a persona so it can provide accurate and relevant data.
QuestionsGenerator Function
Let's create a function that defines the schema of the response we want to receive back from the LLM and pass the prompt and file ID to the OpenAI model to generate our questions. In the utils
create questionsGenerator
.tsx with the following content
Now let's modify our route to use this function and send back the generated questions to our UI, in the api/upload-file/route.tsx
Replace the route with the following
Receiving and parsing a JSON
Now we should change both of our components to receive and process questions in the Dashboard.tsx
We want to create a new state that receives the questions from the API and passes them as props to the Quizzes.tsx
, in the Dashboard.tsx
And in the Quizzes.tsx
We define a props and remove our predefined questions data
The last step before we give it a try is installing Zod since we are using it to define the model response schema. In the command line interface, run npm i zod
Conclusion and Next Steps
Congratulations! 🎉 You’ve successfully built an AI-powered Quiz Generator using OpenAI and Next.js. In this tutorial, we covered:
- Setting up a Next.js project with essential libraries
- Creating a user-friendly interface for educators to upload PDF content
- Uploading files to OpenAI’s storage and extracting content
- Crafting precise prompt engineering to generate structured quiz questions in JSON format
- Dynamically rendering quizzes for students to interact with
You can find the Github Repo here
What’s Next?
- Interactive feedback based on user answers
- Real-time grading and scoring
These features will complete the learning loop, turning your quiz generator into a full-fledged educational tool.
Stay tuned, and happy coding! 🚀