OpenAI API 사용해보자

Taemin Jang·2023년 2월 2일
1

OpenAI

목록 보기
1/1
post-thumbnail

OpenAI API

자연어나 코드를 이해해주거나, 생성하는 것 등 관련된 모든 작업에 적용이 가능하다.

사용법

OpenAI API에서 제공하는 튜토리얼을 따라해보면서 기술을 익혀나가보겠습니다.

설정

Node.js를 설치 한 후 아래 OpenAI에서 제공하는 레포지토리를 복제합니다.

git clone https://github.com/openai/openai-quickstart-node.git

API키 추가

비밀 API키는 다른 사람과 공유하거나 브라우저 또는 기타 클라이언트에 코드를 노출하면 안된다.

아래 사이트에서 API 키를 발급 받아보자

API 키 발급 사이트
발급 받은 키는 처음 한 번만 복사할 수 있으므로 주의해야한다.

비밀 API 키를 관리하기 위해서는 .env 환경 변수 파일안에다가 등록 후 사용해야한다.
.env.example을 복사 후 OPENAI_API_KEY='비밀 API 키 입력'

cd openai-quickstart-node
cp .env.example .env

앱 실행

API 키를 등록 했다면 이제 package.json 파일에 있는 모듈들을 설치하고 앱을 실행한다.

npm install
npm run dev

브라우저에서 http://localhost:3000을 열면 애완동물 이름 생성기가 나타난다.

실행하면 나오는 화면

동물을 입력하면 해당 동물에 맞는 이름을 추천해줌

코드 이해

OpenAI에서 사용한 예제는 React, Next를 사용했다.
나는 둘 다 사용해보지 못했지만 그래도 흐름을 파악하면서 이해해보겠다.

npm run dev를 하게되면 Html파일이 따로 없고 index.js를 보니 return문에 html 코드가 짜여있었다. index.js가 실행이 되는 것 같다.

// index.js
import Head from "next/head";
import { useState } from "react";
import styles from "./index.module.css";

export default function Home() {
  const [animalInput, setAnimalInput] = useState("");
  const [result, setResult] = useState();

  async function onSubmit(event) {
    event.preventDefault();
    try {
      const response = await fetch("/api/generate", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ animal: animalInput }),
      });

      const data = await response.json();
      if (response.status !== 200) {
        throw data.error || new Error(`Request failed with status ${response.status}`);
      }

      setResult(data.result);
      setAnimalInput("");
    } catch(error) {
      // Consider implementing your own error handling logic here
      console.error(error);
      alert(error.message);
    }
  }

  return (
    <div>
      <Head>
        <title>OpenAI Quickstart</title>
        <link rel="icon" href="/dog.png" />
      </Head>

      <main className={styles.main}>
        <img src="/dog.png" className={styles.icon} />
        <h3>Name my pet</h3>
        <form onSubmit={onSubmit}>
          <input
            type="text"
            name="animal"
            placeholder="Enter an animal"
            value={animalInput}
            onChange={(e) => setAnimalInput(e.target.value)}
          />
          <input type="submit" value="Generate names" />
        </form>
        <div className={styles.result}>{result}</div>
      </main>
    </div>
  );
}

useState()는 vue에서 data()와 같은 역할을 하는 것 같다.

우선 넘어가고 try문을 보도록 하겠다.

fetch("/api/generate", {})을 보면 /api/generate에 post로 보내는 것 같다.

전에 express로 잠깐 해봤을 때는 route.post("/generate", (req, res))이런식으로 코드를 짠 것 같은데 Next에서는 어떻게 하는지 궁금해서 api 받는 곳을 찾아봤다.

구조를 보면 api/generate.js에 있는 것 같다는 생각이 들었다.
그런데 문뜩 보니 api/generate로 api 호출한 경로가 비슷한 느낌이었다.

// generate.js
import { Configuration, OpenAIApi } from "openai";

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

export default async function (req, res) {
  if (!configuration.apiKey) {
    res.status(500).json({
      error: {
        message: "OpenAI API key not configured, please follow instructions in README.md",
      }
    });
    return;
  }

  const animal = req.body.animal || '';
  if (animal.trim().length === 0) {
    res.status(400).json({
      error: {
        message: "Please enter a valid animal",
      }
    });
    return;
  }

  try {
    const completion = await openai.createCompletion({
      model: "text-davinci-003",
      prompt: generatePrompt(animal),
      temperature: 0.6,
    });
    res.status(200).json({ result: completion.data.choices[0].text });
  } catch(error) {
    // Consider adjusting the error handling logic for your use case
    if (error.response) {
      console.error(error.response.status, error.response.data);
      res.status(error.response.status).json(error.response.data);
    } else {
      console.error(`Error with OpenAI API request: ${error.message}`);
      res.status(500).json({
        error: {
          message: 'An error occurred during your request.',
        }
      });
    }
  }
}

