기술 스택 및 아키텍처
본 시스템은 최신 Rails 8.1.1과 Ruby 3.3.5를 기반으로 하며, 인프라 복잡도를 최소화하기 위해 다음과 같은 도구들을 선택했습니다.
- 데이터베이스: PostgreSQL과
pgvector확장을 사용하여 벡터 유사도 검색을 수행합니다. - 스토리지: Cloudflare R2를 사용하여 PDF 문서를 저장하며, Active Storage를 통해 S3 호환 인터페이스를 활용합니다. R2는 데이터 송신료(Egress)가 없어 RAG 애플리케이션에 적합합니다.
- 비동기 처리 및 실시간성: Redis 없이
Solid Queue,Solid Cache,Solid Cable을 사용하여 백그라운드 작업과 실시간 스트리밍을 처리합니다. - AI 및 임베딩:
Voyage AI의voyage-3모델로 임베딩을 생성하고,OpenAI의gpt-4o-mini와ruby_llmGem을 사용하여 대화형 응답을 생성합니다.
문서 처리 파이프라인 (Document Pipeline)
사용자가 PDF를 업로드하면 백그라운드에서 다단계 파이프라인이 실행됩니다.
- 텍스트 추출:
pdf-readerGem을 사용하여 PDF 페이지에서 원시 텍스트를 추출합니다. - 시맨틱 청킹 (Chunking): 고정된 길이가 아닌 문단 경계를 존중하여 약 500 토큰 단위로 텍스트를 나눕니다. 이는 문맥의 일관성을 유지하여 의미가 끊기지 않도록 하기 위함입니다.
- 임베딩 및 저장: 각 청크는
Voyage AI를 통해 1024차원 벡터로 변환되며,neighborGem을 통해pgvector인덱스가 적용된document_chunks테이블에 저장됩니다.
RAG 쿼리 흐름 및 실시간 스트리밍
사용자의 질문이 입력되면 시스템은 다음과 같은 절차를 거쳐 답변을 구성합니다.
- 유사도 검색: 질문을 동일한
Voyage AI모델로 임베딩한 후pgvector의 코사인 유사도 검색을 통해 가장 관련성이 높은 상위 5개의 청크를 검색합니다. - 프롬프트 증강: 검색된 문맥을 시스템 프롬프트에 주입하고, LLM에게 답변 시 인용 마커([1], [2] 등)를 사용하도록 지시합니다.
- Turbo Streams 응답:
ruby_llm을 통해 생성되는 토큰을Solid Cable과 Turbo Streams를 사용하여 실시간으로 브라우저에 스트리밍합니다. 이는 사용자가 전체 답변이 완성될 때까지 기다리지 않게 합니다.
사용자 경험을 위한 설계 패턴
- 줌 패턴 (Zoom Pattern): LLM 요약(1단계), 특정 청크 확인(2단계), 전체 소스 문서 보기(3단계)로 이어지는 점진적 정보 공개 방식을 적용하여 정보의 정확성을 검증할 수 있게 합니다.
- 인용 시스템: Stimulus 기반 모달을 통해 사용자가 AI 답변의 근거가 된 원문과 페이지 번호를 즉시 확인할 수 있게 하여 신뢰성을 높였습니다.
- 코퍼스(Corpus) 페이지: 관리자가 업로드한 문서 목록을 공개하여 사용자가 시스템이 알고 있는 지식의 범위를 미리 파악하고 적절한 질문을 할 수 있도록 유도합니다.