[WEB] 프론트엔드

GPT API 사용해서 서비스 만들어보기

[FE] Lighthouse 2024. 7. 13. 14:44

들어가며

오늘은 GPT API를 사용해 서비스를 만드는 과정을 남겨보겠습니다.

 

요즘이라고 하기에는 GPT가 화제가 되기 시작한지가 벌써 3년이 넘었지만 가장 핫하고 뜨거운 주제는 GPT, AI가 아닐까 싶습니다. 실무 레벨에서는 이젠 GPT를 멀리 하는 것이 어려운 세상이 됐습니다. 저도 코딩을 할 때, 글의 초안이 필요할 때 GPT에게 부탁하고는 합니다.

 

최근 어떤 프론트엔드 개발자분께서 원영적 사고라는 아이디어로 GPT API를 활용해 재미있는 서비스를 만들었더라구요. 저도 GPT API가 궁금하기도 했고 어떻게 활용할 수 있을까 생각을 하던 중 가장 간단한 서비스를 만들어보자! 하며 무엇인가를 만들어봤습니다.

 

간단하게 나의 상황과, 기분, MBTI를 클릭하면 GPT가 명언과 함께 조언을 보내주는 서비스 입니다. 궁금하신 분들은 한번 클릭해주세요~

바로가기

 

 

본론으로 돌아와 GPT REST API를 사용하는 과정을 살펴봅시다.

 

Open AI 로그인

요즘 Chat GPT 안써보신 분은 드물것 같습니다. 아래 Open AI 플랫폼 사이트에서 로그인 (계정이 없으면 회원가입) 해주세요. 

https://platform.openai.com/docs/overview

 

Chat GPT는 Rest API를 통해 여러 모델에 접근할 수 있도록 다양한 모델을 제공하고 있습니다. 가장 최근에 나온 버전인 4o 버전도 활용할 수 있습니다.

 

GPT API는 사용하는 모델과 토큰 수에 따라서 가격 정책이 달라집니다. 그럼으로 가장 효율적으로 GPT를 사용하기 위해선 최적화된 프롬프트와 올바른 파인튜닝 이라고 할 수 있겠습니다.

해당 포스팅에서는 프롬프트와 파인튜닝에 대해 다루지 않습니다.

 

API 키 발급하기

우측 상단의 Dashboard 탭으로 접근해 좌측 메뉴의 가장 아래에 있는 API Keys 메뉴로 이동합니다. GPT의 Rest API를 사용하려면 API Key 가 필요합니다. 해당 키는 처음 만들때만 확인할 수 있으니 처음 만들고 발급받은 키는 소중하게 보관해주세요. 키는 절대 유출되면 안됩니다! 해당 키를 통해서 과금이 됨으로 보안에 신경써주세요.

 

Billing, Limit 설정하기

우측 상단의 GNB에서 셋팅 아이콘을 클릭해주세요. 그리고 계정의 빌링 시스템을 활용해 크래딧을 충전해주세요. 크래딧을 충전하고 리밋을 설정해야 API를 정상적으로 사용하실 수 있습니다. 저는 간단하게 사용해보고 싶어서 5불을 충전했습니다. 몇일 테스트를 하다보니 0.03달러를 사용했습니다.

 

리밋을 설정해봅시다. 리밋 시스템을 통해 달별 예산 한도를 설정할 수 있습니다. 저는 혹시 모르는 상황을 대비해 2달라로 리밋을 걸어놨습니다.

 

개발 시작하기

API 키를 발급받고 크래딧을 충전했고 리밋을 설정했다면 초기 준비는 끝났습니다. 발급받은 API 키를 소중하게 보관하고 계신가요? 해당 키는 Open AI의 Rest API를 사용할 때 HTTPS 헤더의 Authorization에 넣어줘야 합니다.

 

개발 환경

저는 너무나 간단한 토이 프로젝트 서비스에서 서버까지 만들고 싶지는 않았습니다. 그래서 Next.js의 서버단을 활용하는 것으로 접근했고 호스팅은 간단하게 Vercel을 이용하기로 결정했습니다.

 

개발 과정

개발 과정은 간단합니다. fetch 함수를 활용해 Open AI 서버에 요청을 보내면 됩니다. API의 형태를 알아봅시다.

