[AI Study] LangChain으로 RAG 시스템 구축하기
문서를 업로드하면 그 내용을 기반으로 답변하는 AI 만들기
🎯 만들 것
"AI 학습 비서 with RAG"
기능:
- PDF/TXT 문서 업로드
- 자동으로 청크 분할 & 벡터DB 저장
- 질문하면 관련 문서 검색
- 문서 기반 정확한 답변
- 출처 표시
🛠️ 기술 스택
- Python 3.11+
- LangChain - AI 워크플로우 프레임워크
- Chroma - 벡터 데이터베이스
- OpenAI API - GPT-4o-mini & Embeddings
- PyPDF - PDF 파일 처리
📦 Step 1. 패키지 설치
1-1 가상환경 활성화
source venv/bin/activate
1-2 패키지 설치
pip install langchain langchain-openai langchain-community langchain-text-splitters chromadb pypdf
각 패키지 역할:
| 패키지 | 역할 |
|---|---|
langchain |
AI 워크플로우 자동화 |
langchain-openai |
OpenAI API 연동 |
langchain-community |
파일 로더 (PDF, TXT) |
langchain-text-splitters |
텍스트 분할 |
chromadb |
벡터 데이터베이스 |
pypdf |
PDF 읽기 |
💻 Step 2. 문서 업로드 함수 구현
rag_cli.py
from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
import os
def upload_document(file_path: str):
"""문서를 청크로 분할하고 벡터DB에 저장"""
global vectorstore
print(f"\n📥 문서 처리 중: {file_path}")
# 1️⃣ 파일 로드
if file_path.endswith('.pdf'):
loader = PyPDFLoader(file_path)
else:
loader = TextLoader(file_path, encoding='utf-8')
docs = loader.load()
# 2️⃣ 텍스트 분할 (청크)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 1000자씩 자르기
chunk_overlap=200 # 200자 겹치기 (문맥 유지)
)
splits = text_splitter.split_documents(docs)
print(f"✂️ {len(splits)}개 청크로 분할됨")
# 3️⃣ 임베딩 & 벡터DB 저장
embeddings = OpenAIEmbeddings(
api_key=os.getenv("OPENAI_API_KEY")
)
if vectorstore is None:
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db" # 저장 위치
)
else:
vectorstore.add_documents(splits)
print(f"✅ 문서 저장 완료!")
💬 Step 3. 질문-답변 함수 구현 (RAG)
from langchain_openai import ChatOpenAI
def chat(message: str):
"""RAG 기반 질문-답변"""
global vectorstore
if vectorstore is None:
return "❌ 먼저 문서를 업로드해주세요!"
print("\n🔍 문서 검색 중...")
# 1️⃣ 관련 문서 검색
retriever = vectorstore.as_retriever(
search_kwargs={"k": 3} # 상위 3개 청크
)
docs = retriever.invoke(message)
print(f"📎 {len(docs)}개 관련 문서 발견")
# 2️⃣ 검색된 문서를 컨텍스트로 결합
context = "\n\n".join([doc.page_content for doc in docs])
# 3️⃣ LLM 호출
llm = ChatOpenAI(
model="gpt-4o-mini",
api_key=os.getenv("OPENAI_API_KEY"),
temperature=0 # 정확한 답변 (창의성 낮춤)
)
messages = [
{
"role": "system",
"content": "제공된 문서를 기반으로 정확하게 답변하는 AI입니다."
},
{
"role": "user",
"content": f"""다음 문서를 참고해서 질문에 답변해주세요.
문서:
{context}
질문: {message}"""
}
]
response = llm.invoke(messages)
answer = response.content
# 4️⃣ 출처 표시
print("\n📎 참고한 문서:")
for i, doc in enumerate(docs, 1):
print(f"\n[출처 {i}]")
print(doc.page_content[:200] + "...")
return answer
🎮 Step 4. 메인 함수 구현
def main():
"""메인 함수"""
print("=" * 50)
print("📚 AI 학습 비서 with RAG")
print("=" * 50)
print("\n명령어:")
print(" upload <파일경로> : 문서 업로드")
print(" list : 업로드된 문서 목록")
print(" clear : 벡터DB 초기화")
print(" exit : 종료")
print(" 그 외 : 질문하기")
print("=" * 50)
while True:
user_input = input("\n입력: ").strip()
if not user_input:
continue
# 종료
if user_input == "exit":
print("\n👋 학습 비서를 종료합니다!")
break
# 문서 업로드
if user_input.startswith("upload "):
file_path = user_input[7:]
if os.path.exists(file_path):
upload_document(file_path)
else:
print(f"❌ 파일을 찾을 수 없습니다: {file_path}")
# 질문하기
else:
answer = chat(user_input)
print(f"\n🤖 답변:\n{answer}\n")
if __name__ == "__main__":
main()
📄 Step 5. 테스트 문서 작성
python_tutorial.txt
Python 기초 가이드
Python은 1991년 귀도 반 로섬이 만든 프로그래밍 언어입니다.
주요 특징:
- 문법이 간단하고 읽기 쉬움
- 다양한 라이브러리 지원
- 인공지능, 웹 개발, 데이터 분석에 사용
기본 문법:
변수 선언: x = 10
조건문: if x > 5: print("크다")
반복문: for i in range(10): print(i)
함수 정의:
def greet(name):
return f"Hello, {name}!"
리스트:
numbers = [1, 2, 3, 4, 5]
numbers.append(6)
딕셔너리:
user = {"name": "철수", "age": 25}
🚀 Step 6. 실행 및 테스트
6-1 프로그램 실행
python rag_cli.py
6-2 문서 업로드
==================================================
📚 AI 학습 비서 with RAG
==================================================
명령어:
upload <파일경로> : 문서 업로드
list : 업로드된 문서 목록
clear : 벡터DB 초기화
exit : 종료
그 외 : 질문하기
==================================================
입력: upload python_tutorial.txt
📥 문서 처리 중: python_tutorial.txt
✂️ 3개 청크로 분할됨
✅ 문서 저장 완료!
6-3 질문하기
입력: Python은 누가 만들었어?
🔍 문서 검색 중...
📎 3개 관련 문서 발견
📎 참고한 문서:
[출처 1]
Python은 1991년 귀도 반 로섬이 만든 프로그래밍 언어입니다.
주요 특징:
- 문법이 간단하고 읽기 쉬움...
[출처 2]
인공지능, 웹 개발, 데이터 분석에 사용됩니다...
🤖 답변:
Python은 1991년에 귀도 반 로섬(Guido van Rossum)이 만들었습니다.
6-4 더 많은 질문
입력: Python 함수는 어떻게 정의해?
🤖 답변:
def 키워드를 사용하여 함수를 정의합니다.
예: def greet(name): return f"Hello, {name}!"
입력: 리스트에 요소를 추가하는 방법은?
🤖 답변:
append() 메서드를 사용합니다.
예: numbers.append(6)
📊 작동 원리 다이어그램
[사전 작업 - 문서 업로드]
python_tutorial.txt
↓
PyPDFLoader/TextLoader
↓
전체 텍스트 (1500자)
↓
RecursiveCharacterTextSplitter
↓
청크 1 (1000자)
청크 2 (700자) ← 200자 겹침
↓
OpenAIEmbeddings
↓
청크 1 → [0.23, -0.51, ...]
청크 2 → [0.25, -0.48, ...]
↓
Chroma DB 저장 (./chroma_db/)
[질문 시 - 실시간]
질문: "Python은 누가 만들었어?"
↓
OpenAIEmbeddings
↓
질문 벡터: [0.24, -0.49, ...]
↓
Chroma DB 검색 (유사도 계산)
↓
청크 1 (유사도: 0.95) ✅
청크 2 (유사도: 0.82) ✅
↓
상위 2개 청크 선택
↓
GPT에게 전달:
"문서: [청크 1] [청크 2]
질문: Python은 누가 만들었어?"
↓
GPT 답변:
"귀도 반 로섬이 만들었습니다"
💰 비용 분석
문서 처리 (1회):
텍스트 (1500자) → 청크 2개
청크 2개 → 임베딩 생성 (약 500 토큰)
비용: $0.00008 (0.1원)
질문 1회:
질문 임베딩: 10 토큰 → $0.000002
청크 검색: 무료 (로컬 계산)
GPT 호출: 200 토큰 → $0.00008
총 비용: $0.000082 (0.1원)
100회 질문:
문서 처리: $0.00008 (1회만)
질문 100회: $0.0082
총: $0.0083 (약 11원)
비교:
일반 ChatGPT (100회): $0.008
RAG (100회): $0.0083
차이: $0.0003 (0.4원)
→ 거의 비슷한 비용으로 정확도 ↑↑
🎓 핵심 개념 복습
1. 청크 (Chunk)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 1000자씩
chunk_overlap=200 # 200자 겹침
)
→ 긴 문서를 작은 조각으로
2. 임베딩 (Embedding)
embeddings = OpenAIEmbeddings()
vector = embeddings.embed_query("Python")
# → [0.23, -0.51, 0.82, ...]
→ 텍스트를 숫자로
3. 벡터DB (Vector Database)
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings
)
→ 의미로 검색하는 DB
4. RAG (Retrieval-Augmented Generation)
docs = vectorstore.search(query) # 검색
context = join(docs) # 증강
answer = llm(context + query) # 생성
→ 검색 + GPT
✅ Day 2 완료 체크리스트
- LangChain 패키지 설치
- 문서 로더 구현 (PDF, TXT)
- 텍스트 분할 (청크) 구현
- 임베딩 생성
- 벡터DB (Chroma) 설정
- 유사도 검색 구현
- RAG 파이프라인 완성
- CLI 인터페이스 구현
- 출처 표시 기능
🚀 다음 단계
다음은 Agent를 배웁니다!
Agent = 스스로 판단하고 도구 선택하는 AI
예:
질문: "2024년 노벨 물리학상은?"
→ Agent: "문서에 없네? 웹 검색!"
질문: "Python 함수는?"
→ Agent: "문서에 있네? 벡터DB 검색!"
📚 참고 자료
반응형
'AI' 카테고리의 다른 글
| [AI Study] 랭체인(LangChain)과 RAG, 한 번에 이해하기 (0) | 2026.01.18 |
|---|---|
| [AI Study] Python + OpenAI로 AI 챗봇 만들기 (0) | 2026.01.16 |
| [AI Study] 청크, 벡터DB, RAG란? - 개념 쉽게 이해하기 (0) | 2026.01.15 |
| [AI Study] Kotlin + Langfuse로 OpenAI API 모니터링하기 (0) | 2026.01.14 |