본문 바로가기
꿀팁

Open Ai api 사용해서 앱/웹 만들기 (Flutter)

by zho 2023. 6. 6.

오늘은 Flutter에서 Open AI api를 이용해서 앱/웹 만드는 법을 소개해보려고 합니다! 매우 쉬우니 따라 해보고 조금만 바꾼다면 각자 자신만의 ai서비스를 만들 수 있을 것입니다. 또한 Open Ai api는 현재 무료로도(제한된 양) 사용이 가능하기 때문에 우리가 서비스를 만들 때 마음껏 써볼 수 있습니다. 

 

Flutter 사용 설정이 되어있다는 가정하에 설명을 진행하도록 하겠습니다. Flutter 설치 방법을 모르겠다면? 아래 글을 참고하시면 됩니다! https://zhocoding.tistory.com/129

 

Mac m1 Flutter 개발세팅하는법(+ flutter doctor 에러 해결법)

Flutter 개발을 위해 설정해야 할 것들은 다음과 같다. 처음 봤을 때는 복잡하다고 생각할 수 있겠지만 정말 간단하니 같이 설치해 보도록 하자 1. Flutter 설치 https://docs.flutter.dev/get-started/install/macos

zhocoding.tistory.com

 

1. 첫번째로 해야 하는 것은 Open ai api key를 발급받는 것입니다. 아래 사이트에 접속에 로그인하면 아래 이미지처럼 나올 텐데, Create new secret key를 눌러 발급받으면 됩니다. 단 한번 발급받고 창을 닫으면 key를 다시 확인할 수 없기 때문에 발급받고 자신만 확인할 수 있는 메모장에 저장해 놓는 것을 추천합니다.

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

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

위 사진에서 Create new secret key를 선택하여 발급받는다

 

2. 이제 Open ai api key를 발급받았으니 Flutter 개발 환경에서 어떻게 사용하는지 알아봅시다.

Future<String> getGPTanswer(String prompt) async {
  String generatedText = "";

  final response = await http.post(
    Uri.parse(apiUrl),
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $openaikey'
    },
    body: jsonEncode({
      //"model": "text-davinci-003",
      'prompt': prompt,
      'max_tokens': 3000,
      'temperature': 0,
      'top_p': 1,
      // 'frequency_penalty': 0,
      // 'presence_penalty': 0
    }),
  );

  if (response.statusCode == 200) {
    var data = jsonDecode(utf8.decode(response.bodyBytes));
    generatedText = data['choices'][0]['text'];
  } else {
    print(response.body);
    generatedText = "Error: ${response.body}";
  }

  return generatedText;
}

위 코드는 Open API에게 요청값을 jsonEncode형식으로 보내서 응답을 받는 형식입니다. 여기서 유의해야하고 개인적으로 수정해야 하는 부분은 apiUrl, openaikey이다. apiUrl은 아래와 같이 작성해도 무방합니다. openaikey는 step1에서 발급받았던 자신만의 key값을 넣어주면 됩니다.

const apiUrl = 'https://api.openai.com/v1/engines/text-davinci-003/completions';

 

여기서 TIP : apikey를 변수에 저장하고 만약 github에 commit하게 된다면 apikey가 노출되었다고 하면서 만료가 되게 됩니다. 따라서 apikey를 잘 처리해야 하는데 저는 .env file을 생성하여 처리하는 방법을 이용했습니다.

 

class _ResultPageState extends State<ResultPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<String>(
          future: getGPTanswer(widget.prompt),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Text(
                'Erroddr: ${snapshot.error}',
                style: const TextStyle(color: Colors.black),
              );
            } else {
              return SingleChildScrollView(
                child: Text(
                  '${snapshot.data}',
                  style: const TextStyle(color: Colors.black),
                ),
              );
            }
          },
        ),
      ),
    );
  }
}

위 코드는 결과값을 return해주는 즉 보여주는 결과 페이지입니다. 에러가 있다면 에러메시지를 출력하고 없다면 이전에 작성했던 getGPTanswer함수에서 가져온 gpt의 응답을 가져옵니다.

 

이제 답변을 생성하고 생성된 답변을 출력하는 세팅을 모두 마쳤습니다! 이제 프롬프트 즉 GPT에게 물어볼 형식을 만들고 어떻게 값을 전달하는지 예시를 통해 보여드리겠습니다.

 

                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) => ResultPage(prompt),
                    ),
                  );

저는 Navigator을 이용해 prompt값을 결과 페이지에 전달하도록 했습니다.

정리하자면 prompt값은 결과 페이지에 전달이 되고 작성했던 아래 코드를 통해 응답을 요청하는 방식입니다.

future: getGPTanswer(widget.prompt),

prompt값은 String으로 선언을 하면 됩니다.

String prompt = "$inputText으로 여행을 갈건데 여행지 추천해줘 두명이서 갈거야";

 

$inputText에 만약 대전이 저장되어있으면 "대전으로 여행을 갈 건데 여행지 추천해 줘 두 명이서 갈 거야"로 전달되는 것입니다. 

이렇게 prompt를 자신이 원하는대로 설정할 수 있고 입력받고 싶은 부분은 $inputText처럼 선언하여 직접 입력받을 수도 있습니다.

 

위 예시를 응용해 만든 Flutter Code입니다.

https://github.com/zhoho/FlutterApp_usingOpenAI

 

GitHub - zhoho/FlutterApp_usingOpenAI

Contribute to zhoho/FlutterApp_usingOpenAI development by creating an account on GitHub.

github.com

 

728x90