
【상세편】 RAG는 모델 '내부'에서 무엇을 하고 있는가 ― hidden state와 층(layer)에 대하여
요약
RAG가 모델 내부의 hidden state와 layer에 미치는 영향을 심층 분석합니다. 검색된 문서가 모델의 가중치를 변화시키지 않으면서도 attention 메커니즘을 통해 어떻게 내부 상태에 영향을 주는지 설명합니다.
핵심 포인트
- 검색 문서는 attention을 통해 모든 층의 hidden state에 영향을 미침
- 층을 통해 흐르는 것은 토큰이 아닌 연속값 벡터인 hidden state임
- 출력은 문서의 단순 복사가 아닌 모델이 새롭게 생성한 결과물임
- RAG는 가중치 변화 없이 입력값의 변화를 통해 외부 지식을 활용함
📚 RAG 입문 시리즈
- 【기초편】 RAG는 실제로 어떤 구조인가?
【상세편】 RAG는 모델 "내부"에서 무엇을 하고 있는가 ← 현재 여기
기초편에서는 RAG를 「검색하여, 프롬프트에 연결하고, 생성하는」 외부의 구조로 구성했습니다. 인덱스 생성 방법, 벡터 검색(vector search), 프롬프트 구성 — 이 모든 것은 모델 외부의 이야기입니다.
이 상세편에서는 거기에서 더 나아가 모델의 내부로 내려갑니다. 다루는 내용은 기초편에서 깊이 들어가지 않았던 다음의 의문들입니다.
- 검색해온 문서는
중간 층(layer)이나 hidden state에도 영향을 주는가? - "매 층마다 동일한 토큰을 전달하고 있는가?" - 검색한 토큰을 그대로 정답으로
**복사(copy)**하고 있는가? - 기초편에서 "모델은 RAG와 직접 입력한 것을 구분하지 않는다"라고 했는데,
그것은 내부에서 봐도 사실인가?
수식은 사용하지 않고, 비유와 이미지 도표로 진행합니다. 각 항목은 공개된 기술 문서 및 논문으로 확인했습니다(끝에 출처 기재).
대상 독자: 기초편을 읽은 분, 혹은 "RAG를 구동할 수는 있지만, 모델 내부에서 어떤 일이 일어나고 있는지는 모호하다"라고 느끼는 분.
💡 구현을 먼저 알고 싶으신 분은 기초편을 먼저 읽으시는 것을 추천합니다. 이 기사는 기초편의 이해를 전제로 그 "뒷면"을 설명하는 것입니다.
먼저 요점부터 말씀드리겠습니다.
- 검색 문서는 attention을 통해
모든 층의 hidden state에 영향을 미친다. 단, 그것은 "가중치(weight)가 변했기" 때문이 아니라, "입력이 변했기" 때문에 발생하는 간접적인 파급에 불과하다. - 층을 가로질러 흐르는 것은
**토큰이 아니라 hidden state (연속값 벡터)**이다. 토큰은 임베딩 층(embedding layer)에서 단 한 번 사용된다. - 출력은 검색 문서의
복사가 아니라, 모델이 읽고
새롭게 생성한 것이다. - RETRO / kNN-LM / FiD와 같이, 검색을
중간 층으로 직접 주입하는 별도의 계통도 존재한다. - 그럼에도 불구하고,
입력에 넣는다고 해서 반드시 따르는 것은 아니다 (지식 충돌).
이하, 순서대로 살펴보겠습니다.
내부 이야기로 들어가기 전에, 기초편의 골격을 한 장으로 복습해 두겠습니다. 이미 알고 계신다면 건너뛰셔도 좋습니다.
RAG (Retrieval-Augmented Generation)는 세 단어로 이루어져 있습니다.
| 단어 | 의미 | 하는 일 |
|---|---|---|
| Retrieval | 검색 | 질문과 관련된 문서를 지식 베이스에서 찾음 |
| Augmented | 확장 | 찾은 문서를 질문과 함께 프롬프트로 연결함 |
| Generation | 생성 | 해당 합성 프롬프트를 사용하여 LLM이 답을 만듦 |
흐름으로 나타내면 다음과 같습니다.
사용자의 질문
│
▼
...
포인트는, 이 과정에서 모델의 가중치는 전혀 변하지 않는다는 점입니다. 파인튜닝 (fine-tuning)처럼 재학습을 하는 것이 아니라, 추가 학습 없이 외부 지식을 사용할 수 있게 하는 것이 RAG의 목표입니다. IBM이나 AWS의 해설에서도 RAG는 "재학습 없이 LLM을 외부 지식 베이스에 연결하는 구조"로 설명됩니다.
이 기사의 출발점은 바로 여기입니다. "가중치가 변하지 않는다면, 모델 내부에서는 도대체 무엇이 변하고 있는가?"를 깊이 파고들어 가겠습니다.
기초편에서도 언급했지만, 내부를 살펴보는 데 있어 토대가 되므로 다시 한번 확인해 두겠습니다.
LLM으로의 입력은 최종적으로 "하나의 토큰 열(token sequence)"일 뿐입니다.
그 토큰 열이,
- 당신이 키보드로 직접 입력한 것인지,
- 검색 시스템이 자동으로 가져온 문서를 연결한 것인지,
모델은 구분할 수 없으며, 구분할 필요도 없습니다.
"RAG 전용의 특별한 입력 포트"가 있는 것이 아닙니다. 검색 문서도 당신이 직접 붙여넣은 텍스트와 동일한 "프롬프트의 일부"로서, 완전히 동일한 입구로 들어갑니다.
직접 입력한 프롬프트: [질문 + 당신이 붙여넣은 자료] ──┐
├──► 동일한 토큰 열로서 모델로 전달
RAG: [질문 + 검색이 가져온 자료] ──┘
즉 "RAG인가, 직접 입력한 프롬프트인가"는 모델 내부의 문제가 아니라, 입력 토큰 열을 누가 어떻게 준비했느냐 하는 파이프라인 측의 문제입니다.
극단적으로 말하면, 당신이 매번 직접 "관련 있어 보이는 사내 문서를 검색해서 복사하여 붙여넣은 뒤 질문하는" 작업을 자동화한 것이 RAG라고 이해해도 크게 틀리지 않습니다.
입력만 같다면 결과도 같습니다. 하지만 실제 운용에서는 다음과 같은 점에서 큰 차이가 발생합니다.
- 스케일 (Scale): 수작업으로는 불가능한 양(수만 건의 DB)으로부터, 질문마다 관련 있는 부분만 동적으로 선택하여 입력할 수 있다.
- 신선도·자동성: 사람이 매번 찾지 않아도, 최신 DB에서 자동으로 가져온다.
- 검색 품질에 전적으로 의존: RAG 답변의 좋고 나쁨은 검색이 적절한 문서를 찾아냈는가에 의해 거의 결정된다.
마지막 점은 중요합니다. RAG 실패의 대부분은 생성 측이 아니라 검색 측(관련 문서를 가져오지 못함, 노이즈를 가져옴)에서 발생합니다. 모델 입장에서는 "전달된 입력이 좋았는지 나빴는지"의 문제일 뿐이기 때문입니다. 엉뚱한 자료를 전달하면, 수작업으로 틀린 자료를 붙여넣는 것과 마찬가지로 답변도 그 영향을 받게 됩니다.
자, 이제부터가 본론입니다. "입력 토큰 열(token sequence)이 바뀔 뿐"이라면, 모델 내부에서는 구체적으로 무엇이 바뀌는 것일까요?
여기서부터 내부로 깊이 들어가 보겠습니다. "입력에 추가했을 뿐이라면, 최종 출력에만 영향을 주는 것 아닌가?"라고 생각할지도 모릅니다. 사실 모든 층의 hidden state (은닉 상태)에 영향을 미칩니다. 다만 그 이유가 중요합니다.
Transformer는 각 층의 self-attention (자기 주의 집중)을 통해 "시퀀스 내의 모든 토큰끼리" 정보를 섞으며 처리합니다. 검색 문서를 맨 앞에 넣으면, 그것이 하나의 토큰으로서 시퀀스에 추가되고, 질문 측 및 답변 측 토큰은 각 층의 attention을 통해 해당 검색 문서를 참조합니다.
[검색 문서 토큰] [질문 토큰] [답변 토큰]
│ │ │
└──── attention으로 참조됨 ──────┘ ← 이것이 모든 층에서 일어남
결과적으로 질문·답변 위치의 hidden state는 모든 층에서 검색 내용의 영향을 받습니다.
단, 오해해서는 안 될 점은 이것이 가중치(weight)가 변했기 때문이 아니라는 것입니다. "입력이 변한 것이 attention을 경유하여 모든 층으로 자연스럽게 파급되는" 간접적인 경로일 뿐입니다.
🔑 이것이 "가중치는 변하지 않는데, 내용은 전부 변한다"의 정체입니다.
기초편의 "RAG는 모델을 재학습하지 않는다"와 이 장의 "모든 층에 영향을 미친다"는 모순되지 않습니다.
"모든 층에 영향을 미친다"라고 하면, "토큰을 각 층에 배분하는 것인가?"라고 생각하기 쉽지만, 아닙니다. 이 부분은 Transformer의 기본으로서 짚고 넘어가야 할 포인트입니다.
토큰(=이산적인 ID)이 사용되는 것은 가장 아래의 임베딩 층 (embedding layer)에서 단 한 번뿐입니다.
토큰 ID 열을 임베딩 벡터 열로 변환한 뒤, 층을 거쳐 흘러가는 것은 **hidden state (연속값 벡터)**이지 토큰 그 자체가 아닙니다.
토큰 ID 열 ──(임베딩·단 1회)──► h⁰
h⁰ ──[층 1]──► h¹
h¹ ──[층 2]──► h²
...
- 같은 것: 시퀀스의 길이(=위치의 수). 10개의 토큰을 넣으면 모든 층에서 "위치 10개"라는 구조는 유지된다.
- 다른 것: 각 벡터의 내용. 층을 올라갈수록 표현은 변화해 나간다. 층 2가 받는 것은 "원래의 토큰"도 "h⁰"도 아닌, 층 1이 출력한 "h¹"입니다.
검색 문서도 이 시퀀스 안의 "위치"를 차지할 뿐입니다. 그리고 각 층은 해당 층의 문서 위치에 있는 hidden state로부터 그 층만의 고유한 Key/Value를 계산합니다. "문서의 K/V를 한 번 만들어 모든 층에서 돌려쓰는" 것이 아니라, 층마다 별도로 가지고 있습니다 (KV 캐시도 층마다 다릅니다). 그렇기에 검색 내용의 영향이 "모든 층에서" 효력을 발휘하는 것입니다.
💡 기초편에서 Embedding Model의 내부도를 보신 분들께:
거기서 [Self-Attention → FFN] × N층이라고 쓴 반복 부분이 바로 이 이야기입니다.
임베딩 모델이든 생성용 LLM이든, 층을 흘러가는 것이 hidden state라는 점은 동일합니다.
또 다른 전형적인 오해입니다.
"RAG는 검색한 토큰을 출력에 사용한다"라고 하면, 검색 문서의 토큰을 그대로 답변으로 가져온다는 이미지를 갖기 쉽습니다. 하지만 일반적인 RAG는 그렇지 않습니다.
| 방식 | 수행하는 일 |
|---|---|
| (a) 일반적인 RAG | 검색 문서를 "정보원"으로 읽고, 그 의미와 사실을 근거로 모델이 새롭게 토큰을 생성 |
| (b) 카피 메커니즘 (Copy Mechanism) | 포인터 네트워크 (Pointer Network) / 추출형 QA 등. 문서 중의 스팬 (span)을 그대로 추출 (일반적인 RAG와는 설계가 다름) |
일반적인 RAG (a)에서는 출력 토큰이 어휘 전체에서 매번 샘플링됩니다. 정답의 내용(사실)은 문서에서 유래했을지라도, 출력 토큰열 그 자체는 모델이 구성하는 것입니다. 고유명사나 수치가 문서와 일치하는 경우가 자주 있지만, 이는 '복사한' 것이 아니라 '읽고, 그것을 바탕으로 스스로 작성한' 결과입니다.
비유하자면:
일반적인 RAG (a)… 자료를 읽고 자신의 언어로 답을 쓰는 사람
복사 메커니즘 (b)… 자료의 해당 부분을 그대로 옮겨 적는 사람
일반적으로 「RAG」라고 하면 (a)를 가리킵니다.
참고로, 출력의 대부분이 검색 문서와 똑같다면(=거의 필사) 요약이나 통합이 요구되는 상황에서는 오히려 바람직하지 않은 동작으로 간주되는 경우가 많습니다.
여기까지는 "임베딩 층(embedding layer)에서 한 번 입력하고, 나머지는 자연스럽게 위로 전파된다"는 표준 RAG의 이야기였습니다. 사실, 검색 결과를 명시적으로 중간층(intermediate layer)에 주입하는 설계도 존재합니다. "RAG가 중간층에 영향을 미치는가"라는 질문에 대해, 더욱 구조적으로 개입하는 사례입니다.
기초편 마지막에 이름만 언급했던 세 가지를 여기서 조금 더 자세히 살펴보겠습니다.
| 기법 | 검색을 어디에서 통합하는가 |
|---|---|
| RETRO (DeepMind) | 특정 중간층에 chunked cross-attention을 삽입하여, 검색 청크(chunk)를 그곳에서 직접 참조하게 함 |
| kNN-LM | 출력 분포 레벨에서, 최근접 검색 결과와 보간(interpolation)함 |
| FiD (Fusion-in-Decoder) | 패시지(passage)를 개별적으로 인코딩하고, 디코더에서 융합함 |
예를 들어 RETRO는 사전 학습된 모델의 가중치(weight)를 동결한 상태로, cross-attention 층을 (논문에서는 6번째 층부터 3개 층마다) 추가하는 방식으로 검색을 통합합니다. 이 메커니즘을 통해 GPT-3급의 성능을 약 25분의 1의 파라미터 수로 달성했다는 점이 당시 화제가 된 성과입니다.
지금까지의 이야기와 대비하면 차이점이 명확해집니다.
표준 RAG: 임베딩 층에서 한 번만 입력 → 이후 attention을 통해 자연스럽게 위로 파급 (간접적)
RETRO 계열: 특정 중간층에 검색 결과를 외부에서 직접 삽입 (구조적·의도적)
입문 단계에서는 "이런 별도의 계통도 있구나" 정도의 이해로 충분합니다. 우선은 표준 RAG(=프롬프트에 연결하는 것)를 확실히 잡아둡시다.
마지막으로, 실무에서 유효한 함정을 하나 소개합니다. 기초편에서도 다루었지만, 내부 이야기를 거친 지금이라면 더 납득이 갈 것입니다.
"검색 문서를 입력에 넣으면 모델은 반드시 그것을 따른다"라고 단정할 수는 없습니다. 모델이 검색 문서를 무시하고, 가중치 측의 지식(=원래 알고 있던 지식)으로 답해버리는 케이스가 실제로 존재합니다. 이는 지식 충돌 (knowledge conflict) / context-unfaithfulness로 연구되고 있는 과제입니다.
서베이 논문에서도 "문맥(context)과 가중치 중 어느 쪽을 우선할지에 대한 결정적인 규칙은 존재하지 않는다"라고 되어 있으며, 모델은 종종 의미적으로 일관되고 설득력 있는 정보를 선택하는 경향이 있다고 보고되고 있습니다. 강력한 모델일수록 올바른 외부 증거가 있어도 자신의 내부 기억에 고집하는 경우가 있다는 지적도 있습니다.
왜 이렇게 되는지는 지금까지의 이야기에서 알 수 있습니다. 검색 문서는 "특별 대우를 받는 진실"로서 들어오는 것이 아니라, 단순한 입력 토큰열로서 가중치가 가진 지식과 동일한 선상에서 처리되기 때문입니다. 우선시된다는 보장은 아키텍처 어디에도 없습니다.
즉, "RAG는 입력이니까 확실히 반영될 것이다"라고 과신하는 것도 정확하지 않다는 뜻입니다. 이 점을 이해해 두면, "검색 문서를 제대로 전달했는데 왜인지 옛날 답이 돌아온다"와 같은 현상을 마주했을 때 원인을 추측하기 쉬워집니다.
상세편의 내용을 한 장으로 정리합니다.
- 검색 문서는 attention을 통해 모든 층의 hidden state에 영향을 준다. 단, 가중치가 변해서가 아니라 입력이 변한 것에 따른 파급이다.
- 층을 흐르는 것은 토큰이 아니라 **hidden state (벡터)**이다. K/V는 층마다 독립적이다.
- 출력은 검색 문서의 복사가 아니라, 읽고 새롭게 생성한 것이다.
- RETRO / kNN-LM / FiD와 같이 검색을 중간층으로 직접 주입하는 별도의 계통도 존재한다.
- 입력에 넣는다고 해서 반드시 따르는 것은 아니다 (지식 충돌). 검색 문서에 특권은 없다.
한마디로 말하자면, RAG란 —
내부 파라미터라는 "생성 엔진"에, 검색 문서라는 "사실의 소재"를 주어 작동시키는 메커니즘입니다.
소재는 외부에서 오고, 문장력이나 논리는 모델에서 유래합니다. 그렇게 파악하면 지금까지의 이야기가 모두 연결됩니다.
기초편에서는 RAG를 **외부적인 메커니즘 (outer mechanism)**으로서 구성했습니다 (인덱스 구축 → 검색 → 프롬프트 구성 → 생성).
상세편 (이 기사)에서는 그 입력이 모델의 내부에서 어떻게 다뤄지는지를 살펴보았습니다.
두 가지를 연결하면 다음과 같습니다.
[기초편의 영역: 당신이 만드는 것] [상세편의 영역: 모델이 하는 것]
문서 → 청크 (chunk) → 벡터화 (vectorization) → 검색 → 토큰 열 (token sequence) → 전 층에 파급 → 생성
↑
...
이 경계선이 어디에 있는지를 파악하는 것이 RAG를 이해하는 가장 빠른 길이라고 생각합니다. 경계의 왼쪽은 스스로 컨트롤할 수 있습니다. 오른쪽은 할 수 없습니다. 그렇기에 정밀도 개선은 왼쪽(=검색)부터 시작한다는 판단을 내릴 수 있게 됩니다.
본 기사의 기술적 주장은 아래에서 확인했습니다 (2026년 7월 시점). 기초편과 공통된 출처도 포함합니다.
- IBM 「What is Retrieval-Augmented Generation (RAG)?」 — RAG의 정의 · 재학습이 불필요하다는 점
- AWS 「What is RAG?」 — retrieval / augment / generation의 흐름
- NVIDIA Blog 「What Is Retrieval-Augmented Generation aka RAG」 — 명칭의 유래, parameterized knowledge에 대한 설명
- Pinecone 「Retrieval-Augmented Generation (RAG)」 — 확장 프롬프트 (augmented prompt)의 구체적인 예
- Borgeaud et al. (2022) "Improving language models by retrieving from trillions of tokens" (RETRO 논문, PMLR) — chunked cross-attention, 6번째 층부터 3개 층마다 추가, 25배 적은 파라미터로 GPT-3급 성능
- Khandelwal et al. (2020) "Generalization through Memorization: Nearest Neighbor Language Models" (kNN-LM) — 출력 분포 (output distribution)의 보간
- Izacard & Grave (2021) FiD — Fusion-in-Decoder
- "Knowledge Conflicts for LLMs: A Survey" (arXiv:2403.08319) — 문맥(context)과 가중치(weight)의 우선순위에 결정적인 규칙은 없음
- "FaithfulRAG" (arXiv:2506.08938) 외 — context-unfaithfulness / 지식 충돌 (knowledge conflict)
※ 본 기사는 입문자를 위해 도표와 비유를 우선시하고 있으며, 세부 사항 (KV 캐시, causal attention의 엄밀한 의존 관계 등)은 간략화했습니다. 정확한 구현이나 최신 연구 동향은 위의 1차 자료를 참조해 주시기 바랍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기