
리뷰기반 맛집 추천 서비스 만들기 with GPT-4
안녕하세요, 테이블링 백엔드 팀의 오세연입니다. 지난 4월 GPT3.5 api 로 간단한 테이블링 챗봇을 만든지 벌써 8개월 정도가 지나갔네요. 지난 11월 6일 OpenAI의 GPT-4 turbo 발표 이후 업무상 자주 사용하던 GPT를 GPT-4로 업그레이드를 했습니다. 사용해 보니 어 생각보다 너무 좋은데..? 싶어서 작은 프로젝트로 <리뷰 기반 맛집 추천 서비스>를 ada model과 GPT-4를 활용해서 완성해 본 과정을 공유해 보려고합니다. Contents GPT-4 개선점 및특징 <리뷰기반 맛집 추천 서비스> 개발 과정 a. 리뷰 데이터 가공 b. 반응형 웹앱 개발 및 호스팅 과정 c. 문제 발견 및 개선 작업 d.디자인 OpenAI API 최종비용 느낀점 GPT-4 특징 먼저 지난 11월 6일 OpenAI 의 Dev Day 영상을 아주 흥미롭게 보았는데요, 샘 알트만이 소개한 GPT-4 turbo 의 개선된 특징을 요약하면 다음과같습니다. 2023년 4월까지의 데이터학습 Input 128,000 토큰 (약 300페이지 분량단어) More control - json 으로 응답받기 가능 - better function calling - reproducible outputs (seed parameters를 넣고 일관성 있는 답변가능) New modalities - DALLE3 이미지 input 가능 / 이미지 생성 - GPT-4 Turbo with Vision (시각 정보 처리) - TTS (Text toSpeech) 인상 깊었던 부분 - GPT-4 는 기존 api 보다 비용이 23배 저렴 - 고객이 입력한 데이터는 절대로 AI에 학습하지 않음 - api 이용에서 발생한 저작권 문제는 OpenAI에서 지불할 것 - AppleStore 같은 GPT Store (GPTs)출시 가장 마음에 들었던 개선점은 input 토큰 값 증가와 이미지 input 값 입력입니다. 특히 이미지를 input 값으로 입력함으로써 더 빠르게 GPT에게 맥락을 이해시키고 정확한 답변을 얻는 것이 가능해졌습니다. 이번 프로젝트를 진행해 보며 가장 많은 도움을 받은 부분이기도 해서 글 중간중간 GPT-4를 어떻게 활용하여 도움을 받았는지 그 방법들도 함께 기술해보겠습니다. 리뷰기반 맛집 추천 서비스 개발과정 위 서비스는 기술공유 목적으로 기획/개발한 것이어서 정식 운영 서비스가 아닌 점을 밝힙니다. 사용한 기술 스택은 아래와같습니다. 데이터 가공 — Django & Python & openAiAPI 백엔드 — Node.js & Typescript 프론트엔드 — React DB — Elasticsearch /mongoDB 호스팅 — AWS ec2, route53,ACM 디자인 — GPT-4 DALLE3 1. 리뷰 데이터 가공 with Ada v2model 11. 23만 건의 리뷰를 Embeddings로 변환 리뷰 내용 자체를 Text search 하는 방법도 있었지만 embeddings 한 결과로 조회를 하면 어떤 결과가 나올지 궁금해서 OpenAI Embeddings model — ada v2 model 을 이용해 보기로 결정했습니다. 대상 리뷰는 지난 6개월 동안 별점 4점 이상의 리뷰로 한정하여 그중, 현재 삭제/보류/숨김 처리된 매장의 리뷰는 제외했습니다. 이렇게 추려내니 대략 23만 건의 리뷰가 조회되었고 ada api 를 통해 1536차원의 vectors 로 변환 후 매장 idx 정보 등과 함께 elasticsearch 에저장했습니다. elasticsearch를 이용한 이유는 vectors 타입 필드에 코사인 유사도 검색(cosineSimilarity search)이 가능하고 또 평소 업무상 익숙하여 elasticsearch를 선택하게되었습니다. async def change_to_vectors(input): response = openai.embeddings.create( input = input, model = 'text-embedding-ada-002', ) return response.data[0].embedding . . . es_result = await async_bulk(es_client, es_bulk_data) 12. 각 매장 별 리뷰를 하나의 평균 Embeddings 로변환 매장이 가진 모든 리뷰 vectors 들을 조회해 와서 평균 embeddings 값을 계산하여 es에 저장했습니다. (하지만 이것은실수였으니.) def mean_vector(vectors): np_vectors = np.array(vectors) mean_vec = np.mean(np_vectors, axis=0) return mean_vec.tolist() 13. 키워드 데이터가공 각각 20여 개씩 준비한 음식, 특징 키워드를 embeddings 로 변환시켜 mongoDB에 저장해 주었습니다. 데이터의 형식 변환과 같이 간단한 작업은 GPT-4에게요청했습니다. 14. 모든 키워드 조합에 대한 매장 조회 결과저장 유저가 음식 종류 1가지, 특징 2가지 총 키워드 3개를 골라 가장 취향에 맞는 매장을 조회하기 위한 데이터는 모두 준비가 되었습니다. 각 조합의 평균 vectors 값으로 elasticsearch의 매장의 리뷰 평균 vectors 가 담긴 index에서 cosineSimilarity search 하여 조회한 값을 mongoDB에 저장했습니다. 매 호출마다 평균값 계산 및 조회할 필요 없이 바로 해당되는 매장을 가져올 수 있도록 하기 위해 미리 저장해 두었습니다. 운영을 목표로 하는 정식 서비스가 아닌 기술공유용 개발이어서 신규 데이터 추가 및 자동화 등의 부담없이진행했습니다. 2. 반응형 웹앱 개발 with React &GPT-4 이제 프론트엔드 부분을 개발할 차례입니다. 이전 테이블링 챗봇을 개발했을 때는 “나는 ~어떠어떠한 화면을 만들고 싶어!” 이렇게 텍스트로 전달했었는데 이번에는 GPT-4의 이점인 이미지 입력 가능한 점을 살려 그리고자 하는 화면을 전달해주었습니다. 21. 처음 React 골격잡기 (개발 완료 후 글 작성하며 다시 재현해 본거라 데이터는 혼합되어있습니다.) 22. 구체적으로 디자인요청하기 GPT-3.5 보다 훨씬 에러가 적은 완성도 높은 코드를 만들어 주어 놀랐습니다. 여기에 “버튼 예쁘게 만들어줘”, “키워드는 최대 3개까지만 클릭 가능하게 만들어줘”, “이 폴더 트리 구조 괜찮아? (사진 첨부)” 등의 질문을 하면서 화면을 조금씩 완성해 나갔습니다. 물론 부분 부분 수정하고 직접 코드를 추가하기도 했지만 React를 잘 모르는 저에겐 처음 React 코드를 작성할 때, 원하는 기능을 추가할 때, 에러를 해결할 때 등 큰 도움이 되었고 생산성을 높힐 수있었습니다. Https 호스팅은 지난 테이블링 챗봇 개발 때와 동일하게 aws의 ec2, route53, ACM 을 이용하여진행했습니다. 3. 문제 발견 및 개선방법 이렇게 만들어진 화면에 가공해 놓은 데이터를 백엔드와 연결하여 테스트를 진행해 보았습니다. 하지만 부푼 기대와는 달리 엉망진창이었습니다. ♀️ 발견한 문제들은 크게 아래4가지입니다. 음식/ 키워드 혼합 검색 결과 — 선택한 음식 종류가 아닌 매장들이노출 “초밥" + “친절한" + “맛있는"의 키워드로 검색하니 ”숯불갈비집" 등 “초밥"과 관련 없는 매장들이 노출되었습니다. 3개의 키워드의 평균 vectors를 구하니 “맛있는" embeddings 값과 가까운 매장들이 “초밥" 집이 아니더라도 포함되는 것같았습니다. 음식 + 키워드 2 평균 vectors를 구할 때 음식에 가중치를 5배 주어 다시 검색 결과를 보았지만 조금 나아졌지만 여전히 만족할 수준은아니었습니다. 음식/키워드를 구분하여 두 번 조회를 하거나 분명 방법이 있을 것 같은데 결국 음식과 키워드 따로 조회하는 걸로 수정했습니다. 운영 서비스로 기획된다면 좀 더 시간을 들여 방법을 강구해 보고 싶은부분이었습니다. 2. 선택한 음식/키워드와 관계없이 동일한 매장들이노출 이 평균 vectors 값이 해당 매장의 모든 리뷰를 잘 포함하고 있겠거니 생각했는데 그건 오산이었습니다. 고민을 해보니 왠지 매장 하나당 수백, 수천 건이 될 수도 있는 리뷰를 모두 하나의 평균값으로 구하다 보니 너무 광범위한 결과로 이어졌나싶었습니다. 매장 별 리뷰 평균값으로 검색하지 않고 전체 리뷰의 vectors를 모두 검색하도록 수정하니 이전보다 훨씬 다양하고 정확한 매장들이노출되었습니다. 3. 리뷰의 키워드문제 “애완 동반”이라는 키워드의 결과 매장들을 쭉 살펴보니 애완 동반이 정말 가능한 경우 20개의 매장 중 9개에 불과했습니다. 매장의 리뷰를 살펴보니 “애완 동반” 과 무관한 “강아지” “애견” 등의 단어가 들어간 리뷰의영향이었습니다. ex) “강아지도 데려오고 싶어요~~”, “애견 동반이면 좋겠어요ㅠㅠ" 이 문제는 해결 방안이 뚜렷했습니다. 매장 DB에 “애견 동반 가능 여부" 데이터가 있다면 근본적인 해결이 가능했으나 DB에 기획에도 없는 데이터를 넣을 수는 없었습니다. 임시방편으로 “애완 동반"이 포함된 277개의 조합을 선택하는 경우 매장에 문의를 부탁드린다는 alert 를띄웠습니다. 4. 냉면을 클릭하면고깃집이? “냉면" 키워드로 맛집 검색을 해보면 고깃집들이 꽤 보입니다. 왜 그럴까 고민해 보니 리뷰만을 가지고 검색을 하니 냉면이 맛있다는 리뷰가 많은 고깃집들이 상위권으로 노출되는 것 같았습니다. 이 부분은 리뷰 100%로 맛집을 찾는 것이 기획 의도에 맞기는 하나 리뷰 + 매장의 메뉴 등 다른 데이터와 함께 추천 서비스를 개발한다면 정확도가 개선이 될 것 같았습니다. 일단은 리뷰만을 데이터로 활용했기 때문에 그대로 유지하는 것으로결정했습니다. 문제점들을 하나씩 해결하며 든 생각은 “리뷰”만을 가지고 추천하다 보니, 리뷰에 있는 내용이 악의적인 내용이거나, 사실과 다르다면 잘못된 데이터로 실제 결과에 영향을 줄 수 있겠구나 싶었습니다. 매장의 메뉴, 특징 등을 모두 종합하여 추천 서비스로 만들면 더욱 정확하고 유용하겠다는 생각이들었습니다. 5. 디자인 호스팅까지 끝나고 모든 기능이 구현되고 이제 디자인만이 남았습니다! 테이블링 로고와 느낌은 비슷하지만 좀 더 캐쥬얼한 이미지로 바꿔보기 위해 GPT-4의 DALLE 3를 이용하였고 아래의 결과물을 얻었습니다. 아래 이미지를 얻기 위한 프롬프트 명령어는 간단히 이미지 아래에적어놓았습니다. 우리 회사 로고를 더 웃상으로 만들어줘 -> 독창적으로만들어줘 음식 추천하는 사진을 보여줘 -> 음식이 좀 더 많으면 좋겠어 -> 이건 너무 무서워 레스토랑을 소개하는 느낌으로 만들어줘 배경이 한국이었으면 좋겠어 -> 간판 글자를 한국어로 써줘 (DALLE3 해당 기능 불가) -> 배경에 한국 국기로바꿔줘 선한 인상으로 바꿔줘 -> 캐릭터화 해줘 -> 애니메이션 느낌으로부탁해 배경에 있는 사람들의 모습 하나하나를 아주 자세히 살펴보면 아직 불완전한 부분도 있지만 그럼에도 불구하고 성능이 굉장히 뛰어나다고 느꼈습니다. 아직 조금 아쉬웠던 점은 “배경을 한국어 간판으로 바꿔줘"라고 했을 때 GPT-4는 정확한 한국어로 이미지를 만들어내기 어려워한점입니다. GPT-4의 답변: “I apologize for the oversight. However, the current setup does not support the generation of images with accurate text in specific languages, including Korean.” (그건 생각 못했네 미안, 근데 한국어를 포함해서 특정 언어의 이미지 생성은 현재 지원하지 않아.) 자세히 보면 아직 불완전한디테일들 디자인도 어느 정도 나왔으니 이제 제 취향대로 GPT-4 가 만들어준 이미지를 하나 선택해서 메인 페이지에 걸어두었습니다. 이렇게 디자인까지 끝났습니다! 키워드를 클릭하여 맛집 리스트 최대 20개까지 조회할 수 있고 매장 이름을 클릭하면 테이블링 어플로 이동하여 매장의 자세한 정보 및 위치를 확인할 수 있습니다. (모바일에서만 어플 오픈가능합니다!) 우여곡절 끝에 완성된 리뷰 기반 맛집 추천 서비스 www.tabling-recommends.com (24.10월부로 호스팅 종료되었습니다!♀️) 6. 최종비용 제가 사용한 OpenAI의 ada v2 embeddings model 호출 비용은 $0.0001/1k tokens입니다. 1천만 개의 토큰을 사용하면 $1으로 꽤나 합리적인 가격입니다. 데이터 가공 및 테스트를 하며 이용한 내역은 아래와같습니다. 총 278,221번의 API호출 13,117,411개의 토큰을사용 총 비용:$1.31 ada v2 embeddins model이 OpenAI API 중 가장 싼 API 이어서 부담없이 잘 사용해 볼 수 있었던 것 같습니다. GPT-4 Turbo API 로 매장별 리뷰를 종합 요약해 보는 것도 해보고 싶었으나 $0.01/1k tokens 로 100배 비싸서 나중에 기회가 되면 해볼까 합니다. 다른 방안으로는 비교적 저렴한 GPT-3.5 Turbo ($0.001/1k tokens) 로 테스트해 보는 것도 좋은 방법일 것같습니다. 느낀점 사실 GPT-3.5를 쓰며 편하기도 했고 불편한 점도 꽤 있었습니다. 최신 언어에 대한 리소스도 부족하고 에러도 많아서 대체 언제 2021년 데이터에서 벗어나지? 싶었는데 불과 몇 개월 만에 2023년 4월 데이터까지 업데이트가 이루어졌습니다. 그리고 DALLE 3 / TTS 등 신기한 기능 (하지만 곧 익숙해질 기술들)까지 앞으로 AI 가 발전되는 속도는 계속해서 더욱 빨라질 것같습니다. GPT-4로 저의 분야가 아닌 부분들도 경험해 보며 (ex.프론트 엔드, 디자인, 인프라 구축 등) GPT-4 이용에 200% 만족 중입니다. 지금은 기술 공유 차원에서 개발을 해보았지만 AI를 접목하여 테이블링 유저들에게 더 편리하고 맞춤화된 서비스를 제공하기를 기대 중입니다. 긴 글 읽어주셔서감사합니다. 테이블링 백엔드팀에서는 기술적인 고민을 함께 나누며, 서비스를 지속적으로 발전시켜 갈 실력 있는 동료분을 모시고 있습니다. 보다 상세한 내용은 채용 공고를 확인 부탁드리며, 많은 관심과 지원 부탁드리겠습니다. 리뷰기반 맛집 추천 서비스 만들기 with GPT-4 was originally published in 테이블링 기술블로그 on Medium, where people are continuing the conversation by highlighting and responding to this story.
