LINER Chat: From Prompt Engineering to Plugins
안녕하세요, 머신러닝 엔지니어 카터입니다. OpenAI가 ChatGPT를 공개한지 4개월이 지난 지금, 세상은 엄청나게 빠르고 급격한 변화를 겪고 있습니다. 이러한 변화의 물결 속에서 라이너 역시 “Help People Get Smart Faster”라는 미션을 해결하기 위해 ChatGPT를 비롯한 Large-scale Language Model (이하 LLM) 을 활용할 수 있는 방안에 있어 많은 고민을 이어오고 있는데요.
지난 3월 23일 여러 고민을 통해 탄생한 LINER Chat을 모바일 어플리케이션에 출시하며, 우리가 제공하고자 해온 기존의 가치와 새로운 인터페이스의 결합을 녹인 기능을 사용자 대상으로 공개하게 되었습니다. 이번 글에서는 LINER Chat에 어떠한 기술적 노하우들이 들어가 있는지, 제품 개발을 위해 추가적으로 고민 중인 사항은 무엇인지 등에 대해 소개드리고자 합니다!
LINER Chat: Now @Prompt Engineering
LINER Chat은 라이너가 제공 중이던 여러 기능과 ChatGPT로 대표되는 대화형 인터페이스를 통합한 제품입니다. 사용자는 LINER Chat을 통해 간단한 대화 뿐만 아니라, 대화형 검색 그리고 대화형 추천 등 여러 기능을 하나의 인터페이스를 통해 접근할 수 있게 되었습니다. 그렇다면 이같은 대화 에이전트 시스템을 어떻게 구축할 수 있을까요?
많은 분들이 인지하고 계시듯, ChatGPT의 선풍적 인기와 함께 세상에 존재하는 수많은 태스크를 ChatGPT를 활용해 해결해보고자 하는 시도들이 우후죽순으로 등장하고 있습니다. 해당 레포지토리만 보더라도, 엄-청나게 많은 수의 문제 해결을 위해 엄-청나게 많은 종류의 프롬프트가 커뮤니티를 통해 공유되고 있는 모습을 확인할 수 있죠. 뿐만 아니라 PromptBase와 같이 프롬프트를 사고 팔 수 있는 플랫폼이 등장하기도 했습니다.
그러나 ChatGPT를 활용해 Single Task를 수행하는 예제는 많지만, 대화 에이전트 서비스를 구축하는 예제는 쉽게 찾아볼 수 없습니다. 실제로 LINER Chat 개발을 위해 수많은 레퍼런스를 서치했지만, 에이전트 구현을 위한 프롬프트 예제를 찾기란 쉽지 않았습니다. 따라서 여러 시행착오를 겪으며, 자체적으로 LINER Chat을 서비스하기 위해 필요한 요소들에 대한 정의를 내리게 되었습니다. 아래 소개드릴 요소들은 대화형 에이전트 서비스를 위해 필수적으로 프롬프트 등에 입력되어야 하는 정보입니다.
Persona
에이전트에게 가장 중요한 요소 중 하나는 일관성 있는 캐릭터입니다. 이는 페르소나
라는 용어로 정의되기도 하며, 이루다 사례를 떠올려 보면 쉽게 이해가 가능합니다. 이루다는 20대 초반의 여성이라는 페르소나를 통해 사용자로 하여금 페르소나 특성에 걸맞는 응답을 기대하도록 했습니다.
라이너 역시 사용자로 하여금 에이전트에게 친밀함을 느끼고, 보다 많은 소통을 장려할 수 있도록 하기 위해 프롬프트에 여러 장치를 마련해두었습니다. 대표적 장치 중 하나는 친근한 의사 소통의 경험을 제공하기 위해 이모지 사용
을 적극적으로 장려한 것입니다.
이모지 사용 장려를 통해 LINER Chat이 내놓는 답변은 통통 튄다는 인상이 생겨나기 시작했습니다.이러한 이모지 장려 뿐만 아니라, 사용자에게 보다 친절하고 위트있게 답변을 제공할 수 있도록 성격을 부여하는 작업 역시 프롬프트 엔지니어링을 통해 가능합니다.
23년 4월 3일 현재, LINER Chat에는 성격
, 이모지 사용 장려
, 질문 장려
, 출생의 비밀
등이 프롬프트로 입력되어 사용자와 교감하고 있습니다.
User
LINER Chat에게 스스로가 누군지에 대한 정보를 전했으니, 이제는 사용자를 알려야 하겠죠? 프롬프트를 통해 사용자에 대한 정보를 제공해, 사용자로 하여금 에이전트가 자신을 인지하고 있다는 경험을 제공해주는 것 역시 대화에 있어 중요한 요소입니다. 이를 위해 시스템 메시지로 매 턴 마다, 사용자 정보를 인입해주고 있습니다. 사용자 정보를 매 턴 입력하는 이유는, 최대 토큰 길이 제한
으로 인해 사용자 정보가 쉽게 휘발되는 것을 방지하기 위함입니다.
사용자 정보에는 사용자 이름, 접속 국가 뿐만 아니라, 사용자가 라이너 서비스를 통해 소비한 콘텐츠 이력도 포함되어 있습니다. 따라서 위 예제처럼, 최근 콘텐츠 소비 이력을 바탕으로 한 LINER Chat과의 대화 역시 가능합니다. 콘텐츠 소비 이력을 통해 사용자가 보다 개인화 된 대화를 나누고 있다는 경험을 느낄 수 있도록 설계된 바이며, 이는 추후 개인화 추천 기능의 고도화를 위해 필수적으로 활용될 정보이기도 합니다.
Reference
ChatGPT가 2021년 9월까지의 학습 데이터를 통해 서비스가 제공되고 있음에 따라 최신 정보를 필요로 하는 대화 주제에 대해 올바른 대답을 하지 못한다는 사실은 많은 분들이 알고 계실텐데요. 이러한 약점을 보완하기 위해 Bing Chat과 Perplexity.ai 등은 검색을 통해 최신 정보를 주입해 ChatGPT가 최신 정보에 대해서도 답변을 생성할 수 있도록 설계되어 있습니다.
LINER Chat 역시 최신 정보를 필요로 하는 사용자 질문의 경우, LINER Chat으로 하여금 검색 엔진을 통해 얻어진 문서를 활용해 답을 생성할 수 있도록 개발이 되어 있습니다. 이 역시 프롬프트 엔지니어링으로 해결하고 있으며, 레퍼런스 문서의 경우 사용자 메시지가 아닌 시스템 메시지로 넘겨줄 때 정말 필요로 하는 경우에만 문서를 참조하는 것을 확인할 수 있었습니다.
현재 Google, Bing 그리고 라이너 자체 검색 엔진을 활용해 LINER Chat이 보다 최신 정보를 반영한 응답을 생성할 수 있도록 하고 있습니다.
Memory
대화 에이전트 서비스에 있어 마지막으로 고려되어야 할 정보는 메모리입니다. 메모리는 에이전트가 사용자와 나눈 대화를 기억한 채 대화를 이어 나가기 위해 필수적으로 챙겨져야 하는 기술입니다. 메모리에는 크게 사용자와 과거부터 나눈 이야기를 기억하는 Long-term Memory
, 그리고 현재 나누고 있는 이야기를 기억하는 Short-term Memory
가 있겠습니다. 먼저, Short-term Memory
에 대해 알아봅시다.
Short-term Memory
에 있어 중요한 요소는 최근 n턴 동안 나눈 대화를 얼마나 기억할 수 있느냐입니다. 현재 모든 생성 모델은 최대로 다룰 수 있는 콘텍스트 길이에 강한 제약이 있기 때문에 사용자와 나눈 모든 대화 내역을 기억한 채 대화를 이어나갈 수 없습니다. 따라서 LINER Chat에서는 Short-term Memory
를 위해 윈도우 버퍼 개념의 메모리를 적용하였습니다.
윈도우 메모리 버퍼는 모든 대화를 기억하지 않고, Last n턴의 대화만을 기억하겠다는 전략입니다. 따라서 사용자와 LINER Chat이 나눈 대화 중 Last n턴을 캐시에 남기는 방식으로 메모리를 구현하게 됩니다. n개 버퍼에서 밀려난 과거 대화 이력은 자연스레 캐시에서 지워지게 되며, 이에 따라 LINER Chat은 해당 정보를 맥락에서 잊어버리게 됩니다.
즉, 최근 n턴 안에 나눈 대화를 기반으로 사용자가 대화를 이어나가고자 한다면 LINER Chat은 대화 이력을 바탕으로 답변을 생성할 수 있게 됩니다. 프롬프트 관점에서 보자면 <페르소나>
+ <사용자 정보>
+ <메모리>
+ <사용자 메시지>
와 같은 형태로 정보가 LINER Chat에 인입된다고 생각하시면 됩니다.
그렇다면 사용자가 일주일 전 LINER Chat과 나눈 대화를 상기시키고자 한다면 어떻게 해야 할까요? 해당 질문에 대한 답은 Long-term Memory
에서 찾을 수 있습니다. Long-term Memory
는 목적에 따라 여러 방법으로 구현될 수 있습니다. 이 중 가장 간단한 구현 방안은 사용자와 에이전트가 나눈 대화에서 중요하게 다루어 졌던 엔티티를 추출해 엔티티 단위로 기억을 형성하는 방식입니다.
그리고 최근에는 사용자와 에이전트 간 대화를 요약해 기억을 형성하려는 시도 역시 등장하기 시작했습니다. 뿐만 아니라 일자 별로 대화 내역을 텍스트로 저장해두었다가, 참조 정보 형식으로 Retrieve 해 맥락에 추가하는 방법 역시 Long-term Memory
구축을 위해 가능한 방안입니다. 현재 LINER Chat에는 Short-term Memory
만 구현되어 있으며, 2분기 Long-term Memory
구현을 통해 보다 개인화 된 대화의 경험을 제공하고자 합니다.
지금까지 현재 LINER Chat이 구현된 방식과 이를 위해 활용된 프롬프트 정보, 이를 활용한 엔지니어링에 대한 소개를 드렸습니다. 다음으로 LINER Chat의 미래안에 대해 살펴보겠습니다.
LINER Chat: Future @Plugins
LINER Chat이 공개된 3월 23일 OpenAI는 ChatGPT Plugins를 공개하며, 세상을 또 한 번 놀라게 했습니다. ChatGPT가 단순히 생성만 잘 하는 모델이 아닌, 뛰어난 Reasoning을 기반으로 세상에 존재하는 수많은 외부 API와의 연동 가능함을 세상에 보여준 것인데요.
사실 ChatGPT를 자체 서비스에 통합하기 위해 여러 장치를 고민하고 계셨던 분들이라면 이미 아키텍쳐 관점에서 LangChain 등을 통해 LLM이 어떻게 개발과 제품 생태계에 영향을 미치게 될 것인지에 대해 그림을 그려보셨을 것입니다. Microsoft는 같은 맥락에서 이미 Semantic Kernel 프로젝트를 활발히 진행 중이기도 하고요.
ChatGPT Plugins, LangChain, Semantic Kernel 등이 공통적으로 제시하는 미래상은 ChatGPT와 같은 대화형 모델이 사용자 요청을 받아, 사용자 요청 태스크를 수행하기 위해 외부 API / 데이터베이스 / 모델 등에 접근하고, 태스크 수행 결과를 조합해 다시 자연어로 사용자에게 반환하는 안입니다. 이는 최근 Microsoft에서 공개한 TaskMatrix.ai에서도 잘 소개되고 있습니다.
즉, 이제 LLM은 더 이상 Internal Memory & Knowledge에만 의존하는 단순 생성 모델이 아니라, 태스크 수행을 위해 외부 세계와 연결될 수 있는 인터페이스가 된 셈입니다. 그리고 해당 패러다임은 지구상에 존재하는 모든 IT 프로덕트 기업들로 하여금 제품 인터페이스 측면에서 새로운 고민의 장을 열어주게 되었습니다.
라이너 역시 ChatGPT 도입을 통해 가능해진 대화형 인터페이스의 제품 적용을 성공적으로 마친 후, Plugins
관점에서 여러 기능을 대화형 인터페이스에 통합하는 시도를 준비하고 있습니다. 순차적으로 보자면 (1) 사용자가 대화형 인터페이스를 통해 남긴 자연어 요청에 따른 태스크 수행을 위해 외부 기능 연동이 필요한지 판단합니다. (2) 외부 API가 필요한 경우 미리 등록해둔 여러 자체 도구 중 어떤 도구를 사용할지 결정 후, 실제 API 결과를 받아옵니다. (3) 최종적으로 API 결과를 활용해 답변을 생성해 사용자에게 반환합니다.
Plugins
프로젝트를 통해 우리는 LINER Chat을 사용자의 학습 여정을 기억하고, 사용자가 더 빨리 똑똑해질 수 있도록 도울 수 있는 개인화 에이전트로 발전시키고자 합니다. 따라서 LINER Chat은 학습 이력을 바탕으로 한 개인화 콘텐츠 추천, 콘텐츠 소비, 대화 등 여러 다양한 기능을 제공할 수 있는 개인화 에이전트로 진화하게 될 것 입니다.
맺으며…
LINER Chat은 ChatGPT가 불러온 새로운 패러다임에 있어, 대화형 인터페이스에 대해 팀원들과 여러 고민을 끝에 출시하게 된 제품입니다. 프로젝트를 진행하며 제가 특히 흥미롭게 관측한 것은 LINER Chat 배포 이후, 팀원들이 제품을 활용하는 방식이었습니다.
현재 LINER Chat이 제공 중인 기능이 아님에도, 으레 물어볼 법한 정보를 LINER Chat에게 자연스럽게 질문하는 팀원들이 많이 생겨난 것인데요. "당연히 대답할 수 있겠지"
와 같은 전제 하에 대화를 나누는 모습이었습니다. 때문에 날씨를 물어보는 팀원, 길을 물어보는 팀원, 주가를 물어보는 팀원, 예약 메시지를 부탁하는 팀원, … 정말 다양한 유즈 케이스가 발견되었습니다.
엔지니어인 저에게는 이러한 유즈 케이스들은 굉장히 흥미롭게 다가왔습니다. LINER Chat이 팀원들의 유즈 케이스를 모두 커버하며, 우리가 그 동안 갈고 닦아온 개인화 기술과 콘텐츠 소비 기술까지 하나의 인터페이스를 통해 제공할 수 있다면 흥미로운 그림이 그려질 수 있겠다는 생각이 들었기 때문입니다.
물론 이를 위해 풀어야 할 과제는 여전히 너무나도 많이 남아있습니다. 이번 글을 통해 소개드린 Prompt Engineering 역시 많은 부분에서 발전이 필요하며, Plugins 연동을 위해 외부 도구 선정 및 활용을 도와줄 수 있는 LangChain과 같은 프레임워크의 적용, 대화 경험 증진을 위한 Memory 강화 등 여러 챌린징 한 과제들을 풀어 나가며 라이너 만의 Help People Get Smart Faster 가치를 제공할 수 있는 개인화 에이전트를 만들어 보고자 합니다.
혹시 이번 글을 읽으며 흥미가 생기셨나요? 라이너는 LINER Chat, 개인화 추천 등 머신러닝을 통해 사용자에게 가치를 제공할 수 있는 태스크에 관심 있는 모든 분들에게 열려 있습니다! 전 세계 사용자들이 더 빨리 똑똑해질 수 있도록 돕기 위해 라이너가 나아가고 있는 여정에 많은 관심과 참여를 부탁드리며 글을 마치겠습니다. 긴 글 읽어주셔서 감사합니다 🙏