Sign In

"왜 전에 그거 있잖아"를 없애는 사내 챗봇 개발기

요원 B
카테고리
  1. DevOps
태그
  1. RAG
  2. Slack
  3. ChatGPT
  4. Elasticsearch
안녕하세요, 세탁특공대 DevOps 요원 웨스트입니다.
저는 "개발자가 개발에만 집중할 수 있게 만든다"는 목표로 다양한 활동을 하고 있어요. 그중에서도 오늘은 지식 관리와 정보 공유에 대해 이야기해 보려고 합니다.
스타트업이다 보니, 회사의 많은 정보나 기술적인 내용이 Slack에서 정말 빠르게 오가요. 그런데 시간이 지나다 보면 정보가 파편화되거나 문서화되지 않아 기존 크루에게는 당연한 것도, 새로 오신 크루분들에겐 큰 장벽이 되는 경우가 많았어요. 가끔은 기존 크루들도 예전에 했던 작업을 찾느라 시간을 허비하기도 하고요.
이 문제를 해결하기 위해 저는 RAG(Retrieval-Augmented Generation)을 활용해서, Slack에서 오간 정보를 효율적으로 저장하고 재활용할 수 있는 챗봇, ye-bot을 만들게 되었어요. (왜 ye-bot이냐고요? 제 코드네임이 웨스트인데, '칸예 웨스트'에서 따왔다고 하면... 😎)
이 글에서는 ye-bot을 어떻게 개발했는지, 실제로 어떻게 활용하고 있는지 공유해보려고 해요.

📖 먼저, 이 글을 읽는 데 도움이 될 개념 정리

RAG (Retrieval-Augmented Generation)
LLM(대형 언어 모델)이 헛소리를 하지 않도록, 검색과 생성을 결합한 방식이에요.
질문을 받으면 관련 정보를 데이터베이스에서 먼저 검색하고,
그 정보를 바탕으로 GPT가 보다 정확한 답변을 생성합니다.
환각 (Hallucination)
LLM이 진짜처럼 보이지만 사실이 아닌 정보를 말할 때 쓰는 표현이에요. 예를 들면, 존재하지 않는 API 문서를 만들어서 답해주는 식이죠. 그래서 RAG 같은 검색 기반 생성 방식이 중요해요.
임베딩 (Embedding)
텍스트를 숫자로 바꿔서, 의미적으로 비슷한 문장을 찾을 수 있게 해주는 기법이에요.
예: "서버가 다운됐어요"와 "서버 장애 발생"은 의미는 비슷하지만, 단어가 다르잖아요?
벡터 검색 (Vector Search)
임베딩된 문서들을 벡터 공간에 저장해두고, 질문과 가장 유사한 문서를 찾아주는 검색 방식이에요. 저희는 Elasticsearch의 kNN 기능을 써요.

📚 데이터를 어떻게 저장하나요? (Embedding + Elasticsearch)

Slack에서 받은 메시지나 스레드를 OpenAI API로 임베딩한 후, Elasticsearch에 저장해요.
# 예시 코드
embedding = get_openai_embedding(content)
...
es.index(index="ye-bot-doc", body=doc_body)
콘텐츠는 OpenAI의 text-embedding-3-small 모델로 벡터화되고,
원본 내용과 요약본을 같이 저장해서 검색 정확도를 높였어요.

🔍 검색 정확도를 높이기 위한 전략 (kNN + 키워드 + RRF)

사용자 질문이 들어오면, 벡터 검색(kNN)과 키워드 검색을 같이 돌리고,
RRF (Reciprocal Rank Fusion) 방식으로 두 결과를 조합해요. 이렇게 하면 더 정확한 결과를 찾을 수 있어요.
# 예시: search_elasticsearch(question)
# k=50, num_candidates=200, boost=0.7, rrf.rank_constant=10 설정
k값, num_candidates, boost, rank_constant 등은 정확도와 속도 사이의 밸런스를 맞추기 위해 조정했어요.

✏️ 최적의 답변 고르기

Elasticsearch에서 가져온 결과 중 점수가 제일 높은 문서를 골라요.
content가 너무 짧으면 요약본을 대신 사용해요.
# 예시: extract_best_response(elastic_results)

🤖 GPT로 최종 응답 생성하기 (Prompt Engineering)

검색된 정보를 그대로 주는 대신, 질문에 맞춰 요약하고 재구성해주는 역할을 GPT가 해요.
# 예시: ask_gpt_direct(question, best_content)
temperature는 0.2로 낮게 설정해서 안정적인 답변을 만들고 있어요.

📈 실제 사용 예시 & 앞으로의 계획

예시 1 - Slack에서 개선사항 저장하기

잘 배운 예봇
동료가 개선사항을 공유하면, "스레드를 추가해줘"라고 ye-bot에게 말해요.
그러면 ye-bot이 내용을 요약해서 Elasticsearch에 저장하고,
나중에 관련 질문이 들어오면 바로 답할 수 있게 도와줘요.

예시 2 - 잘못된 답변 수정하기

잘못된 답변을 받으면, 사용자가 직접 정보를 수정할 수 있어요.
다음번에 같은 질문이 들어오면, 수정된 정보를 우선적으로 활용하게 돼요.

앞으로의 계획

한국어 특화 모델 테스트
Kanana 등 한국어와 영어에 강한 모델을 적용해보려 해요.
메타데이터 확장
현재는 기본 정보만 저장하지만, 스레드 주제나 유형도 함께 저장해보려고 해요.
문서 신선도 관리
오래된 정보가 자꾸 노출되는 걸 방지하기 위한 가중치 설정을 고려 중이에요.
다중 문서 통합
지금은 하나의 문서만 기준으로 답변을 생성하는데, 여러 문서를 통합해 더 풍부한 답변을 주고 싶어요.
전체 예시 코드는 GitHub에서 확인해주세요.

다음 요원은 당신입니다 🫵

세탁특공대 팀 블로그
Subscribe to '세탁특공대 팀 블로그'
Subscribe to my site to be the first to receive notifications and emails about the latest updates, including new posts.
Join Slashpage and subscribe to '세탁특공대 팀 블로그'!
Subscribe
👍