const response = await fetch(`https://api.openai.com/v1/chat/completions`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.OPEN_AI_SECRET_KEY}`,
  },
  body: JSON.stringify({
    model: "gpt-3.5-turbo",
    messages: [
      {
        role: "user",
        content: prompt,
      },
    ],
    temperature: 0.8,
    max_tokens: 250,
  }),
});

 

앤드포인트와 메서드는 위 코드를 참고해주세요. body에는 사용할 model, GPT의 창의력 수준인 temperature(0 ~ 1), 응답 받을 최대 토큰 수를 정해줄 수 있습니다. message 필드를 사용해서는 질의할 prompt를 보내줄 수 있습니다. 아래 공식 문서를 참고하시면 더 정확한 정보를 확인하실 수 있습니다.

https://platform.openai.com/docs/api-reference/introduction

 

이제 요청을 보내봅시다! 그런데 그 전에 생각해야 할 내용이 있습니다. API 키는 소중하게 다뤄야 한다고 했습니다. 하지만 브라우저 단에서 API 키를 헤더에 넣어서 보내면 네트워크 탭에서 소중한 API Key가 노출되고 맙니다.

 

이를 방지하기 위해 API키를 환경 변수에 담아주고 Open AI 서버에 요청은 Next.js 백그라운드 서버에서 보내기로 합니다. 그림으로 표현하면 다음과 같습니다.

브라우저에서는 사용자에게 간단한 인터렉션을 입력받고 Next 서버로 요청을 보냅니다. Next 서버에서는 API Key를 헤더에 장착하고 OpenAI 서버에 요청을 보냅니다. Next 서버에서 응답을 받고 그대로 브라우저에 응답을 합니다.

 

위 아키텍처를 활용하면 API 키를 브라우저에 노출하지 않고 안전하게 요청을 보낼 수 있습니다. 그럼 Next.js에서 서버를 이용해봅시다!

 

app 라우터 하위에 api디렉토리를 만들어줍니다. 그리고 브라우저에서 요청을 보낼 라우트로 폴더 구조를 잡아준 뒤 route.ts 폴더를 만들어줍니다.

import { CreateEnvelopeDTO } from "@/shared/type/create.dto";
import { NextResponse, NextRequest } from "next/server";

const BASE_URL = process.env.OPEN_AI_BASE_URL;

export const POST = async (req: NextRequest) => {
  try {
    const reqBody: CreateEnvelopeDTO = await req.json();
    const prompt = `나는 ${reqBody.feeling}해. 오늘은 ${reqBody.situation}이 있어. 나의 MBTI는 ${reqBody.mbti}야. ${reqBody.situation}과 관련된 실존한 유명한 위인의 명언과 너의 조언 한 문장을 내 MBTI 성향을 고려해서 보내줘.`;
    const response = await fetch(`${BASE_URL}v1/chat/completions`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.OPEN_AI_SECRET_KEY}`,
      },
      body: JSON.stringify({
        model: "gpt-3.5-turbo",
        messages: [
          {
            role: "user",
            content: prompt,
          },
        ],
        temperature: 0.8,
        max_tokens: 250,
      }),
    });

    const responseData = await response.json();
    const message = responseData.choices[0].message.content;

    return NextResponse.json({ envelope: message });
  } catch (error) {
    return NextResponse.json({ error: "An error occurred" });
  }
};

 

저는 브라우저에서 사용자에게 입력받은 값을 프롬프트로 활용하고 싶었습니다. 하여 request 파라미터의 body에서 데이터를 꺼내 프롬프트를 만들었습니다. API 키와 BaseURL은 env파일에 숨겨놨고 해당 환경 변수에 접근해서 변수에 담아줬습니다. 그리고 그대로 OpenAI 서버에 요청을 보내줍니다.

 

브라우저에서 요청하는 API 코드는 다음과 같습니다.

export async function postEnvelope(params: CreateEnvelopeDTO) {
  const { feeling, situation, mbti } = params;
  const res = await fetch("/api/envelope", {
    method: "post",
    body: JSON.stringify({
      feeling,
      situation,
      mbti,
    }),
  });
  const envelope: EnvelopeRes = await res.json();

  return envelope;
}

 

브라우저의 네트워크 탭을 살펴봅시다. Next서버로 요청을 보내고 응답을 받았습니다. API 키 또한 브라우저에서 노출하지 않고 있습니다.

 

이렇게 응답을 받아서 서비스를 구성하시면 됩니다. 정말 간단하죠?

 

마무리하며

결론은 돈만 내면 쉽게 사용할 수 있습니다. 요즘 GPT를 사용해 어떤 서비스를 만들수 있을까 하는 고민을 계속 해보고 있습니다. 대 AI의 시대, LLM을 만들지 못한다면 LLM을 활용해 여러 대중들이 유용하게 사용할 수 있는 서비스를 만들어보고 싶습니다.