function generatePrompt(animal) {
  const capitalizedAnimal =
    animal[0].toUpperCase() + animal.slice(1).toLowerCase();
  return `Suggest three names for an animal that is a superhero.

Animal: Cat
Names: Captain Sharpclaw, Agent Fluffball, The Incredible Feline
Animal: Dog
Names: Ruff the Protector, Wonder Canine, Sir Barks-a-Lot
Animal: ${capitalizedAnimal}
Names:`;
}

진짜로 generate.js에서 api를 처리하고 있었다!
express로 밖에 경험해보지 못한 나는 이렇게 동작하는 것이 정말 신기했다.

공식 문서를 찾아보니 pages/api/generate.js -> /api/generate로 라우팅을 해준다고 한다.
Next 라우팅에 대해 추가로 보시려면 아래 공식문서에서 보시면 된다.
Next.js 공식 문서

이어서 코드를 보면 index.js의 input에서 입력받은 animalInput을 JSON으로 변환 후 post로 넘겨준다.
generate.js의 req.body.animal로 데이터를 받는다.

위 사진에 있는 코드를 보이는데로 이해해보면
=> text-davinci-003이라는 모델을 사용하며, 받은 데이터를 generatePrompt()로 전달하고, 온도는 0.6으로 설정한 completion을 만든다.

여기서 우리가 알아야하는 단어는 completion, model, prompt, temperature가 있다.

  • model : 자연어나 코드를 이해, 생성하는 것 등 관련된 모든 작업을 해주는 역할
    그 중 대표적으로 GPT-3가 있으며 GPT-3 모델에는 text-davinci-003, text-curie-001, text-babbage-001, text-ada-001이 있다.
  • prompt : 지침과 단어가 주어지면 모델을 통해 지침에 맞는 단어를 반환해주는 역할
  • temperature : 예측을 할 때 모델의 신뢰도를 제어할 수 있는 0과 1 사이의 값으로, 온도를 낮추면 위험이 줄어들고 completion이 더 정확해진다. 온도를 높이면 더욱 다양하고 창의적인 completion을 얻을 수 있다.
  • completion : 모델, 프롬프트에 맞는 하나 이상의 결과를 반환한다.

여기서 사용한 text-davinci-003은 GPT-3에서 가장 유능한 모델이며, 다른 모델이 할 수 있는 모든 작업을 수행할 수 있다.

이제 generatePrompt(animal)을 실행하면 무엇이 반환되는지 알아보자.
generatePrompt()에서 중요한 부분은 return문이다.

return문을 보면 첫번째 줄은 지침이 나와있다.
그 아래는 지침에 대한 예상되는 출력의 예를 추가해준 것이다.
예를 추가해준 이유는 우리가 원하는 답변을 모델이 제공하는데 도움이 되기 때문이다.

만약 예를 다르게 변경하거나, 지침을 변경하면 그에 맞게 답변도 변경되어 제공된다.

return `Suggest three names for an animal that is a superhero.

Animal: Cat
Names: Captain Sharpclaw, Agent Fluffball, The Incredible Feline
Animal: Dog
Names: Ruff the Protector, Wonder Canine, Sir Barks-a-Lot
Animal: ${capitalizedAnimal}
Names:`;

마무리

튜토리얼을 통해 OpenAI API를 사용해보고 코드를 이해해보았습니다.

AI를 다른 어려운 지식을 모르는 상태에서도 쉽게 사용해 볼 수 있다는 것에 놀랐고, 다양한 곳에 적용해보고 싶은 생각이 들었습니다.

아직 사용해보지 않으신 분들은 한 번 해보는 것을 추천드립니다!

운세보는 챗토끼

이번에 openAI API를 사용해서 간단하게 운세봐주는 챗토끼를 개발해봤습니다.
아마 추후에 벨로그에 올릴 것 같아요!
오늘의 운세 한번 받아보고 가세요~!
운세보는 챗토끼

profile
하루하루 공부한 내용 기록하기

0개의 댓글