RAG – 원리와 쓰지 않아도 되는 경우
RAG는 검색 증강 생성(Retrieval-Augmented Generation)의 줄임말입니다. 모델이 답을 만들기 전에 지식 베이스에서 관련 정보를 검색해 프롬프트에 붙여 주는 방법이에요.
이 글의 앞쪽에서는 RAG가 어떤 순서로 동작하고 어떤 한계가 알려져 있는지를 RAG 모델을 소개한 2020년 논문과 Anthropic의 글을 근거로 정리합니다. 뒤쪽은 제 프로젝트 이야기인데, 먼저 밝혀 두면 제 프로젝트는 RAG를 쓰지 않습니다. 대신 어떤 방식으로 AI에게 문서를 읽히는지를 실제 규칙 파일과 함께 적었습니다.
RAG란 무엇인가
RAG라는 말이 붙은 모델을 소개한 논문은 2020년 5월 arXiv에 올라온 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks입니다. Patrick Lewis 외 11명이 썼고, 초록 페이지에는 NeurIPS 2020에 채택됐다고 적혀 있어요.

초록이 짚는 배경은 이렇습니다. 사전 학습된 언어 모델은 사실 지식을 파라미터 안에 저장하지만, 그 지식을 꺼내 정밀하게 다루는 능력에는 한계가 있고, 답의 출처를 제시하는 일과 지식을 갱신하는 일도 풀리지 않은 문제로 남아 있다는 거예요. 논문은 여기에 두 가지 기억을 결합한 모델을 내놓습니다. 하나는 사전 학습된 생성 모델이고, 다른 하나는 위키백과를 벡터로 색인해 둔 외부 기억인데, 이 외부 기억은 사전 학습된 검색기로 찾아 씁니다.

Anthropic은 2024년 9월 19일에 올린 글에서 RAG를 이렇게 설명합니다. 지식 베이스에서 관련 정보를 검색해 사용자의 프롬프트에 덧붙이는 방법이라는 거죠. 고객 지원 챗봇이 그 회사에 대한 지식을 알아야 하는 경우를 예로 듭니다.
문서를 조각내서 답을 만들기까지
Anthropic의 글이 설명하는 RAG의 동작 순서를 그림으로 옮기면 아래와 같습니다. 앞의 세 단계는 미리 해 두는 준비이고, 뒤의 두 단계는 질문이 들어올 때마다 일어납니다.

- 지식 베이스의 문서를 작은 조각으로 나눈다. 보통 수백 토큰을 넘지 않는 크기다
- 임베딩 모델로 각 조각을 의미를 담은 벡터로 바꾼다
- 벡터를 의미가 비슷한 것끼리 찾을 수 있는 벡터 데이터베이스에 저장한다
- 질문이 들어오면 질문과 의미가 가장 가까운 조각을 찾는다
- 찾은 조각을 프롬프트에 넣어 모델이 답을 만든다
같은 글은 이 방식의 쓸모를 규모에서 찾습니다. 프롬프트 하나에 담을 수 있는 분량을 훨씬 넘는 지식 베이스까지 비용을 아끼며 확장할 수 있다는 설명이에요.
AI 적용 사례 – Contextual Retrieval로 RAG 검색 실패 줄이기임베딩 검색이 놓치는 것
한계도 같은 글에 적혀 있습니다. 임베딩은 의미의 관계를 잘 잡지만 글자가 정확히 일치해야 하는 검색에서는 중요한 것을 놓칠 수 있다고 해요. 글이 드는 예는 기술 지원 문서에서 특정 오류 코드를 찾는 경우입니다. 임베딩 모델은 오류 코드 일반에 대한 내용을 찾아 주면서 정작 그 코드가 적힌 문서는 빠뜨릴 수 있습니다.
이럴 때 같이 쓰는 것이 BM25입니다. 단어나 구절이 정확히 일치하는 것을 찾는 순위 함수로, 글은 고유 식별자나 기술 용어가 든 질문에 특히 효과적이라고 소개합니다. 임베딩 검색과 BM25 검색의 결과를 합쳐서 쓰는 구성도 함께 설명하고요.
두 번째 한계는 조각내기에서 생깁니다. 조각 하나만 떼어 놓으면 맥락이 사라지거든요. “회사의 매출이 전 분기보다 3% 늘었다”는 조각만 봐서는 어느 회사의 어느 분기 얘기인지 알 수 없고, 그러면 맞는 조각을 찾기도, 찾은 조각을 쓰기도 어려워집니다.
조각에 맥락을 붙이는 Contextual Retrieval
Anthropic의 Contextual Retrieval은 이 두 번째 한계를 다루는 방법입니다. 조각을 임베딩하거나 BM25 색인을 만들기 전에, 그 조각이 전체 문서의 어디에 해당하는지를 설명하는 짧은 글을 조각 앞에 붙여요. 설명은 사람이 쓰지 않고 모델에게 문서 전체와 조각을 같이 주고 쓰게 하는데, 보통 50~100토큰 길이라고 합니다.
전통적인 RAG의 조각
- 조각의 본문만 임베딩한다
- 어느 문서의 어느 부분인지가 조각에 남지 않는다
Contextual Retrieval의 조각
- 맥락 설명을 앞에 붙인 뒤 임베딩한다
- BM25 색인도 맥락이 붙은 조각으로 만든다
글에 실린 실험 수치는 다음과 같습니다.
이 숫자에는 조건이 붙어 있습니다. 앞의 두 숫자는 코드베이스, 소설, 논문 등 여러 분야의 평균이고, 시험한 것 가운데 성적이 가장 좋았던 임베딩 구성에서 상위 20개 조각을 가져왔을 때의 결과예요. 실패율은 관련 문서가 상위 20개 조각 안에 들어오지 못한 비율을 뜻합니다. 답변의 정확도를 잰 것은 아니고 검색 단계에서 잰 숫자입니다.

