LLMLLM 기초 · 3기초

RAG — 외부 지식을 LLM에 연결하는 방법

LLMRAG벡터DB검색증강생성ChromaDB

"오늘 회의록을 요약해줘" — LLM이 모르는 내용

LLM은 학습 데이터에 없는 내용은 모릅니다. 회사 내부 문서, 어제 올라온 뉴스, 사용자의 개인 메모. 이런 정보를 LLM이 활용하게 만들려면 어떻게 해야 할까요?

파인튜닝? 비용이 너무 많이 듭니다. 매번 새 문서가 생길 때마다 모델을 재학습할 수는 없습니다.

RAG(Retrieval-Augmented Generation, 검색 증강 생성) 가 현실적인 해법입니다.


RAG란?

LLM에게 답변을 요청하기 전에, 관련 문서를 검색해서 컨텍스트로 함께 전달하는 방법입니다.

flowchart LR
    subgraph Without_RAG["❌ RAG 없이"]
        Q1["'3분기 매출은?'"] --> LLM1["LLM\n(학습 데이터만 앎)"]
        LLM1 --> A1["'모르겠습니다' 또는\n잘못된 답변"]
    end

    subgraph With_RAG["✅ RAG 적용"]
        Q2["'3분기 매출은?'"] --> R["관련 문서 검색\n(3분기 보고서)"]
        R --> LLM2["LLM\n+ 검색된 문서"]
        LLM2 --> A2["'3분기 매출은\n12.4억 원으로...'"]
    end

RAG 전체 파이프라인

RAG는 크게 인덱싱(준비)검색·생성(실행) 두 단계로 나뉩니다.

flowchart TB
    subgraph INDEX["📚 인덱싱 단계 (사전 준비)"]
        direction LR
        D["문서\n(PDF, 노션, 웹...)"]
        C["청킹\n(500토큰 단위로 분할)"]
        E["임베딩 모델"]
        V["벡터 DB\n(ChromaDB, Pinecone...)"]

        D --> C --> E --> V
    end

    subgraph QUERY["🔍 검색·생성 단계 (실행)"]
        direction LR
        Q["사용자 질문"] --> QE["질문 임베딩"]
        QE --> SIM["유사도 검색\n(Top-K 문서 조각)"]
        V --> SIM
        SIM --> PROMPT["프롬프트 조합\n질문 + 검색 문서"]
        PROMPT --> LLM["LLM"]
        LLM --> ANS["답변"]
    end

    INDEX --> QUERY

핵심 개념 1: 청킹 (Chunking)

문서를 통째로 넣을 수 없으니 적절한 크기로 나눠야 합니다.

flowchart LR
    subgraph DOC["원본 문서 (10,000 토큰)"]
        P1["1~500 토큰\n(1장: 회사 소개)"]
        P2["501~1000 토큰\n(2장: 제품 설명)"]
        P3["1001~1500 토큰\n(3장: 가격표)"]
        P4["..."]
    end

    P1 --> C1["청크 1"]
    P2 --> C2["청크 2"]
    P3 --> C3["청크 3"]
    P4 --> C4["청크 N"]

    C1 & C2 & C3 & C4 -->|"각각 임베딩"| VDB["벡터 DB"]

청크 크기 선택이 성능에 큰 영향을 미칩니다.

청크 크기장점단점
작게 (200~300 토큰)정밀한 검색문맥이 잘림
크게 (800~1000 토큰)문맥 유지노이즈 포함 가능성
적절 (400~600 토큰)균형

핵심 개념 2: 벡터 DB

임베딩된 청크들을 저장하고 빠르게 유사도 검색하는 데이터베이스입니다.

flowchart LR
    subgraph VDB["벡터 DB"]
        direction TB
        R1["청크1 → [0.8, 0.2, ...]"]
        R2["청크2 → [0.3, 0.9, ...]"]
        R3["청크3 → [0.7, 0.1, ...]"]
        R4["청크N → [0.6, 0.4, ...]"]
    end

    Q["질문 벡터\n[0.75, 0.18, ...]"] -->|"유사도 계산"| VDB
    VDB -->|"Top-3 반환"| RESULT["청크1, 청크3, 청크N\n(가장 관련 있는 문서 조각)"]

대표적인 벡터 DB:

DB특징
ChromaDB로컬 실행, 개발·테스트에 적합
Pinecone클라우드 관리형, 대규모 프로덕션
Weaviate오픈소스, 자체 호스팅 가능
pgvectorPostgreSQL 확장, 기존 DB와 통합

프롬프트 조합 패턴

검색된 문서를 어떻게 프롬프트에 넣느냐가 답변 품질을 결정합니다.

[시스템 프롬프트]
당신은 사내 문서를 기반으로 답변하는 어시스턴트입니다.
아래 제공된 문서 내용만을 근거로 답변하세요.
문서에 없는 내용은 "해당 정보가 문서에 없습니다"라고 말하세요.

[검색된 문서 컨텍스트]
--- 문서 1 (2024 3분기 보고서, 5페이지) ---
3분기 총 매출은 12.4억 원으로 전분기 대비 8.3% 증가했습니다...

--- 문서 2 (2024 3분기 보고서, 7페이지) ---
제품별 매출 비중: A 제품 42%, B 제품 35%, 기타 23%...

[사용자 질문]
3분기 매출은 얼마이고, 어떤 제품이 가장 많이 팔렸나요?

RAG의 한계와 보완책

flowchart TD
    subgraph LIMITS["RAG 주요 한계"]
        L1["청크 경계에서\n문맥 잘림"]
        L2["관련 문서를\n못 찾는 경우"]
        L3["검색된 문서가\n너무 많아 노이즈"]
    end

    subgraph SOLUTIONS["보완 전략"]
        S1["청크 오버랩\n(앞뒤 50토큰 중복)"]
        S2["하이브리드 검색\n(키워드 + 벡터)"]
        S3["리랭킹 모델\n(관련도 재정렬)"]
    end

    L1 --> S1
    L2 --> S2
    L3 --> S3

언제 RAG를 쓸까?

상황권장 방법
자주 바뀌는 정보 (뉴스, 공지)RAG
사내 전용 문서·매뉴얼RAG
특정 말투·형식을 학습파인튜닝
일반적인 도메인 지식LLM 기본 능력

정리

개념내용
RAG검색된 문서를 컨텍스트로 전달해 LLM 답변 강화
청킹문서를 처리 가능한 크기로 분할
벡터 DB임베딩 저장·유사도 검색 전문 데이터베이스
인덱싱문서 → 청크 → 임베딩 → DB 저장 (사전 준비)
하이브리드 검색키워드 + 벡터 검색 병행으로 정확도 향상

다음 편에서는 LLM 평가와 한계 — 모델을 어떻게 비교하고 선택하는지 알아봅니다.

궁금한 점이 있으신가요?

협업·의뢰는 아래로, 가벼운 소통은 인스타그램 @bluefox._.hi도 환영이에요.