반응형
지난번 LangChain이란? 포스팅에서 RAG를 아래와 같이 설명했다.
1. RAG
- = Retrieval Augmented Generation, 검색 증강 생성
- 외부 데이터를 참조하여 LLM의 정확도와 신뢰성 향상에 도움을 주는 기술
그런데 왜 외부 데이터를 참조해야 하는 걸까? 그냥 LLM이 가진 정보만으로도 응답이 잘 만들어지지 않나? 의문을 가질 수 있다.

2. 왜 외부 데이터를 참조해야 할까?
LLM은 학습된 데이터를 이용해 응답을 생성한다. 만약 내 구글 캘린더 등에 저장된 데이터를 기반으로 질문한다면 LLM은 잘못된 정보를 응답할 가능성이 크다.

이때 내 구글 캘린더의 정보를 LLM에게 전달할 수 있다면? LLM은 해당 정보를 기반으로 올바른 응답을 생성할 수 있다.

RAG를 한국어로 직역하면 검색 증강 생성이다. 단어만 보면 굉장히 어렵게 느껴지지만, 동작 과정을 하나하나 생각해 보면 단어 뜻 그대로인 이름이다.


❓ RAG와 자주 비교되는 파인 튜닝은 무엇일까?
- 기존 딥러닝 모델의 가중치를 새로운 데이터셋에 맞게 다시 학습시키는 과정 (=모델의 재학습 필요)
- RAG와 달리 검색 과정이 필요가 없어 상대적으로 처리 속도가 빠름
3. RAG의 동작 흐름
RAG는 이론적인 개념이므로 상세 구현 방식은 프레임워크마다 다를 수 있다. 이 글에서는 LangChain을 기준으로 정리하였다. 다른 프레임워크(ex: Spring AI)와 유사하게 사용하는 용어들도 많으니 이해가 어렵진 않다.
| LangChain | Spring AI | |
| 문서 로딩 | Document Loader | ResourceLoader |
| 벡터화 | Vector Embedding | EmbeddingModel |
| 검색 | Retriever | VectorStoreRetriever |

- Document Loaders: 외부 데이터(ex: 문서, pdf) 불러오기
- Text Splitters
- 불러온 데이터를 문장, 토큰 등 의미 단위로 분할
- LLM이 처리하기 적합하게 준비
- 분할된 것을 청크라고 부르기도 함
- vector embeddings
- 텍스트를 임베딩 모델로 변환하여 벡터 형태로 전환
- 생성된 벡터들을 vector store(벡터 저장소)에 저장
- retriever: 사용자의 질문과 유사한 데이터를 vector store에서 검색
- chain
- 검색된 텍스트를 LLM에 전달하고, LLM의 응답을 이용해 최종 답변 생성
- 전처리/후처리/추가 연산 등을 설정 가능
4. RAG의 주요 구성요소
Document Loader
- 외부 데이터(ex: text, pdf, 웹페이지,...)를 RAG 전용 객체로 불러오는 역할
Text Splitter
- 큰 문서를 여러 개의 작은 청크로 나누는 역할 (= 데이터를 의미 단위로 분할하는 역할)
- LLM은 토큰 제한이 있기 때문에 적당한 단위로 청크를 나누는 게 중요

- 여러 개의 청크로 나누기 -> 각 청크마다 적절한 벡터 찾기 -> 벡터를 LLM에게 넘기기

- character text splitter
- 구분자 1개 기준으로 구분
- 토큰 제한(max_token)을 맞추기 어려움
- ex: 줄 바꿈일 때 분할
- recursive character text splitter
- 구분자 여러 개를 재귀적으로 돌아가면서 분할
- ex: 줄 바꿈일 때 분할 -> (max_token 못 지키면) 다음, 로 분할
- chunk overlap
- 청크를 나눌 때 이전 청크의 일부를 포함시켜서 분할
- 벡터 찾을 때 이전 청크의 마지막 문장 참고할 수 있도록 하기 위해 (컨텍스트의 연결)
- token text splitter
- 글자 수가 아닌 실제 토큰 단위로 분할
- 글자수로 자를 경우, '이 정도면 LLM이 감당 가능한 토큰 수로 변환되겠지'라고 생각해도 토큰 제한 수를 넘어가는 경우 발생 가능
Embedding
- 텍스트를 벡터 형태의 수치화된 데이터로 변환
- 문장 간의 의미적 유사도를 계산할 수 있게 함
- pre-trained embedding model
- 대규모 데이터로 사전 학습된 모델
- 유료인 경우가 많으며, 다양한 기능이 제공됨
- OpenAI 등에서 제공
- local embedding model
- 임베딩 전용 모델을 로컬 환경에 직접 띄워서 사용
- 언어나 환경 제약 등 불편함 존재
- 보안상 유리할 수 있음 (로컬에 직접 띄우니까 데이터를 외부 서버에 있는 LLM에 전달할 필요가 없음)
Vector Store
- 변환된 벡터(=수치화된 값, 임베딩된 값)를 저장하는 저장소
- 의미 기반 검색이 가능
- ex: FAISS, Milvus, Chroma,...
Retriever
- vector store에서 사용자의 질의와 가장 유사한 데이터를 검색
- 검색된 결과는 사용자 질문과 함께 엮어 LLM에게 넘김
Chain
검색된 결과를 어떻게 조합하고 전달하느냐에 따라 다양한 방식의 체인 존재
- stuff documents chain
- 가장 단순한 형태
- 질의와 검색된 텍스트를 그대로 프롬프트에 삽입
- 찾아온 컨텍스트를 그대로 넘기기 때문에 토큰 이슈 발생 가능
- map reduce documents chain
- map: 텍스트 청크들 각각에 대해 요약 수행 (병렬 수행 가능)
- reduce: 생성된 요약에 대해 최종 요약 생성
- 최종 요약을 생성하기 위해 LLM 다수 호출 필요 → 속도 느리고 비용 증가
- refine documents chain
- 청크를 순차적으로 처리하며 답변을 누적
- 품질이 뛰어나고 시간이 오래 걸림
- 질문 + (질문 + n-1번째 컨텍스트)로 만든 답변 + n번째 컨텍스트

- map re-rank documents chain
- 각 청크별로 '청크 + 질문'으로 LLM에게 답변받아냄
- 위 답변에 스코어(사용자 질문과의 연관성)를 받아서 높은 스코어를 가진 답변을 활용
출처 및 참고
- 모두의AI님 유튜브 - LangChain 뿌시기
- 2025 우아콘 김태정 님 발표 - RAG, 들어는 봤는데... 내 서비스엔 어떻게 쓰지?
- https://docs.langchain.com/oss/python/langchain/overview
- https://blogs.nvidia.com/blog/what-is-retrieval-augmented-generation/?utm_source=chatgpt.com
반응형
'Develop > AI' 카테고리의 다른 글
| LangChain이란? (2) | 2025.11.03 |
|---|