토이 프로젝트 일지 2 : ChatGPT 서비스를 활용하는 크롬 플러그인 만들기

그림 1. 프로그램 동작 화면

그림 1. 프로그램 동작 화면

1. 시작 계기

최근 IT 쪽에서 ChatGPT가 상당한 주목을 받고 있다. ChatGPT는 언어 생성 모델로, 매우 큰 범용성을 가지고 있기 때문에 다른 자동화 툴하고 연계할 경우 큰 시너지를 일으킬 수 있다. 이미 ChatGPT for Google과 같은 ChatGPT를 활용한 플러그인들이 다수 출시되고 있는데 이러한 플러그인들은 Open AI의 API Key를 활용하거나 Open AI에서 제공하는 Chat 서비스 서버와 간접적으로 통신해서 ChatGPT를 활용하고 있다. 이러한 프로그램들을 보니 필자도 ChatGPT를 활용하는 프로그램을 만들어보고 싶게 되어서 이번 프로젝트를 시작하게 되었다.

2. 프로젝트 개요

가. 프로젝트 소개

1. 프로젝트 유형: 개인 토이 프로젝트

2. 구현 서비스 : 구글 검색 시 ChatGPT에 질문해서 응답을 보여주는 크롬 플러그인

3. 개발 환경 : VS Code

4. 구동 환경 : Linux, Windows

5. 활용 기술

- 리버스 엔지니어링

6. 개발 기간: 2023.2.4 ~ 2023.2.10

Open AI에서 제공하는 Chat 서버의 통신을 모방해서 결과를 출력시킬 것이다. 실제 내부 동작을 자세히 모르기 때문에 통신을 수행할 때, 패킷들을 캡처해서 각각의 엔드포인트들이 어떤 동작을 일으키고, 어떤 상호작용을 하는지 파악해야 한다. 이러한 부분은 리버스 엔지니어링에 속한다.

나. 프로젝트 목표

이번 프로젝트에서는 크롬 플러그인 Manifest 3 버전으로 개발한다. 2 버전으로 개발하는 경우는 많았으나, 3 버전으로 개발하는 것은 경험이 많지 않기 때문에 이 부분에 대한 경험을 쌓는 게 중요한 목표다. 또한, 모르는 부분들이 나왔을 경우 ChatGPT로 최대한 물어봐서 ChatGPT에 익숙해지는 것도 주요 사항이다.

3. 프로젝트 구현

가. ChatGPT 웹통신 과정 분석

그림 2. Chat 서비스 엔드포인트 용도 분석
그림 2. Chat 서비스 엔드포인트 용도 분석

네트워크 디버깅을 통해서 각각의 엔드포인트의 용도를 분석했다. 대부분의 엔드포인트들은 대화를 위해서 필수적으로 사용해야 한다. 다만, "moderations" 엔드포인트는 단지 전체 대화 내용을 보내기만 하고 실제로 대화하는 부분에서는 전혀 영향을 주지 않았다. 사용자가 대화한 내용을 저장하기 위한 용도로만 사용하는 것으로 보인다.

그림 3. Chat 서비스 엔드포인터 통신 절차 분석
그림 3. Chat 서비스 엔드포인터 통신 절차 분석

Chat 서비스는 다음과 같은 과정을 통해서 서로의 필요한 정보를 제공해서 통신했다. 이 부분을 크롬 플러그인으로 그대로 구현하면 될 것으로 보인다.

나. CORS 를 우회해서 통신하기

그림 4. CORS 정책 관련 에러 로그가 출력된 모습
그림 4. CORS 정책 관련 에러 로그가 출력된 모습

하지만 구글 검색창에서 바로 Open AI 관련 도메인으로 요청을 할 수는 없는데, CORS 정책에 걸리기 때문이다. 일반적으로는 서버 측에서 보내는 헤더를 수정해서 이러한 에러를 수정할 수 있으나, 현재는 할 수 없으므로 다른 방법을 생각해야 한다.

그림 5. CORS 문제를 해결하기 위해서 서비스 워커를 통해서 통신하는 순서도
그림 5. CORS 문제를 해결하기 위해서 서비스 워커를 통해서 통신하는 순서도

다행히도 크롬 플러그인에서는 service worker라는 공간을 제공해주며, 이 공간에서는 host_permissions에 등록해 놓은 도메인인 경우 CORS 문제 없이 통신이 가능하다. service worker에 접근하기 위해서는 서로 메세지 형태로 교환해야 하는데 이러한 교환 과정이 그림 5에 나와 있다.

다. SSE 통신 처리하기

그림 6. SSE 통신으로 서버가 클라이언트에게 텍스트 생성 결과를 전달하는 모습
그림 6. SSE 통신으로 서버가 클라이언트에게 텍스트 생성 결과를 전달하는 모습

텍스트 생성인 경우에는 헤더의 content-type이 text/event-stream으로 나오는데, 모델에서 텍스트를 생성하는 데 시간이 꽤 걸리기 때문에 실시간으로 텍스트가 생성되는 과정을 보여주기 위해서 SSE 통신을 사용한 것으로 보였다.

그림 7. SSE 통신 결과를 서버스 워커에서 지속적으로 받아서 상호작용하는 과정
그림 7. SSE 통신 결과를 서버스 워커에서 지속적으로 받아서 상호작용하는 과정

SSE 통신인 경우에는 한 번 왕복으로 끝나지 않고, 서버로부터 지속적으로 받아야 하기 때문에 서비스 워커로부터 입력 스트림을 생성시켜서 끝 도달 여부가 발생할 때까지 계속 메세지 통신을 해야 한다. 입력 스트림을 통째로 content_scripts에 넘기면 편하겠지만 실제로 해보면 빈 객체가 전달되어서 제대로 되지 않기 때문에 현재로서는 다음과 같은 방식이 최선인 듯하다.

라. UI 설계

그림 8. UI 설계
그림 8. UI 설계

UI는 그림 8과 같이 검색 키워드에 대한 ChatGPT 질문 결과가 오른쪽에서 실시간으로 출력되도록 설계했다.

4. 프로젝트 소감

크롬 플러그인으로 CORS를 우회하는 방법이나 SSE 통신 관련 부분은 처음 알게 된 내용이라서 상당히 유익했다. 그리고, ChatGPT는 많이 활용해보면서 ChatGPT가 필자가 처음에 생각했던 것보다 훨씬 잠재성이 높다는 점도 알게 되었다. 앞으로도 ChatGPT를 자주 사용할 것 같다.

5. 관련 링크

관련 Github 저장소(v1.0.2) >

이 블로그의 인기 게시물

토이 프로젝트 일지 6 : React/SpringBoot 기술 스택으로 코딩 테스트 서비스 만들기

토이 프로젝트 일지 7 : RedKiwi와 유사한 이벤트 스토밍 기반 마이크로 서비스 만들기