Tell-i : LLM Agent 서비스 구축기 (1)

LLM AI Agent 도입에 필요한 기술을 소개합니다.(MSA, RAG, Embedding)
김건호's avatar
Oct 08, 2024
Tell-i : LLM Agent 서비스  구축기 (1)

1. 들어가며


 
🧑‍💻
반갑습니다, AI Product 팀 (이하 AIP)의 Data Scientist 김건호입니다.
AIP는 머신러닝, 딥러닝, LLM 등 AI 기술에 기반한 서비스를 통해 유저들에게 더욱 편의성 높은 서비스를 구축하는 것을 목표로 하고 있습니다. 특히, 리뷰를 비롯하여 다양한 정보를 찾아 떠나는 잡플래닛 유저 분들의 여정에 지도와 이정표가 되는 서비스를 만들고 있습니다.
 
이번 포스팅에서는 AIP의 챗봇 서비스 Tell-i 에 사용된 기술에 대한 개념, 그리고 서비스의 핵심이 되는 RAG 기술을 위한 Vector Database의 개발 여정을 소개합니다.
 
Tell-i는 최신 LLM 기술들과 프레임워크에 기반한 서비스로, 잡플래닛 유저 여러분들이 한자리에서 잡플래닛의 방대한 데이터를 챗봇과의 대화를 통해 탐험하실 수 있도록 개발되었습니다. 유저분들께서는 필요한 정보를 찾기 위해 검색하는 과정에서 불편함을 느끼셨을 것으로 생각합니다. 원하는 정보를 확인하기 위해 수많은 리뷰 페이지를 하나씩 찾아보거나, 채용 공고를 하나씩 뒤적이는 과정은 생각보다 많은 시간이 소모되었을 거예요. Tell-i는 유저분들의 이러한 불편함을 조금이나마 덜어드리고자 개발되었습니다.
notion image

2. LLM as a Service


2. 1. LLM 기반의 서비스를 구축한다는 것

 
Image Generated by GPT-4o
Image Generated by GPT-4o
 
LLM 기반 챗봇은 대형 언어 모델(Large Language Model)을 활용하여 자연스러운 대화와 높은 수준의 이해력을 제공하는 시스템입니다. 이러한 챗봇은 방대한 양의 데이터를 학습하여 문맥을 이해하고, 다양한 주제에 대해 유연하게 대응할 수 있습니다. 이를 통해 사용자에게 보다 개인화된 경험과 정확한 정보를 제공할 수 있습니다.
 
그러나 LLM 기반 서비스를 구축하는 데에는 몇 가지 어려움이 있습니다.
 
첫째, LLM은 고도의 연산 자원이 필요하므로 서버 비용이 급증할 수 있습니다. 또한, 모델을 지속적으로 학습하고 배포하기 위해서는 연산 자원뿐 아니라, 데이터의 수집 및 정제 작업에 대한 꾸준한 관리가 필요하며, 이를 담당할 인적 자원을 전담 배치해야 하는 부담 또한 발생할 수 있습니다.
 
둘째, 모델의 크기와 복잡성이 증가함에 따라 배포 및 업데이트 과정도 복잡해지고, 시간이 더 많이 소요됩니다. 모델이 커질수록 서비스 품질은 향상되지만, 그만큼 비용 증가와 배포 지연이 발생해 서비스 개선에 있어 큰 걸림돌이 될 수 있습니다.
 
저희는 이러한 어려움을 미리 인지하고, 최근 주목받고 있는 상대적으로 작은 언어 모델인 SLM(Small Language Model)을 재학습하고 테스트를 통해 적용해 보았습니다. 그러나 유지 관리 비용과 성능이 떨어지는 문제로 인해 OpenAI의 GPTGoogle의 Gemini같은 상업용 LLM모델들이 더 나은 선택임을 확인하였습니다. 이 모델들은 성능 면에서 우수할 뿐 아니라, 오히려 비용 또한 더 경제적이었습니다.
따라서 저희는 서비스에 상업용 LLM을 도입하기로 결정하였습니다. 특히, 상업 모델 중 가장 저렴한 옵션을 선택하는 한편, RAG (Retrieval-Augmented Generation) 기법을 통해 Hallucination 현상을 제거하여 답변의 안정성을 도모하고, 동시에 비용 최소화를 달성하였습니다.
 
