본문 바로가기

B급 개발물/메타휴먼 프로젝트

5. 대화 History와 Retrieval 정리

서론

대화 맥락을 잘 유지하는 챗봇은 어떻게 만들까?

LLM이 나오기전 전통적 챗봇들중에 일상대화에서 멀티턴을 제공하는 챗봇은 드물었다.

하지만 LLM이 나온뒤로는 대화 History를 넣을시 자동으로 맥락에 맞추어 대답하는 챗봇을 만들기 쉬워졌다.

 

그래도 아직 만능은 아닌데, 그 이유는 다음과 같다.

현재까지 나온 대부분의 LLM모델이 입출력값의 토큰수(길이)가 일정 갯수를 초과할 수 없다.

그렇다면 매우매우 긴 대화 데이터를 history 맥락으로서 제공해야한다면, 입력토큰 수 제한에 막혀 대화맥락을 모두 고려해서 말할 수 없게 된다.

 

이를 해결하기 위한 다양한 방법들에 대해서 정리해봤다.

본론

History

우선 chatbot이 대화맥락을 잘 유지하게 하기 위해서는 이전의 대화 데이터를 참고하여 대답 할 수 있게 해야한다.

그렇다면 가장 간단하게 생각해 볼 수 있는 아이디어는 그냥 단순히,

지금까지 대화했던 정보들을 전부 프롬프트에 입력시키는 방법이다.

 

예시를 들면 다음과 같다.

Step1

history: 

currunt conversation:
날렵한곰 : 난 공놀이를 좋아해

---------------------------------------
output:
AI : 공놀이를 좋아하는군요!
Step2

history: 
날렵한곰 : 난 공놀이를 좋아해
AI : 공놀이를 좋아하는군요!

currunt conversation:
날렵한곰 : 내가 뭘 좋아한댔지?

---------------------------------------
output:
AI : 공놀이요!
Step3

history: 
날렵한곰 : 난 공놀이를 좋아해
AI : 공놀이를 좋아하는군요!
날렵한곰 : 내가 뭘 좋아한댔지?
AI : 공놀이요!

currunt conversation:
날렵한곰 : 지금까지 우린 어떤 대화를 했지?

---------------------------------------
output:
AI : 저에게 공놀이를 좋아한다는 사실을 알려줬어요

 

이렇게 추가하면 확실히 맥락을 잘 유지하지만 문제가 있다.

 

대화의 내용이 너무 길어지면, 대답에 필요로 하지 않는 데이터까지 참고하여 대답하게 되고, 이는 성능 저하로 이어진다.

그리고 내용이 일정 이상 길어지게 된다면, LLM의 최대 토큰수에 걸려서 문제가 생긴다.

 

그렇다면 이런 문제들은 어떻게 해결할까?

 

Conversation Summarization

첫번째로 대화를 요약하는 방식이다.

대화를 요악하는 방식은 다양하지만 간단한 예시로 설명하자면 다음과 같은 구조를 두면 된다.

 

 

간단하게 그려보면 다음과 같은 구조가 되는것이다.

 

 

KnowLedge Graph

기존의 대화를 대화 형식이 아닌 지식 그래프화 시켜 용량을 압축하는것이다.

 

이것도 간단하게 예시를 들어보자면 다음과 같다. 어떤 문장에서 의미있는 정보만을 추출하여 데이터화 시키는 것이다. 

지식 그래프는 만드는 방법이 여러가지 있는데 아래의 예시는 3단 지식 그래프이다.

주체= 김민수, 속성= 좋아하는 운동, 대상= 축구

 

이렇게 만들어서 데이터베이스화 시켜놓으면 좋은 점이, 참고할 것만 가져오면 된다는 것이다.

예를들면 유저가 김민수가 좋아하는 음식은 뭐야? 라고 질의했을때!

[김민수, 좋아하는, 음식] 이렇게 3개만으로 검색해도 지식그래프에서 유의미한 정보를 찾아낼 수 있고

찾아낸 내용들을 프롬프트에 삽입하는 방법도 가능해진다. 

 

더 나아가서 이런 지식그래프의 기반이 되었던 텍스트 정보도 같이 입력해준다면,

너가 어제 축구 좋아한다고 말했었잖아~ 같은 흐름의 대화도 얻을 수 있게 되는 디테일이 생긴다.

 

Vector DB

벡터 데이터베이스를 이용하는 방법이다.

Vector DB는 vector 데이터를 이용하여 데이터를 검색할 수 있게한 데이터베이스다.
이는 Embedding 모델이랑 사용하면 매우 유용하게 사용할 수 있다.

 

예를 들면 "야 농구장에서 치킨 시켜먹을래?" 라는 질문을 받았을때,

AI가 "그래 양념치킨으로 시키자" 라고 대답했다면

 

이 대화 쌍이 Vector Embedding 되어서 데이터베이스에 저장된다.

그러면 이후에 "우리 저번에 농구장에서 뭐시켜 먹었지?" 라는 질의를 했을때

해당 대화를 벡터화 한뒤에 벡터데이터베이스에서 가장 벡터거리가 가까운 대화 쌍을 N개 검색하여,

해당 대화를 참고할 수 있게 로직을 작성할 수 있다.

 

이런 구조로 사용이 가능하다.

 

응용구조

다음의 방법들을 선행했다면 해당 방법들 혹은 다른 방법들을 잘 섞어서 효율적인 흐름을 구현해 낼 수 있다.

프롬프트 엔지니어링 응용 시뮬레이터를 구현한 논문인 Generative Agent 에서는 다음과 같은 구조로 작성되었다.

해당 논문이 가장 해당 모델들을 잘 응용 한 기초 논문이라 생각 되어 가볍게 언급하려한다.

 

사실 해당 논문은 이 프로젝트를 하고자하는 발동(?)을 걸어준 논문 중 하나이다.

 

https://arxiv.org/abs/2304.03442
https://arxiv.org/abs/2304.03442

해당 논문에서는 이전의 기록들을 참고하기 위한 우선순위를 정하는 것이 최신성, 중요도, 관련도를 모두 고려하여 점수를 정하게 하고 해당 점수가 높은 N개의 데이터를 참고하게 했다. 또한 Reflect 스텝으로 지식 그래프를 더 확장하기도 한다.

 

결론

다음과 같이 History와 Retrieval에 대하여 간단하게 정리해봤다. 히스토리는 대화에 있어서 단연 중요한 요소이다. 대화의 맥락을 유지시켜주고 중요한 내용을 떠올리게 만들어주고 지식들을 연결시켜주기 때문이다. 이를 적절히 구현하는것이 대답의 퀄리티를 크게 바꾸어 놓기 때문에 계속해서 구조를 변경하며 실험해야 할 것 중 하나이다.

 

 

 

 

'B급 개발물 > 메타휴먼 프로젝트' 카테고리의 다른 글

7. RAG를 위한 Vector DB 비교  (0) 2024.03.05
6. 첫번째 POC 개발 및 테스트  (0) 2024.03.04
4. LLM 모델조사  (0) 2024.03.01
3. TTS 모델 조사  (0) 2024.02.28
2. STT 구현 고찰 및 모델 조사  (0) 2024.02.24