GPT-4를 이용해 초록마을 검색엔진 만들기

: 사용자의 의도를 파악하는 초록마을의 검색엔진

DALL-E generated main image

배경 및 동기

모든 일의 시작은 시리얼이었습니다. 얼마전에 유기농 현미코코아볼(240g)을 구매해서 매우 맛있게 먹었었습니다. 아침이 되어 또 즐거운 시작을 위해 시리얼을 그릇에 부었는데, 충분히 만족스러운 양이 담기지 않더군요. 이걸 미리 사두었어야하는데, 어제 생각만 했어도 오늘 새벽 배송으로 받았었을텐데 하는 아쉬움과 함께 남은 우유를 마셔버린 후 출근 준비를 했습니다. 출근을 하면서 초록마을 앱을 켜서 이 코코아볼을 구매하려고 했습니다. 그런데, 코코아볼을 찾을수가 없더군요. 대충 뭘 먹었는지는 기억을 하지만 첵스나 콘푸라이트, 후르츠링과 같이 어릴때부터 이름을 수없이 들어온 제품이 아닌 이상 정확한 상품 명이 기억이 나지가 않았습니다. 시리얼, 초코볼, 초코, 우유, 씨리얼 등을 검색해보다가 도저히 답이 없어서 이번에는 카테고리에서 코코아볼을 찾기 시작했습니다.

결국 검색이 아니라 카테고리를 기준으로 제품을 찾아다니다보니 코코아볼을 금방 찾을 수는 있었지만, 우리의 서비스를 이용하는 고객들도 똑같은 상황을 겪고 있을 것을 생각하니 도저히 이대로 둘 수가 없었습니다. 그래서 검색 서비스에 대해서 본격적으로 알아보았습니다.


직전까지의 상황

초록마을은 1999년에 설립되어 이후로 시스템 개선, 고도화, 신사업 등을 거쳐서 지금은 온라인에서 웹과 앱 서비스를 모두 운영하고 있습니다. 하지만 IT영역에서는 외주 개발로 발전해왔고 특히 온라인 커머스의 영역에서는 계속해서 외부 업체를 통해 서비스를 만들고 운영해왔습니다. 이러다보니 각각의 기술들이 더욱 발전할 수 있는 기회를 갖추지 못하고 아주 기초적인 상태에서 구색만 맞추고 있는 상태였습니다. 하지만 정육각이 22년에 인수를 한 이후로 소프트웨어 개발 영역에서의 결합과 내재화는 온라인 영역에서 한계를 넘어서지 못하던 기술들을 변화시킬 수 있는 발판을 마련해주었습니다.

물론 레거시라 불리는 것들을 모두 이해하고 하나씩 바꿔나가는 과정은 매우 어렵고 오래걸리는 과정이었습니다. 하지만 이제 어느정도 익숙해져가면서 무언가를 바꿀 수 있다는 자신감이 붙었고 이때 마침 초록마을의 앱도 단순히 웹뷰로 모바일 웹을 표시하던 것에서 벗어나 완전한 네이티브 앱으로 출시가 되어 아주 좋은 시점이었습니다. 이때 시리얼 그러니까 검색엔진이 딱 걸린 상황이었습니다.


목표와 문제확인

목표는 아주 단순했습니다. 검색을 하기 전에 사용자가 떠올린 상품이 있다면 검색을 통해 아주 간단하게 그 상품을 찾을 수 있게 하자는 생각이었습니다. 초록마을에서 판매하고 있고 어떤 맛인지까지 다 기억하고 있는 코코아볼을 검색을 통해 찾을 수 있게 하자는 것이죠.

하지만 본격적으로 문제를 파악해보니 목표의 달성이 처음 생각보다 쉽지 않아보였습니다. 검색엔진에 대해서 공부해보면 이게 거의 완성되어 있는 기술이며, 검색엔진 자체는 누구든지 어렵지 않게 도입할 수 있다는 것을 알 수 있습니다. 특히 루씬, 그리고 이를 이용한 엘라스틱 서치는 워낙 자료가 방대하고 다양해서, 조금 과장하자면 한두시간만에 기초적인 검색엔진을 완성시킬 수 있습니다. 하지만 제가 생각한 저 목표가 문제였습니다.

