Using Streamlit and GPT-4 to prototype a web app for suggesting personalised early-years activities

Kostas Stathoulopoulos
Discovery at Nesta
Published in
7 min readAug 8, 2023

Introduction

Nesta’s Discovery Hub recently launched a new project to investigate how generative AI, especially large language models (LLMs), can be used for social good. We’re currently exploring the potential of LLMs for early-years education, and we will discuss the technical aspects of our early prototypes in a series of blogs.

We will share our code, the demos we’ve built as well as our concerns on the use of generative AI for social good. In parallel, we will gather feedback about these prototypes from domain experts.

Here we share a technical guide on how OpenAI’s GPT-4 could assist caregivers and educators by suggesting personalised activities that are anchored in the UK’s Early Years Foundation Stages (EYFS) statutory framework.

Generating activity ideas grounded in Early Years Foundation Stages

EYFS sets the standards that all early-years providers must meet to ensure that children from birth to five years old learn and develop well, and are kept healthy and safe. It promotes teaching and learning to ensure children’s school-readiness and a broad range of knowledge and skills that provide the right foundation for good progress through school and life.

Our first prototype explores how LLMs could suggest topics for conversation, activities and experiences that help children develop in EYFS’s seven areas of learning:

  1. Communication and language
  2. Physical development
  3. Personal, social and emotional development
  4. Literacy
  5. Mathematics
  6. Understanding the world
  7. Expressive arts and design

We also wished to personalise the suggestions to the specific interests that a child might have on a given day — be it snails, dinosaurs, fire trucks or anything else. The practice of responding to a child’s interests with questions and activities, also known as contingent talk, is vital in supporting language development.

The inspiration for this use case came from talking with early-years professionals.

Let’s dive into what we built.

Using OpenAI’s ChatCompletion API

LLMs are notoriously expensive to train from scratch, however, there are a handful of companies that provide access to their models through an application programming interface (API) such as OpenAI, Anthropic and Cohere. We opted for OpenAI’s models as they are pretty good and affordable and many of us in the Discovery Hub are ChatGPT users.

Developers can use GPT-3.5 and GPT-4 through OpenAI’s Chat Completion API endpoint. The interaction with the LLM happens in a chat-like manner; you send messages in English and the LLM responds back. Each message has a “role”, which can be one of the following:

  • system: sets the behaviour of the model throughout the conversation
  • user: requests or instructions about a task the LLM has to respond to
  • assistant: stores responses of the LLM
  • function: structures the LLM’s output in a way that it’s easily consumed by downstream tasks like a Python function

Taken together, those messages form your “prompt”, the text you send to the LLM to elicit a response.

Some other options worth tweaking are the model, for example gpt-3.5-turbo for fast responses or gpt-4 for slower but higher quality ones, and the temperature. Low-temperature values make the model more deterministic while high-temperature values increase variance in the response.

Assuming you use Python and you have installed the openai package, here is an example API call:

import openai
import os

openai.api_key = <OPENAI_API_KEY>

openai.ChatCompletion.create(
model="gpt-3.5-turbo",
temperature=0.6,
messages=[
{"role": "system", "content": "You are a standup comedian."},
{"role": "user", "content": "Tell me a funny joke about dogs."},
]
)

The response contains metadata about the API call as well as a choices field which contains the LLM’s role and reply.

{'id': 'chatcmpl-7j601NNwOFu5Dbi882q3Brc85tSNl',
'object': 'chat.completion',
'created': 1690982177,
'model': 'gpt-3.5-turbo-0613',
'choices': [{'index': 0,
'message': {'role': 'assistant',
'content': "Sure! Here's one for you:\n\nWhy did the dog sit in the shade?\n\nBecause he didn't want to be a hot dog!"},
'finish_reason': 'stop'}],
'usage': {'prompt_tokens': 26, 'completion_tokens': 28, 'total_tokens': 54}}

Working with prompts

Prompts modify the behaviour of the LLM and provide it with task instructions. Writing a good prompt is currently more art than engineering and it requires trial and error. Check out the Prompt Engineering Guide and OpenAI’s documentation if you are interested in learning about best practices. Generally, we would recommend versioning your prompts as you would with your data, model and code in other traditional machine learning tasks.

We decided to store our prompts in JSON format and version them with our code on GitHub. In the future, we would like to experiment with solutions like Weights & Biases Prompts and LangSmith for experiment tracking and monitoring.

Prompt engineering for EYFS-related activities

