8개월간 900만 페이지의 문서를 처리하며 프로토타입과 프로덕션 사이의 깊은 골짜기를 경험한 개발자의 생생한 실전 기록입니다. Youtube 튜토리얼로 시작해 일주일 만에 ‘완성’했지만, 실제로는 그때부터 진짜 전쟁이 시작됐습니다.
핵심 포인트:
- Reranking은 5줄 코드의 마법: 50개 청크 입력 → 15개 출력 구성으로 청크 순위가 예상보다 훨씬 크게 변화. 잘못된 설정도 충분한 청크만 입력하면 보완 가능
- Query Generation으로 검색 범위 확장: 사용자의 마지막 질문만으로는 컨텍스트 포착 불가. LLM이 대화 맥락을 검토해 semantic + keyword 쿼리를 병렬 생성하는 방식으로 표면적 대폭 확대
- Chunking에 가장 많은 시간 투자: 청크가 단어나 문장 중간에서 잘리지 않는지, 각 청크가 독립적인 논리 단위인지 확인하는 커스텀 플로우 구축이 핵심
RAG 프로토타입의 함정: 100개 문서와 500만 문서는 다르다
Usul AI의 Abdellatif가 자신의 블로그에 공개한 ‘Production RAG: what I learned from processing 5M+ documents‘는 8개월간 RAG 시스템을 구축하며 얻은 실전 노하우를 담고 있습니다. Usul AI(900만 페이지)와 이름을 밝히지 않은 법률 AI 기업(400만 페이지)의 RAG 시스템을 만들며 겪은 시행착오가 고스란히 담겨 있죠.

처음에는 Youtube 튜토리얼을 따라 Langchain으로 시작했습니다. 며칠 만에 프로토타입이 완성됐고, 100개 문서로 테스트했을 때 결과는 훌륭했어요. 일주일 후 프로덕션 데이터셋에서 모든 게 작동했습니다. 완벽해 보였죠.
하지만 실제로는 완벽과 거리가 멀었습니다. 최종 사용자들만이 그 차이를 알 수 있었어요. 결과가 기대에 미치지 못했던 겁니다. 그 후 몇 달 동안 시스템을 하나씩 다시 작성하며 원하는 성능 수준에 도달했습니다. 프로토타입은 시작일 뿐이었습니다.
ROI가 가장 높았던 5가지 전략
Abdellatif는 ROI 순서대로 효과적이었던 전략들을 공유합니다.
1. Query Generation: 검색 표면적을 넓혀라
사용자가 “그럼 비용은 어때?”라고 물었다고 해봅시다. 이 질문만으로는 무엇에 대한 비용인지 알 수 없죠. 하지만 이전 대화를 보면 “Pinecone의 성능”에 대해 논의했다는 걸 알 수 있습니다.
Abdellatif의 팀은 LLM이 전체 대화 맥락을 파악해서 여러 개의 검색 쿼리를 자동으로 만들도록 했습니다. 위 예시라면 “Pinecone 가격”, “Pinecone 비용 구조”, “vector database pricing comparison” 같은 쿼리들이 생성되는 거죠. 의미 기반 검색(semantic)과 키워드 검색을 섞어서 만들어냅니다.
이렇게 생성된 여러 쿼리를 동시에 실행한 뒤, 모든 결과를 reranker에 넣습니다. 단일 쿼리로는 놓칠 수 있는 정보들을 다각도로 수집할 수 있게 됐죠. 하이브리드 검색에서 계산되는 점수 하나에 의존하는 것보다 훨씬 안정적이었습니다.
2. Reranking: 가장 높은 ROI의 5줄 코드
“추가할 가장 가치 있는 5줄 코드”라고 Abdellatif는 표현합니다. Reranker를 추가한 후 청크 순위가 예상보다 훨씬 크게 바뀌었어요.
가장 이상적인 설정은 50개 청크를 입력해서 15개를 출력하는 구성이었습니다. 흥미로운 점은 충분한 청크만 입력하면 reranking이 잘못된 초기 설정을 많이 보완할 수 있다는 겁니다. 초기 검색 품질이 완벽하지 않아도 reranker가 진짜 관련성 있는 청크를 걸러낼 수 있죠.

