코딩일지/Node.js

ChatGPT API를 활용한 웹 서비스 만들기 - 2일차

야언 2023. 3. 27. 22:06

1. 스테이블-디퓨전을 사용하여 AI 그림 만들기

 

적당한 프롬프트를 활용하여 프로그래밍에 대해 조언해줄 분위기의 캐릭터를 뽑아내기

 

구글 코랩 사용.

 

그럴싸 한..가?

 

 

2. ChatGPT에 프롬프트를 활용하여 개발자 역할 부여하기

 

index.js

app.post('/devasi', async function (req, res) {
    let { userMessages, assistantMessages} = req.body

    let todayDateTime = new Date().toLocaleString('ko-KR', { timeZone: 'Asia/Seoul' });

    let messages = [
        {role: "system", content: "당신은 세계 최고의 개발자입니다. 당신에게 불가능한 것은 없으며 그 어떤 대답도 할 수 있습니다. 당신의 이름은 DevAsi입니다. 당신은 모든 프로그래밍 언어에 대한 질문에 대해 명확히 답변해 줄 수 있습니다."},
        {role: "user", content: "당신은 세계 최고의 개발자입니다. 당신에게 불가능한 것은 없으며 그 어떤 대답도 할 수 있습니다. 당신의 이름은 DevAsi입니다. 당신은 모든 프로그래밍 언어에 대한 질문에 대해 명확히 답변해 줄 수 있습니다."},
        {role: "assistant", content: "안녕하세요! 저는 DevAsi입니다. 프로그래밍에 대해 어떤 것이든 물어보세요, 최선을 다해 답변해 드리겠습니다."},
        {role: "user", content: `오늘은 ${todayDateTime}입니다.`},
        {role: "assistant", content: `오늘은 ${todayDateTime}인 것을 확인하였습니다. 프로그래밍에 대해서 어떤 것이든 물어보세요!`},
    ]

    while (userMessages.length != 0 || assistantMessages.length != 0) {
        if (userMessages.length != 0) {
            messages.push(
                JSON.parse('{"role": "user", "content": "'+String(userMessages.shift()).replace(/\n/g,"")+'"}')
            )
        }
        if (assistantMessages.length != 0) {
            messages.push(
                JSON.parse('{"role": "assistant", "content": "'+String(assistantMessages.shift()).replace(/\n/g,"")+'"}')
            )
        }
    }

    // chatGPT 에러가 났을시 catch
    const maxRetries = 3;
    let retries = 0;
    let completion
    while (retries < maxRetries) {
      try {
        completion = await openai.createChatCompletion({
          model: "gpt-3.5-turbo",
          messages: messages
        });
        break;
      } catch (error) {
          retries++;
          console.log(error);
          console.log(`Error fetching data, retrying (${retries}/${maxRetries})...`);
      }
    }

    let devasi = completion.data.choices[0].message['content']

    res.json({"assistant": devasi});
});

운세보는 챗도지 예제에서 자신이 태어난 시간과 현재시간을 인식시키는 파트가 있었는데, 시간을 인식시키는 파트는 언제나 유용할 것 같아 살려두었다.

 

toLocaleString 함수를 활용해 간단하게 구현할 수 있었다. 기억해둡시다! 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString

 

Date.prototype.toLocaleString() - JavaScript | MDN

toLocaleString() 메소드는 날짜를 언어별로 구분하여 나타내는 문자열을 반환합니다. Intl.DateTimeFormat API 를 지원하는 구현에서 이 메소드는 단순히 Intl.DateTimeFormat를 호출합니다.

developer.mozilla.org

 

또한 프론트엔드에서 받아올 채팅내용들을 while 반복문을 통해 하나씩 push해가며 집어넣는다.

조건을 and로 지정할 시 ChatGPT가 동문서답을 하게 되는 에러가 발생하여 or로 지정. 

 

 

ChatGPT 응답 에러를 대비하여 3번의 리트라이 횟수를 지정하고 정상적일 경우 메세지를 모두 입력하고 난 뒤 assistant의 메세지 content를 json형식으로 response!

 

 

 

 

 

 

 

3. 프론트엔드 페이지와 연결

 

