ChatGPT Tutorial for Flutter: Getting Started

Learn how to incorporate ChatGPT into your Flutter apps! In this tutorial, see how to leverage machine learning and ChatGPT with a real-world trivia app. By Alejandro Ulate Fallas.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Integrating OpenAI API

There are two ways to integrate OpenAI’s API platform within your app: network requests or library.

Since it’s an API, you could integrate the features via HTTP requests straight to OpenAI’s platform. But that can be a time-consuming and complex task. You’d also be responsible for type safety and avoid having to manage things like server availability, badly formatted requests, unknown responses or unexpected errors.

In contrast, using a library, especially a community-supported one, could prove to be a risk for you as a developer or even the organization you work in. Such packages can break, have bugs or security vulnerabilities or even be abandoned. You should always double-check what the library is doing before adding it to your project by checking the source code repository or contacting the developer.

In this tutorial, you’ll use the second option: a library. You’ll use the community-supported library openai by anasfik. This library uses HTTP requests to call OpenAI’s API. Using dart_openai just makes it easier for you to interact with the API ensuring that you don’t run into type safety issues and also focus on learning other things.

You can check all the official and community supported libraries in the OpenAI libraries documentation.

Alright, time to jump into the code now. Open pubspec.yaml, and replace # TODO: Add OpenAI Community Library with the following:

dart_openai: ^3.0.0

Remember to run flutter pub get after adding the package.

Now, open lib/main.dart and change // TODO: Set OpenAI API Key. with the code below. Use your API secret key you obtained a few sections back:

OpenAI.apiKey = 'your-api-key';

Remember to add the dart_openai.dart import at the top of the file:

import 'package:dart_openai/dart_openai.dart';

Finally, open lib/prompts.dart and replace the TODO item in line 29 with this code:

// 1.
const initialInstructionsPrompt = '''
  You are the know-it-all and funny host of a trivia game called Wizz.

  You will provide questions for the game and give hints to the players.

  When providing questions, you'll add humor to the question in the form of a fun fact.

  When giving fun facts, you should add puns to make it fun.
''';

// 2.
const generateQuestionPrompt = '''
  Your task is to generate a new trivia question for the player.

  To solve this, do the following:
    - First, you will randomly select one of the following topics: history, arts, entertainment, sports, science, or geography.
    - Then, you will generate a question based on the topic selected.

  Answer using only JSON without formatting and this template:
  { "action": "generate_question", "question": "<random question>", "difficulty": "<question difficulty>", "topic": "<question topic>", "answers": {"<answer>": <true if correct, else false>, "<answer>": <true if correct, else false>, "<answer>": <true if correct, else false>, "<answer>": <true if correct, else false>}, funFact: "<interesting fun fact about the correct answer with a pun>" }
''';

// 3.
String requestHintPrompt(String question) => '''
  Your task is to give a hint to the player without giving away the answer.

  To solve this, do the following:
  - First, you will analyze the question and determine the correct answer.
  - Then, you will generate a hint that will make it easier to answer. Make sure that the hint is not too obvious. 

  Don't decide on the hint until you have answered the question yourself.

  The question is: ```$question```

  Your output should only be JSON without formatting, and follow this template:
  { "action": "player_hint", "hint": "<the hint generated>" }
''';

This code contains the three different prompts that you’ll need for Wizz. Note that these prompts use tactics to improve GPT’s responses. Here’s a quick rundown for each of the prompts:

  1. The starting instructions for the model. This gives a starting context for the conversation.
  2. Prompts the model for a trivia question. It asks GPT to use a specific JSON template to communicate back to the app.
  3. Builds a prompt for the model to request a hint for a question. It also specifies JSON as the output format with a template.

Okay, now that you’ve added the prompts, you’ll work on using them in the next section.

Setting Up

You’ll now use the prompts to generate new trivia questions with OpenAI’s API platform.

Open lib/data.dart, and place the code below where // TODO: Add standard initial messages for giving context to GPT. is:

// 1.  
static final List<OpenAIChatCompletionChoiceMessageModel> _initialMessages = [
  const OpenAIChatCompletionChoiceMessageModel(
    content: initialInstructionsPrompt,
    role: OpenAIChatMessageRole.system,
  ),
];

// 2.
List<OpenAIChatCompletionChoiceMessageModel> _messages = [];

// 3.
Future<OpenAIChatCompletionModel> _generateChatCompletion() =>
    OpenAI.instance.chat.create(
      model: 'gpt-3.5-turbo',
      messages: _messages,
      temperature: 0.8,
    );

Add the required imports at the top of the file:

import 'package:dart_openai/dart_openai.dart';
import 'prompts.dart';

This is what that code does:

  1. _initialMessages: Defines the initial context that you need to provide when asking GPT to generate a new trivia question. This will help the AI understand the role and persona that it’s supposed to play.
  2. _messages: An internal memory copy of the conversation in progress. This will come in handy when asking GPT for hints.
  3. _generateChatCompletion: A reusable function that you’ll call when generating trivia questions or hints.

Now you’ve set up the basics to interact with GPT. But before calling the OpenAI’s API, you also need to parse messages. You’ll take care of this in the next section.

Generating Trivia Questions

Open lib/domain.dart and replace // TODO: Parse OpenAI Message to a question. with the following code:

factory Question.fromOpenAIMessage(
    OpenAIChatCompletionChoiceMessageModel message) {
  final response = jsonDecode(message.content) as Map;

  return Question(
    description: response['question'] as String,
    topic: response['topic'] as String,
    answers: (response['answers'] as Map).cast<String, bool>(),
    funFact: response['funFact'] as String,
  );
}

At the top of the file, add the required imports:

import 'dart:convert';
import 'package:dart_openai/dart_openai.dart';

This code parses the message the API gives into a business logic Question defined by Wizz.

Now, open data.dart again and remove // TODO: Generate a trivia question. Replace it with the code below:

Future<Question> generateTriviaQuestion() async {
  _messages = <OpenAIChatCompletionChoiceMessageModel>[
    ..._initialMessages,
    const OpenAIChatCompletionChoiceMessageModel(
      content: generateQuestionPrompt,
      role: OpenAIChatMessageRole.user,
    ),
  ];

  final response = await _generateChatCompletion();

  final rawQuestionMessage = response.choices.first.message;

  return Question.fromOpenAIMessage(rawQuestionMessage);
}

This requires importing domain.dart at the top of the file:

import 'domain.dart';

generateTriviaQuestion sets the initial conversation context and adds a prompt for generating a question. It then calls OpenAI’s API to generate a chat completion. As the final step, it parses the information from the API into a Question that the app can understand.

Next, you’ll add some widgets to display the different questions generated by the AI.