---
시작하기 전에
저는 HolySheep AI에서 2년 넘게 AI API 통합 업무를 해온 엔지니어입니다. 수많은 개발자들이 "RAG가 뭔가요?", "벡터数据库를 처음 써봐야 할까요?"라는 질문으로 시작하시는데, 이 튜토리얼은 그런 분들을 위한 입문서입니다. **한 줄 요약: RAG는 AI가 자신만의 데이터로 답변할 수 있게 해주는 기술**이고, 벡터 데이터베이스는 그 데이터를 빠르게 찾는 창고 같은 역할을 합니다.
이 가이드를 마치면:
- 문서 내용을 이해하고 질문하면 정확한 답을 주는 AI 시스템을 만들 수 있습니다
- HolySheep AI를 통해 비용 효율적으로 RAG를 구현할 수 있습니다
- 실제 서비스에 바로 적용 가능한 코드를 얻을 수 있습니다
---
1. RAG와 벡터 데이터베이스란 무엇인가요?
1.1 왜 RAG가 필요한가요?
기존 AI 모델의 문제점을 이해해보겠습니다.
**일반 AI 모델의 한계:**
질문: "우리 회사 반품 정책은 어떻게 되나요?"
AI 답변: "죄송합니다. 저는 2024년 4월까지의 데이터로 학습되었으므로
Specific公司的具体정책은 알 수 없습니다."
AI는 학습된 데이터만 알고 있어, 회사 내부 문서나 실시간 정보에 대해선 "모르겠습니다"라고 답합니다.
**RAG를 적용한 결과:**
질문: "우리 회사 반품 정책은 어떻게 되나요?"
RAG 시스템:
1단계: 관련 문서를 벡터 데이터베이스에서 검색
2단계: 검색된 내용 + 질문을 AI에 전달
AI 답변: "반품 정책은 다음과 같습니다:
- purchased일로부터 30일 이내 반품 가능
- 포장 미개봉 상태여야 함
- 교환은 무제한 가능..."
1.2 핵심 용어 정리
| 용어 | 쉬운 설명 | 비유 |
|------|-----------|------|
| **RAG** | 검색해서 찾은 내용을 AI 답변에 활용 | 도서관에서 책 찾고 내용을 요약하는 것 |
| **벡터** | 문장을 숫자 나열로 변환한 것 | 문장의 "지문" 같은もの |
| **임베딩** | 텍스트를 벡터로 변환하는 과정 | 한국어를 영어로 번역하는 것 |
| **벡터 DB** | 벡터들을 저장하고 빠르게 찾는 데이터베이스 | 숫자로 정리된 서류 캐비닛 |
| **유사도 검색** | 질문과 비슷한 내용을 찾는 것 | "비슷한 질문 가진 사람 찾아봐" |
1.3 시스템 동작 흐름
[사용자 질문]
↓
[질문을 벡터로 변환] ← 임베딩 모델
↓
[벡터 DB에서 유사한 문서 검색]
↓
[검색된 문서 + 질문을 AI에 전달]
↓
[정확한 답변 생성]
---
2. 준비물 설치하기
2.1 필요한 도구들
이 튜토리얼에서 사용할 도구들을 설치하겠습니다.
# 핵심 라이브러리 설치
pip install openai faiss-cpu sentence-transformers python-dotenv langchain langchain-community
프로젝트용 디렉토리 생성
mkdir rag-tutorial
cd rag-tutorial
**각 도구의 역할:**
- **openai**: HolySheep AI API에 연결
- **faiss-cpu**: 무료 벡터 데이터베이스 (로컬 PC에서 작동)
- **sentence-transformers**: 텍스트를 벡터로 변환
- **langchain**: RAG 파이프라인 구축을 쉽게 해주는 프레임워크
- **python-dotenv**: API 키를 안전하게 관리
2.2 프로젝트 구조 만들기
rag-tutorial/
├── .env # API 키 저장 (보안)
├── documents/ # 검색할 문서들
│ ├── policy.txt
│ └── faq.txt
├── main.py # 메인 코드
└── requirements.txt # 필요한 패키지 목록
# requirements.txt 파일 생성
echo "openai>=1.0.0
faiss-cpu>=1.7.0
sentence-transformers>=2.0.0
python-dotenv>=1.0.0
langchain>=0.0.300
langchain-community>=0.0.1" > requirements.txt
---
3. HolySheep AI API 키 받기
3.1 가입하고 API 키 발급받기
HolySheep AI는 해외 신용카드 없이도 로컬 결제가 가능해서 정말 편리합니다.
지금 가입하면 무료 크레딧도 받을 수 있어요.
**순서:**
1. HolySheep AI 웹사이트 접속 → "시작하기" 클릭
2. 이메일로 회원가입 (가장 빠른 방법)
3. 대시보드 → "API Keys" → "새 키 생성"
4.
sk-...로 시작하는 키를 복사
3.2 API 키를 코드에 안전하게 저장하기
**.env 파일 만들기:**
#rag-tutorial 디렉토리에서
touch .env
**.env 파일 내용:**
HOLYSHEEP_API_KEY=sk-your-actual-api-key-here
**중요:**
.env 파일을 절대로 GitHub나 외부에 공유하지 마세요.
.gitignore에 추가하는 것을 잊지 마세요.
echo ".env" >> .gitignore
---
4. 실습용 문서 준비하기
4.1 검색할 문서 만들기
실제로 작동하는 RAG 시스템을 위해 간단한 문서를 만들어보겠습니다.
**documents/policy.txt:**
=== 회사 반품 및 환불 정책 ===
제1조 (반품 기간)
- 상품을 받은 날로부터 30일 이내 반품 신청 가능
- 30일 이후는 반품 불가 (단, 제품 불량 시 예외)
제2조 (반품 조건)
- 제품 포장이 개봉되지 않은 상태여야 함
- 영수증 또는 주문确认서 필수
- 직접 구매한 제품만 반품 가능 (타인 양도품 제외)
제3조 (환불 방법)
- 카드 결제: 5~7 영업일 내 환불
- 계좌이체: 3~5 영업일 내 환불
- 현금 영수증 발급 시: 소득공제 취소 처리
제4조 (교환 정책)
- 동일 제품 사이즈 교환: 무제한 가능
- 다른 제품으로 교환: 차액 정산 후 가능
- 교환 배송비: 편도 3,000원 (회사는 불량품만 부담)
**documents/faq.txt:**
=== 자주 묻는 질문 (FAQ) ===
Q: 반품은 어떻게 하나요?
A: 마이페이지 > 주문내역 > 반품신청 에서 가능합니다.
Q: 반품비谁来 부담하나요?
A: 고객 변심으로 인한 반품은 고객 부담이며, 불량품은 회사 부담입니다.
Q: 교환도 가능하나요?
A: 네, 동일 제품 사이즈 교환은 무료로 가능합니다.
Q: 영수증 분실 시 반품 가능한가요?
A: 이메일로 주문确认서를 보내주시면 처리 가능합니다.
---
5. RAG 시스템 구현하기
5.1 전체 코드 구조 이해하기
우리의 RAG 시스템은 크게 4부분으로 구성됩니다:
┌─────────────────────────────────────────────────────┐
│ RAG 시스템 │
├─────────────────────────────────────────────────────┤
│ 1. 문서 로더: txt 파일 읽어들이기 │
│ 2. 텍스트 분할: 긴 문서를 작은 청크로 나누기 │
│ 3. 임베딩: 청크를 벡터로 변환 + FAISS에 저장 │
│ 4. 검색 + 생성: 질문 → 유사 문서 검색 → AI 답변 │
└─────────────────────────────────────────────────────┘
5.2 메인 코드 작성하기
**main.py:**
"""
RAG 시스템: 문서 검색 + AI 답변
HolySheep AI API를 사용한 실전 예제
"""
import os
from dotenv import load_dotenv
from openai import OpenAI
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
.env 파일에서 API 키 로드
load_dotenv()
HolySheep AI API 설정 (중요: api.holysheep.ai 사용)
client = OpenAI(
api_key=os.getenv("HOLYSHEEP_API_KEY"),
base_url="https://api.holysheep.ai/v1" # 절대로 api.openai.com 사용 금지!
)
def load_documents(directory="documents"):
"""documents 폴더에서 모든 txt 파일 읽기"""
documents = []
for filename in os.listdir(directory):
if filename.endswith(".txt"):
filepath = os.path.join(directory, filename)
loader = TextLoader(filepath, encoding="utf-8")
docs = loader.load()
documents.extend(docs)
print(f"✓ {filename} 로드 완료 ({len(docs)} 문서)")
return documents
def split_documents(documents):
"""긴 문서를 작은 청크로 나누기"""
splitter = RecursiveCharacterTextSplitter(
chunk_size=200, # 한 청크의 크기 (글자 수)
chunk_overlap=50, # 인접 청크 간 겹침 (맥락 유지를 위해)
length_function=len
)
chunks = splitter.split_documents(documents)
print(f"✓ {len(chunks)}개의 청크로 분할 완료")
return chunks
def create_vector_store(chunks):
"""청크를 벡터로 변환하여 FAISS에 저장"""
# 무료 임베딩 모델 사용 (로컬 PC에서 작동)
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
# 벡터 DB 생성
vectorstore = FAISS.from_documents(
documents=chunks,
embedding=embeddings
)
# 로컬에 저장 (다음 실행 시 다시 계산 불필요)
vectorstore.save_local("faiss_index")
print("✓ 벡터 데이터베이스 저장 완료 (faiss_index 폴더)")
return vectorstore
def load_vector_store():
"""저장된 벡터 DB 로드"""
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
return FAISS.load_local(
"faiss_index",
embeddings,
allow_dangerous_deserialization=True
)
def search_and_answer(vectorstore, question, top_k=3):
"""
RAG의 핵심: 검색 + 답변 생성
1. 질문과 유사한 문서를 벡터 DB에서 검색
2. 검색된 문서 + 질문을 AI에 전달
3. 답변 반환
"""
# 1단계: 유사한 문서 검색
docs = vectorstore.similarity_search(question, k=top_k)
print(f"\n{'='*50}")
print(f"검색된 관련 문서 ({len(docs)}개):")
print('='*50)
for i, doc in enumerate(docs, 1):
preview = doc.page_content[:100].replace('\n', ' ')
print(f"[{i}] {preview}...")
# 2단계: 검색된 문서를 컨텍스트로 사용하여 AI 답변 생성
context = "\n\n".join([doc.page_content for doc in docs])
response = client.chat.completions.create(
model="gpt-4.1", # HolySheep AI에서 지원되는 모델
messages=[
{
"role": "system",
"content": """당신은 회사 정책을 안내하는 상담원입니다.
검색된 문서를 기반으로 정확하게 답변해주세요.
답변을 모르는 경우 "문서에서 해당 정보를 찾을 수 없습니다"라고 말해주세요."""
},
{
"role": "user",
"content": f"검색된 문서:\n{context}\n\n질문: {question}"
}
],
temperature=0.3, # 정확한 답변을 위해 낮은 온도
max_tokens=500
)
answer = response.choices[0].message.content
return answer
def main():
print("=" * 50)
print(" RAG 시스템 시작 - HolySheep AI 활용")
print("=" * 50)
# 벡터 DB가 없으면 새로 생성
if not os.path.exists("faiss_index"):
print("\n[1단계] 문서 로딩 중...")
docs = load_documents("documents")
print("\n[2단계] 문서 분할 중...")
chunks = split_documents(docs)
print("\n[3단계] 벡터 데이터베이스 생성 중...")
vectorstore = create_vector_store(chunks)
else:
print("\n[저장된 벡터 DB 로딩 중...]")
vectorstore = load_vector_store()
print("✓ 벡터 DB 로드 완료")
# 대화형 검색 테스트
print("\n" + "=" * 50)
print(" 질문 입력 (종료: 'quit' 또는 '종료')")
print("=" * 50)
while True:
question = input("\n❓ 질문: ").strip()
if question.lower() in ['quit', '종료', 'exit', 'q']:
print("감사합니다! 좋은 하루 되세요!")
break
if not question:
continue
answer = search_and_answer(vectorstore, question)
print("\n📝 답변:")
print("-" * 50)
print(answer)
print("-" * 50)
if __name__ == "__main__":
main()
5.3 실행方法和注意事项
**터미널에서 실행:**
cd rag-tutorial
python main.py
**실행 화면 예시 (스크린샷 힌트: 검은색 터미널, 흰색/녹색 텍스트):**
==================================================
RAG 시스템 시작 - HolySheep AI 활용
==================================================
[1단계] 문서 로딩 중...
✓ policy.txt 로드 완료 (1 문서)
✓ faq.txt 로드 완료 (1 문서)
[2단계] 문서 분할 중...
✓ 12개의 청크로 분할 완료
[3단계] 벡터 데이터베이스 생성 중...
✓ 벡터 데이터베이스 저장 완료 (faiss_index 폴더)
==================================================
질문 입력 (종료: 'quit' 또는 '종료')
==================================================
❓ 질문: 반품은 며칠까지 가능한가요?
5.4 실제 대화 테스트
# 실행 후 아래 질문들을 입력해보세요:
❓ 질문: 반품은 며칠까지 가능한가요?
📝 답변: 상품을 받은 날로부터 30일 이내 반품 신청이 가능합니다.
30일 이후는 반품이 불가하나, 제품 불량 시에는 예외적으로
처리가 가능합니다.
❓ 질문: 카드결제한 경우 환불은 얼마나 걸리나요?
📝 답변: 카드 결제 환불은 5~7 영업일 내 처리됩니다.
❓ 질문: 사이즈 교환은 무료인가요?
📝 답변: 동일 제품 사이즈 교환은 무제한으로 무료로 가능합니다.
다만 다른 제품으로 교환 시에는 차액 정산이 필요하며,
교환 배송비 3,000원이 부과됩니다 (불량품 제외).
---
6. 웹 인터페이스 만들기 (Streamlit)
터미널 대신 웹 브라우저에서 사용하고 싶다면 Streamlit을 활용하세요.
pip install streamlit
**app.py:**
"""
Streamlit 기반 RAG 웹 인터페이스
브라우저에서 문서 검색 AI를 사용할 수 있습니다
"""
import streamlit as st
import os
from dotenv import load_dotenv
from openai import OpenAI
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
API 설정
load_dotenv()
client = OpenAI(
api_key=os.getenv("HOLYSHEEP_API_KEY"),
base_url="https://api.holysheep.ai/v1"
)
벡터 DB 로드
@st.cache_resource
def load_vector_db():
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
return FAISS.load_local(
"faiss_index",
embeddings,
allow_dangerous_deserialization=True
)
메인 UI
st.set_page_config(page_title="RAG 문서 검색 AI", page_icon="📚")
st.title("📚 RAG 문서 검색 시스템")
st.markdown("**HolySheep AI**를活用한 대화형 검색 예제")
사이드바: 시스템 정보
with st.sidebar:
st.header("💡 사용법")
st.write("""
1. 아래 입력창에 질문을 입력하세요
2. AI가 문서에서 관련 내용을 찾아 답변합니다
3. 여러 번 질문하며 대화가 가능합니다
""")
st.markdown("---")
st.caption("Powered by HolySheep AI")
st.caption("Models: GPT-4.1")
벡터 DB 로드
try:
vectorstore = load_vector_db()
except:
st.error("벡터 DB가 없습니다. 먼저 python main.py를 실행해주세요.")
st.stop()
세션 상태로 대화 기록 관리
if "messages" not in st.session_state:
st.session_state.messages = []
이전 대화 표시
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
사용자 입력
if prompt := st.chat_input("질문을 입력하세요..."):
# 사용자 메시지 표시
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# AI 답변 생성
with st.chat_message("assistant"):
with st.spinner("검색 중..."):
# 관련 문서 검색
docs = vectorstore.similarity_search(prompt, k=3)
context = "\n\n".join([doc.page_content for doc in docs])
# AI 응답 생성
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{
"role": "system",
"content": """당신은 회사 정책을 안내하는 상담원입니다.
검색된 문서를 기반으로 정확하게 답변해주세요."""
},
{
"role": "user",
"content": f"검색된 문서:\n{context}\n\n질문: {prompt}"
}
],
temperature=0.3,
max_tokens=500
)
answer = response.choices[0].message.content
st.markdown(answer)
# 참조 문서 표시 (접기 가능한 expander)
with st.expander("📄 참조한 문서 보기"):
for i, doc in enumerate(docs, 1):
st.text(f"[{i}] {doc.page_content}")
# 대화 기록 저장
st.session_state.messages.append({"role": "assistant", "content": answer})
**실행方法:**
streamlit run app.py
**화면 미리보기 (스크린샷 힌트: 파란색/보라색 Streamlit 테마, 중앙 정렬된 입력창):**
┌─────────────────────────────────────────────────────────┐
│ 📚 RAG 문서 검색 시스템 [Streamlit] │
├─────────────────────────────────────────────────────────┤
│ │
│ 💡 사용법 │
│ 1. 아래 입력창에 질문을 입력하세요 │
│ 2. AI가 문서에서 관련 내용을 찾아 답변합니다 │
│ ... │
│ │
├─────────────────────────────────────────────────────────┤
│ │
│ ❓ 반품은 며칠까지 가능한가요? │
│ │
│ 📝 답변: │
│ 상품을 받은 날로부터 30일 이내 반품 신청이 가능합니다. │
│ │
│ 📄 [참조한 문서 보기 ▼] │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ 질문을 입력하세요... [입력] │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
---
7. HolySheep AI 비용 최적화 팁
저는 실제로 HolySheep AI를 사용하면서 비용을 절감한 노하우를 공유드립니다.
7.1 모델 선택 가이드
| 작업 | 추천 모델 | 비용 ($/1M 토큰) | 적합한 상황 |
|------|-----------|------------------|-------------|
| **RAG 답변 생성** | Gemini 2.5 Flash | $2.50 | 대량 쿼리, 비용 효율적 |
| **정확한 분석** | GPT-4.1 | $8.00 | 복잡한 추론 필요 시 |
| **저렴한 대안** | DeepSeek V3.2 | $0.42 | 간단한 질문만 있을 때 |
7.2 비용 최적화 코드 적용
def search_and_answer_optimized(vectorstore, question, budget="low"):
"""
예산에 따른 모델 선택 로직
- budget="low": Gemini Flash (가장 저렴)
- budget="medium": GPT-4.1 (균형)
- budget="high": Claude Sonnet (고품질)
"""
# 모델 매핑
models = {
"low": {
"model": "gemini-2.5-flash",
"cost_per_mtok": 2.50,
"description": "저렴하고 빠른 응답"
},
"medium": {
"model": "gpt-4.1",
"cost_per_mtok": 8.00,
"description": "균형 잡힌 성능"
},
"high": {
"model": "claude-sonnet-4.5",
"cost_per_mtok": 15.00,
"description": "최고 품질"
}
}
selected = models.get(budget, models["medium"])
docs = vectorstore.similarity_search(question, k=3)
context = "\n\n".join([doc.page_content for doc in docs])
# 선택된 모델로 API 호출
response = client.chat.completions.create(
model=selected["model"],
messages=[
{"role": "system", "content": "검색된 문서를 기반으로 답변해주세요."},
{"role": "user", "content": f"문서:\n{context}\n\n질문: {question}"}
],
temperature=0.3,
max_tokens=500
)
# 토큰 사용량 확인 (비용 추적용)
usage = response.usage
estimated_cost = (usage.prompt_tokens / 1_000_000) * selected["cost_per_mtok"]
print(f"📊 예상 비용: ${estimated_cost:.6f}")
print(f" 사용 모델: {selected['model']}")
print(f" 입력 토큰: {usage.prompt_tokens}")
print(f" 출력 토큰: {usage.completion_tokens}")
return response.choices[0].message.content
사용 예시
answer = search_and_answer_optimized(
vectorstore,
"반품 정책 알려주세요",
budget="low" # 가장 저렴한 모델 사용
)
7.3 HolySheep AI 대시보드 활용
실제 비용을 확인하고 싶다면 HolySheep AI 대시보드에서:
- **사용량 그래프**: 일별/주별 토큰 사용량 확인
- **비용 분석**: 모델별 지출 내역
- **예산 알림**: 월별 한도 설정 가능
---
8. 자주 발생하는 오류와 해결책
실제 개발 과정에서 마주친 오류들과 해결 방법을 정리했습니다.
8.1 오류 1: API 키 인증 실패
**에러 메시지:**
AuthenticationError: Incorrect API key provided
**원인:**
-
.env 파일에서 API 키를 제대로 로드하지 못했거나
- 잘못된 API 키를 입력했거나
- base_url이
api.openai.com으로 설정되어 있어 HolySheep 키가 인식되지 않음
**해결 코드:**
# ✅ 올바른 설정
from dotenv import load_dotenv
load_dotenv() # 반드시 main.py 최상단에 위치
client = OpenAI(
api_key=os.getenv("HOLYSHEEP_API_KEY"),
base_url="https://api.holysheep.ai/v1" # HolySheep 전용 URL
)
✅ API 키 확인 코드 (디버깅용)
print(f"API 키 로드: {'✅ 성공' if os.getenv('HOLYSHEEP_API_KEY') else '❌ 실패'}")
print(f"Base URL: https://api.holysheep.ai/v1")
**추가 확인사항:**
# .env 파일 존재 확인
ls -la .env
.env 파일 내용 확인 (키 값만 확인)
cat .env | grep API_KEY
8.2 오류 2: 벡터 DB 로드 실패
**에러 메시지:**
FileNotFoundError: faiss_index folder not found
**원인:**
-
main.py을 한 번도 실행하지 않아 벡터 DB가 생성되지 않음
-
faiss_index 폴더가 다른 디렉토리에 있거나 삭제됨
**해결 코드:**
import os
def ensure_vector_db_exists():
"""벡터 DB가 없으면 새로 생성하는 안전장치"""
index_path = "faiss_index"
if not os.path.exists(index_path):
print("⚠️ 벡터 DB가 없습니다. 새로 생성합니다...")
# 문서 로드
docs = load_documents("documents")
# 분할 및 임베딩
chunks = split_documents(docs)
vectorstore = create_vector_store(chunks)
print("✅ 벡터 DB 생성 완료!")
return vectorstore
else:
return load_vector_store()
메인에서 호출
vectorstore = ensure_vector_db_exists()
8.3 오류 3: 임베딩 모델 다운로드 실패
**에러 메시지:**
HTTPError: 403 Forbidden downloading model
**원인:**
- HuggingFace 서버 접속 문제
- 네트워크 지연으로 타임아웃
- 모델 파일 크기(90MB)에 따른 다운로드 실패
**해결 코드:**
from sentence_transformers import SentenceTransformer
import os
def download_embedding_model():
"""임베딩 모델을 안전하게 다운로드"""
model_name = "sentence-transformers/all-MiniLM-L6-v2"
cache_dir = "./model_cache"
os.makedirs(cache_dir, exist_ok=True)
try:
print(f"📥 '{model_name}' 모델 다운로드 중...")
model = SentenceTransformer(model_name, cache_folder=cache_dir)
print("✅ 모델 다운로드 완료!")
return model
except Exception as e:
print(f"⚠️ 다운로드 실패: {e}")
print("💡 대안: 다른 임베딩 모델 사용")
# 대안 모델 (더 가벼운 모델)
alt_model_name = "paraphrase-MiniLM-L3-v2"
model = SentenceTransformer(alt_model_name, cache_folder=cache_dir)
return model
사용
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
**대안: 온라인 임베딩 API 사용**
로컬 다운로드가 불안정하면 HolySheep AI의 임베딩 API를 사용할 수 있습니다.
def get_embedding_with_holysheep(text, client):
"""HolySheep AI를 사용한 임베딩 (대안 방법)"""
response = client.embeddings.create(
model="text-embedding-3-small", # OpenAI 호환 모델
input=text
)
return response.data[0].embedding
배치 처리 예시
def embed_documents_batch(documents, client, batch_size=100):
"""여러 문서를 배치로 임베딩"""
embeddings = []
for i in range(0, len(documents), batch_size):
batch = documents[i:i+batch_size]
response = client.embeddings.create(
model="text-embedding-3-small",
input=batch
)
embeddings.extend([item.embedding for item in response.data])
print(f"✅ 배치 {i//batch_size + 1} 완료 ({len(embeddings)}/{len(documents)})")
return embeddings
8.4 오류 4: 한국어 검색 결과가 정확하지 않음
**에러 메시지:**
검색 결과: []
또는 관련 없는 문서가 검색됨
**원인:**
- 기본 임베딩 모델이 한국어 성능이 낮음
- 문서 분할 시 의미가 끊어짐
- 검색어와 문서의 벡터 방향이 다름
**해결 코드:**
from langchain.text_splitter import RecursiveCharacterTextSplitter
def korean_aware_splitter():
"""한국어에 최적화된 텍스트 분할기"""
return RecursiveCharacterTextSplitter(
chunk_size=300, # 한국어는 조금 더 크게
chunk_overlap=80, # 맥락 유지를 위해 겹침 증가
length_function=len,
separators=[
"\n\n", # 문단 분리
"\n", # 줄바꿈
"다.", # 문장 단위 (한국어)
"이다.", # 문장 단위 (한국어)
". ", # 영어 문장
" ", # 단어
"" # 문자
]
)
사용
splitter = korean_aware_splitter()
chunks = splitter.split_documents(documents)
검색 시 한국어 최적화
def search_with_re_ranking(vectorstore, query, top_k=5):
"""한국어 검색 정확도를 높이기 위한 리랭킹"""
# 먼저 더 많은 결과 검색
docs = vectorstore.similarity_search(query, k=top_k * 2)
# HolySheep AI를 사용한 리랭킹
prompt = f"""다음 검색 결과 중 '{query}'와 가장 관련된 순서대로
0부터 {len(docs)-1}까지의 번호를 comma로 구분하여 반환해주세요.
질문: {query}
결과:
"""
for i, doc in enumerate(docs):
prompt += f"{i}: {doc.page_content}\n"
response = client.chat.completions.create(
model="gemini-2.5-flash", # 비용 효율적인 모델
messages=[{"role": "user", "content": prompt}],
temperature=0
)
# 번호 파싱 및 정렬
ranking = [int(x.strip()) for x in response.choices[0].message.content.split(',')]
ranked_docs = [docs[i] for i in ranking[:top_k]]
return ranked_docs
8.5 오류 5: Rate Limit 초과
**에러 메시지:**
RateLimitError: Rate limit exceeded for model gpt-4.1
**원인:**
- 너무 많은 요청을 짧은 시간에 보냄
- HolySheep AI의 무료 티어 제한 초과
**해결 코드:**
import time
from collections import defaultdict
class RateLimiter:
"""간단한 레이트 리밋러"""
def __init__(self, max_requests=10, time_window=60):
self.max_requests = max_requests
self.time_window = time_window
self.requests = defaultdict(list)
def wait_if_needed(self):
now = time.time()
# 현재 시간창의 요청 수 확인
recent = [t for t in self.requests['default'] if now - t < self.time_window]
if len(recent) >= self.max_requests:
# 가장 오래된 요청 후 대기
wait_time = self.time_window - (now - recent[0])
print(f"⏳ Rate limit 도달. {wait_time:.1f}초 대기...")
time.sleep(wait_time + 1)
self.requests['default'] = [time.time()]
사용
limiter = RateLimiter(max_requests=10, time_window=60)
def safe_search_and_answer(vectorstore, question):
"""Rate limit을 고려한 안전한 검색"""
limiter.wait_if_needed() # Rate limit 체크
docs = vectorstore.similarity_search(question, k=3)
context = "\n\n".join([doc.page_content for doc in docs])
try:
response = client.chat.completions.create(
model="gemini-2.5-flash",
messages=[
{"role": "system", "content": "검색된 문서를 기반으로 답변해주세요."},
{"role": "user", "content": f"문서:\n{context}\n\n질문: {question}"}
],
max_tokens=500
)
return response.choices[0].message.content
except Exception as e:
return f"오류 발생: {str(e)}"
---
9. 다음 단계: 더 나은 RAG를 위한 팁
9.1 문서 전처리 개선
def clean_text(text):
"""문서 텍스트 정리"""
import re
# 여러 공백을 하나로
text = re.sub(r'\s+', ' ', text)
# 특수문자 정리
text = re.sub(r'[^\w\s가-힣.,!?()\[\]]', '', text)
return text.strip()
def add_metadata(documents):
"""문서에 메타데이터 추가 (검색 정확도 향상)"""
for doc in documents:
# 파일명에서 카테고리 추출
filename = doc.metadata.get('source', '')
if 'policy' in filename:
doc.metadata['category'] = 'policy'
elif 'faq' in filename:
doc.metadata['category'] = 'faq'
doc.metadata['source'] = os.path.basename(filename)
return documents
9.2 하이브리드 검색 구현
```python
def hybrid_search(vectorstore, query, keyword_weight=0.3