더하여, 업데이트 및 배포 과정에 있어서 유연한 대응을 위해 MSA(Microservices Architecture) 구조를 채택하였습니다. 마이크로서비스 아키텍처를 통해 대화 처리, 데이터 업데이트, 데이터 관리 등 각 기능을 독립적인 서비스로 분리하여 개발하고 배포하였습니다. 이를 통해 특정 기능을 수정하거나 확장할 때 전체 시스템에 미치는 영향을 최소화할 수 있었으며, 모바일 애플리케이션 배포와 별개로 서비스 업데이트를 할 수 있었습니다.
 

2. 2. Microservice Architecture (MSA)

notion image

모놀리식 아키텍쳐 (Monolithic Architecture)

모놀리식 아키텍처는 애플리케이션의 모든 기능이 하나의 통합된 코드베이스로 구성된 구조를 말합니다. 이 방식에서는 사용자 인터페이스, 비즈니스 로직, 데이터베이스 접근 등 모든 요소가 단일 프로젝트 내에서 관리됩니다. 개발과 배포 과정이 단순하여 작은 규모의 프로젝트나 초기 단계의 제품 개발에 적합합니다.
하지만 모놀리식 구조는 애플리케이션이 커질수록 유지보수와 확장이 어려워지는 단점이 있습니다. 하나의 기능에 변경을 가하더라도 전체 애플리케이션을 재배포해야 하며, 이는 개발 속도를 저하하고 오류 발생 시 전체 시스템에 영향을 미칠 수 있습니다.
 

마이크로서비스 아키텍쳐 (Microservice Architecture; MSA)

마이크로서비스 아키텍처는 애플리케이션을 여러 개의 작은 서비스로 분할하여 각각 독립적으로 개발하고 배포하는 방식입니다. 각 서비스는 특정 기능이나 비즈니스 영역을 담당하며, 다른 서비스들과 API를 통해 통신합니다. 이를 통해 각 서비스는 독립적으로 업데이트하고 확장할 수 있어 유연성이 높아집니다.
예를 들어, 온라인 쇼핑몰에서는 결제 서비스, 상품 관리 서비스, 사용자 인증 서비스 등을 개별의 마이크로서비스로 분리할 수 있습니다. 이렇게 하면 결제 서비스에 문제가 생기더라도 다른 서비스에는 영향을 최소화하여 전체 시스템의 안정성을 높일 수 있습니다.
 

저희는 MSA를 채택했어요.

모놀리식마이크로서비스의 차이점은 시스템 구성 방식과 유연성에 있습니다. 모놀리식은 모든 기능이 하나의 애플리케이션에 포함되어 있어 개발과 배포가 단순하지만, 확장성과 유지보수에 한계가 있습니다. 반면 마이크로서비스는 기능별로 서비스를 분리하여 독립적으로 관리함으로써 유연성과 확장성을 높입니다.
 
마이크로서비스를 사용하면 팀 간 협업이 용이해지고, 각 서비스에 적합한 기술 스택을 선택할 수 있어 개발 효율성이 향상됩니다. 또한 서비스별로 독립적인 스케일링이 가능하여 리소스 활용을 최적화할 수 있습니다. 이는 대규모 시스템에서 성능과 안정성을 유지하는 데 큰 장점으로 작용합니다.
 
notion image
 
저희 AIP는 이러한 마이크로서비스의 장점을 활용하고자, Tell-i를 두 개의 레이어로 분리했습니다. RAG에 필요한 데이터를 Vector DB에 Embedding 하는 Database Layer, 그리고 유저의 질문에 맞추어 답변하는 LLM 서비스가 구축되어 있는 Service Layer로 구성하였습니다.
 
이를 통해서, 데이터를 변환 및 저장에 있어서 변동사항이 발생하거나 새로운 데이터를 추가하는 데에 서비스에 지장을 주지 않고 업데이트 할 수 있도록 하였습니다. 더해서, App과 분리된 Service Layer로 App의 종류, 배포 일정과 관련없이 서비스를 꾸준히 업데이트할 수 있도록 구성하였습니다.
 

2. 3. Retrival-Agumented Generation (RAG)

Image Generated by GPT-4o
Image Generated by GPT-4o
 
