| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 |
- aws SAA-c03
- 올 겨울은 조금 따뜻할 것 같다.
- level2
- Next.js
- server engineer
- java #추상클래스
- 주니어 백엔드 개발자
- 서버 엔지니어
- 서버 개발자
- java #예외처리 #throw #throws
- 자바 #자바문법 #자바기초 #참조형 #기본형
- level3
- server developer
- tibero 7.23
- 넥슨개발자컨퍼런스
- 25304번
- 반복문
- ndc2025
- heap area #stack area #static area #jvm
- 이분탐색
- software enginner
- 나는야 4학년 #5학년 까지 가보자구
- AWS
- Spring
- static #자바 메모리 구조 #멤버 변수
- 2026 하반기 대기업 반드시 갑니다
- 백엔드 개발자 로드맵
- 정보처리기사 실기 #정처기 실기 #2024년 2회 #정처기 2024년 2회 #공부법 # 꿀팁
- object 클래스 # java
- tmax tibero
- Today
- Total
개발자 쿠키
[AI] RAG 본문
RAG (Retrieval-Augmented Generation)
LLM이 모르는 것을 지어내지 않게 만드는 방법. 질문에 답하기 전에 외부 문서에서 근거를 먼저 찾아오는 구조
1. 왜 RAG가 필요한가
LLM 단독 사용의 한계는 크게 세 가지
| 한계 | 내용 |
|---|---|
| 환각 (Hallucination) | 모르는 내용을 그럴듯한 문장으로 생성. 사실 여부와 무관하게 확신에 찬 어조 유지 |
| 도메인 지식 부재 | 사내 규정, 제품 매뉴얼, 내부 FAQ 등 학습 데이터에 없는 정보는 답변 불가 |
| 최신 정보 미반영 | 학습 시점(knowledge cutoff) 이후 정보 부재. 재학습 비용이 커서 실시간 반영 불가 |
파인튜닝은 모델 자체를 바꾸는 방식이라 비용과 주기가 부담.
RAG는 모델을 건드리지 않고 프롬프트에 근거 문서를 끼워 넣는 방식이라 문서만 갱신하면 즉시 반영
2. RAG 동작 흐름
크게 인덱싱과 서빙 두 단계. 시점이 다르다는 게 핵심

인덱싱 서비스 배포 전 미리 돌려두는 배치
문서 로딩 → 청킹 → 임베딩 → Vector Store 저장. 문서가 바뀔 때만 재실행
서빙 요청이 들어올 때마다 실시간
질문 임베딩 → 유사 조각 top-k 검색 → 컨텍스트로 프롬프트 구성 → LLM 답변 생성
핵심은 LLM에게 "기억해서 답해"가 아니라 "이 문서 보고 답해"로 바꾸는 것. 근거가 프롬프트 안에 있으니 환각 감소, 출처 표시도 가능
3. 검색 방식: 키워드 vs 의미 기반
| 구분 | Lexical Search | Semantic Search |
|---|---|---|
| 기준 | 단어의 문자열 일치 | 벡터 공간에서의 의미 거리 |
| 대표 기법 | TF-IDF, BM25 | 임베딩 + 코사인 유사도 |
| 강점 | 고유명사, 코드, 제품명 등 정확한 토큰 매칭 | 동의어와 문장 표현 차이 흡수 |
| 약점 | "환불"과 "반품"을 다른 것으로 인식 | 희귀 고유명사에 취약, 임베딩 비용 발생 |
실무에서는 둘을 함께 쓰는 Hybrid Search가 일반적. BM25 점수와 벡터 유사도 점수를 가중 합산하거나 RRF(Reciprocal Rank Fusion)로 순위 병합
4. 임베딩과 코사인 유사도
임베딩은 텍스트를 고차원 실수 벡터로 변환하는 작업. OpenAI text-embedding-3-small은 1536차원

코사인 유사도
cos(A, B) = (A · B) / (|A| × |B|)
두 벡터가 이루는 각도의 코사인 값. 범위는 -1 ~ 1이고, 1에 가까울수록 의미가 유사. 벡터 크기(문서 길이)의 영향을 받지 않는 것이 유클리드 거리 대비 장점
"주문 취소하고 싶어요"와 "결제 철회 방법 알려줘"는 겹치는 단어가 하나도 없음. 키워드 검색으로는 못 찾지만 임베딩 공간에서는 각도가 좁아 가깝다고 판단. 이게 의미 기반 검색이 가능한 이유
5. Vector Store
임베딩 벡터를 저장하고 유사도 검색을 수행하는 데이터베이스. 전체 벡터를 일일이 비교하면 O(N)이라 느리므로 ANN(Approximate Nearest Neighbor) 알고리즘으로 근사 검색. HNSW, IVF 등이 대표적인 인덱스 구조
| 제품 | 특징 |
|---|---|
| ChromaDB | 로컬 임베디드 실행. 학습, 프로토타입용으로 진입 장벽 낮음 |
| FAISS | Meta 개발 라이브러리. 인메모리 기반이라 빠르지만 영속화는 직접 관리 |
| Pinecone | 완전 관리형 SaaS. 운영 부담 적고 스케일아웃 용이 |
| pgvector | PostgreSQL 확장. 기존 RDB 트랜잭션과 함께 관리 가능 |
6. 청킹 전략
긴 문서를 통째로 임베딩하면 의미가 뭉개지고 프롬프트 토큰 한도도 초과. 적절한 크기로 분할 필요
chunk_size 청크 최대 길이
작으면 검색 정밀도는 올라가지만 답변에 필요한 문맥이 잘림
크면 문맥은 살지만 노이즈가 섞여 유사도가 희석됨
chunk_overlap 청크 간 겹치는 구간
경계에서 문장이 끊기는 문제를 완화. 보통 chunk_size의 10 ~ 20% 수준
정답 없음. 문서 성격에 따라 다름. FAQ처럼 항목이 짧고 독립적이면 작게, 기술 문서처럼 맥락이 이어지면 크게. 실제 질의 셋으로 검색 결과를 눈으로 비교하며 튜닝하는 게 가장 확실
7. Retriever와 파이프라인
Retriever는 쿼리 임베딩과 Vector Store 검색을 감싼 컴포넌트. LangChain에서는 vectorstore.as_retriever(search_kwargs={"k": 4}) 형태로 생성. top-k 개수는 정확도와 토큰 비용의 트레이드오프
LangGraph StateGraph 구성
State에 question, context, answer 등을 정의
retrieve 노드에서 검색 결과를 State에 채움
generate 노드에서 context를 프롬프트에 주입해 LLM 호출
노드를 엣지로 연결하고 컴파일 후 invoke
단순 체인 대신 그래프로 구성하는 이유는 확장성. 검색 결과가 부실할 때 재검색하는 분기, 답변 검증 노드 추가 등 조건부 흐름을 붙이기 쉬움
'AI' 카테고리의 다른 글
| [AI] 머신러닝(ML), 딥러닝(DL), 자연어처리(NLP) 용어 정리 (0) | 2026.08.11 |
|---|---|
| [Claude] Figma MCP 연동하기 (windows11) (0) | 2026.03.20 |