우선 어떤 상품을 검색에서 제공하고자 한다면 그 상품에 대한 정보가 모두 인덱싱되어 있어야 합니다. 결국 검색이라는 것은 많은 값들 중에서 내가 원하는 값을 빠르게 찾아주는 것이지 존재하지 않는 의미를 찾아서 알려줄 수는 없었습니다. 문제를 아주 간단하게 해결해보자면 코코아볼 제품의 검색용 키워드에 “시리얼”을 추가하면 되는 것이었지만 “시리얼”, “씨리얼”, “콘푸레이크”, “초코볼” 등 사람들이 각자의 경험을 바탕으로 이 제품에 대해 생각하는 키워드는 모두가 다르기 때문에 이를 하나씩 맞출 순 없었습니다. 이를 위해서 많은 회사들은 각 상품의 공급사 그리고 MD, 운영팀에서 최대한 많은 정보를 정리해서 데이터베이스에 포함시키고, 동의어 사전을 구축하고, 정보의 전처리를 하지만 이것에는 분명히 한계가 있어보였습니다.

오픈마켓이 아닌 초록마을의 상품 구성은 당연히 오픈마켓인 네이버 스마트스토어나 쿠팡에 비하면 아주 적지만 상품 마스터 데이터를 조회하면 2만개에 달하는 상품의 상세정보들이 검색 대상 정보로 조회되는 상황이었습니다. 그러니 이 상품들에 대해 팀원들이 하나씩 충분한 양질의 정보를 넣기는 너무 쉽지 않아 보였습니다.


기술확인 및 검토

그래서 생각해낸 방법이 지금까지와는 전혀 다른 검색엔진을 만들어 보자는 것이었습니다. 이 글을 읽는 모든 분들이 아마 2023년에 기술적으로 어떤 사건들이 있었는지 알고 계실텐데요, 바로 그 GPT를 이용해보자는 생각을 했습니다. 현재 ChatGPT를 필두로 하는 언어를 처리하는 챗봇의 기술은 거의 하나의 특이점에 와 있다고 해도 과언이 아닙니다. 심지어 마이크로소프트 빙 검색에 붙어있는 모델은 “초록마을에서 파는 시리얼을 알려줘”라고 질의했을 때 다음과 같은 답변을 내놓는 수준이었습니다. ChatGPT의 결과를 가져올 수 있으면 좋겠지만 여기에는 느리다는 치명적인 단점이 존재했고, 그래서 일반적인 검색엔진을 사용하되 만약 전처리를 GPT를 이용해서 하면 어떨까 라는 생각을 해보았습니다.

(무려 40초의 시간이 걸렸다는 부분만 제외하면) 초록마을의 검색엔진보다 더 나은 결과를 보여주었다. (무려 40초의 시간이 걸렸다는 부분만 제외하면) 초록마을의 검색엔진보다 더 나은 결과를 보여주었다.

무엇보다 마이크로소프트 그리고 OpenAI가 GPT-3를 출시하기전인 22년 7월부터 마이크로소프트와 협업을 해오게 되면서 초록마을과 정육각의 모든 기반기술을 Azure로 통합하고 사업을 진행하기로 했었기 때문에 GPT의 사용에서 아주 유리한 부분도 있었습니다. 이 생각을 떠올리자마자 Teams를 통해 마이크로소프트의 지원팀과 얘기를 해보았고 목요일마다 있는 정기 미팅에서 좀더 자세히 논의를 진행하기로 했습니다. 그리고 곧 FastTrack이라 불리는 기술 지원 프로그램을 열게 되었습니다. (FastTrack은 저희가 원하는 기술적 목표 달성을 위해서 마이크로소프트의 각 전문가들을 연결해서 개발을 해나가는 프로그램으로, 한국, 호주에 있는 엔지니어들과 같이 진행을 하였습니다)

현재 최종 적용된 초록마을의 전처리한 정보를 활용하는 검색엔진 프로세스 현재 최종 적용된 초록마을의 전처리한 정보를 활용하는 검색엔진 프로세스

ChatGPT가 아주 빠르게 원하는 결과를 알려줄 수 있다면 간단하게 ChatGPT를 도입하면 되겠지만 매우 비싼 비용이 문제였고 무엇보다도 답을 얻을 때 까지 매우 오래걸린다는 것이 걸림돌이었습니다. 이에 대해 정육각과 초록마을의 기술지원을 맡고 있는 엔지니어들과 많은 논의를 했고 다른 접근 방법을 찾을 수 있었습니다. 현재의 검색엔진 대신 Azure AI Search(이전에는 Cognitive Search였는데 이름이 바뀌었습니다.)를 이용하고 여기에 Azure OpenAI, GPT-4를 이용해 기존의 검색 데이터에 전처리를 하여 새로운 인덱싱을 만들면 어떨까 라는 생각이었죠. 결론을 얻은 즉시 바로 개발을 하여 적용을 해 보았습니다. 이미 일부 데이터 영역들을 Azure로 통합하는 작업이 진행되고 있었기에 상품정보는 이미 Azure CosmosDB에 들어 있던 상태였고, Azure OpenAI에 대한 사용 권한도 지원팀에서 다 받아준 상태였기 때문에 거의 즉시 데이터 전처리를 해볼 수 있었습니다.

