안녕하세요, 저의 챗봇 제작 여정 그 첫 번째로 챗봇에게 CSV 파일을 먹여 본 후기를 공유합니다 😃
Pain Point
저는 국내 최대 규모 포켓몬 배틀 공략 웹사이트 포케모음(https://pokemoem.com/)을 운영하고 있는 학생 개발자 류나(류준범)입니다.
제 웹사이트는 포켓몬 게임의 배틀 컨텐츠에 대한 공략을 다양한 방식으로 제공하여 월 방문횟수 약 10만 명을 달성하고 있으며, 사용자들이 추가적으로 소통할 수 있고 게임 대회도 진행되는 디스코드 서버 또한 900명 정도의 인원으로 활성화되어 있습니다.
웹사이트와 디스코드 서버 운영자로서, 웹사이트에서 어렵지 않게 확인할 수 있는 내용을 포함해서 배틀 공략에 대한 기본적인 질문들이 디스코드에 종종 올라온다는 것이 챗봇을 구상하게 된 Pain Point가 되었습니다. 저는 취업 준비나 학교 일 등으로 매우 바쁘고 디스코드 서버 스태프들도 마찬가지로서 질문에 일일히 대답해 줄 시간이 부족합니다. 한편 사용자들은 포켓몬 게임의 특성 상 저연령층이 대부분이기 때문에 웹사이트의 다양한 정보를 해석하기 어려워할 수도 있어서 챗봇이 있다면 이용할 유인은 충분히 있다고 생각하였습니다.
라고 거창하게 적어 두지만… 사실 별 거 없습니다.
뭔가 되게 멋진 챗봇을 만들고 싶었는데 여러 번의 시도가 실패해서 꿈이 쪼그라들어 작고 귀여운 챗봇을 만드는 것으로 선회하였습니다!
챗봇 개발 과정
2024 년 1월에 챗봇을 처음으로 개발하려고 시도하였고, 이때는 RAG의 개념을 전혀 몰랐기 때문에 OpenAI GPT API가 지원하는 function call 기능을 최대한 사용하려고 하였습니다.
예를 들어, ‘피카츄’의 게임 내 기본 정보를 반환하는 함수, ‘피카츄’가 배틀 컨텐츠에서 어떤 쓰임새를 가지는지의 정보를 반환하는 함수, ‘피카츄’가 ‘10만볼트’ 기술을 사용하여 ‘꼬부기’에게 얼마의 데미지를 줄 수 있는지 계산한 결과를 반환하는 함수 등 제가 원하는 기능들을 Python으로 구현한 뒤 GPT API에 붙여 FastAPI로 배포해 보았습니다.
그러나 RAG를 사용하지 않은 초기 챗봇은 다음의 문제를 가지고 있었습니다.
한 번에 한 가지 기능밖에 하지 못합니다. 즉 여러 방면의 정보를 적절히 혼합하여 해석하지 못하기 때문에 여러번 묻고 그 결과들을 사용자가 직접 조합해야 합니다.
Function call을 사용할 때 답변 속도가 매우 느립니다. 짧으면 40초, 길면 2분 가량 걸렸습니다.
토큰 수 제한에 걸려 답변을 제대로 생성하지 못하고 에러가 자주 납니다. 이것은 Function call로 반환된 데이터의 크기가 클 수 있기 때문으로 생각됩니다.
특히 느린 속도가 큰 문제였기 때문에 결국 챗봇이 올라간 웹사이트의 높은 접근성이라는 장점에도 불구하고, 챗봇 서비스의 사용 자체가 매우 적은 상황이었습니다.
초기에는 위와 같은 어려운 점들이 있었고… RAG가 구세주라고 생각했지만! 현실이 그리 간단하지는 않습니다.
RAG를 알게 된 뒤 처음에는 txt 형식으로 정보를 줄글로 변형해 보았고요, 원하는 결과가 나오지 않는 상황에서 부트캠프 OT 때 csv 형 식으로 바꿔 보는 것이 어떻겠냐고 추천을 받았습니다.
그래서 6개의 CSV 파일을 만듭니다.
pokedex.csv 포켓몬의 종류와 기본 정보
abilities.csv 포켓몬의 특성
items.csv 포켓몬이 장비할 수 있는 도구
moves.csv 포켓몬의 기술
natures.csv 포켓몬의 성격
typechart.csv 포켓몬의 타입 간의 상호작용
그리고 벨루가(Veluga)와 GPTs 챗봇을 각각 만들었습니다.
Veluga에는 고급 설정을 하고 싶었는데, 프롬프트를 잘 만드는 법을 몰라서 못 했어요 😞 여러분의 비결을 알려주세요… 그리고 앞서 만든 CSV 파일들을 때려넣어 학습시킵니다.
GPTs에도 마찬가지로 파일을 때려넣는데, CSV 파일은 TXT 등과 다르게 ‘코드 인터프리터’ 기능을 켜야만 사용할 수 있다는 사실을 알게 됩니다. 그래서 GPTs의 지침에다가 ‘CSV 파일을 읽으려면 코드 인터프리터를 꼭 사용할 것’을 명시해 두었습니다.
결과물 공유
질문 1. 스텔라 타입은 어떤 타입이고, 다른 타입과 어떻게 상호작용하는지 설명해 줘.
정답 1. 스텔라 타입은 포켓몬의 타입 중 하나. 스텔라 타입 이외의 타입과는 상호작용 없이 1배의 데미지를 주고받음. 스텔라 타입끼리는 2배의 데미지를 주고받음.
질문 의도: typechart.csv의 내용을 이용한 간단한 추론 테스트.
Veluga: 스텔라 타입은 Normal 타입이며, 다른 타입과 상호작용할 때 특별한 효과가 있지 않습니다.
=> Normal 타입이라는 게 어떤 의미인지 이해하기 어렵습니다. 뒤의 설명은 맞습니다.
GPTs: 스텔라 타입은 대부분의 다른 타입에 대해 피해를 표준적으로 받지만, 스텔라 타입의 기술은 스텔라 타입의 포켓몬에게 2배의 데미지를 입히는 특성이 있습니다. 다른 모든 타입들은 스텔라 타입에 대해 표준 1배의 피해를 입힙니다.
=> 정확한 설명입니다.
질문 2. 사령탑 특성은 어떤 포켓몬이 가지고 있고, 어떻게 상호작용이 이루어지는지 설명해 줘.
정답 2. 사령탑 특성은 싸리용(Tatsugiri)만이 가지며, 싸리용과 어써러셔(Dondozo)가 필드에 함께 나와 있는 상황에서 싸리용이 어써러셔의 입 안으로 들어가 지시를 내리는 방식으로 상호작용이 이루어짐. 이 과정에서 어써러셔의 모든 능력이 2배로 오름.
질문 의도: abilities.csv의 내용과 pokedex.csv의 내용을 모두 사용하는 추론 테스트.
Veluga: Commander (사령탑)
영문 이름: Commander
국문 이름: 사령탑
일본어 이름: しれいとう
설명: 이 포켓몬이 Tatsugiri이고 Dondozo가 활성 상태인 경우, 이 포켓몬은 Dondozo의 입으로 들어갑니다. Dondozo의 공격, 특수 공격, 속도, 방어, 특수 방어가 2단계씩 상승합니다. 이 효과 중에는 Dondozo를 교체할 수 없으며, 이 포켓몬은 행동을 선택할 수 없으며, 이 포켓몬을 향한 공격은 피할 수 있지만 간접적인 피해를 입습니다. 이 포켓몬이 효과 중에 쓰러지면 대체 포켓몬을 교체할 수 있지만 Dondozo는 여전히 교체할 수 없습니다. 효과 중에 Dondozo가 쓰러지면 이 포켓몬은 다시 행동을 선택할 수 있습니다.
특성: {'틀깨기로 깨질 수 있음': False, '화학변화가스로 억제될 수 없음': False, '스킬스웹하면 실패함': True, '트레이스할 수 없음': True, '변신해도 복사되지 않음': False}
=> 매우 정확하고 예상보다도 더욱 자세한 설명인데, 파일에 언급된 내용을 전부 답변에 때려넣은 느낌
GPTs: "사령탑" 특성을 가진 포켓몬은 다음과 같은 특징을 가지고 있습니다:
특성 이름(영어): Commander
설명: 이 포켓몬이 타츠구리일 경우, 그리고 이 포켓몬과 돈도조가 동시에 전투에 참가하고 있을 때, 돈도조의 공격력이 2배가 됩니다.
"사령탑" 특성은 전투 상황에서 포켓몬 타츠구리와 돈도조가 함께 있을 때 매우 강력한 상호작용을 제공합니다. 이 특성은 팀 전략에 있어서 중요한 역할을 하며, 돈도조의 공격력을 강화하여 상대방에게 더 큰 피해를 입힐 수 있도록 돕습니다.
=> 포켓몬 명칭과 설명이 약간 부정확하지만, 일단은 핵심을 담고 있어서 통과
질문 3. 오거폰-화덕과 다투곰-붉은달 간에 각자의 타입들로 공격했을 때 효과가 어떻게 돼?
정답 3: 오거폰-화덕 (풀 + 불꽃 타입) → 다투곰-붉은달 (노말 + 땅 타입) : 풀은 노말에 1배, 땅에 2배로 합산 2배. 불꽃은 노말, 땅에 각각 1배로 합산 1배.
다투곰-붉은달 → 오거폰-화덕 : 노말은 풀, 불꽃에 각각 1배로 합산 1배. 땅은 풀에 0.5배, 불꽃에 2배로 합산 1배.
질문 의도: pokedex.csv, typechart.csv의 내용을 모두 사용하는 계산 능력 테스트.
Veluga: 오거폰-화덕은 Grass, Fire 타입이고, 다투곰-붉은달은 Fighting, Dark 타입입니다. Grass는 Fighting에 약하고, Fire는 Dark에 효과적입니다. 따라서 오거폰-화덕의 Fire 타입 공격은 다투곰-붉은달에게 효과적일 것이며, Grass 타입 공격은 효과적이지 않을 것입니다.
=> 오거폰 타입만 맞히고, 나머지는 이상한 소리! ㅎㅎ
그래서 추가 질문했습니다: 다투곰-붉은달은 Normal, Ground 타입이야. 이 점 참고해서 다시 한 번 생각해 볼래?
Veluga: 다투곰-붉은달은 Normal, Ground 타입이에요. 이 정보를 고려하여 다시 한 번 생각해 보세요.
=> 재질문의 의도를 이해하지 못한 것 같은데, 앞선 질문 내용을 기억하고 있지 않는 것일 수도 있다는 생각이 들었습니다. ㅠㅠ
GPTs: 오거폰-화덕과 다투곰-붉은달의 타입 간 상호 효과는 다음과 같습니다:
오거폰-화덕의 풀 타입이 다투곰-붉은달의 땅 타입에 대해 0.5배의 효과를 가집니다.
오거폰-화덕의 풀 타입이 다투곰-붉은달의 노말 타입에 대해 1.0배의 효과를 가집니다.
오거폰-화덕의 불꽃 타입이 다투곰-붉은달의 땅 타입에 대해 2.0배의 효과를 가집니다.
오거폰-화덕의 불꽃 타입이 다투곰-붉은달의 노말 타입에 대해 1.0배의 효과를 가집니다.
다투곰-붉은달의 땅 타입이 오거폰-화덕의 풀 타입에 대해 2.0배의 효과를 가집니다.
다투곰-붉은달의 땅 타입이 오거폰-화덕의 불꽃 타입에 대해 1.0배의 효과를 가집니다.
다투곰-붉은달의 노말 타입이 오거폰-화덕의 풀 타입에 대해 1.0배의 효과를 가집니다.
다투곰-붉은달의 노말 타입이 오거폰-화덕의 불꽃 타입에 대해 1.0배의 효과를 가집니다.
상호 작용에 따른 효과의 차이가 각 타입과 조합에 따라 달라지는 것 을 확인할 수 있습니다.
=> 기술을 사용하는 타입과 받는 타입을 전부 거꾸로 말하더라고요… 원래는 땅 타입이 풀 타입에 대해 0.5배의 효과를 가지는 거거든요. 그래도 코드 인터프리터로 계산해서 낸 답이라서 그런지 계산 결과 자체는 정확합니다. 아마 뭔가 더 전달을 잘 해서 주면 맞는 답을 낼 것 같아요.
나름의 결론
많이 테스트해 본 것은 아니지만 포켓몬 배틀에 대한 몇 가지 질문을 두 챗봇에게 해 본 결과, Veluga는 CSV 자료에 언급된 내용의 retrieval을 좀 더 잘 하며, GPTs 쪽이 추론 방면에서는 좀 더 나은 것 같다고 판단했습니다. 챗봇 제작 경험이 적은 저에게는 이 정도라도 충분히 뜻깊은 결과입니다 🥹
이 게시물은 [PRO캠프] 챗봇 2.0: RAG 기반 챗봇 업그레이드의 발표를 위해 준비했어요. 다음 주의 발표에서는, 이번에 한 게 RAG가 맞나 싶고(…) Veluga 등 활용해서 좀 더 RAG다운 것을 해 보고 싶어서 적절한 사용 예시를 찾고 있습니다.
읽어 주셔서 감사합니다 🙂
#10기RAG