TABLE OF CONTENTS
1. How to use OpenAI API in my web app?
아키텍쳐를 보자.
React Web App을 Static Hosting하기 위해서 S3를 앞에 박아두자. 그 후 유저가 채팅을 입력하게 되면 API GW(REST)로 Lambda가 호출이 되서 이 Lambda에 채팅이 입력된 후 DynamoDB에 저장을 한다. 그 다음 SQS Queue에다가 전달을 해서(왜 바로 Lambda로 보내지 않고 SQS Queue에 전달을 하는가?) 다른 Lambda가 SQS를 구독해서 받아다가 실제 ChatGPT에게 API기반의 request를 해서 response를 받아오면 이걸 다시 API GW(Web Socket)을 통해서 User에게 실시간으로 전달해준다.
Frontend는 React 기반의 앱을 S3 Static Hosting으로 배포할 거고,
Backend는 Serverless Framework를 이용해서 API GW + Lambda + DynamoDB를 배포한다. 일단 API Gateway Rest로 API를 생성하고, WebSocket으로 실시간 응답을 유저에게 제공하므로 API GW가 2개가 생성된다.
Decoupling 같은 경우에는 ChatGPT의 경우 Response가 1-2분 정도로 오래 걸리는 경우가 발생하게 되는데 API GW + Lambda의 제한 시간이 30초이므로 30초가 넘어버리면 Timeout이 발생하기 때문에 SQS로 Decoupling을 해서, 거기서 Lambda가 뽑아오게 되면 15분정도까지 시간 제한이 늘어나므로 ChatGPT의 Response를 위한 충분한 시간을 확보해주자.
DB는 DynamoDB를 사용해서 여기에 현재 User의 WebSocket을 위한 ConnectionID와 채팅을 저장하도록 한다.
ChatGPT API를 위해서는 OpenAI.com에서 아래와 같이 API key를 생성하도록 하자.
응답이 굉장히 느리므로 SQS로 Decoupling 해주자.
참고로 만약 이 api key를 이용해서 접근할때 410에러나 503에러가 난다면 gpt plus 멤버가 아니라서 권한이 없기 때문에 발생하는 것이다.
serverless framework를 설명하자면 아래와 같다.
aws serverless로 된 프로젝트는 아래와 같이 보통 Lambda에 올라가는 Source Code 부분과 AWS 인프라(CloudFormation)으로 구분이 되는데 이것을 하나의 파일인 serverless.yml로 합쳐서 serverless framework가 배포를 해서 하나의 거대한 CloudFormation Stack을 만들어내는 것이다.
serverless service 프로젝트를 진행하다보면 아래와 같이 각각의 lambda가 중첩되어 얽혀 있는데 이걸 하나 하나 배포하게 되면 복잡하고 중첩될 수도 있으므로 하나의 환경에서 통합적으로 배포하는게 중요하므로 serverless framework를 이용해서 각각의 lambda handler를 동시에 배포하도록 하자.
2. Asynchronously Integrating ChatGPT on Web App
이제 소스코드를 설명한다. 먼저 백엔드부터 설명한다. 아래와 같이 lambda함수가 총 5개가 존재한다.
일단 첫번째 소스코드인 get.js는 유저가 접속을 했을때 dynamoDB에서 채팅 내용을 가져오는 부분(http GET method와 비슷한 느낌)으로 쿼리를 보내서 받아온 데이터를 JSON 형식으로 response를 보내는 부분이다.
onConnect.js는 User가 Websocket API GW에 접속했을 때 부여되는 Connection ID를 DynamoDB에 저장을 하는 부분이다.
API GW(Websocket)에서 유저한테 채팅 내용을 보내고 싶다면 즉 get.js가 동작하려면 connetionID가 필요하므로 user가 내 api gw에 접속했을때의 connection ID를 dynamoDB에 저장하고 있다가 누군가가 이 유저한테 뭔가 보내고 싶을 때는 이 dynamoDB에 들어있는 connectionID를 받아다가 이 connectionID로 이 API GW(Websocket)이 해당 무언가를 보내게 되는 것이다. 따라서 API GW(Websocket)에서 발급한 connectionID를 유저가 onConnect 하자마자 connection ID를 발급해서 dynamodb의 user list table에 넣어주도록 하자.
onDisconnect는 간단하다. 유저가 접속이 끊기면(웹 소켓 연결이 끊기면) 해당 connectionID를 내 DynamoDB의 user list table에서 삭제하는 것이다.
그다음은 put.js은 두 부분으로 나뉘는데
첫번째 부분은 일단 채팅이 입력되었을때 먼저 채팅을 DynamoDB에 저장하고, DynamoDB에서 해당 채팅방에 접속한 모든 유저들의 목록(해당 채팅방에 접속되어 있는 모든 ConnectionID)을 가져와서 이 유저들에게(채팅방에 있는 모든 유저들에게) 채팅을 보내기 위해 이 ConnectionID들을 API Gateway에 던지게 되면 이 API Gateway가 접속이 되어 있는 유저들에게 동일한 채팅 내용을 보내게 된다.
두번째 부분은 chatgpt의 응답이 느릴 수 있기 때문에 SQS에 채팅 내용, 채팅방관련 정보를 적어서 SQS에 넣게 된다.
그리고 이제 마지막 코드는 processQueue.js로 위에서 SQS에 넣은 부분을 처리하는 코드로 SQS에 message가 날라오면 일단 유저 목록을 조회하고(ConnectionID 조회) 그 다음 OpenAI에서 제공해줬던 OpenAPI key를 넣은 부분을 통해서 gpt에게 request를 날리도록 한다(이 부분은 AWS에서 공식문서로 제공해줌). 그렇게 response를 받으면 아까 조회했던 ConnectionID들에게 이 message를 보내도록 한다.
다대다 채팅 느낌으로 구현을 하기 위해 이렇게 채팅방에 동시에 접속한 ConnectionID들에게 싹다 보내도록 하는 것이다.
그리고 이제 serverless.yml을 보도록 한다.
일단 OpenAI에서 제공한 Open API key를 붙여넣고(환경 변수 느낌), 이 yml에선 SQS 큐를 만들고, Lambda를 위한 IAM Role을 정의하고, 채팅메시지를 담아둘 DynamoDB 테이블을 설정해두고, 유저 목록을 담아둘 DynamoDB 테이블을 만들어 둔 다음 API Gateway와 WebSocket API Gateway를 담는 parameter store를 만들어 준 다음 소스코드에 해당하는 5개의 lambda함수를 적어두도록 하자.
이후 aws profile(내 local에서 적용될 aws id)를 설정한 후 serverless deploy로 배포해주도록 하자.
이렇게 배포가 되면 REST API용 api gw id와 web socket용 api gw id가 나오게 되는데 이 2개의 id를 프론트엔드 클라이언트(여기선 React 사용)에 넣어두어야 한다.
아래 DynamoDB를 보게 되면 message가 전달되는 table과 userlist(ConnectionID 존재)가 존재하는 table로 총 table이 2개가 있는 것을 볼 수 있다.
그럼 이제 프론트엔드를 살펴보도록 하자. React로 이루어져있고 간단하게 채팅을 입력할 수 있게 되어 있다.
App.js를 보게 되면 유저가 접속을 하게 되면 Web Socket에 접속 해서 Web Socket을 받아오게 되고, 유저의 채팅이 입력되면 채팅을 WebSocket api gateway로 이것의 endpoint를 이용해서 보내주게 된다. 또한 채팅을 받아오는 부분은 REST api gateway로 이것의 endpoint를 이용해서 받아오면 된다.
그 후 실행해보면 정상 동작이 된다.
그러고 실제로 chatgpt의 response를 받아오는 Lambda함수에서 CloudWatch Log를 보게되면 실제로 response가 이쪽으로 도착하는 것을 볼 수 있다.
또한 지금까지는 local에서 실행되고 있는데 웹사이트에 올리기 위해서 S3 버킷을 만들고 이것을 CloudFront와 Route53으로 호스팅해두자.
그 후 이 프론트엔드 프로젝트 전체를 build해서 build해서 나오게된 폴더 전체(아래)를 이 S3에 업로드를 하면 된다.
[Reference]
1. https://www.freecodecamp.org/news/create-a-serverless-chatgpt-app/
How to Create a Serverless ChatGPT App in 10 Minutes
Since OpenAI released an official API for ChatGPT [https://openai.com/blog/introducing-chatgpt-and-whisper-apis] in March 2023, many developers and entrepreneurs are interested in integrating it into their own business operations. But some significant barr
www.freecodecamp.org
2. https://velog.io/@iamjaeholee/Go-ChatGPT-AWS-Serverless-API
Go ChatGPT AWS Serverless API
Go 기반 ChatGPT 서버리스 REST API를 작업한 후기를 공유합니다.소스코드ChatGPT 는 OpenAI에서 만든 AI입니다. 홈페이지에서 로그인을 한 후 다음과 같이 REST API를 만들 때 사용할 Secret Key 를 먼저 발급
velog.io