Our main idea was to make the LLM act as an agent who designs early-year education programmes and give it enough context about the EYFS statutory framework so that it suggests relevant activities. We specified its behaviour in the system prompt and copied the description of each area of learning and development from the statutory guidance document to anchor its responses to EYFS.

We described the task: we wanted the LLM to suggest topics for discussion, games and crafts that are fun and engaging but also promote learning.

We opted for dynamically editing parts of our prompt based on user input (see flowchart below). For example, only the text of user-selected areas of learning is added to the prompt. You can also select whether the activity takes place indoors, outdoors or both and pick the number of activities the LLM will suggest.

Finally, we’ve set a few constraints; the description of each activity should be three or four sentences long and they should be formatted in a certain way. As our prompt has a few distinct sections, we help the LLM distinguish them by using hashtags, as recommended in OpenAI’s documentation.

You can find our prompts in GitHub, and here’s an example of a prompt configured to consider the Mathematics and Understanding the world areas of learning and suggest activity ideas:

[
{
"role": "system",
"content": "You are a very creative and highly educated assistant who loves designing early year education programmes."
},
{
"role": "user",
"content": "###Context###The UK's Early Years Foundation Stage framework recommends that educational programmes must involve activities and experiences for children, as set out under each of the areas of learning described below.\n\n##Areas of Learning###\n##Mathematics##\nDeveloping a strong grounding in number is essential so that all children develop the necessary building blocks to excel mathematically. [...cropped the description for the blog, see our github repo...].\n\n##Understanding the World##\nUnderstanding the world involves guiding children to make sense of their physical world and their community. [...cropped the description for the blog, see our github repo...]\n\n###Instructions###\nI am an early years educator and I am working with children 3-4 years old. I will describe you a situation in the ###Description### section. Please propose conversations and activities I could do with the children to extend their learning.\n\nTypes of activities:\n- Conversations: Asking them questions about the topic\n- Puzzles, games, role play, arts and crafts\n\n###Formatting###\nReturn the proposed activities in the following format:\n\n## Conversations\n### <activity_name>\n\n**Activity description**:<activity_description>\n\n**Areas of learning**:<list_of_areas_of_learning>\n\n### <activity_name>\n\n**Activity description**:<activity_description>\n\n**Areas of learning**:<list_of_areas_of_learning>\n\n## Games and Crafts\n### <activity_name>\n\n**Activity description**:<activity_description>\n\n**Areas of learning**:<list_of_areas_of_learning>\n\n### <activity_name>\n\n**Activity description**:<activity_description>\n\n**Areas of learning**:<list_of_areas_of_learning>\n"
},
{
"role": "user",
"content": "###Requirements for the activities###\n1. Your suggestions must be fun and engaging for the children.\n2. Your suggestions must be novel, inspiring and memorable.\n3. You must suggest topics for conversation with the children and questions to ask them.\n4. Your proposed activities engage children in the following Areas of Learning: ['Understanding the World', 'Mathematics'].\n5. You must generate 10 activities.\n6. Your proposed activities must be played Indoor or Outdoor\n7. Describe the activities in 3-4 sentences."
},
{
"role": "user",
"content": "###Description###\nLet's create activities educating children on how whales breath\n\n###Activities###\n"
}
]

Building a Streamlit app

We built a Streamlit app to showcase our first prototype. Streamlit enables you to create applications in Python quickly; you focus on the logic without worrying about front-end development.

Using Streamlit’s functionality, we added a sidebar and input widgets like sliders, text fields and dropdown menus so that you can modify the prompt to your liking. Moreover, add-ons like the streamlit-option-menu enable you to add pages to your application, which we have used to organise all the prototypes we have been developing.

Deploying the app

Currently, we are hosting the app on Streamlit’s Community Cloud. However, it provides only 1GB of RAM so we might move it to another provider like Hugging Face Spaces.

Read our instructions on GitHub if you want to deploy the app locally with Docker.

Meanwhile, check out the video to see the prototype in action.

What’s next?

OpenAI and Streamlit enabled us to rapidly prototype an LLM application for caregivers and educators to generate personalised activity ideas for young children.

This simple approach of editing a prompt based on user input and then calling OpenAI’s model can be used in other LLM applications where some degree of personalisation is needed.

This is an early, rough-and-ready prototype to start exploring the potential and usefulness of generative AI in the early-years sector. We hope such prototypes can ignite further interest and explorations in this direction, and we’ll spend the next few months gathering feedback and working on other use cases for generative AI for social good.

We’ll keep sharing our demos and learnings in this blog and our code on GitHub.

Get in touch if you would like to find out more or give us feedback!

--

--