RAG(Retrieval-Augmented Generation, 검색 증강 생성)검색 시스템과 대형 언어 모델(LLM)의 강점을 결합하여, 정보에 기반한 문맥을 반영한 응답을 생성하는 기술입니다. RAG는 LLM 기술 중에서 널리 알려진 편이지만, 아직은 기술 도입 초기 단계로, 대중적이진 않습니다. 우선, RAG의 각 구성 요소를 자세히 살펴보고, 예시를 통해 그 작동 방식을 이해해 보겠습니다.
 
1. 질문 (Question)
RAG 시스템의 시작점은 사용자가 제시하는 질문입니다. 이 질문은 자연어로 표현되며, 사용자는 이에 대한 명확하고 신뢰할 수 있는 답변을 기대합니다. 질문은 단순한 사실 확인부터 복잡한 개념의 이해까지 다양할 수 있습니다.
 
🔎
예시 "2020년 노벨 물리학상 수상자는 누구이며, 그들이 수상한 업적은 무엇인가요?"
 
2. 검색기 (Retriever)
검색기는 질문에 대한 관련 정보를 대규모 데이터베이스나 인터넷에서 찾아내는 역할을 합니다. 이 단계에서는 자연어 처리 기술과 정보 검색 알고리즘이 활용됩니다. 검색기는 질문의 핵심 키워드를 파악하고, 이에 맞는 최신의 정확한 정보를 수집합니다.
 
  • 질문 분석: 질문에서 중요한 키워드와 개념을 추출합니다. 예를 들어 "2020년", "노벨 물리학상", "수상자", "업적" 등이 있습니다.
  • 정보 수집: 추출된 키워드를 기반으로 신뢰할 수 있는 출처에서 관련 문서나 데이터를 검색합니다.
  • 관련성 평가: 수집된 정보 중 질문과 가장 밀접하게 관련된 내용을 선별합니다.
 
🔎
예시 검색기는 "로저 펜로즈, 라인하르트 겐첼, 안드레아 게즈가 2020년 노벨 물리학상을 블랙홀 연구로 수상했다"는 내용을 포함한 기사를 찾아냅니다.
 
3. 문맥 (Context)
검색기를 통해 수집된 정보는 LLM이 답변을 생성하는 데 필요한 문맥을 제공합니다. 이 문맥은 답변의 정확성과 깊이를 결정하는 중요한 요소로서, 단순한 사실 나열이 아닌 질문의 의도와 관련된 상세한 정보를 포함합니다.
 
🔎
예시 문맥에는 각 수상자의 연구 분야, 그들이 발견한 내용, 해당 연구의 중요성 등이 포함됩니다. 예를 들어, 로저 펜로즈는 일반 상대성이론과 블랙홀의 형성에 대한 이론적 연구를 수행했고, 라인하르트 겐첼과 안드레아 게즈는 우리 은하 중심의 초대질량 블랙홀의 존재를 관측을 통해 확인했습니다.
 
4. 대형 언어 모델 (Large Language Model)
LLM은 제공된 문맥과 사용자의 질문을 함께 처리하여 자연스럽고 일관된 답변을 생성합니다. 이 모델은 방대한 학습 데이터를 기반으로 언어의 구조와 의미를 이해하며, 복잡한 정보도 쉽게 이해할 수 있는 형태로 재구성합니다.
 
  • 문맥 이해: LLM은 제공된 문맥의 내용을 심층적으로 분석하여 핵심 정보를 파악합니다.
  • 질문 해석: 사용자의 질문 의도를 정확히 이해하고, 어떤 정보가 필요한지 결정합니다.
  • 응답 생성: 문맥에서 필요한 정보를 추출하여 질문에 직접적으로 답변하는 문장을 생성합니다.
 
🔎
예시 LLM은 "2020년 노벨 물리학상은 로저 펜로즈가 블랙홀 형성에 대한 이론적 연구로, 라인하르트 겐첼과 안드레아 게즈가 우리 은하 중심의 초대질량 블랙홀을 발견한 공로로 수상했습니다."라는 완성도 높은 답변을 만들어냅니다.
 
5. 응답 (Response)
최종 단계에서는 LLM이 생성한 답변을 사용자에게 전달합니다. 이 응답은 정확하고 유용한 정보를 담고 있으며, 자연스러운 언어로 표현되어 사용자의 이해를 돕습니다.
 
