
websocket
으로 채팅 서비스를 구현하려고 찾아보다가 @chatscope/chat-ui-kit-react 라이브러리를 알게 됐다.
Chat GPT와 연동하는 예제를 찾아서 내가 세팅한 환경에 맞게 typescript
와 custom hook
으로 코드를 변경해서 코딩해 보았다.
먼저 OpenAI 웹사이트에서 로그인 후 API 키를 발급 받으면 된다.
⚠️ 주의 할 점은 🆗버튼을 클릭하기 전에 복사 후,
.env
파일에 먼저 붙여넣기 해야한다는 것!
코드 분석
@chatscope/chat-ui-kit-react
라이브러리를 사용해서 채팅창의 전체적인 form을 만들어 준다.
useChatGPT
훅을 사용하여 messages
, isTyping
, 그리고 sendMessage
를 가져온다.
이 훅은 초기 메시지를 매개변수로 받아온다.
TSX1import { 2 MainContainer, 3 ChatContainer, 4 MessageList, 5 Message, 6 MessageInput, 7 TypingIndicator, 8} from "@chatscope/chat-ui-kit-react"; 9import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css"; 10import { useChatGPT } from "hooks/useChatGPT"; 11 12export default function ChatForm() { 13 const { messages, isTyping, sendMessage } = useChatGPT([ 14 { 15 message: "Hello, I'm ChatGPT! Ask me anything!", 16 sentTime: "just now", 17 sender: "ChatGPT", 18 direction: "outgoing", 19 position: "first", 20 }, 21 ]); 22 23 return ( 24 <div style={{ position: "relative", height: "500px", width: "500px" }}> 25 <MainContainer> 26 <ChatContainer> 27 <MessageList 28 scrollBehavior="smooth" 29 typingIndicator={ 30 // ChatGPT가 현재 타이핑 중인지의 여부 31 isTyping ? <TypingIndicator content="ChatGPT is typing" /> : null 32 } 33 > 34 {messages.map((message, i) => { 35 // 현재 채팅 화면에 표시되어야 하는 메시지 목록 36 return <Message key={i} model={message} />; 37 })} 38 </MessageList> 39 40 <MessageInput 41 placeholder="Type message here" 42 onSend={sendMessage} // 사용자가 새 메시지를 보내려고 할 때 호출되는 함수 43 /> 44 </ChatContainer> 45 </MainContainer> 46 </div> 47 ); 48}
다음으로 useChatGPT
hook 코드를 분석해 본다.
API_KEY
: 발급 받은 API KEY를 상수변수로 지정해 준다.
systemMessage
: GPT-3에게 어떤 방식으로 대답을 할지 지시하는 역할.
TSX1const API_KEY = process.env.REACT_APP_CHATGPT_API_KEY; 2const systemMessage = { 3 role: "system", 4 content: 5 // 2년 경력의 소프트웨어 전문가에게 설명하는 것처럼 답변을 제공 6 "Explain things like you're talking to a software professional with 2 years of experience.", 7};
전반적으로, useChatGPT`` 훅은
ChatGPT`와의 인터랙션을 관리하며, 메시지를 전송하고 받는 기능을 한다.
TSX1export function useChatGPT(initialMessages: MessageModel[]) { 2 const [messages, setMessages] = useState<MessageModel[]>(initialMessages); 3 const [isTyping, setIsTyping] = useState<boolean>(false); 4 5 const sendMessage = async (message: string): Promise<void> => { 6 // 사용자의 메시지를 newMessage 객체에 저장하고, messages 상태에 추가 7 const newMessage: MessageModel = { 8 message, 9 direction: "outgoing", 10 sender: "user", 11 position: "first", 12 }; 13 // OpenAI API로 요청을 보내기 전에, 모든 메시지를 apiMessages 배열로 변환 14 const newMessages = [...messages, newMessage]; 15 16 setMessages(newMessages); 17 setIsTyping(true); 18 19 const apiMessages = newMessages.map((messageObject) => { 20 const role: "assistant" | "user" = 21 messageObject.sender === "ChatGPT" ? "assistant" : "user"; 22 return { role: role, content: messageObject.message }; 23 }); 24 25 const apiRequestBody = { 26 model: "gpt-3.5-turbo", 27 messages: [systemMessage, ...apiMessages], 28 }; 29 30 try { 31 const response = await axios.post( 32 "https://api.openai.com/v1/completions", 33 apiRequestBody, 34 { 35 headers: { 36 Authorization: `Bearer ${API_KEY}`, 37 "Content-Type": "application/json", 38 }, 39 } 40 ); 41 42 const receivedMessage: MessageModel = { 43 message: response.data.choices[0].message.content, 44 sender: "ChatGPT", 45 direction: "incoming", 46 position: "single", 47 }; 48 49 setMessages([...newMessages, receivedMessage]); 50 setIsTyping(false); 51 } catch (error) { 52 console.error("Error making the API call:", error); 53 setIsTyping(false); 54 } 55 }; 56 57 return { messages, isTyping, sendMessage }; 58}
결과를 확인해 보면 현재는 잦은 요청으로 에러를 뱉고있지만, 통신이 잘 된다는 것을 확인 할 수 있다.
어려웠던 점은 chatGPT에게 물어보면서 해결했다.
오늘 구현한 것은 라이브러리로 간편하게 구현할 수 있었지만, 시간이 된다면 websocket
을 사용해서
직접 구현도 해봐야겠다는 생각이 들었다.

(CI/CD)Github 작업을 사용하여 AWS S3에 React 배포하기(2)Github Action 설정

input object 타입 동적 업데이트현업에서 사용하는 object 타입 동적 업데이트