처음에는 reranker를 사용하지 않았고, 이후 Cohere 3.5로 전환했다가 최종적으로 Zerank를 선택했습니다. Zerank는 덜 알려진 선택지지만 실제로 성능이 좋았다고 합니다.
3. Chunking Strategy: 가장 많은 시간을 투자해야 할 곳
Chunking은 많은 노력이 필요하며, 아마도 가장 많은 시간을 쓰게 될 부분입니다. 두 기업 모두를 위해 커스텀 플로우를 구축했어요.
데이터를 이해하고, 청크를 검토하고, 두 가지를 확인해야 합니다. 첫째, 청크가 단어나 문장 중간에서 잘리지 않는지. 둘째, 각 청크가 논리적 단위를 구성하고 자체적으로 정보를 담고 있는지.
기본적으로 Unstructured.io를 사용했지만, 엔터프라이즈 프로젝트에서는 커스텀 솔루션이 필요했습니다. 문서의 구조와 특성을 깊이 이해하고 그에 맞는 chunking 전략을 설계하는 게 핵심입니다.
4. Metadata를 LLM에 전달하라
처음에는 청크 텍스트만 LLM에 전달했습니다. 실험을 통해 제목, 저자 등 관련 메타데이터를 함께 주입하면 컨텍스트와 답변이 크게 개선된다는 걸 발견했어요.
메타데이터는 청크에 추가적인 맥락을 제공합니다. 같은 내용이라도 누가 작성했고, 어떤 문서에서 나왔는지 알면 LLM이 더 정확한 답변을 생성할 수 있죠.
5. Query Routing: 불필요한 RAG 호출 제거
많은 사용자가 RAG로 답할 수 없는 질문을 합니다. “이 글을 요약해줘”, “누가 이걸 썼어?” 같은 질문들이죠. 이런 질문들은 벡터 검색이 필요 없습니다. 문서 메타데이터나 LLM의 요약 기능만으로 충분하죠.
Abdellatif의 팀은 질문 유형을 먼저 분류하는 작은 라우터를 만들었습니다. 벡터 검색이 필요한 질문(“계약서에서 위약금 조항이 뭐야?”)과 불필요한 질문(“이 문서 누가 작성했어?”)을 구분하는 거죠.
RAG가 필요 없는 질문은 API 호출로 메타데이터를 가져오거나 LLM에 직접 요약을 요청합니다. 전체 RAG 파이프라인을 거치지 않으니 불필요한 벡터 검색, 임베딩 계산, reranking 과정을 모두 건너뛸 수 있었습니다. 비용과 응답 시간 양쪽에서 이득이었죠.
실전에서 검증된 기술 스택
Abdellatif의 팀이 사용한 기술 스택도 주목할 만합니다. 각 선택에는 분명한 이유가 있었죠.
Vector Database: Azure → Pinecone → Turbopuffer로 진화했습니다. Turbopuffer는 저렴하면서도 keyword 검색을 기본으로 지원합니다. 가격 대비 성능이 뛰어났죠.
Chunking: 기본적으로 Unstructured.io를 사용하고, 엔터프라이즈에는 커스텀 솔루션을 구축했습니다. Chonkie도 좋다는 평가를 들었다고 합니다.
Embedding: text-embedding-large-3를 사용했으며, 다른 옵션은 테스트하지 않았습니다.
Reranker: 처음에는 사용하지 않았고, Cohere 3.5를 거쳐 Zerank로 정착했습니다.
LLM: GPT 4.1 → GPT 5 → GPT 4.1로 변경했으며, Azure 크레딧으로 비용을 충당했습니다.
오픈소스로 공개된 노하우
Abdellatif 팀은 8개월간의 학습 결과를 agentset-ai/agentset라는 오픈소스 프로젝트로 공개했습니다. MIT 라이선스로 제공되며, RAG 애플리케이션 구축을 위한 end-to-end 도구를 제공합니다.
이 프로젝트는 ingestion, chunking, embeddings, retrieval뿐만 아니라 벤치마크, 평가, 채팅 플레이그라운드, 호스팅, 그리고 깔끔한 API를 포함합니다. 프로토타입에서 프로덕션으로 넘어가는 과정에서 겪는 많은 문제들에 대한 실전 검증된 솔루션이 고스란히 담겨 있죠.
프로토타입과 프로덕션 사이의 간극은 생각보다 큽니다. 100개 문서에서 잘 작동하던 시스템이 500만 개 문서에서는 완전히 다른 문제를 만들어냅니다. Abdellatif의 기록은 그 간극을 메우는 구체적이고 실용적인 가이드가 될 것 같네요.
참고자료: Production RAG: what I learned from processing 5M+ documents

답글 남기기