중급읽는 시간 8분·

RAG로 지식베이스 Q&A 시스템 만들기

LLM은 여러분의 비공개·최신 자료를 모르고 환각을 일으키기 쉽습니다. RAG(검색 증강 생성)는 "먼저 검색하고, 그다음 생성한다"는 방식으로 신뢰할 수 있는 지식베이스에 근거해 답하게 합니다. 오늘날 가장 실용적인 프로덕션 방식 중 하나입니다.

작성자AI Resource Hub

RAG가 필요한 이유

모델을 직접 파인튜닝해 지식을 주입하는 방식은 비싸고 갱신이 느립니다. RAG는 지식을 외부 데이터베이스에 두고 필요할 때 관련 조각을 검색해 모델에 전달합니다. 저렴하고 항상 최신입니다.

파이프라인 개요

전형적인 RAG 시스템은 두 단계로 나뉩니다. 문서를 검색 가능한 벡터로 가공하는 오프라인 "인덱싱 단계"와, 사용자 질문을 바탕으로 검색해 답을 생성하는 온라인 "질의 단계"입니다.

문서 청킹과 임베딩

먼저 문서를 적절한 크기의 청크로 나눕니다. 너무 크면 검색이 부정확해지고, 너무 작으면 맥락을 잃습니다. 보통 수백 토큰 정도에 약간의 겹침을 두는 방식을 씁니다.

그다음 임베딩 모델로 각 청크를 벡터로 바꿔 벡터 데이터베이스(pgvector, Milvus, Qdrant 등)에 저장합니다.

벡터 검색과 Top-K

사용자가 질문하면 그 질문도 벡터로 바꾸고, 데이터베이스에서 유사도 검색을 실행해 가장 관련 있는 청크(Top-K)를 가져옵니다.

키워드 검색을 결합해 "하이브리드 검색"을 구성하고, 리랭킹으로 재현율 품질을 한층 더 끌어올릴 수 있습니다.

컨텍스트 구성과 답변 생성

검색된 청크를 프롬프트에 넣고, 모델에게 "제공된 자료만을 근거로 답하고, 자료에 답이 없으면 분명히 밝혀라"라고 지시하세요. 환각이 크게 줄어듭니다.

고급 최적화로는 질의 재작성, 출처 인용, 컨텍스트 길이 제어, 검색 결과의 중복 제거와 필터링 등이 있습니다.

벡터 데이터베이스 선택하기

벡터 데이터베이스는 RAG의 핵심입니다. 프로토타입에는 설정 없이 메모리에서 실행되는 Chroma가 적합합니다. 프로덕션 작업 부하에는 Rust 기반 Qdrant와 완전 관리형 Pinecone이 프로덕션 배포용으로 설계되어 있습니다. 현재 제한과 확장 옵션은 각 문서에서 확인하세요. 이미 PostgreSQL을 쓴다면 pgvector로 새 인프라 추가를 피할 수 있고, 내장 벡터화 모듈과 GraphQL API가 필요할 때 Weaviate가 빛납니다.

RAG 품질 평가하기

RAG 시스템은 검색과 생성 둘 다만큼 좋습니다. 검색은 Recall@K(올바른 청크가 Top-K 결과에 나오는가)로 측정하고, 생성은 충실도(답변이 검색된 컨텍스트에 근거하는가)와 관련성(실제로 질문에 답하는가)으로 측정합니다. RAGAS 같은 프레임워크가 이 지표들을 자동화해 주므로, 청킹 전략·임베딩 모델·프롬프트 템플릿을 반복하면서 품질을 추적할 수 있습니다.

시작 전 준비: 사전 요구 사항

작지만 대표성 있는 문서 집합, 이를 사용할 권한, 깨끗한 텍스트를 추출하는 파서가 필요합니다(PDF와 스캔 문서는 대개 OCR이 필요합니다). 내 환경에서 실행할 수 있는 임베딩 모델과 벡터 저장소를 고르고, 차원과 언어 지원을 확인하세요. 실제 질문 20~50개를 준비하고 각 질문에 답해야 할 문서나 구절을 표시합니다. 마지막으로 문서 갱신 방식과 누가 어떤 컬렉션을 읽을 수 있는지 정하세요. 권한은 UI가 아니라 검색 시점에 강제되어야 합니다.

시작에 거대한 코퍼스는 필요 없습니다. 잘 구조화된 수백 페이지면 규모를 키우기 전에 파이프라인을 검증하기에 충분합니다.

검증: 답변보다 검색을 먼저 확인하기