GPT-4 32K를 이용해 생성한 유기농 코코아볼(240g)에 대한 일부 전처리 정보 GPT-4 32K를 이용해 생성한 유기농 코코아볼(240g)에 대한 일부 전처리 정보

최종 전처리 결과를 공개하긴 어렵지만 전처리를 해보면 예상했던 것 보다 훨씬 멋진 정보들을 얻어낼 수 있습니다. GPT-4로 생성한 정보 원천데이터에 결합하여 AI Search를 통해 검색의 프로토타입을 만들었고 이 검색엔진은 예상했던것 보다 훨씬 좋은 결과를 보여주었습니다. 상품정보를 데이터베이스에 넣고 인덱싱을 통해 검색엔진에서 검색하여 정보를 전달하는 것은 일반적인 검색엔진과 별다른 차이가 없습니다. 하지만 초록마을의 검색엔진에는 GPT-4 32K를 이용한 생성정보가 검색데이터에 추가되어 있다는 점이 다르며 이것이 아주 특별한 검색 결과를 제공하였습니다.

GPT-4를 이용해 전처리를 하기 위해서 반드시 Fine-tuning이 필요한 것은 아닙니다. 기사에서 많이 나오는 것 처럼 프롬프트를 자세하고 명확하게 작성하기만 해도 충분이 목표하는 결과를 얻을 수 있습니다. GPT-4를 한 명의 사람으로 생각하고 하고 싶은 전처리의 형태, 결과의 모습, 고려해야하는 예외사항 들을 입력하면 결과를 얻을 수 있으며 초록마을의 경우 하나의 제품에 대한 결과를 얻는데 평균 48초 정도의 시간과 2000 토큰(OpenAI에서 사용량을 측정하는 단위)이 소요되었습니다.


검색엔진의 도입 그리고 점수 프로필

프로토타입의 결과만으로도 기존의 검색엔진의 성능을 아득히 뛰어넘는 결과를 보여주었기에 초록마을의 모바일 앱에 바로 해당 기능을 적용하였습니다.

“시리얼”로 검색을 했을 때 표시되는 검색 결과 중 상위 16개의 제품 (더 하위 순위로 가면 우유도 표시된다.)

“시리얼”로 검색을 했을 때 표시되는 검색 결과 중 상위 16개의 제품 (더 하위 순위로 가면 우유도 표시된다.)

이로써 얼마전에 저를 불편하게 했던 시리얼에 대한 문제가 해결되었습니다. 더이상 제품정보에 운영자가 시리얼이라는 정보를 입력하지 않더라도 시리얼, 그리고 나아가 시리얼로써 먹기 좋은 제품들까지 결과에 노출되게 되었습니다. 검색 성능도 기대를 충족하는 결과가 나왔는데 이렇게 검색을 하는 경우 AI Search의 응답속도는 50ms이하로 사용하는데 전혀 불편함이 느껴지지 않는 속도를 보여주었습니다.

전처리를 통해 각 상품의 사용방법과 새로 생성된 키워드들이 추가되어 있다보니 좀더 새로운 형식의 검색도 가능해졌습니다. 예를들어 미역국을 검색하면 기존에는 완제품으로서의 미역국, 미역라면, 사골곰탕, 미역이 검색되었지만 이제는 사용자의 검색 의도를 파악해내기 때문에 완제품으로서의 미역국도 당연히 우선순위로 노출되지만 미역국을 끓이기 위한 부재료로서 한우 국거리용이라던가 바지락살, 국물용멸치, 심지어 간장까지도 검색 결과로 표시됩니다.

하지만 지금 이순간에 초록마을 앱을 다운받아서 확인할 수 있는 검색 결과는 프로토타입에서 구현했던 수준은 아니고 이후에 점수 프로필을 매우 섬세하게 조정하여 최적화한 결과입니다. 앞서 설명드린 미역국의 결과는 최초의 도입버전에서 이미 얻을 수 있었지만 상품의 정렬 순서가 제가 의도하는 것과 차이가 있었습니다. 저는 검색어의 정의에 가장 가까운 상품을 먼저 표시하며, 여기에서 멀지만 원물에 가까운 상품을 그다음, 검색어가 의도한 상품을 구성하는 요소나 이를 응용한 상품을 마지막으로 붙여서 표시되게 하고 싶었습니다. 이는 전체 텍스트 쿼리 및 인덱싱 엔진 아키텍처로 루씬을 적용하고 있는 AI Search의 점수 프로필을 조정해서 얻어낼 수 있었고 지금의 결과를 만들어 냈습니다.


