[Flutter] OpenAI API 연동하기

서로·2024년 3월 29일
2

Flutter

목록 보기
2/2
post-thumbnail

서론

AI 심리상담 모바일 앱을 개발하기 위해 OpenAI API를 연동하였다.
플러터 앱에 OpenAI API를 어떻게 연동하는지 그 과정을 기록하고 공유하려 한다!

➊ dart_openai 라이브러리 설치

https://pub.dev/packages/dart_openai

OpenAI 관련 라이브러리 중 가장 사용자가 많은 dart_openai를 설치하였다.
아래 명령어를 터미널에 입력하여 라이브러리를 설치한다.

$ flutter pub add dart_openai

➋ OpenAI Key 발급 받기

https://platform.openai.com/api-keys

위의 경로로 들어가 OpenAI 키를 발급받는다.
(아마 카드 등록이 필요할 수도 있다.
필자는 카드 등록만 하려고 했다가 11달러가 결제돼서 울었다.)

키는 처음 발급받을 때를 제외하고는 확인할 수 없으니 미리 어딘가에 복사해두도록 하자!
또한 키는 보안상 유출되지 않도록 조심해야 한다.
(깃허브에 잘못 올리지 않도록 주의한다!)

➌ envied 라이브러리 설치

dart_openai 공식 문서를 살펴보면 비밀 키를 .env 파일에 보관하고
앱 실행 중에 .env 파일로부터 키를 불러오기 위해 envied 라이브러리를 설치하라고 한다.
그래서 envied 공식 문서를 읽어보니 아래 3가지 라이브러리를 설치하라고 한다.
시키는 대로 해보자!

$ flutter pub add envied
$ flutter pub add --dev envied_generator
$ flutter pub add --dev build_runner

➍ OpenAI 키를 env 파일에 저장하기

라이브러리를 다 설치했으면 프로젝트 폴더 안에 .env 파일을 생성한다.

// .env
OPEN_AI_API_KEY=<REPLACE WITH YOUR API KEY>

위와 같은 형식으로 .env 파일 안에 OpenAI 키를 적는다.

그 다음 'lib/env' 경로에 다음과 같은 내용의 파일을 생성한다.

// lib/env/env.dart
import 'package:envied/envied.dart';
part 'env.g.dart';

@Envied(path: ".env")
abstract class Env {
  @EnviedField(varName: 'OPEN_AI_API_KEY') // the .env variable.
  static const apiKey = _Env.apiKey;
}

총 파일을 2개 생성했으면 아래 명령어를 실행한다.

$ dart run build_runner build

위의 명령어를 통해 'lib/env' 경로에 'env.g.dart' 파일이 생성되었을 것이다.

위 파일에는 .env에서 불러온 비밀 키가 포함되어 있으니 .gitignore에 올려 유출되지 않도록 조심하자!

암튼 위 파일이 생겼으면 이제 진짜 dart_openai를 연동할 준비가 됐다!

➎ OpenAI 모델 생성

OpenAI 연동을 위한 파일 및 클래스를 새로 생성해주었다.
먼저 파일의 상단에 아래 코드를 추가하여 임포트한다.

import 'package:dart_openai/dart_openai.dart';
import 'package:emotion_chat/env/env.dart';

그 다음 모델을 생성하는 데 필요한 OpenAI 키를 불러온다.

OpenAI.apiKey = Env.apiKey;

모델에게 대화의 방향성을 알려주는 메세지를 작성해야 한다.
이러한 메시지는 role: OpenAIChatMessageRole.system 으로 설정해주어야 한다.

필자는 심리 상담 앱을 개발하고 있기 때문에
"You're a psychological consultant."라는 메시지를 작성했다.
(사실 한글로 작성해도 무방하다.)
(또한 프롬프트 튜닝을 위해 여러 줄로 작성해도 된다.)

// Assistant에게 대화의 방향성을 알려주는 메시지
final systemMessage = OpenAIChatCompletionChoiceMessageModel(
  content: [
    OpenAIChatCompletionChoiceMessageContentItemModel.text(
      "You're a psychological consultant.",
    ),
  ],
  role: OpenAIChatMessageRole.system,
);

그 다음 사용자가 모델에게 전송할 메시지를 작성한다.
이러한 메시지는 role: OpenAIChatMessageRole.user 으로 설정해주어야 한다.

아래의 "Hi I'm so sad :(" 부분을 지우고 원하는 메시지로 교체한다.

// 사용자가 보내는 메시지
final userMessage = OpenAIChatCompletionChoiceMessageModel(
  content: [
    OpenAIChatCompletionChoiceMessageContentItemModel.text(
      "Hi I'm so sad :(",
    ),
  ],
  role: OpenAIChatMessageRole.user,
);

final requestMessages = [
  systemMessage,
  userMessage,
];

모델에게 방향성을 제시하는 메시지와 사용자가 보내는 메시지를 묶어 requestMessages 배열 안에 담았다.
이제 모델을 생성하여 requestMessages를 전송한다.

현재는 'gpt-3.5-turbo' 모델을 생성했고 maxTokens는 250으로 했지만 상황에 따라 자유자재로 변경해도 된다.

OpenAIChatCompletionModel chatCompletion =
  await OpenAI.instance.chat.create(
    model: 'gpt-3.5-turbo',
    messages: requestMessages,
    maxTokens: 250,
  );

String message =
  chatCompletion.choices.first.message.content![0].text.toString();

message를 출력하면 모델이 생성한 답변을 볼 수 있다.

필자는 모델이 생성한 답변을 채팅창에 표시하도록 하였다.

연동 성공!

⬇️ 전체 코드 한눈에 보기

import 'package:dart_openai/dart_openai.dart';
import 'package:emotion_chat/env/env.dart';

class OpenAIService {
  Future<String> createModel(String sendMessage) async {
    OpenAI.apiKey = Env.apiKey;
    OpenAI.requestsTimeOut = const Duration(seconds: 60); // 시간 제한 늘림

    // Assistant에게 대화의 방향성을 알려주는 메시지
    final systemMessage = OpenAIChatCompletionChoiceMessageModel(
      content: [
        OpenAIChatCompletionChoiceMessageContentItemModel.text(
          "You're a psychological consultant.",
        ),
      ],
      role: OpenAIChatMessageRole.system,
    );

    // 사용자가 보내는 메시지
    final userMessage = OpenAIChatCompletionChoiceMessageModel(
      content: [
        OpenAIChatCompletionChoiceMessageContentItemModel.text(
          sendMessage,
        ),
      ],
      role: OpenAIChatMessageRole.user,
    );

    final requestMessages = [
      systemMessage,
      userMessage,
    ];

    OpenAIChatCompletionModel chatCompletion =
        await OpenAI.instance.chat.create(
      model: 'gpt-3.5-turbo',
      messages: requestMessages,
      maxTokens: 250,
    );

    String message =
        chatCompletion.choices.first.message.content![0].text.toString();
    return message;
  }
}

-끝-

잘못된 정보, 오탈자를 발견하면 편하게 댓글로 말씀해주시면 감사하겠습니다!

profile
완벽주의가 아닌 꾸준한 대충주의 🐢

0개의 댓글