반응형
💼 전문가 지식 기반 응답 에이전트
회사 내부 구성원들이 사용할 수 있는
전문적인 지식 기반 질문응답(Q&A) 에이전트를 구축합니다.
이 에이전트는 높은 정확도를 유지해야 하며, 구현 비용은 낮게 유지하는 것이 중요합니다.
이 프로젝트에서는 질문에 대한 높은 정확도를 보장하기 위해
RAG (Retrieval Augmented Generation) 방식을 활용합니다.
Gradio 챗봇 만들기 전에 알아야 할 파이썬 필수 라이브러리 정리 (os, glob, dotenv, gradio)
# 📦 필수 라이브러리 임포트 (환경 설정 + UI 구성 등)
import os # 🧭 파일 경로 및 환경 변수 관리를 위한 표준 라이브러리
import glob # 📂 폴더 내 특정 패턴의 파일을 일괄 탐색할 때 사용 (ex: 모든 .txt 불러오기)
from dotenv import load_dotenv # 🔐 .env 파일에 저장된 환경변수(예: API 키) 불러오기
import gradio as gr # 💬 Gradio로 간단한 웹 기반 UI(예: 챗봇 인터페이스) 구성
💡 언제 쓰이나요?
- os, glob: 문서 파일 경로 탐색, API 키 설정 등 기본 작업에 필수
- dotenv: .env 파일에 저장된 민감한 정보(API 키 등)를 안전하게 불러옴
- gradio: 실제로 사용자와 상호작용할 수 있는 챗봇 UI를 만들 때 사용됨
LangChain으로 RAG 구현 준비: 문서 불러오기와 청크 분할 완전 정복
# 📦 LangChain 기반 RAG 구현을 위한 핵심 모듈 불러오기
from langchain.document_loaders import DirectoryLoader, TextLoader
# 📂 DirectoryLoader: 지정한 폴더 내의 모든 텍스트 파일을 일괄 로드할 때 사용
# 📄 TextLoader: 단일 텍스트 파일을 불러올 때 사용
# ✅ 두 로더 모두 문서형 데이터셋 구축 시 필수 (예: 나만의 knowledge base 구성)
from langchain.text_splitter import CharacterTextSplitter
# ✂️ CharacterTextSplitter: 긴 문서를 일정 길이로 잘라서 나누는 도구
# - LLM 입력 길이 제한을 고려하여 문서를 "청크(chunk)" 단위로 나누는 데 사용
# - RAG 문맥 검색 정확도를 높이기 위해 매우 중요한 과정
💡 언제 유용할까?
상황 | 사용 모듈 |
폴더에 있는 여러 문서를 한 번에 로드하고 싶을 때 | DirectoryLoader |
단일 텍스트 문서를 로드할 때 | TextLoader |
너무 긴 문서를 적절한 길이로 쪼개야 할 때 | CharacterTextSplitter |
gpt-4o-mini와 vector_db로 효율적인 RAG 시작하기
# 💰 회사의 예산 제약을 고려해, 비용이 낮은 경량 모델(gpt-4o-mini) 사용
# - gpt-4o-mini: OpenAI의 저비용 고성능 모델 (빠르고 비용 효율적)
MODEL = "gpt-4o-mini"
# 🗃️ 벡터 데이터베이스 이름 설정
# - 문서 임베딩을 저장하고 검색할 때 사용할 로컬/클라우드 DB 이름
# - 이후 Chroma, FAISS 등에서 해당 이름으로 저장소 생성
db_name = "vector_db"
💡 보충 설명
항목 | 설명 |
gpt-4o-mini | RAG에서 context 기반 응답만 하므로, 고가 모델보다 경량 모델이 적절 |
vector_db | 임베딩된 문서들을 저장하는 DB 이름. 검색 성능 향상에 핵심 역할 |
Python에서 OpenAI API 키를 안전하게 불러오는 .env 설정법 (load_dotenv 실습 포함)
# 🔐 .env 파일에 저장된 환경 변수 불러오기
# - API 키, 토큰 등 민감 정보를 코드에 직접 노출하지 않기 위한 보안 관행
# - .env 파일에 OPENAI_API_KEY="sk-..." 형식으로 작성해두면 안전하게 불러올 수 있음
load_dotenv(override=True)
# ✅ OPENAI_API_KEY를 환경변수로 설정
# - .env에 값이 있으면 그걸 사용하고, 없을 경우 기본값("your-key-if-not-using-env")을 사용함
# - 이후 openai 라이브러리에서 자동으로 해당 키를 참조함
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')
💡 언제 유용하냐면?
- .ipynb 공유하거나 GitHub에 올릴 때 API 키가 유출되지 않도록 함
- 팀 단위로 개발할 때 각자 .env 파일만 맞춰두면 코드 수정 없이 실행 가능
.env 파일 예시
# .env 파일 예시
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
HF_TOKEN=hf_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
LangChain으로 문서 자동 불러오기: RAG 지식베이스 구축의 첫 단계
# 📚 LangChain을 사용해 지식 문서(.md)를 일괄 불러오는 단계
# - knowledge-base/ 폴더 내 모든 하위 폴더를 탐색
# - 각 폴더는 staff, products 등 문서 유형별로 구분되어 있음
folders = glob.glob("knowledge-base/*")
# 🔍 knowledge-base 아래 있는 모든 하위 폴더 경로를 리스트로 수집
# 🛠️ 일부 시스템(특히 Windows)에서 인코딩 오류를 방지하기 위한 설정
text_loader_kwargs = {'encoding': 'utf-8'}
# 💡 만약 위 설정이 실패할 경우 아래 코드로 자동 인코딩 감지를 사용할 수 있음
# text_loader_kwargs = {'autodetect_encoding': True}
documents = [] # 최종적으로 로딩된 문서들을 담을 리스트
for folder in folders:
doc_type = os.path.basename(folder) # 폴더 이름(staff, products 등)을 문서 유형으로 저장
# 📂 해당 폴더 내 모든 .md 파일을 재귀적으로 불러오기
loader = DirectoryLoader(
folder,
glob="**/*.md", # 하위 디렉토리까지 포함
loader_cls=TextLoader, # .md 파일을 텍스트로 읽는 로더 클래스 지정
loader_kwargs=text_loader_kwargs # 인코딩 옵션 전달
)
folder_docs = loader.load() # 문서 로딩 실행
for doc in folder_docs:
doc.metadata["doc_type"] = doc_type # 문서에 유형 정보를 메타데이터로 저장
documents.append(doc) # 전체 문서 리스트에 추가
이 코드는 LangChain을 활용해 knowledge-base 폴더 내 모든 하위 폴더의 문서를 읽어오는 부분입니다.
💡 설명 요약
항목 | 설명 |
DirectoryLoader | 폴더 내 문서(.md)를 자동으로 불러오는 LangChain 도구 |
TextLoader | 각 문서를 텍스트로 로드하는 역할 |
doc.metadata["doc_type"] | 향후 분류나 필터링에 사용할 수 있는 문서 유형 정보 저장 |
LangChain 문서 불러오기 이후 꼭 확인해야 할 한 줄: len(documents) 활용법
# 📊 불러온 전체 문서 개수 출력
# - documents는 위에서 LangChain으로 불러온 모든 문서의 리스트
# - 이 코드를 통해 knowledge-base에 포함된 총 문서 수를 확인할 수 있음
# - 문서가 제대로 불러졌는지 sanity check(기본 점검) 용도로도 자주 사용됨
len(documents)
💡 예시 출력
48 # → 총 48개의 .md 문서가 knowledge-base 하위 폴더에서 로딩됨
🧪 실무에서 이렇게 써요:
- 문서 수가 0이면 경로 오류 or 인코딩 문제일 가능성이 있음
- 문서 개수를 기준으로 embedding 처리 진행 여부를 조건부로 설정할 수도 있음
LangChain 문서 객체(Document)의 구조 살펴보기: 내용과 메타데이터 한눈에 이해하기
# 📄 25번째 문서 객체 확인 (인덱스는 0부터 시작하므로 24는 25번째)
# - documents 리스트는 LangChain의 DirectoryLoader로 불러온 문서 객체들의 모음
# - 각 요소는 LangChain의 Document 객체이며, 아래와 같은 구조를 가짐:
# - doc.page_content: 문서 내용 (본문)
# - doc.metadata: 문서의 파일 경로, 유형(doc_type) 등 메타 정보 포함
documents[24]
documents[24]는 documents 리스트에서 25번째 문서 객체를 가져오는 코드입니다.
💡 예시 결과 형태
Document(
page_content="Shopwise의 결제 시스템은 PayNow, QuickPay를 포함하며 고객의 편의성에 중점을 두고 있습니다.",
metadata={
'source': 'knowledge-base/products/payment.md',
'doc_type': 'products'
}
)
🔍 활용 팁
- documents[24].page_content: 문서 본문만 보기
- documents[24].metadata: 어떤 문서에서 왔는지 확인 (분류, 경로 등)
반응형
'🧠 LLM 엔지니어링' 카테고리의 다른 글
LangChain과 Chroma를 활용한 문서 임베딩 시각화 실습 01 (0) | 2025.04.26 |
---|---|
LLM 문서에서 특정 키워드 추출하는 방법 02 (Shopwise 지식기반 예제) (1) | 2025.04.25 |
LangChain으로 시작하는 RAG 파이프라인 구축 여정 (1) | 2025.04.23 |
RAG와 벡터 임베딩 이해하기 (1) | 2025.04.22 |
LLM 챗봇 만들기: 전자상거래 회사 지식 기반 질문응답 시스템 (RAG 구현 예제) (1) | 2025.04.21 |