스스로 성능을 개선하고 사용자의 의도를 파악하는 검색엔진

여기까지만 하더라도 사용하는데 전혀 불편함이 없는 검색엔진이라 감히 말할 수 있었지만, 여기에서 만족할 수는 없었습니다. 최초의 목표는 달성 하였으니 이제 사용자가 원하는 의도를 제대로 표현하지 못한 순간들에 대해서도 보정해 줄 수 있는 검색엔진을 만들고 싶었습니다. 예를들어 “샤인머스캣 포도”와 같이 오타가 아니더라도 외래어 표기는 사용자 별로 “샤인머스켓”이나 “사인머스캣”과 같이 다른 글을 입력하는 순간이 있을 수 있고, 모바일에서는 많이 줄어들었지만 한영 전환을 잘못 누른 순간이 있을 수 있습니다.

동의어일 가능성이 있는 검색어의 예시 동의어일 가능성이 있는 검색어의 예시

앞서 표현된 검색엔진 프로세스에 검색 결과들을 별도로 저장하여 자동보정하는 프로세스로 표현되어 있는 이 보정기능은 내 자신이 입력한 검색어가 원하는 결과를 보여주지 못했다는 것을 사용자가 즉시 알아차릴 수 있다는 것을 응용하였습니다. 대부분의 사용자들은 입력한 단어에 대해 원하는 결과를 얻지 못하면 동일한 의미를 같지만 다른 단어를 검색하여 원하는 상품을 찾아내려고 합니다. 따라서 각 사용자별로 단시간에 여러번 검색을 하였으며, 검색 후 결과가 아무것도 나오지 않았거나 나왔더라도 스크롤 또는 상품을 선택하지 않고 재검색을 한 행동이 있다면 이를 잠재적으로 동의어로 판단할 수 있습니다. 여기에 몇가지 알고리즘을 더해 스스로 사용자의 실수를 보정해주는 검색엔진을 완성할 수 있었습니다.

할인율에 따라 정렬된 할인상품들, 증정, 특가, 인기상품 심지어 각 개인의 기록에 따라 알려주는 자주 구매하는 상품의 검색결과 할인율에 따라 정렬된 할인상품들, 증정, 특가, 인기상품 심지어 각 개인의 기록에 따라 알려주는 자주 구매하는 상품의 검색결과

또한 초록마을은 많은 기획전과 행사들, 그리고 365일 하루에 하나씩 정해서 파격적인 할인을 하는 365 특가도 운영하고 있습니다. 초록마을 뿐만 아니라 많은 온라인 커머스 서비스를 사용하다보면 내가 원하는 상품을 찾는 것과 별개로 또다른 요구사항이 생기는 순간이 있는데 바로 할인 상품을 찾는 것입니다. 그래서 상품 검색의 최상단에 별도의 레이어를 구축하였습니다. 이 레이어는 사용자의 검색이 특정 상품을 찾는 것인지 아니면 전반적인 상품을 둘러보기를 원하는 것인지를 파악합니다. 이를 통해 만약 사용자가 할인상품을 찾는 것이 목적이거나 다른 의도가 파악된다면 키워드 검색이 아닌 다른 조건의 검색을 통해 기대받은 결과를 표시하게 하였습니다.


마무리

이 초록마을의 아주 특별한 검색엔진은 본격적으로 작업이 시작되어 개발이 완료될 때 까지 채 1개월이 걸리지 않았습니다. 물론 그 전에 Azure로 모든 클라우드 인프라를 통합하는 작업이 진행되고 있었고 마이크로소프트의 특별한 지원이 있었기 때문에 가능했던 일이지만, 아주 멋진 검색엔진을 만드는 것이 구글 그리고 네이버만이 할 수 있는 일은 아니다 라는 것도 알게 되었습니다. 지금 초록마을의 검색엔진은 모바일 앱과 웹 모두에 적용이 되어 있습니다. 새로운 검색 기록들이 더 많이 쌓일 수록 더 완전한 검색엔진이 될 것으로 기대하고 있습니다. 이 검색엔진을 보시려면 초록마을 앱을 다운받아 많은 검색을 해봐주세요. 겸사겸사 맘에 드는 상품을 발견하면 구매해보시는 것도 좋습니다. 누구보다 빠른 매장 배송을 통해 배달 해 드릴테니까요. 그럼 저는 이만 시리얼을 먹으러 가보겠습니다.


이어지는 이야기

이런 검색엔진으로 시작한 Azure OpenAI의 적용은 두달이 지나 인공지능 인터프리터 “아서”로 발전하게 됩니다. 아서에 대해 알고 싶다면 아서를 만난 이야기를 읽어보세요.