🔎
예시 사용자는 "2020년 노벨 물리학상은 로저 펜로즈, 라인하르트 겐첼, 안드레아 게즈가 블랙홀 연구로 수상했습니다. 펜로즈는 블랙홀 형성에 대한 이론적 기반을 마련했으며, 겐첼과 게즈는 우리 은하 중심의 초대질량 블랙홀을 관측했습니다."라는 상세한 답변을 받게 됩니다.
 

2. 4. 프레임워크 Framework

notion image
Llama IndexLangChain은 모두 대형 언어 모델(LLM)을 활용한 애플리케이션 개발을 돕는 라이브러리입니다. 하지만 각각의 목적과 기능에 차이가 있어, 필요에 따라 적절한 선택이 중요합니다.
 
Llama Index는 LLM이 외부 데이터 소스와 효율적으로 상호작용을 할 수 있도록 돕는 데이터 프레임워크입니다. 주로 문서, 데이터베이스 등 다양한 형태의 데이터를 인덱싱하여 LLM이 필요한 정보를 신속하게 검색하고 활용할 수 있게 해줍니다. 예를 들어, 방대한 양의 문서를 Llama Index를 통해 인덱싱하면, 사용자는 자연어 질문을 통해 원하는 정보를 정확하게 얻을 수 있습니다.
 
반면에 LangChain은 LLM 기반 애플리케이션을 구축하기 위한 보다 일반적인 프레임워크입니다. LangChain은 프롬프트 체인, 메모리 관리, 에이전트 구성 등 다양한 컴포넌트를 제공하여 복잡한 언어 모델 애플리케이션을 개발할 수 있게 해줍니다. 예를 들어, LangChain을 사용하면 사용자 입력을 기반으로 여러 단계의 처리 과정을 거쳐 결과를 도출하는 챗봇이나 자동화된 의사결정 시스템을 구축할 수 있습니다.
 
두 라이브러리의 주요 차이점은 목적과 활용 범위에 있습니다. Llama Index는 데이터 인덱싱과 검색에 특화되어 있어, LLM이 외부 데이터를 효율적으로 활용하는 데 초점을 맞추고 있습니다. 반면 LangChain은 애플리케이션 로직과 흐름 제어에 중점을 두어, 복잡한 상호 작용과 프로세스를 관리하는 데 적합합니다.
notion image
저희 AIP는 면밀히 두 프레임워크를 비교 후, Llama Index를 채택했습니다. Llama Index를 사용한 이유는 다음과 같습니다. 우선, Tell-i는 대량의 문서를 처리하면서 사용자 질문에 대해 정확하고 빠른 응답을 제공해야 했습니다. 이때 Llama Index의 강력한 인덱싱 기능을 활용하여 데이터를 구조화하고, Embedding까지의 파이프라인을 빠르고 효율적으로 구축할 수 있었습니다. 더하여, 유연한 Retrieval 모듈을 통해 LLM과 연계하여 효율적인 검색 시스템을 구축할 수 있습니다.
 
물론, 저희의 경우에도 Langchain의 로직과 흐름 제어 기능의 수준을 서비스에 반영할 필요가 있었습니다. 하지만 두 개의 프레임워크를 혼용해서 사용한다면 향후 유지보수 및 개발 복잡도 상승이 예상되었습니다. 따라서 reverse enginnering을 통해 Llama Index의 모듈을 low-level에서 접근하여 기능들을 구현하였습니다.
 

3. 데이터


3. 1. 문서 Document

 
그렇다면 RAG를 위해서는 어떤 형태의 데이터가 필요할까요? 이 질문에 대한 답은 ‘문서 Document’라고 할 수 있습니다. 여기서 문서란, 기술적인 의미에서 Document DB와 그에 대응하는 저장되는 JSON 구조를 의미하는 것이 아닌, 우리가 일상적으로 사용하는 문서를 의미합니다. 예를 들어서, 저희 AIP에서 현재 채용 중인 아래의 백엔드 엔지니어 포지션의 공고는 하나의 문서로, 방대한 양의 정보를 포함하고 있습니다. RAG는 답변에 필요한 정보를 마치 하나의 워드 파일과 같이 작성되어 있는 문서를 기반으로 동작합니다.
 
notion image
 
