카페 메뉴 데이터를 작은 지식 베이스로 삼아 검색 증강 생성(Retrieval-Augmented Generation, RAG)의 전체 흐름을 단계별로 익히는 학습 저장소입니다. Python으로 직접 만든 파이프라인과 LangChain·FAISS 기반 파이프라인을 나란히 구현해, 각 단계가 왜 필요한지와 프레임워크가 무엇을 대신 처리하는지 코드로 비교합니다.
완성된 챗봇보다 불러오기 → 분할 → 임베딩 → 저장 → 검색 → 생성의 연결 원리를 이해하는 데 초점을 맞춥니다.
- 텍스트 문서를 불러오고 검색에 적합한 크기로 분할합니다.
- 문서와 질문을 같은 임베딩 모델로 벡터화합니다.
- 코사인 유사도 또는 FAISS로 질문과 가까운 문서를 검색합니다.
- 검색 결과를 프롬프트의 문맥으로 전달해 근거 기반 답변을 생성합니다.
- 직접 구현과 LangChain 구현의 차이를 코드 수준에서 비교합니다.
카페 메뉴 문서
↓ Load
문서 객체
↓ Split
검색용 청크
↓ Embed
임베딩 벡터
↓ Store
벡터 저장소
↓ Search ← 사용자 질문
관련 문서
↓ Augment + Generate
근거 기반 답변
이 프로젝트는 text-embedding-3-small로 문서와 질문을 임베딩하고, gpt-4o-mini로 최종 답변을 생성합니다. 검색 단계에서는 직접 계산한 코사인 유사도와 FAISS 인덱스를 각각 사용합니다.
| 구분 | 직접 구현 | LangChain 기반 구현 |
|---|---|---|
| 문서 로딩 | Python 파일 I/O | TextLoader |
| 문서 분할 | 빈 줄 기준 직접 분할 | RecursiveCharacterTextSplitter |
| 임베딩 | OpenAI SDK | OpenAIEmbeddings |
| 벡터 저장 | Python 리스트와 pickle | FAISS 로컬 인덱스 |
| 유사도 검색 | 코사인 유사도 직접 계산 | Retriever 인터페이스 |
| 답변 생성 | OpenAI Chat Completions | ChatOpenAI 파이프라인 |
| 경로 | 학습 내용 |
|---|---|
1-load/ |
일반 Python 코드와 LangChain으로 문서 불러오기 |
2-split/ |
빈 줄 분할과 재귀 문자 분할 방식 비교 |
3-embed/ |
OpenAI 임베딩 생성 및 벡터 유사도 확인 |
4-store/ |
임베딩과 문서를 pickle 벡터 저장소에 보관 |
5-search/ |
코사인 유사도 검색과 LLM 답변 생성까지 직접 구현 |
6-langchain/ |
LangChain, FAISS, Retriever를 이용한 RAG 구현 |
data/cafe_menu.txt |
검색 대상이 되는 카페 메뉴 지식 문서 |
oneshot.py |
전체 메뉴를 한 번에 프롬프트에 넣는 기준 예제 |
config.py |
프로젝트 공통 데이터 경로 설정 |
- Python 3.9 이상
- OpenAI API 키
git clone https://github.com/jaehunshin-git/openai-faiss-rag-study.git
cd openai-faiss-rag-study
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt프로젝트 루트에 .env 파일을 만들고 API 키를 설정합니다.
OPENAI_API_KEY="your-openai-api-key"실제 API 키가 코드나 Git 커밋에 포함되지 않도록 주의하세요.
각 스크립트는 이전 단계의 결과를 다음 단계에 연결하는 방식으로 구성되어 있습니다.
python3 1-load/load_with_code.py
python3 1-load/load_with_langchain.py
python3 2-split/split_with_code.py
python3 2-split/split_with_langchain.py
python3 3-embed/embed.py
python3 4-store/store.py
python3 5-search/search.py
python3 6-langchain/langchain_ver.py3-embed/load_split_embed.py는 초기 학습 기록으로 Windows 절대 경로가 남아 있습니다. 실행하려면 파일 경로를 현재 환경에 맞게 변경해야 합니다.
python3 5-search/search.py첫 실행에서는 메뉴 문서를 분할하고 임베딩한 뒤 5-search/data/vector_store.pickle에 저장합니다. 이후 실행에서는 저장된 벡터를 불러와 질문과 유사한 메뉴 청크를 검색합니다.
python3 6-langchain/langchain_ver.py첫 실행에서는 FAISS 인덱스를 6-langchain/data/faiss_index/에 생성합니다. Retriever가 관련 문서를 검색하고, LangChain 파이프라인이 검색 문맥과 질문을 조합해 답변을 생성합니다.
빽다방 카페인이 높은 음료와 가격은?
검색 결과에는 메뉴 문서에 기록된 고카페인 음료와 가격 정보가 포함되며, LLM은 검색된 내용 안에서 답변을 구성합니다. 모델 응답은 실행 시점과 모델 버전에 따라 달라질 수 있습니다.
- 청크 크기와 분할 기준이 검색 결과에 어떤 영향을 주는지 비교합니다.
- 문서와 질문에 반드시 같은 임베딩 모델을 사용합니다.
- 검색 개수
k를 변경하며 관련 정보와 불필요한 문맥의 균형을 확인합니다. - 벡터 저장소를 재사용하면 문서 임베딩 API 호출을 줄일 수 있습니다.
- 임베딩과 답변 생성은 OpenAI API를 호출하므로 사용량에 따라 비용이 발생합니다.
chunk_size와chunk_overlap을 바꾸고 검색 결과를 비교합니다.- 검색 문서 수
k를 조절해 정답률과 불필요한 문맥의 변화를 관찰합니다. - 메뉴 외의 텍스트 파일을 추가해 지식 베이스를 확장합니다.
- 질문·기대 답변 묶음을 만들어 검색 품질을 정량적으로 평가합니다.
- FAISS의 거리 함수나 인덱스 유형을 바꾸어 검색 특성을 비교합니다.
- Python
- OpenAI API
- LangChain
- FAISS
- NumPy 및 scikit-learn
이 저장소는 RAG의 핵심 개념을 작은 데이터셋으로 관찰하기 위한 학습용 예제입니다. 운영 환경에서는 데이터 변경 감지, 인덱스 버전 관리, 메타데이터 필터링, 평가 데이터셋, 보안 및 오류 처리 등을 추가로 고려해야 합니다.