이종관
글 목록으로

RAG: 검색 강화 생성

LLM의 내부 지식만 사용하는 대신, 외부 데이터베이스에서 관련 정보를 검색하여 응답 생성에 활용하는 기법

2026년 2월 1일·7 min read·
agent
rag
retrieval
knowledge-base

Retrieval-Augmented Generation (검색 강화 생성)

개념

RAG는 LLM의 내부 지식만 사용하는 대신, 외부 데이터베이스에서 관련 정보를 검색하여 응답 생성에 활용하는 기법이다.

동작 구조

  1. 질문 입력: 사용자가 질문을 제출한다.
  2. 문서 검색: 벡터 DB에서 관련 문서를 검색한다.
  3. 컨텍스트 결합: 검색 결과와 질문을 함께 LLM에 전달한다.
  4. 답변 생성: LLM이 검색된 문서를 참고하여 답변을 생성한다.

왜 RAG가 필요한가?

LLM의 근본적인 한계:

한계설명
지식 단절학습 이후 정보를 알 수 없음
할루시네이션모르는 것을 지어냄
출처 불명정보의 근거 확인 어려움

RAG의 장점

장점설명
최신 정보학습 데이터 이후 정보 접근
할루시네이션 감소실제 문서 기반 응답
투명성출처 확인 가능
도메인 특화특정 분야 문서로 전문성 확보

예시

질문: "2024년 노벨 물리학상 수상자는?"

LLM만 사용 "2024년 노벨 물리학상 수상자에 대한 정보가 학습 데이터에 포함되어 있지 않다." (또는 할루시네이션)

RAG 사용

  1. 벡터 DB 검색: "2024 노벨 물리학상"
  2. 관련 문서 검색됨: 뉴스 기사, 위키피디아
  3. LLM에 문서와 함께 질문 전달
  4. 답변: "2024년 노벨 물리학상은 존 홉필드와 제프리 힌턴이 수상했다."

벡터 검색 원리

임베딩 생성

문서: "한국의 수도는 서울이다" 임베딩 모델을 통해 변환한다. 벡터: [0.23, -0.45, 0.12, ...]

유사도 검색

질문: "한국의 수도는?" 질문 임베딩: [0.21, -0.43, 0.15, ...] 벡터 DB에서 가장 유사한 문서를 검색한다. 결과: "한국의 수도는 서울이다" (유사도: 0.95)

RAG 파이프라인

  1. 인덱싱 단계: 문서를 청크로 분할하고, 임베딩을 생성하여 벡터 DB에 저장한다.
  2. 쿼리 단계: 질문을 임베딩하고, 유사 문서를 검색한 뒤 LLM에 전달하여 답변을 생성한다.

청킹 전략

전략설명적합한 경우
고정 크기500자씩 분할일반적
문장 기반문장 단위 분할짧은 QA
의미 기반단락/섹션 단위긴 문서
겹침 사용청크 간 중복 포함문맥 보존

GraphRAG: 구조화된 지식

기본 RAG는 텍스트 덩어리를 검색한다. GraphRAG는 지식 그래프를 활용한다.

질문: "페니실린은 누가 발견했는가?" 지식 그래프에서 경로를 추적한다: Alexander Fleming → discovered → Penicillin Alexander Fleming → year → 1928 답변: "알렉산더 플레밍이 1928년에 발견"

지식 그래프 예시

Alexander Fleming

  • discovered → Penicillin
  • nationality → Scottish
  • profession → Bacteriologist

Penicillin

  • type → Antibiotic
  • discovered_year → 1928

RAG vs Fine-tuning

RAGFine-tuning
지식 업데이트문서만 추가재학습 필요
비용낮음높음
출처 확인가능어려움
도메인 적용빠름느림
정확도검색 품질 의존모델 품질 의존

구현 예시

python
from langchain import VectorStore, LLM
 
class RAGSystem:
    def __init__(self, documents):
        # 문서 임베딩 및 저장
        self.vector_store = VectorStore.from_documents(
            documents,
            embedding_model="text-embedding-ada-002"
        )
        self.llm = LLM(model="gpt-4")
 
    def query(self, question):
        # 1. 관련 문서 검색
        relevant_docs = self.vector_store.similarity_search(
            question,
            k=3  # 상위 3개 문서
        )
 
        # 2. 프롬프트 구성
        context = "\n".join([doc.content for doc in relevant_docs])
        prompt = f"""다음 문서를 참고하여 질문에 답하세요.
 
문서:
{context}
 
질문: {question}
 
답변:"""
 
        # 3. LLM 응답 생성
        answer = self.llm.generate(prompt)
 
        return {
            "answer": answer,
            "sources": [doc.source for doc in relevant_docs]
        }

고급 기법

Hybrid Search

벡터 검색 + 키워드 검색 결합:

질문: "Python GIL이란?"

벡터 검색: 의미적으로 유사한 문서를 검색한다. 키워드 검색: "GIL"이 포함된 문서를 검색한다.

두 결과를 결합하여 더 정확한 검색 결과를 얻다.

Re-ranking

검색 결과를 LLM으로 재정렬:

검색 결과 10개를 가져온 뒤, LLM이 질문과 가장 관련 있는 순서로 재정렬한다. 최종적으로 재정렬된 결과를 활용한다.

Query Expansion

질문 확장:

원래 질문: "파이썬 속도 개선" 확장된 질문: "파이썬 성능 최적화", "Python performance", "파이썬 프로파일링"

확장된 질문들로 더 많은 관련 문서를 검색한다.

한계

  1. 검색 품질 의존: 관련 문서를 못 찾으면 실패
  2. 컨텍스트 한계: 너무 많은 문서는 처리 불가
  3. 실시간 정보: DB 업데이트 지연
  4. 복잡한 추론: 여러 문서 조합 어려움

관련 개념

  • LLM Agent Survey: 메모리 메커니즘
  • ReAct: 도구 사용 (검색 포함)
  • MADKE: 지식 풀 기반 토론