2025-08-23
1일 1아티클
요즘IT
RAG 기반 사내 지식 챗봇
문제 상황
- 정보의 홍수
- 문서량이 너무 많아 적합한 정보를 찾는 데 어려움
- 사내 위키, 사내 기술 블로그, 매뉴얼, etc. → 맥락 있는 답변 제공에 한계
- 일반적인 LLM은 고정된 파라미터 내에 저장된 지식을 바탕으로 답변
RAG(Retrieval-Augmented Generation)
- 문맥 중심의 답변 가능
- 정보 검색(Retrieval) + 텍스트 생성(Generation) 결합 구조
- 외부의 정보 소스를 질의 시점에 검색, LLM이 참고할 수 있도록 함
- 보다 질문에 정확하고 사실적인 응답 생성
- 사내 위키, 매뉴얼, 프로젝트 기록 등 비정형 문서가 많을수록 유용
- ex. 사내 지식 Q&A 챗봇 : 위키, 매뉴얼, 슬랙 대화 등 벡터화한 실시간 질의응답
- ex. 고객지원 챗봇 : 제품 설명서, 정책 문서 기반 상담 자동화
- ex. 개발자 도구 : API 문서, 예제 코드 검색 등으로 보완적인 정보 제공
RAG 개발 방식
- 데이터 수집 및 임베딩 자동화
- 사내 위키, 마크다운 문서, 기술 블로그 등 다양한 소스로부터 새로운 데이터 수집
- 수집된 문서를 문단 단위로 분할 → LlamanIndex 라이브러리로 벡터화
- 벡터를 Milvus(오픈소스 벡터 DB)에 저장, Kubeflow Pipeline을 통해 일련의 과정 자동화
- 문서 변경 시 최신화, 매일 새벽 주기적 실행
- 질문에 맞는 문서 검색
- 사용자가 챗봇에 질문 입력 → 벡터로 변환하여 Milvus에 쿼리
- 벡터 DB에 저장된 유사도가 가장 높은 문서들을 Top-K로 검색
- 이때 Milvus는 GPU 리소스 사용, 쿠버네티스 클러스터 안에서 안정적 성능
- 답변 생성
- 검색된 문서 기반의 프롬프트 구성, 질문과 함께 LLM에 내용 전달
- 이떄 LLM 모델은 KServe를 통해 쿠버네티스 상 서빙, 추론 담당의 쿠버네티스 파드는 GPU 리소스 사용
- LLM 모델은 벡터 DB 검색 내용 바탕으로 사용자의 프롬프트에 부합하는 답변 생성
- 각 Micro service 부하 증가 시 자동으로 파드 및 노드 수 증가시키도록 스케일링 설정
- 사용자를 위한 웹 UI
- Open WebUI를 활용하여, LLM 모델을 쉽게 추가 및 선택할 수 있도록 구성
- 사용자 질문 입력 → Milvus 검색 → 검색 결과 프롬프트 구성 → LLM 추론 요청 → LLM 응답 반환
기술적 문제
- 다양한 형식의 문서를 내용 및 문맥의 손실 없이 벡터화하기
- 대부분의 중요 문서를 마크다운 형식으로 변환 (순수 텍스트에 가까우며, 토큰 효율성이 높아 LLM 모델과 호환성 높음)
- Marker + MarkItDown 활용
- 문서의 양이 증가하여도 프롬프트 응답 속도가 느려지지 않도록 시스템 성능 유지하기
- 초기 테스트에서는 RAG 응답 시간이 최대 10초
- chunking 전략 개선
- 문단 단위로 나누어도 문단마다 길이가 달라 검색 효율 저하
- 한 cunk 당 토큰 수를 일정하게 유지하는 방식으로 전환
- 300~500 토큰 크기일 때 가장 균형잡힌 결과
- chunk 분할 방식 개선
- 단순 고정 길이 분할은 문맥 단위를 고려하지 않음
- 문맥 단위를 고려한 semantic chunk 분할
- Top-K 조절 및 재정렬
- Top-K : 벡터 검색 시 LLM에 전달하는 문맥 조각의 수
- 일반적으로 Top-5 사용
- 내부 실험에서 K=4 전후에서 속도/정확도 효율적
- K를 늘릴 경우 : 정답 포함 확률 증가 but 입력 길이 증가로 인한 응답 시간 증가 및 노이즈 포함
- K를 줄일 경우 : 응답 시간 감소 및 노이즈 포함 가능성 적음 but 필요한 문맥도 포함 가능성 적음
- 기타 최적화 방안
- 프롬프트 구성 간결화 및 지시문 정제
- 벡터 DB 검색 결과 캐싱
- LLM 응답 캐싱 및 세션 재사용
- 복수 사용자의 동시 요청 시 임베딩 처리 비동기화
RAG
의 핵심은검색
과문맥
. 데이터 정제 중요.
오늘 배운 것
- 인덱스
- N번 페이지의 M개 게시글 가져올 때 성능을 최적화하려면?
- Pagination, 무한스크롤의 원리 및 성능 확인
- Primary Key 생성 전략
- DB의 자체
AUTO_INCREMENT
전략 : 각 샤드에서 독립적으로 번호 생성, 중복 발생 가능 Unique String or Number
(UUID, 난수) : 랜덤 데이터이므로 성능 저하 발생 가능Unique Sorted String
: PK가 클수록 공간 많이 차지하여, 비용 증가Unique Sorted Number
(Snowflake, TSID) : 위 방식보다 적은 공간 사용
- DB의 자체
클러스터 인덱스는 정렬된 상태를 유지한다!
내일 할 일
- 상담 피드백 바탕으로 포트폴리오 수정 (다음주 주말까지는 완료)