RAG란? — LLM에 내 데이터를 붙이는 법과 한계까지

@JavaPark · 2026년 8월 16일 · 12 min read

RAG 검색 증강 생성 원리 커버 — 질문을 벡터로 바꿔 관련 문서를 찾아 프롬프트에 넣는 흐름
RAG 검색 증강 생성 원리 커버 — 질문을 벡터로 바꿔 관련 문서를 찾아 프롬프트에 넣는 흐름

안녕하세요, 자바파커입니다.

"우리 회사 문서로 챗봇을 만들고 싶은데, 모델을 새로 학습시켜야 하나요?"

거의 항상 답은 아니오입니다. 학습은 비싸고 느리고, 문서가 바뀔 때마다 다시 해야 합니다.

결론부터 말씀드리면 — RAG는 모델을 다시 가르치는 게 아니라, 질문이 들어올 때마다 관련 문서를 찾아서 프롬프트에 끼워 넣는 방식입니다. Retrieval-Augmented Generation, 검색 증강 생성이라고 부릅니다.

비유하자면 오픈북 시험입니다. 학생(LLM)을 다시 가르치는 대신, 시험장에 교재를 들고 들어가게 하는 것이죠. 그리고 이 비유는 RAG의 한계까지 정확히 설명해 줍니다 — 책에서 엉뚱한 페이지를 펼치면 답도 틀립니다.


LLM만 쓰면 생기는 문제

LLM은 모르는 것을 모른다고 말하지 않습니다. 학습 시점 이후의 일이나 내부 문서처럼 본 적 없는 내용을 물으면, 그럴듯한 문장을 만들어 냅니다. 이걸 환각(Hallucination)이라고 합니다.

문제는 틀린 답이 맞는 답과 똑같이 자신 있게 나온다는 점입니다. 사내 규정이나 제품 사양처럼 정확해야 하는 영역에서는 치명적입니다.

RAG가 하는 일 — 5단계

1. 문서를 조각낸다 (청킹)

문서 전체를 통째로 넣을 수는 없습니다. 컨텍스트 한계도 있고 비용도 듭니다. 그래서 문단 단위 정도로 잘라 둡니다. 보통 수백~1,000토큰 정도이고, 조각끼리 조금씩 겹치게(overlap) 잘라 문맥이 끊기는 걸 줄입니다.

2. 조각을 벡터로 바꾼다 (임베딩)

각 조각을 임베딩 모델에 넣어 숫자 배열로 바꿉니다. 핵심은 의미가 비슷한 문장이 좌표상 가까운 곳에 놓인다는 것입니다.

"환불 규정"과 "반품 절차"는 글자가 겹치지 않지만 벡터 공간에서는 가깝습니다. 키워드 검색으로는 못 찾는 걸 찾을 수 있는 이유입니다.

3. 질문도 같은 방식으로 벡터로 바꾼다

사용자 질문을 같은 임베딩 모델로 벡터화합니다. 같은 모델을 써야 같은 공간에 놓입니다.

4. 가까운 조각을 찾는다 (유사도 검색)

질문 벡터와 가장 가까운 조각 K개(보통 3~5개)를 벡터 DB에서 꺼냅니다. 거리는 보통 코사인 유사도로 잽니다.

5. 프롬프트에 끼워 넣고 LLM에 넘긴다

찾아온 조각을 원문 그대로 프롬프트에 붙입니다.

아래 문서를 참고해서 질문에 답하세요.
문서에 없는 내용은 모른다고 답하세요.

[문서 1] 환불은 구매 후 7일 이내 ...
[문서 2] 단, 개봉한 제품은 ...

질문: 개봉했는데 환불되나요?

**"문서에 없으면 모른다고 답하라"**는 지시가 중요합니다. 이게 있어야 환각이 줄어듭니다. 그리고 어떤 조각을 썼는지 알고 있으니 출처를 함께 보여줄 수 있습니다.

파인튜닝과 뭐가 다른가

RAG 파인튜닝
하는 일 프롬프트에 문서를 넣어 준다 모델 가중치를 바꾼다
지식 갱신 문서만 다시 인덱싱 (즉시) 다시 학습 (비용·시간)
출처 표시 가능 어려움
잘하는 것 사실·지식을 다루는 것 말투·형식·스타일
비용 낮음 높음

기억할 기준은 하나입니다. "무엇을 아는가"는 RAG, "어떻게 말하는가"는 파인튜닝. 둘은 배타적이지 않고 같이 쓰기도 합니다.


RAG를 붙였는데도 답이 틀리는 5가지

여기가 실무의 진짜 영역입니다. RAG의 품질은 생성이 아니라 검색이 결정합니다.

1. 검색이 틀리면 답도 틀린다

가장 흔하고 가장 근본적입니다. LLM은 받은 문서 안에서만 답합니다. 엉뚱한 조각이 올라오면 그걸 근거로 그럴듯하게 틀린 답을 만듭니다. 오픈북 시험에서 잘못된 페이지를 펼친 것과 같습니다.