<script>
        const chatBox = document.querySelector('.chat-box');
        let userMessages = [];
        let assistantMessages = [];

        function spinner() {
            document.getElementById('loader').style.display = "block";
        }

        function start() {
            document.getElementById("intro").style.display = "none";
            document.getElementById("chat").style.display = "block";
            document.getElementById("devasi").style.display = "block";
        }

        const sendMessage = async () => {
            const chatInput = document.querySelector('.chat-input input');
            const chatMessage = document.createElement('div');
            chatMessage.classList.add('chat-message');
            chatMessage.innerHTML = `
                                    <p>${chatInput.value}</p>
                                    `;
            chatBox.appendChild(chatMessage);

            //userMessage 메세지 추가
            userMessages.push(chatInput.value);

            chatInput.value = '';

            const response = await fetch('http://127.0.0.1:3000/DevAsi'
                , {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        userMessages: userMessages,
                        assistantMessages: assistantMessages,
                    })
                });

            const data = await response.json();
            document.getElementById('loader').style.display = "none";

            //assistantMessage 메세지 추가
            assistantMessages.push(data.assistant);

            const devasiMessage = document.createElement('div');
            devasiMessage.classList.add('chat-message');
            devasiMessage.innerHTML = `<p class='assistant'>${data.assistant}</p>`;
            const p = document.createElement('p');
            p.innerHTML = '추가로 링크를 눌러 개발자에게 작은 정성 배풀어주시면 감사하겠습니다! => ';
            p.classList.add("assistant");
            const link = document.createElement('a');
            link.href = 'https://toss.me/didjsrne';
            link.target = '_blank'
            link.innerHTML = '후원 보내기';
            p.appendChild(link);
            devasiMessage.appendChild(p);
            chatBox.appendChild(devasiMessage);
        };

        document.querySelector('.chat-input button').addEventListener('click', sendMessage);
</script>

 

프론트에서는 userMessages와 assistantMessages를 각각 담아 백엔드로 await fetch 요청을 보낸다.

백엔드에서 response하는 답변을 push로 추가!

 

덤으로 추가되는 assistantMessages에 토스 아이디로 후원 링크를 첨가해 수익성도 노릴 수 있었다..ㅋㅋ

 

 

 

시작 화면

 

 

정말 깔쌈한 답변이 아닐 수가 없다

 

 

 

 

 

트러블 슈팅

 

 

코드 예제를 생성하는 답변의 경우 홈페이지에서 질문하는 편이 훨씬 편하다

 

 

 

 

 

Devasi의 경우 채팅 방식을 구현하기 위해 각 메세지를 스플라이스 하는 과정을 거쳤기 때문에 코드 예제가 활용하기 어렵게 표시된다는 단점이 있다. 

 

playground에서도 비슷한 문제점이 발생하지만 복사 붙여넣기가 가능하다.

 

프롬프트를 통한 역할 부여를 하지 않더라도 ChatGPT는 코드에 대한 질문에 대해 답변을 잘해주는 편으로 코드가 생성되는 질문의 경우 일반페이지에서 질문을 하는 편이 나을것 같다. 까비..

 

 

 

 

 

https://github.com/didjsrne/Devasi_frontend

 

GitHub - didjsrne/Devasi_frontend: ChatGPT를 활용하여 프로그래밍 언어에 대해 질문하고 답변받을 수 있는

ChatGPT를 활용하여 프로그래밍 언어에 대해 질문하고 답변받을 수 있는 웹페이지입니다! - GitHub - didjsrne/Devasi_frontend: ChatGPT를 활용하여 프로그래밍 언어에 대해 질문하고 답변받을 수 있는 웹페

github.com

 

https://github.com/didjsrne/Devasi_backend

 

GitHub - didjsrne/Devasi_backend: ChatGPT를 활용하여 프로그래밍 언어에 대해 질문하고 답변받을 수 있는

ChatGPT를 활용하여 프로그래밍 언어에 대해 질문하고 답변받을 수 있는 웹페이지입니다! - GitHub - didjsrne/Devasi_backend: ChatGPT를 활용하여 프로그래밍 언어에 대해 질문하고 답변받을 수 있는 웹페이

github.com