Transforming the Learning Experience: Implementing ChatGPT in an Educational App

Integrating ChatGPT into educational apps has the potential to reshape how students learn and interact with content. In this article, we delve into the specifics of incorporating ChatGPT into an app, focusing on its ability to generate practice questions, create mini-lessons, and adapt to users' needs.

By understanding the underlying mechanisms and benefits, we can appreciate the transformative power of ChatGPT in revolutionizing the educational landscape.

A 3D brain representing Artificial Intelligence, that helps Transforming the Learning Experience with Chat GPT

12 minutes read time

Published:31/03/2023

Author:Marius Manea, Full Stack Developer

Category:Web Development, Cross-platform Apps

Technology:JavaScript

Introduction:

In the rapidly evolving world of technology, embracing innovation and harnessing cutting-edge tools' potential to create transformative learning experiences is crucial. That's why we at ProAppTech, decided to integrate ChatGPT, OpenAI's state-of-the-art language model, into an educational app, FactSumo.

The journey to bring this AI-driven technology into the hands of students and educators worldwide was both exciting and challenging. In this article, we'll walk you through the steps, lessons we learned, and the incredible impact ChatGPT has had on how the app functions.

Why ChatGPT?

Implementing ChatGPT was based on its exceptional ability to understand and generate human-like text. By leveraging this powerful language model, we aimed to provide users with an interactive and personalized learning experience that adapts to their needs and skill levels.

Incorporating ChatGPT into FactSumo has allowed us to create a learning environment where content creators for decks can engage in dynamic conversations with the AI, receive instant suggestions for deck creations, and access a wealth of suggestions at their fingertips. Content creators can take suggestions and make decks even faster than before.

*Deck = a set of questions from a different field integrated into the app.

Our Journey to Integration:

1. Choosing the GPT Version and Deploying the API

Selecting the right GPT version was critical in ensuring our app delivered the desired user experience. After a thorough evaluation, we chose GPT-3.5 Turbo for its ability to generate fast and accurate responses while maintaining high-quality results. This choice allowed us to balance speed, cost-efficiency, and performance perfectly.

To integrate the API, we purchased it directly from OpenAI's website. The following code snippets demonstrate how we set up the API integration and effectively utilized it within our application:

a. API Integration Code

The "generateChatGPTResponse" function is an essential part of our integration. It inputs user data and optional parameters, then constructs the API request body with the appropriate model and message roles.

export const generateChatGPTResponse = (data, options = {}) => {
	const body = {
		model: Config.CHAT_GPT_MODEL,
	};
	const rolesArray = [];
	// ...code to set up rolesArray based on options...
	Object.assign(body, {
		messages: rolesArray,
	});
	return fetch(calls.generateChatGPTResponse(body)).catch(err => { throw err; });
}

An essential feature in the code above is "rolesArray" which can generate content using the ChatGPT API. This array includes three crucial roles that interact with the API: the user, assistant, and system roles.

a. User role: This role sends the prompt to ChatGPT, setting the stage for the content generation process. The user role specifies the topic, format, and any other requirements or details needed for the generated content.

b. Assistant role: The assistant position offers a way to provide additional context and data for content generation. For instance, in Factumo, previously generated content from a mini-lesson can be used as context when generating practice questions. The assistant role can also handle extra information, such as generation limits, ensuring the output meets the desired criteria.

c. System role: This role sets the purpose of ChatGPT within the content generation process. In the case of Factumo, the system role defines ChatGPT as a quiz generator by providing the sentence "You are a quiz generator used to." This hint helps the model understand the context in which it will be utilized and the type of content it should produce.

By incorporating these three roles, the GPT Chat offers a more versatile and powerful content generation tool, allowing creators to generate highly customizable and context-aware content for various questions.

b. API Call Code

The following code snippet demonstrates the API call to OpenAI's GPT-3.5 Turbo. The generateChatGPTResponse function prepares the request and passes it to the API, which returns a response.

generateChatGPTResponse: data => ({
		url: 'https://api.openai.com/v1/chat/completions',
		method: 'POST',
		headers: {
			Accept: 'application/json',
			'Content-type': 'application/json',
			Authorization: Bearer ${ Config.CHAT_GPT_SECRET_KEY }
		},
		body: data
	}),

Let's break down the key aspects of the code:

