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 봇으로 배포했더니 반응이 좋았다. 특히 온보딩 중인 팀원들이 자주 사용했다. 다만 임베딩 비용이 생각보다 나와서 월간 배치로 업데이트 주기를 조정했다.

참고