Prompt Engineering and Course Creation.

Alexander Gould
6 min readJan 22, 2023

I, like the many other denizens of the internet in the past several weeks, found myself fascinated by chatGPT, so much potential for change and growth comes with the advent of this technology, and leveraging it to build novel applications is truly an exciting prospect. As I was approaching building my capstone project for Flatiron School, I thought that there would be no better technology to explore and implement than the GPT API, an api that allows one to access the language models developed by OpenAI for programmatic use in your own applications.

I wanted to build an application that leveraged the openAI api to help users explore and build their own courses in any given area they wish. the powerful thing about using LLM’s to do this, is it enables you to have an instantaneous learning plan for what subjects to tackle in order to learn any given subject. Often the hardest part of learning something new is knowing where to start, and how to search the large volume of information on the internet in order to follow the right steps to go from clueless to understanding. Dialogium solves this problem by providing users with a clear lesson plan, and giving them the ability to search youtube for videos relevant to learning each topic in that plan.

Learning OpenAI API

The first challenge I tackled when beginning this project was learning how to make use of OpenAI’s robust API. One of the requirements for my final project was learning and using a new technology, and this API more than fulfills this requirement. I had to learn the meaning of “temperature” when querying large language models, how to engineer a prompt that returns data in a format that is easy to parse and use in your application, and finally how to parse the prompt such that it creates consistent data to be passed to the models and views of my final application. The result is an amazing workflow that generates courses in seconds.

Temperature

Temperature is a vital parameter for building applicaitons with the OpenAI API as it determines the randomness of the response you will recieve. In some cases, a higher degree of variance is preferable, if you were generating a fictional story, for example. In my case, I needed uniform responses to be generated, meaning that they did not vary far from the prompt that I gave to the system, but also took some liberty in building courses, so that I didn’t have several users generating the exact same course plans over and over again. I used temperature 0.5, and this seemed to work very well to generate a consistently formatted response, with some degree of variation in the actual output if i query the model for the same subject matter more than once.

Prompt Engineering:

The next challenge to tackle was the engineering of the actual prompt, I needed to learn over several iteratinos how to ask for what i wanted in order to get a uniform response that oculd be parsed in the same way each time. I was asking for a course broken up into sections and lessons on a given topic. The response generates the framework for a course in my final application, that users can then add to, update, and change around to serve their own purposes.

Prompt Generated Course.

This is the prompt that I arrived at that consistently returns my requested information:

‘Generate a course syllabus of nine lessons for’+ params[:topic] +’such that I would have a basic understanding of the topic upon completion of the course.

Separate the course into three sections of three lessons.

Include a real and, to the best of your knowledge active link to a youtube video that covers the topic for each lesson.

Format the syllabus in the following way:

Title: `Course Title`

Section 1:

Lesson A:

Name: `Lesson Name`

Subject: `Lesson Subject`

Video: `Youtube video title`

Channel: `Youtube video Channel`

Link: `Youtube Video Link`

(Continue with lessons B and C for each section)(ONLY write “Sections” and “Lessons” as “Section 1:”, “Lesson A:”, etc, DO NOT include any further text to the line upon which those important keywords appear.)

Repeat this formatting for all the sections and lessons for’+params[:topic]+’

If more subject matter is required in order to have a basic understanding of’ + params[:topic]+’,

Include a final section labled “Section 4” with any relevent information you think is nessecary for a complete basic understanding of’ + params[:topic]+’.

Please follow the requested formatting exactly as it appears. Thank you.’

As you can see, I had to get extremely specific in asking for how I wanted the course to be formatted in order to return consistent data on each request. The specificity of this data remained extremely important when parsing the returned data.

The response of the openAI API is not parseable json to the degree of specificity necessary to parse what is inside the response, so I had to develop a custom “parse_completion” method that allowed me to pull out all of the returned information based on specific markers in my returned text, such as “section(section number) and lesson(lesson letter).”

def parse_completion
parsed_response={}
lines = self.text.split("\n")
new_lines = lines.map do |line|
new_line = line.strip
new_line
end
#new_lines.compact_blank
lines_to_split = new_lines.compact_blank
#puts lines_to_split
title = lines_to_split.shift
parsed_response[:title] = title
parsed_response[:course] = find_sections(lines_to_split)
#puts parsed_response
return parsed_response
end

Parsing Data

Using several private methods, I parse my response into a useable object (parsed response). I then use this parsed response to generate all the sections and lessons of the course my user wants to generate:

 def self.generate_course_from_completion(parsed_completion, user_id, topic)
title = parsed_completion[:title]
oneA = parsed_completion[:course][:section1][:lesson_a]
oneB = parsed_completion[:course][:section1][:lesson_b]
oneC = parsed_completion[:course][:section1][:lesson_c]
section_2 = parsed_completion[:course][:section2]
twoA = parsed_completion[:course][:section2][:lesson_a]
twoB = parsed_completion[:course][:section2][:lesson_b]
twoC = parsed_completion[:course][:section2][:lesson_c]
section_3 = parsed_completion[:course][:section3]
threeA = parsed_completion[:course][:section3][:lesson_a]
threeB = parsed_completion[:course][:section3][:lesson_b]
threeC = parsed_completion[:course][:section3][:lesson_c]

course = Course.create(title: title, user_id: user_id, topic: topic)

s1 = course.sections.create(number: 1)
s2 = course.sections.create(number: 2)
s3 = course.sections.create(number: 3)

l1a = s1.lessons.create(name: oneA[:name], subject: oneA[:subject])
l1b = s1.lessons.create(name: oneB[:name], subject: oneB[:subject])
l1c = s1.lessons.create(name: oneC[:name], subject: oneC[:subject])
l2a = s2.lessons.create(name: twoA[:name], subject: twoA[:subject])
l2b = s2.lessons.create(name: twoB[:name], subject: twoB[:subject])
l2c = s2.lessons.create(name: twoC[:name], subject: twoC[:subject])
l3a = s3.lessons.create(name: threeA[:name], subject: threeA[:subject])
l3b = s3.lessons.create(name: threeB[:name], subject: threeB[:subject])
l3c = s3.lessons.create(name: threeC[:name], subject: threeC[:subject])
end

Using these methods, with a single click, a user can instantly generate the framework for an entire course (pictured above).

Building the Application

Once I figured out how to allow users to create courses, and had seeded a couple of courses of my own, I was ready to build the rest of the application. This involved querying the Youtube API to allow users to add videos to the lessons that the prompt generated, and creating models and controllers on the back end for courses, lessons, users, and videos to allow users to interact with the created courses, decide to take the course, add lessons, videos, and courses to the site, and interact with other users who are fellow students, and creators of the various courses on the site.

In my React frontend, I used Material UI to handle styling, generating a clean and clear user interface. I am excited at the ability to build and share courses that you have created to help expand the global learning community and share ideas.

I am looking forward to continuing to explore the possibility of GPT and other Large Language models as they develop in the future.

--

--