โœ๏ธ What I Learned/TIL

[TIL] React ์ฑ—๋ด‡ ๋งŒ๋“ค๊ธฐ1 - OpenAI api ์„ธํŒ… ๋ฐ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• (ChatGPT)

Jiwon() 2023. 8. 7. 21:48

๐Ÿ’ก 20230807 TIL : OpenAI api ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์— ์„ธํŒ…ํ•œ ๊ณผ์ • ์ •๋ฆฌ

 

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ ์ฑ—๋ด‡ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜์˜€๋‹ค. ์ฑ—๋ด‡์€ ์›น ์‚ฌ์ดํŠธ ์–ด๋””์—์„œ๋“  ๋ชจ๋‹ฌ์ฐฝ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ชจ๋‹ฌ์—์„œ OpenAI api๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ช…, ๋ณ€์ˆ˜๋ช…์„ ์ง€์–ด๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ์ฑ—๋ด‡์„ ๋งŒ๋“œ๋Š”๊ฒŒ ๋ชฉํ‘œ์ด๋‹ค. OpenAI api๋Š” ์ฒ˜์Œ ์‚ฌ์šฉํ•ด๋ณด๋Š”๊ฑฐ๋ผ, ๊ณต์‹ ๋ฌธ์„œ์™€ ๋ธ”๋กœ๊ทธ๋“ค์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ผ๋‹จ์€ ์–ด์„คํ”„๊ฒŒ ๊ตฌํ˜„์— ์„ฑ๊ณตํ•˜์—ฌ ๊ทธ ๊ณผ์ •์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

์ฐธ๊ณ ๋กœ ์ง„ํ–‰ ์ค‘์ธ ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง„ํ–‰ ์ค‘์ด๋‹ค.

 


1. ์„ธํŒ…

API ์‚ฌ์šฉ ์ „, APIํ‚ค ๋ฐœ๊ธ‰ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ ์„ธํŒ…์„ ์™„๋ฃŒํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

 

1) React ํ”„๋กœ์ ํŠธ์— openai ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

// npm ์„ค์น˜
npm install openai

// yarn ์„ค์น˜
yarn install openai

 

 

2) API Key ์„ธํŒ…

  • OpenAI ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ API Key๋ฅผ .env ํŒŒ์ผ์— `REACT_APP_OPENAI_API_KEY` ๋ณ€์ˆ˜๋ช…์— ์„ค์ •ํ•ด์ค€๋‹ค.
  • .env ํŒŒ์ผ์€ package.json๊ณผ .gitignore ํŒŒ์ผ์ด ์œ„์น˜ํ•˜๋Š” ๋ฃจํŠธ ๊ฒฝ๋กœ์— ์œ„์น˜ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
REACT_APP_OPENAI_API_KEY = "๋ฐœ๊ธ‰๋ฐ›์€ API KEY ์ž…๋ ฅ"

 

OpenAI API ํ‚ค ๋ฐœ๊ธ‰๋ฐ›๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜ ๋ฒจ๋กœ๊ทธ์— ์ž์„ธํžˆ ๋‚˜์™€์žˆ์œผ๋‹ˆ ์ฐธ๊ณ 
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ chatGPT API ํ™œ์šฉ๋ฒ• (+ react, flask)

 

 


2. ์ž‘์„ฑ ์ฝ”๋“œ

์ฝ”๋“œ๋Š” ์šฐ์„  api ํŒŒ์ผ์ธ openaiapi.ts ํŒŒ์ผ๊ณผ, ChatGPT.tsx ์ปดํฌ๋„ŒํŠธ ๋‘ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ž‘์„ฑํ•˜์˜€๋‹ค.

1) openaiapi.ts - api ์„ค์ •ํŒŒ์ผ

import { Configuration, OpenAIApi } from "openai";

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

export const openai = new OpenAIApi(configuration);
  • api ์„ค์ • ์ฝ”๋“œ๋ฅผ ๋”ฐ๋กœ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•  ํ•„์š” ์—†์ด ChatGPT.tsx ์ปดํฌ๋„ŒํŠธ์— ์ž‘์„ฑํ•ด๋„ ๋˜๋Š”๋ฐ, ๊ทธ๋ƒฅ ํ•œ ์ค„์ด๋ผ๋„ ๊น”๋”ํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์–ด์„œ ์ผ๋‹จ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค.

 

2) ChatGPT.tsx ์ปดํฌ๋„ŒํŠธ

import { useState } from "react";
import { openai } from "../../libs/services/openaiapi";
import styled from "styled-components";