먼저 검색을 테스트하세요. 라벨이 붙은 각 질문으로 검색을 실행하고 상위 결과를 확인합니다. 기대한 구절이 Top-K에 나와야 하고, 무관한 청크가 상위를 차지하지 않아야 합니다. 그렇지 않다면 생성 프롬프트를 건드리기 전에 청크 크기, 겹침, 메타데이터 필터, 임베딩 모델을 조정하세요. 다음으로 답변을 확인합니다. 모델은 검색된 구절을 인용하거나 발췌해야 하고, 자료에 답이 없을 때는 없다고 분명히 말해야 합니다. 고정 평가 세트를 두고 변경할 때마다 다시 실행해 회귀를 파악하세요. 답이 없는 질문, 비슷한 문서가 두 개인 질문, 지원하는 각 언어의 질문도 테스트합니다.

RAG에서 흔한 실패 문제 해결

이 순서로 디버깅하세요. 검색 결과가 없으면 문서가 인덱싱되었는지, 질의와 문서가 같은 임베딩 모델과 차원을 쓰는지, 필터가 컬렉션을 제외하지 않는지 확인합니다. 올바른 청크가 있는데 순위가 낮으면 청크 경계를 살피고 하이브리드 키워드 검색이나 리랭킹을 시도하세요. 답변이 검색된 컨텍스트를 무시하면 청크가 실제로 프롬프트에 들어갔는지, 잘리지 않았는지 확인한 뒤 제공된 자료만 근거로 답하고 출처를 인용하라는 지시를 강화합니다. 답변이 오래되었으면 문서 갱신 후 재인덱싱 작업이 실행됐는지 확인하세요. 중복이 Top-K를 채우면 삽입 전에 문서 ID나 내용 해시로 중복을 제거합니다. 마지막으로 접근 제어 필터가 생성 후가 아니라 검색 시점에 적용되는지 확인하세요.

RAG가 적합하지 않은 경우

전체 지식베이스가 모델의 컨텍스트 윈도에 넉넉히 들어가고 거의 바뀌지 않는다면 RAG는 적합하지 않습니다. 문서를 직접 넘기는 편이 더 간단합니다. 자료가 신뢰할 수 없거나 서로 모순되거나, 쓸 만한 텍스트 없이 이미지 위주라면 효과가 약합니다. 계산, 트랜잭션, 실시간 상태가 필요하면 그에 관한 글을 검색하는 대신 데이터베이스나 API를 호출하세요. 한 번의 권위 있는 조회가 필요한 질문에는 검색 인덱스나 구조화 질의가 더 정확할 수 있습니다. 인덱스를 관리할 사람이 없으면 검색 시스템은 빠르게 낡습니다. 더 작고 잘 정리된 문서가 사용자에게 더 유용할 수 있습니다.

청킹 한 단계

이 함수는 임베딩 전에 문서를 나누는 인덱싱 단계를 해결합니다. 시작용 초안이지, 측정 결과가 아닙니다. 실패: overlap이 0이면 절단선에 걸친 사실이 어느 청크에도 들어가지 않아 검색으로 되돌릴 수 없습니다.

def chunk_text(text, size=400, overlap=50):
    chunks = []
    start = 0
    while start < len(text):
        chunks.append(text[start:start + size])
        if start + size >= len(text):
            break
        start += size - overlap
    return chunks
RAG벡터 데이터베이스임베딩지식베이스

관련 튜토리얼

관련 리뷰

Chroma
Chroma는 간단한 Python·JavaScript API로 몇 분 만에 RAG 프로토타입을 실행할 수 있는 개발자 친화적 오픈소스 임베딩 데이터베이스입니다. 로컬 개발 시 인프로세스로 동작하고 호스티드 클라우드로 확장할 수 있어, 대부분의 개발자에게 벡터 검색의 가장 쉬운 진입점입니다.
Qdrant 벡터 데이터베이스
Qdrant는 프로덕션용으로 설계된 고성능 오픈소스 벡터 데이터베이스·유사도 검색 엔진입니다. Rust로 작성되었으며, 풍부한 페이로드 필터링, 멀티 테넌시, 셀프호스팅·관리형 클라우드 배포를 지원하여 RAG 파이프라인, 추천 시스템, 시맨틱 검색을 구동합니다.
LangChain 프레임워크 튜토리얼
LangChain 프레임워크의 아키텍처와 핵심 모듈인 Chains·Agents·Memory를 실전 예제와 함께 체계적으로 다루는 튜토리얼입니다. RAG 통합, 커스텀 도구 개발, 디버깅 전략까지 다루며, 단순 프롬프트를 넘어 프로덕션급 LLM 앱을 구축하려는 개발자에게 적합합니다.
LlamaIndex 프레임워크 튜토리얼
LLM을 커스텀 데이터 소스에 연결하는 RAG 앱 구축을 위한 프레임워크 LlamaIndex 실전 튜토리얼입니다. 데이터 수집 파이프라인, 인덱싱 전략, 쿼리 엔진, 에이전트 기반 검색을 다루며 PDF·웹·데이터베이스 커넥터에 대한 실전 예제를 제공합니다. 자체 문서를 기반으로 한 도메인 특화 AI 어시스턴트를 구축하려는 개발자에게 적합합니다.