답이 이상할 때 모델을 의심하기 전에 무엇이 검색됐는지 먼저 찍어 보세요. 대부분 여기서 원인이 나옵니다.

2. 청킹이 문맥을 자른다

"이 경우에는 예외로 한다"라는 문장이 앞 문단과 분리되면, 무엇의 예외인지 알 수 없는 조각이 됩니다. 표가 중간에서 잘리는 것도 흔한 사고입니다.

문단·제목 경계를 존중해서 자르고, 조각에 문서 제목이나 상위 섹션을 메타데이터로 붙여 두면 많이 좋아집니다.

3. 유사도는 정답을 보장하지 않는다

벡터 검색이 찾는 건 **"의미가 비슷한 것"**이지 **"질문에 답이 되는 것"**이 아닙니다.

"환불 안 되는 경우"를 물었는데 "환불 되는 경우"를 설명한 문단이 올라올 수 있습니다. 의미 공간에서는 아주 가깝기 때문입니다. 부정 표현에 특히 약합니다.

키워드 검색(BM25)과 섞은 하이브리드 검색, 그리고 가져온 뒤 다시 순위를 매기는 리랭킹이 이 문제를 완화합니다.

4. 관계를 따라가지 못한다

"A 팀장의 상사가 속한 부서의 예산은?" 같은 질문은 벡터 검색으로 풀리지 않습니다. 답이 한 조각에 들어 있지 않고, 여러 사실을 연결해야 나오기 때문입니다.

유사도는 "닮음"은 알지만 "관계"는 모릅니다. 이게 벡터 검색의 구조적 한계입니다.

5. 인덱싱하지 않으면 모른다

문서를 고쳐도 다시 임베딩해서 벡터 DB에 넣지 않으면 옛 내용으로 답합니다. RAG는 자동으로 최신이 되지 않습니다 — 파이프라인을 돌려야 최신이 됩니다.


그다음 — 벡터 검색만으로 부족할 때

위의 4번(관계를 못 따라간다) 이 계속 걸린다면, 벡터 검색 위에 구조를 얹어야 합니다. 사실을 문장 덩어리가 아니라 노드와 관계로 저장하는 방식, 즉 지식 그래프와 온톨로지입니다.

그 과정을 블로그 자체 검색을 만들면서 7편으로 기록해 두었습니다. 이 글 다음으로 읽기 좋은 순서입니다.

  1. 온톨로지 기반 검색이란? — 벡터 검색만으로 부족했던 이유
  2. 검색을 위한 온톨로지 설계
  3. 지식 그래프 구축 실전 — Neo4j vs RDF
  4. LLM으로 본문에서 자동 추출
  5. GraphRAG로 자연어 질의 풀기
  6. 운영하며 배운 것 — 비용·한계
  7. 정형 DB·빅데이터와 함께 가기

자주 묻는 질문 (FAQ)

Q. 벡터 DB를 꼭 따로 써야 하나요?

문서가 수천 건 수준이면 필요 없습니다. PostgreSQL의 pgvector나 라이브러리 하나로 충분합니다. 전용 벡터 DB는 규모가 커지고 필터링·메타데이터 조건이 복잡해질 때 의미가 생깁니다. 처음부터 인프라를 늘리지 마세요.

Q. 컨텍스트 윈도우가 커졌는데 그냥 문서를 다 넣으면 안 되나요?

넣을 수는 있지만 비용이 토큰 수에 비례해 늘고, 문서가 길수록 중간에 있는 내용을 놓치는 경향이 있습니다. 그리고 어떤 근거로 답했는지 특정하기 어려워집니다. 관련 조각만 골라 넣는 편이 싸고 정확하고 추적 가능합니다.

Q. 답변 품질을 올리려면 어디부터 손대야 하나요?

검색부터입니다. 순서는 (1) 무엇이 검색됐는지 로깅 → (2) 청킹 전략 조정 → (3) 하이브리드 검색·리랭킹 도입 → (4) 프롬프트 수정 입니다. 프롬프트를 먼저 만지는 경우가 많은데, 대개 효과가 가장 작습니다.


정리

  • RAG는 모델을 다시 가르치는 게 아니라 질문할 때마다 문서를 찾아 프롬프트에 넣는 것
  • "무엇을 아는가"는 RAG, "어떻게 말하는가"는 파인튜닝
  • 품질을 결정하는 건 생성이 아니라 검색입니다. 답이 이상하면 무엇이 검색됐는지부터 보세요
  • 유사도는 "닮음"은 알아도 "관계"는 모릅니다 — 여기서 막히면 지식 그래프로 넘어갈 때입니다

RAG를 붙였는데 기대만큼 안 나왔던 경험, 원인이 어디였나요? 댓글로 나눠 주세요.


참고 자료

@JavaPark
AI 시대의 개발자 도구, 실전 경험을 공유합니다