LangChain으로 사내 문서 검색 RAG 시스템 구축하기
문제 상황
회사 기술 문서가 Confluence, Notion, GitHub Wiki 등에 분산되어 있었다. 신규 입사자나 다른 팀 프로젝트를 파악할 때마다 여러 곳을 뒤져야 했고, 검색도 제대로 되지 않았다.
기술 선택
RAG(Retrieval Augmented Generation) 방식을 선택했다. LangChain을 사용하면 문서 로딩부터 벡터 저장까지 파이프라인 구성이 간편했다.
- Embedding: OpenAI text-embedding-ada-002
- Vector DB: Pinecone (관리형이라 운영 부담 적음)
- LLM: GPT-4 Turbo
구현 과정
1. 문서 수집 및 청킹
from langchain.document_loaders import ConfluenceLoader, NotionDBLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
loader = ConfluenceLoader(
url="https://company.atlassian.net",
username=username,
api_key=api_key
)
docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
splits = text_splitter.split_documents(docs)
청킹 사이즈는 여러 번 테스트 후 1000자로 결정했다. 너무 작으면 문맥이 끊기고, 너무 크면 검색 정확도가 떨어졌다.
2. 벡터 저장
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
import pinecone
pinecone.init(api_key=pinecone_key, environment="us-west1-gcp")
embeddings = OpenAIEmbeddings()
vectorstore = Pinecone.from_documents(
splits,
embeddings,
index_name="company-docs"
)
3. 검색 및 응답 생성
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(model_name="gpt-4-turbo-preview", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
return_source_documents=True
)
result = qa_chain({"query": "결제 API 인증 방식은?"})
개선 포인트
- 메타데이터 활용: 문서 작성일, 작성자, 태그 등을 메타데이터로 저장해 필터링에 활용
- Hybrid Search: 키워드 검색과 벡터 검색을 결합하면 정확도가 올라갔다
- 캐싱: 동일 질문은 Redis에 캐싱해 비용 절감
결과
사내 Slack 봇으로 배포했더니 반응이 좋았다. 특히 온보딩 중인 팀원들이 자주 사용했다. 다만 임베딩 비용이 생각보다 나와서 월간 배치로 업데이트 주기를 조정했다.
참고
- LangChain 문서: https://python.langchain.com/
- OpenAI Embeddings 가이드