지식 베이스가 작으면 RAG 없이 통째로 넣는다
같은 글의 앞부분에는 RAG를 쓰지 않아도 되는 경우가 먼저 나옵니다. 지식 베이스가 20만 토큰(약 500쪽 분량)보다 작으면 전체를 프롬프트에 넣으면 되고 RAG나 비슷한 방법이 필요 없다는 안내예요. 반복해서 쓰는 프롬프트를 캐시해 두는 프롬프트 캐싱을 쓰면 이 방식이 더 빠르고 싸진다고 덧붙입니다. 지식 베이스가 커지면 더 확장할 수 있는 방법이 필요하다는 말이 바로 뒤에 이어집니다.
여기에 제 프로젝트의 방식을 하나 더해 세 가지를 나란히 놓으면 이렇습니다. 앞의 두 줄은 Anthropic 글에 근거가 있고, 마지막 줄은 공식 기준 없이 제가 쓰는 방식입니다.

| 방식 | 문서를 고르는 방법 | 쓰는 경우 |
|---|---|---|
| RAG | 조각을 임베딩해 두고 질문과 가까운 조각을 검색한다 | 컨텍스트 윈도에 다 들어가지 않는 큰 지식 베이스 |
| 통째로 넣기 | 고르지 않고 전체를 프롬프트에 넣는다 | 지식 베이스가 20만 토큰보다 작을 때 |
| 목차 두고 찾아 읽기 | 목차 파일로 위치를 알려 주고 검색해서 구간만 읽는다 | 제 프로젝트의 방식. 어느 규모까지 맞는지 공식 기준은 없다 |
제 프로젝트는 목차 파일로 문서 위치를 알려 준다
앱인토스 미니앱을 만드는 제 저장소에는 임베딩도 벡터 데이터베이스도 없습니다. AI가 읽어야 하는 문서는 저장소 안에 파일로 들어 있고, AI 코딩 도구가 그 파일을 직접 찾아 읽어요. Claude Code 공식 문서는 기본 도구로 파일 읽기와 검색을 들고, 검색 도구가 하는 일을 패턴으로 파일 찾기와 정규식으로 내용 검색하기로 설명합니다.
찾아 읽게 하려면 어디에 무엇이 있는지를 알려 줘야 하는데, 그 역할을 세션마다 읽히는 규칙 파일이 맡습니다. 아래는 그 파일의 해당 부분 첫머리예요.
## Where knowledge lives
This file is a table of contents, not the knowledge itself. Open a document only when the task
needs it; none of these are session-start reading.
| Need | Go to |
| --- | --- |
| How to build/ship an app | `appintoss/harness/SKILL.md` |
| Live SDK or ad policy | `appintoss/harness/OFFICIAL_SOURCES.md` |이 파일은 지식 자체가 아니라 목차이고, 표에 적힌 문서는 작업에 필요할 때만 연다는 뜻입니다. 표는 “이런 게 필요하면 이 문서로 가라”는 줄이 이어지는 형태예요.
문서를 열 때의 규칙도 한 줄 있습니다.
- 토큰: 앱 하나 = 세션 하나. 메인 세션에서 PNG를 `Read`하지 않고, 긴 문서는 `grep -n` 뒤 `sed -n`으로 구간만 읽는다.grep -n은 찾는 말이 몇 번째 줄에 있는지를 알려 주고, sed -n은 지정한 줄 범위만 출력하는 명령입니다. 표의 마지막 줄은 외부 매뉴얼을 모아 둔 폴더인데, 688KB 분량이라 검색만 하고 통째로 열지 말라고 적어 뒀어요. 지난 작업 기록 문서에도 전체를 읽지 말라는 표시가 붙어 있습니다.
두 명령을 규칙 파일 자체에 돌려 보면 이렇게 나옵니다. 제목이 있는 줄 번호를 먼저 얻고, 그 줄부터 아홉 줄만 읽은 출력이에요.