const ChatGPT = () => {
  const [prompt, setPrompt] = useState("");
  const [apiRes, setApiRes] = useState<string>("");
  const [loading, setLoading] = useState(false);

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setPrompt(e.currentTarget.value);
  }

  const handlePromptSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setLoading(true);
    try {
      const res = await openai.createCompletion({
        model: "text-davinci-003",
        prompt,
        temperature: 0.8,
        max_tokens: 256,
      })
      console.log(res);
      if (res?.data.choices[0]?.text) {
        setApiRes(res.data.choices[0].text);
      } else {
        setApiRes("์ •์ƒ์ ์œผ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.");
      }
    } catch (err) {
      console.log(err);
      setApiRes("์ •์ƒ์ ์œผ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.")
    }
    setLoading(false);
  }

  return (
    <>
      <ChatBotContainer>
        <div>
          <ChatBotTitle>๋ณ€์ˆ˜๋ช…, ํ•จ์ˆ˜๋ช…์„ ๋ฌผ์–ด๋ณด์„ธ์š”!</ChatBotTitle>
          {apiRes && (
            <ChatBotResContainer>
              <h3>์ฑ—๋ด‡ ๐Ÿค–</h3>
              <pre>{apiRes}</pre>
            </ChatBotResContainer>
          )}
          <form onSubmit={handlePromptSubmit}>
            <ChatBotPromptInput
              type="text"
              value={prompt}
              onChange={onChange}
              placeholder="์งˆ๋ฌธ์„ ์ž…๋ ฅํ•˜์„ธ์š”!"
            />
            <button
              disabled={loading}
            >{loading ? "๋‹ต๋ณ€ ์ƒ์„ฑ ์ค‘.." : "์ „์†ก"}
            </button>
          </form>
        </div>
      </ChatBotContainer>
    </>
  );
};

export default ChatGPT;

const ChatBotContainer = styled.div`
  width: 70%;
  margin: 10px;
  padding: 10px;
  border: 1px solid gray;
  border-radius: 10px;
`

const ChatBotResContainer = styled.div`
  padding: 10px;
  margin: 10px;
  border: 1px solid gray;
  border-radius: 10px;
`

const ChatBotTitle = styled.h1`
  font-size: 18px;
  text-align: center;
  margin: 20px;
`

const ChatBotPromptInput = styled.input`
  width: 80%;
  margin: 10px;
  padding: 10px;
`;

 

 


3. ๊ฒฐ๊ณผ

ํ•จ์ˆ˜๋ช…์„ ์ง€์–ด๋‹ฌ๋ผ๊ณ  ํ–ˆ๋Š”๋ฐ ํ•จ์ˆ˜ ์ „์ฒด๋ฅผ ๋งŒ๋“ค์–ด์คฌ๋‹ค..ใ…Žใ…Ž(๋ฐ”๋ณด๊ฐ™์€ ๋…€์„) CSS๋„ ์—‰๋ง์ด๊ณ  ๋‹ต๋ณ€๋„ ์—‰๋ง์ด์ง€๋งŒ ์ผ๋‹จ ๊ฒ€์ƒ‰ํ•˜๋ฉด ๊ทธ์— ๋งž๋Š” ๋‹ต๋ณ€์ด ๋‚˜์˜ค๋Š”๊ฒŒ ์‹ ๊ธฐํ–ˆ๋‹ค!

 

 


4. ํ•ด์•ผ ํ•  ์ผ

  • ์šฐ์ธก ํ•˜๋‹จ์— ์ฑ—๋ด‡ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ
  • ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ผ์ • ํฌ๊ธฐ์˜ ์ฑ—๋ด‡ ๋ชจ๋‹ฌ์ด ๋‚˜ํƒ€๋‚˜๋„๋ก ๋งŒ๋“ค๊ธฐ
  • ์œ ์ €๊ฐ€ ๋‚จ๊ธด ์งˆ๋ฌธ, ์ฑ—GPT๊ฐ€ ๋‚จ๊ธด ๋‹ต๋ณ€์„ ์ฑ„ํŒ…์ฐฝ์ฒ˜๋Ÿผ ๋กœ๊ทธ ๋‚จ๊ธฐ๊ธฐ
    • ์ง€๊ธˆ์€ ์งˆ๋ฌธ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒˆ๋กœ submitํ•˜๋ฉด ๊ธฐ์กด ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์ด ๋‚จ์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€๋งŒ ๋ณด์ž„

 

 


์ฐธ๊ณ  ์‚ฌ์ดํŠธ

How to use OpenAI with React

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ chatGPT API ํ™œ์šฉ๋ฒ• (+ react, flask)

ChatGPT API ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ๋ฐ ํ”„๋กฌํ”„ํŠธ ์ตœ์ ํ™” ๋น„๋ฒ• - ์—ญํ• (Role), ์˜จ๋„(temperature), ํ…์ŠคํŠธ์˜ ์ตœ๋Œ€ ๊ธธ์ด(max_tokens) ํ™œ์šฉ๋ฐฉ๋ฒ•