RAG는 이러한 문서를 컴퓨터가 인식할 수 있는 숫자로 바꾸어주는 임베딩 Embedding을 통해 변환합니다. 그리고 앞서 설명해 드린 ‘검색기 Retriever’는 유저의 질문을 임베딩하고, 수학적으로 유사한 문서를 대조하는 방법을 통해서 질문에 알맞은 문서를 찾아냅니다. 따라서 문서는 RAG 기술의 도입을 위해서 반드시 구축되어야 하는 데이터 형태로 볼 수 있습니다.
 
그럼 실제 데이터는 어떻게 저장되어 있을까요? 저희 잡플래닛을 비롯해, 대부분의 회사는 기본적으로 관계형 데이터베이스(Relational Database; 이하 RDB)에 데이터를 저장합니다. 많이 사용하시는 엑셀이나 구글 스프레드시트 같은 방식을 생각하시면 됩니다. 다만, 파일이 너무 커질 수 있으니 파일을 나누어 둔 것과 같습니다.
 
notion image
 

3. 2. 관계형 데이터베이스에서 문서

RDB를 하나의 문서로 재구성하려면, 분리되어 있는 파일들을 합친 뒤, 각 열(Column)에 맞게 데이터를 재조합해 주면 됩니다. 방법은 다양하지만, 보통 SQL Query에서 지원하는 concat을 사용해 합쳐준다면, 여러 데이터베이스를 조회하여 문서로 통합하는 것이 어렵지 않습니다.
 
하지만, 단순하게 문서를 합쳐서 임베딩 하는 것이 끝은 아닙니다. 왜냐하면, 저희는 Tell-i의 답변에 정확성과 더불어 일관성을 확보해야 하기 때문입니다. 따라서 문서에 요약키워드 추출 을 통해서 답변의 토대를 갖추고, 이후 전체 문서와 유저의 질문과 결합해서 답변을 생성합니다.
 
요약키워드 추출 을 위해서는 별도의 프롬프트 엔지니어링을 통해서 퀄리티를 확보하였습니다. 가장 단순한 형태의 프롬프트, 예컨대, “다음의 글을 요약해줘”와 같은 프롬프트도 충분히 유용합니다. 하지만 요약이 너무 짧게 되거나, 반드시 들어가야 할 정보가 누락되어 요약되는 경향성이 있습니다. 마찬가지로 키워드 추출 역시 비즈니스와 관련하여 강조가 필요한 영역에 대해서 별도의 프롬프팅을 통해서 수행하였습니다.
 
생성된 요약과 키워드는 메타데이터 Metadata를 별도의 항목으로 구성하여 추가하였습니다. 미래의 활용성을 고려하여 ID 코드와 같은 정보들을 더해서 한 건의 문서를 조회 할 때, 다양한 방식으로 확장이 가능한 Multi-soruce Multi-Use 를 추구하였습니다.
 

3. 3. 임베딩 Embedding

 
데이터를 충분히 정리되었다면, 임베딩을 수행할 차례입니다. 기본적으로 언어모델을 사용하는 것이기 때문에, 이 과정에서 로컬 모델 Local Model 을 쓸 것인지, 아니면 상용 모델 Commercial Model 을 쓸 것인지, 또 세부적으로 어떤 모델을 채택할 것인지에 대한 의사결정을 해야합니다. 모델이 한번 결정되면 이를 변경하는 것은 몹시 어렵습니다. 각 모델 마다 임베딩 된 숫자가 다르고, 따라서 기존의 임베딩은 다른 모델로 검색(retrival) 할 수 없기 때문입니다.
따라서, 저희는 다음의 두 관점에 기반하여 임베딩 모델을 결정하였습니다.
 
첫번째 관점은 비용입니다. 로컬 모델을 사용한다면 이를 위한 GPU 서버를 구성해야하고, 데이터를 업서트(Upsert; 기존 데이터를 업데이트하거나 새로운 데이터를 삽입하는 것) 마다 서버와 통신이 필요합니다. 따라서 GPU 서버에 대한 별도의 리소스가 필요합니다. 반면, 상용 모델을 사용 할 경우, 별도의 GPU 서버가 필요없습니다. 또한 임베딩의 경우 그 비용이 몹시 저렴하여 상용 모델을 채택하였습니다.
 