검색에서 빼는 폴더와 읽는 범위
검색 범위를 정하는 규칙은 Codex 터미널용으로 따로 둔 정책 문서에도 있습니다. 이 문서는 첫머리에 목적을 적어 두었는데, 필요한 코드와 상태만 읽어 컨텍스트 낭비를 제한한다는 것입니다. 검색할 때는 아래처럼 빌드 결과물과 설치된 패키지 폴더, 번들 파일을 기본으로 제외하게 했어요.
rg --glob '!**/dist/**' --glob '!**/node_modules/**' --glob '!**/*.ait' <pattern>읽는 순서도 여기에 적혀 있습니다. 작업은 context 명령으로 시작해서 출력에 나온 readNext 파일을 먼저 읽고, 부족한 사실이 생길 때만 좁은 범위로 파일을 검색합니다. readNext 목록을 만드는 코드는 AI 하네스 글에서 다뤘습니다.
검색어는 AI가 정한다
RAG는 질문과 가까운 조각을 검색 시스템이 골라 프롬프트에 넣어 줍니다. 제 프로젝트에서는 AI 코딩 도구가 검색 명령을 직접 실행하고, 규칙 파일은 어디를 찾고 어디를 찾지 말지, 찾은 뒤 어떻게 읽을지를 정해 둡니다.
공식 문서는 주소만 적어 둔다
앱인토스 공식 문서처럼 저장소 밖에 있는 자료는 주소 목록으로 관리합니다. 목록 파일의 첫머리에는 지금 작업에 필요한 페이지만 열라는 것과, 이 실시간 페이지들이 예전에 저장소에 두던 문서 사본을 대신한다는 것이 적혀 있어요.
주소는 .md로 끝나는 것을 쓰게 했습니다. 목록 파일에 적힌 이유는 .md 주소가 마크다운 원문을 바로 돌려줘서 요청 한 번으로 끝나고 읽는 데 드는 토큰이 적다는 것입니다. 규칙 파일에는 이 목록을 최신 정책이나 API 확인이 필요할 때만 쓰라는 줄도 있습니다.
RAG 자주 묻는 질문
RAG가 뭔가요?
검색 증강 생성(Retrieval-Augmented Generation)의 줄임말입니다. 지식 베이스에서 질문과 관련된 정보를 검색해 프롬프트에 붙인 뒤 모델이 답을 만들게 하는 방법입니다.
문서가 많지 않아도 RAG를 써야 하나요?
Anthropic의 Contextual Retrieval 글은 지식 베이스가 20만 토큰(약 500쪽)보다 작으면 전체를 프롬프트에 넣으면 되고 RAG 같은 방법이 필요 없다고 안내합니다. 지식 베이스가 그보다 커지면 확장할 수 있는 방법이 필요하다고 덧붙입니다.
이 블로그의 미니앱 프로젝트는 RAG를 쓰나요?
쓰지 않습니다. 임베딩이나 벡터 데이터베이스 없이, 규칙 파일을 목차로 두고 필요한 문서만 검색해서 해당 구간을 읽게 합니다.
글에 나온 규칙 파일과 에이전트는 Claude Code에서 쓰는 방식이고, 공식 안내는 Claude Code 공식 문서에 있습니다.
이 글은 직접 만들고 운영하며 남긴 기록입니다. 적힌 수치는 작성 시점의 제 계정 기준이며, 같은 결과나 수익을 보장하지 않습니다.

7 Comments