728x90
이제까지 우리는 LangChain을 사용해 문서를 임베딩하고,
ChromaDB에 저장하며,
Retriever → QA Chain → Conversational QA Chain으로 이어지는
전체 RAG 시스템의 기본 구조를 구현해왔습니다.
이번 글에서는 이 구조를 FastAPI 웹 서버 형태로 감싸서
📡 외부에서 HTTP 요청을 통해 RAG 시스템을 호출할 수 있도록 구성합니다.
- 사용자는 /rag/query로 질문을 보내면
- 서버는 문서를 검색하고 GPT가 응답을 생성하여
- 응답과 함께 참조 문서까지 반환합니다
🎯 목표
- LangChain QA 체인을 FastAPI로 래핑
- /rag/query POST API 구현
- 질문, 응답, 참조 문서를 포함한 JSON 응답 반환
🗂️ 디렉토리 구조 예시
rag-iceberg-project/
├── src/
│ ├── rag_server.py ← 이번 글에서 작성할 FastAPI 서버
│ └── conversational_chain.py ← ConversationalRetrievalChain 생성 모듈
├── chroma_db/ ← 벡터 DB
└── docs/ ← 문서 저장 디렉토리
⚙️ Step 1. 대화형 QA 체인 생성 함수 (재사용)
# src/conversational_chain.py
from langchain.chains import ConversationalRetrievalChain
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.memory import ConversationBufferMemory
def create_conversational_chain(db_path: str, collection_name: str, k: int = 2):
"""
GPT 모델 + 벡터 검색기 + 대화 히스토리를 포함한 체인을 생성합니다.
이 체인은 FastAPI에서 요청마다 호출되어 대화 흐름을 유지할 수 있습니다.
"""
# ✅ 문서 임베딩 모델 설정
embedding = OpenAIEmbeddings()
# ✅ ChromaDB 벡터 저장소 로딩
vectordb = Chroma(
persist_directory=db_path,
embedding_function=embedding,
collection_name=collection_name
)
# ✅ GPT 모델 (gpt-3.5-turbo 사용)
llm = ChatOpenAI(
model_name="gpt-3.5-turbo",
temperature=0.2
)
# ✅ 대화 히스토리 저장용 메모리 객체
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# ✅ 대화형 QA 체인 구성
chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectordb.as_retriever(search_kwargs={"k": k}),
memory=memory,
return_source_documents=True
)
return chain
🚀 Step 2. FastAPI 서버 구현
# src/rag_server.py
from fastapi import FastAPI, Request # FastAPI 웹 서버 구성 요소
from pydantic import BaseModel # 요청 body를 구조화하기 위한 데이터 모델
from src.conversational_chain import create_conversational_chain # QA 체인 불러오기
import uvicorn # 로컬 테스트용 웹 서버 실행기
# ✅ FastAPI 애플리케이션 객체 생성
app = FastAPI()
# ✅ 질문 요청을 위한 Pydantic 모델 정의
class QueryRequest(BaseModel):
question: str
# ✅ RAG QA 체인 초기화 (앱 시작 시 1회 실행)
qa_chain = create_conversational_chain(
db_path="chroma_db", # 벡터 DB 경로
collection_name="iceberg_tables", # 컬렉션 이름
k=2 # top-k 검색
)
# ✅ 질문을 처리할 POST API 엔드포인트 정의
@app.post("/rag/query")
async def rag_query(request: QueryRequest):
"""
사용자의 질문을 받아 LangChain QA 체인에 전달하고,
응답과 참조 문서를 반환하는 API 엔드포인트입니다.
"""
question = request.question # 요청에서 질문 추출
result = qa_chain(question) # 체인을 통해 응답 생성
# GPT의 응답 텍스트
answer = result["result"]
# 참조 문서들 (각 문서의 page_content만 추출)
sources = [doc.page_content for doc in result["source_documents"]]
# ✅ 응답 JSON 구성
return {
"question": question, # 입력 질문
"answer": answer, # GPT 응답
"sources": sources # 참조된 문서 리스트
}
# ✅ 로컬 실행용 엔트리포인트
if __name__ == "__main__":
uvicorn.run("src.rag_server:app", host="0.0.0.0", port=8000, reload=True)
▶️ 실행 테스트
# 서버 실행
python src/rag_server.py
▶️ POST 요청 예시 (httpie 또는 curl 사용)
http POST http://localhost:8000/rag/query question="상품 테이블의 컬럼은 뭐야?"
✅ 응답 예시:
{
"question": "상품 테이블의 컬럼은 뭐야?",
"answer": "상품 테이블에는 product_id, product_name, category 컬럼이 있습니다.",
"sources": [
"📂 테이블명: products\n🧾 컬럼 목록:\n- product_id (long)\n- product_name (string)\n- category (string)"
]
}
📎 요약 및 핵심 정리
- LangChain QA 체인을 FastAPI 서버로 감싸서 웹 API 형태로 서비스할 수 있게 구성했습니다.
- /rag/query POST API를 통해 질문을 전달하면, GPT 응답과 참조 문서를 JSON으로 반환합니다.
- 내부적으로는 Chroma 검색기 + GPT + 대화형 메모리가 연결된 구조입니다.
- 이후 이 API를 기반으로 웹 UI, 슬랙봇, RAG 클라이언트 등 다양한 연동이 가능합니다.
728x90
'LLM & Generative AI > RAG in Practice' 카테고리의 다른 글
[LangChain RAG 구축 시리즈 Ep.25] 🛡️ 사용자 인증이 포함된 RAG API 구성 전략 (1) | 2025.04.05 |
---|---|
[LangChain RAG 구축 시리즈 Ep.24] 🧑💻 Streamlit 기반 RAG 웹 UI 만들기 (1) | 2025.04.05 |
[LangChain RAG 구축 시리즈 Ep.22] 📊 RAG 성능 평가 지표와 테스트 전략 설계하기 (1) | 2025.04.05 |
[LangChain RAG 구축 시리즈 Ep.21] 🧬 멀티 문서 및 멀티 컬렉션 처리 전략 설계하기 (1) | 2025.04.05 |
[LangChain RAG 구축 시리즈 Ep.20] 🧪 RetrievalQA Chain 성능 최적화 전략 (top-k, score threshold) (0) | 2025.04.05 |