두번째 관점은 성능입니다. 최근 가장 각광 받는 모델은 단연 OpenAItext-embedding-3-smalltext-embedding-3-large, Googletext-embedding-004text-multilingual-embedding-002 이 있습니다.
 
성능 비교에 앞서 비용에 대해서 우선적으로 검토하였습니다. 비교 단위가 글자 수(Character)와 토큰 (Token, 문자가 숫자로 변환되었을 때 단위) 로 다르지만, 80배가량의 차이가 있습니다. 실제 데이터에서는 약 30~50배 차이를 예상하였습니다. 따라서, 비용 우위에 있어서는 Google의 모델들이 상당히 강한 우위에 있는 것으로 판단됩니다. 따라서 성능에 있어서 OpenAI의 모델들이 강한 성능 우위에 있어야 합니다.
 
Provider
모델
비용 (달러)
Google
text-embedding-004 (영문 특화)
$0.00025 / 1M Character
Google
text-multilingual-embedding-002 (다국어)
$0.00025 / 1M Character
OpenAI
text-embedding-3-small
$0.02 / 1M Tokens
OpenAI
text-embedding-3-large
$0.13 / 1M Tokens
 
모델 간의 성능 비교를 위해서 문서를 구성 후, 임베딩 - 검색(retrival)을 차례로 테스트하여 데이터셋 내, 적절한 문서 찾아내는지 평가하였습니다. 아래의 결과에 제시된 바와 같이 종합 결과는 OpenAI text-embedding-3-large > Google text-multilingual-embedding-002 > OpenAI text-embedding-3-small > Google text-embedding-004 순으로 성능에 차이가 있었습니다.
OpenAI text-embedding-3-large 의 성능이 Google text-multilingual-embedding-002 에 비하여 우수하지만, 저희는 비용적인 측면을 고려할 때 압도적인 수준이라 판단하지 않아 최종적으로 Google text-multilingual-embedding-002 모델을 채택하였습니다.
 
notion image
 

4. 끝으로

 
LLM 기반 서비스들이 많이 나오고 있지만, 아직은 기반 기술에 대한 대중적인 인지도는 그리 높지 않습니다. 특히, Tell-i 는 그 중에서도 최신 기술인 LLM Agent를 기반으로 하기 때문에, 이해하는데에 조금 어려움이 있으 실 수 있어서 기본 개념을 설명드리는 포스팅을 작성하였습니다. 다시 한번 주요 개념에 대해서 정리해보겠습니다.
 
  • 마이크로서비스 아키텍처 Microservices Architecture; MSA 애플리케이션을 작은 독립적인 서비스들로 분리하여 개발하고 배포하는 방식입니다. 각 마이크로서비스는 특정 기능을 담당하며, 서로 독립적으로 동작하고 배포될 수 있습니다.
  • RAG Retrieval-Augmented Generation 언어 모델에서 정보를 생성할 때, 검색기 Retriever를 통해 답변과 관련있는 정보를 외부 데이터베이스나 문서에서 찾아 더욱 정확한 답변을 제공하기 위한 기술입니다.
  • 임베딩 Embedding 텍스트 데이터를 수치화하여 모델이 이해할 수 있는 형태로 변환하는 기술입니다. 글자(텍스트)는 비구조화된 데이터로서, 언어 모델이 이를 직접 처리하기 어렵습니다. 따라서 언어 모델이 이해 할 수 있는 형태인 숫자로 변환하여 이를 해결하는 기술입니다.
 
 
이제 ‘LLM은 신기해!’ 라는 기술 인지 단계에서 ‘LLM으로 무엇을 만들어야하지?’라는 기술 도입 단계로 전환이 이루어지고 있습니다. 아직은 서비스 구축을 위한 레퍼런스가 적어서 많은 시도와 어려움을 겪었는데요.
 
다음 포스팅부터
 
  • 데이터를 확보하기위한 기준과 자동화, 그리고 one-source-multi-use 를 위한 접근 방법
  • 일관성 있는 답변을 제공하기 위한 Agent Tool System
 
을 개발하면서 겪었던 Trial and error, 그리고 구축기에 대해서 공유드리겠습니다.
 
 
Share article
Subscribe to 잡플래닛 테크블로그

#잡플래닛 테크블로그 #잡플래닛 기술블로그