Build an AI Quiz Generator with OpenAI: Step-by-Step Tutorial Part 2

Brief recap of Part 1

In the first part of this tutorial series, we created the foundation of an AI-powered Quiz Generator using OpenAI and Next.js. Here’s what we accomplished:

  • The Project set up with Next.js and essential libraries like OpenAI API, DaisyUI, and react-hot-toast for notifications.
  • Educator interface allowing users to upload PDF content.
  • File upload handling that stores files on OpenAI’s platform.
  • Prompt engineering to generate multiple-choice quiz questions in a structured JSON format based on uploaded content.
  • Dynamic quiz rendering for students, displaying generated questions and options interactively.

This setup allows educators to upload documents and automatically generate quizzes, while students can view and select answers for the generated questions.

What We’re Building in Part 2

Now that we have the quiz questions generated and displayed, it’s time to close the learning loop by adding:

  • Interactive User Feedback: Immediate, personalized feedback after students select their answers to help reinforce learning and clarify misunderstandings.
  • Automated Grading: Real-time scoring of student responses with a clear grade summary at the end of the quiz.

Interactive feedback

To implement this feature, we add an event listener to each question. When the user picks an answer, we provide the question, the correct answer, and the Content source, which is our file in the OpenAI storage, and ask LLM to provide feedback for the user to show it in the UI. The Feedback should be in Markdown format.

Pass the file ID

Let's pass the file ID down from the Dashboard to the Quizzes component so we can use it in the LLM prompt.

In the Dashboard.tsx, where you render the Quizzes, add fileId as props

In the Quizzes.tsx make sure you are getting that prop

Implementing the Event Listener

What we want to do here is, when a user clicks on a choice, we grab the question, the correct answer, and the user's answer.

Open the Quizzes.tsx file and add an event handler to the Quizzes component like the following

For each Input radio add this event handler, onChange

Your file should look like the following

Now, when you interact with a question, you should see userAnswer printed in the browser console:

Feedback API Endpoint

We are going to create an endpoint that receives userAnswer via a POST call and passes it to the LLM to get feedback. In the api directory, create a new folder called feedback and create a route.tsx file in it.

We create a simple POST API that checks if we are receiving all the necessary data, and when all checks pass, we return feedback to the UI. We will implement the util function next, so we can provide real feedback.

Let's change our Quizzes component

  1. Converting it to a client component so it can save all the answers with their feedback in the component state
  2. Instead of printing the userAnswerMake a POST call to the endpoint and send the userAnswer
  3. Upsert userAnswer for that question, with the feedback LLM generates for us
  4. Make the handleOptionChange async function so it can handle the fetch call
  5. Make the message green if the answer is correct and orange if the answer is incorrect
  6. Parse feedback Markdown

Let's first install the Markdown parser libraries we need npm i react-markdown remark-gfm

Now open the Quizzes.tsx and change its content to the following

Generate LLM feedback

In the utils directory, create a new file called feedback.tsx to

  1. Pass the user's answer and file ID to it
  2. Create a prompt and ask to generate feedback for the answer.
  3. Return the feedback in markdown format

Now let's change our feedback route to return the LLM feedback instead of hardcoded text

Grading

For this section, we are not going to use AI for grading since we have multiple-choice questions, and we know the correct answer and the user's response. Let's define 3 as the total score for our question, and when the user clicks on submit, we show a modal with a breakdown of the grade per question and total score. Open the Quizzes.tsx file and change it to the following to show a modal when the user clicks on the submit button. This modal shows the total grade and breakdown of each question's score in the table

With the interactive feedback and grading system now in place, your AI Quiz Generator has become a much more engaging and effective learning tool. Students receive immediate, personalized insights on their answers, and the grading breakdown helps them understand their overall performance clearly.

However, there are still areas we can improve to enhance the user experience further. For example, the current feedback generation depends on calls to the language model, which can introduce some latency, meaning students might wait a bit before seeing their feedback. Also, managing multiple attempts or allowing users to reset their answers and try again will make the quiz more flexible and learner-friendly.

Conclusion

Congratulations! 🎉 In this second part of our tutorial, you successfully implemented:

  • Interactive user feedback powered by OpenAI’s language model, providing helpful, encouraging responses based on student answers.
  • Real-time grading with a clear breakdown of scores per question and total quiz score.
  • A dynamic UI that updates feedback instantly and visually distinguishes correct and incorrect answers.

These features significantly improve the learning experience by closing the feedback loop and motivating students to engage deeply with the material.

You can find the Github Repo here

What’s Next?

In the upcoming Part 3, we’ll focus on:

  • Reducing feedback latency using streaming.
  • Adding a reset button and answering logic to allow students multiple attempts.

Related Blogs

Looking to learn more about openai, nextjs, edtech, education and ? These related blog articles explore complementary topics, techniques, and strategies that can help you master Build an AI Quiz Generator with OpenAI: Step-by-Step Tutorial Part 2.