The generateChatGPTResponse function is responsible for constructing the API request, including the model and message roles.

  • rolesArray is an array that holds message objects, where each object represents a role (system, assistant, or user) and the corresponding content.

  • The Object.assign method combines the body object with the messages key containing the rolesArray.

  • The fetch function sends the API request, and if there are any errors, they are caught and thrown.

By integrating the ChatGPT API using this code, our educational app effectively leverages GPT-3.5 Turbo's capabilities to deliver an engaging and interactive learning experience for students and educators alike.

2. How GPT Chat Works in the App

The educational app offers a seamless experience for content creators by integrating ChatGPT functionality into the creator panel. Content creators can quickly generate decks with questions and answers on various topics, which can be presented as video, visual, or audio content.

Within the creator panel, GPT chat functionality is accessible through several options:

  • Type Idea: In the "type idea" area, content creators can enter a chat prompt, and the ChatGPT will generate 15 questions for them to use.

  • Generate a Story: Content creators can provide a topic, and ChatGPT will create a story based on that topic. Although the report is initially generated in pieces, the code can be adjusted to solve this issue, enabling creators to structure questions and develop information more efficiently.

The app supports multiple languages, catering to a diverse range of users. If content creators are unsatisfied with the generated content, they can reset everything or press the button again for regeneration.

In summary, the integration of ChatGPT into the app provides content creators with an efficient and versatile tool for generating diverse and engaging content. This functionality, combined with support for multiple languages and the option to regenerate content, ensures that the app delivers an optimal experience for content creators and learners.

The code consists of two main functions: generatePracticeQuestions and generateMiniLesson. These functions generate content using the ChatGPT API for different purposes.

a. _generatePracticeQuestions:

This function generates practice questions based on the provided form input and lesson content. It begins by extracting the language name based on the language ID:

const languageName = languages?.data?.find(l => l.id === form?.languageOfPracticeId)?.name;

Then, it sets the isGeneratingData state to true, indicating that the content generation process has started. It calls generateChatGPTResponse, passing the form data and some additional options to generate the content:

const generatedContent = await generateChatGPTResponse(
  { ...form, languageOfPractice: languageName || 'English' },
  {
    generate: 'facts',
    fromLesson: !!miniLessonsContent?.content?.length,
    lessonGenerationOutput: miniLessonsContent?.content,
    miniLessonSettings: miniLessonsContent?.miniLessonSettings,
  }
);
If the generated content is valid, the function processes the content by creating an array of question objects:
const factsData = ( generatedContent?.choices?.[0]?.message?.content || '' ).split('\n').filter(a => a && a.indexOf('C:') !== -1).map((str, idx) => {
  // question objects creation
});

After processing, the function updates the component's state with the generated content and facts data using this.setState() and saves the generated content and related metadata to the ChatGPT log by calling saveChatGPTLog().

b. _generateMiniLesson:

This function generates a mini-lesson based on the provided form input. It starts by extracting the language name based on the language ID:

const languageName = languages?.data?.find(l => l.id === form?.languageOfPracticeId)?.name;
const generatedContent = await generateChatGPTResponse(
  { ...form, languageOfPractice: languageName || 'English' },
  { generate: 'lesson', }
);

If the generated content is valid, the function processes the content by creating an array of lesson objects:

const miniLessonsData = (
  form?.miniLessonSetting === 'story' ?
    generatedContent?.choices?.[0]?.message?.content?.replace(/\n/g, '')?.split('.')?.map(s => s.trim()) :
    form?.miniLessonSetting === 'questions' ?
      generatedContent?.choices?.[0]?.message?.content?.split('\n')?.map(s => s.trim()) : []
    || []
)?.filter(s => !!s)?.map((s, idx) => ({
  primaryQuestion: {
    type: 'rich',
    value: <p>${ s?.substring(0, 100) }</p>,
  },
  primaryType: 'rich',
  type: 'rich',
  order: idx + 1,
}));

After processing, the function updates the component's state with the generated content, mini-lessons data, and mini-lesson settings using this.setState(). It then saves the generated content and related metadata to the ChatGPT log by calling saveChatGPTLog().

In both functions, if an error occurs during content generation (catch (err)), a toast error message is displayed with the error details. Once the process is complete, the isGeneratingData state is set back to false in the finally