본문 바로가기
🚀 AI 연구소/AI 활용 가이드

내 데이터로 만드는 나만의 AI 비서: RAG와 랭체인(LangChain) 완벽 가이드 (코딩 초보도 가능?)

by 노마드데이터랩 2025. 11. 30.

안녕하세요, nomadlab.kr의 수석 에디터입니다.

오늘날 우리는 '생성형 AI'의 홍수 속에 살고 있습니다. ChatGPT, Claude, Gemini 등 수많은 모델이 쏟아져 나오고 있죠. 하지만 여러분도 이런 경험 한 번쯤 있으시죠?

"ChatGPT는 똑똑하긴 한데, 우리 회사 내부 규정은 전혀 모르네..."
"내 개인적인 메모나 논문 내용을 기반으로 요약해 줄 수는 없을까?"

범용 LLM(거대언어모델)은 세상의 방대한 지식을 학습했지만, '당신의 데이터'는 학습하지 않았습니다. 그렇다고 민감한 내부 문서를 무턱대고 학습 데이터로 넘길 수도 없는 노릇입니다. 여기서 등장하는 개념이 바로 RAG(Retrieval-Augmented Generation, 검색 증강 생성)입니다.

오늘은 2024년 AI 개발 트렌드의 핵심인 RAG와 이를 가장 쉽게 구현할 수 있게 도와주는 도구인 랭체인(LangChain)에 대해 아주 깊이 있게, 그리고 실전 코드와 함께 분석해 보겠습니다.



1. 심층 분석: 왜 LLM만으로는 부족한가? (RAG의 필요성)

1.1. 할루시네이션(Hallucination)과 데이터의 최신성

LLM은 기본적으로 '다음에 올 단어를 확률적으로 예측하는 기계'입니다. 그렇기 때문에 사실이 아닌 정보를 그럴듯하게 지어내는 '환각 현상(Hallucination)'이 발생합니다. 또한, 모델이 학습된 시점(Cut-off date) 이후의 정보는 알지 못합니다.

예를 들어, 오늘 발표된 삼성전자의 주가나 지난주에 변경된 여러분 회사의 취업 규칙은 GPT도 알 수 없습니다. 이를 해결하기 위해 매번 모델을 새로 학습(Fine-tuning)시키는 것은 비용과 시간 측면에서 비효율적입니다.

1.2. RAG(검색 증강 생성)의 작동 원리

RAG는 '오픈북 테스트'와 같습니다. 시험을 볼 때 머릿속에 있는 지식(Pre-trained Knowledge)만으로 푸는 것이 아니라, 참고서(External Data)를 옆에 두고 필요한 부분을 찾아보며 답을 작성하는 방식입니다.

RAG의 프로세스:

  1. 질문(Query): 사용자가 질문을 던집니다.
  2. 검색(Retrieve): 질문과 관련된 문서를 미리 구축된 데이터베이스(Vector DB)에서 찾습니다.
  3. 증강(Augment): 찾은 문서를 질문과 함께 프롬프트에 포함시킵니다.
  4. 생성(Generate): LLM이 검색된 정보를 바탕으로 정확한 답변을 생성합니다.

1.3. 랭체인(LangChain): AI 애플리케이션의 오케스트라 지휘자

이 RAG 과정을 파이썬 코드로 밑바닥부터 짜려면 매우 복잡합니다. API 호출, 데이터 전처리, 벡터 변환 등을 모두 관리해야 하죠. LangChain은 이 모든 과정을 모듈화하여 레고 블록처럼 조립할 수 있게 해주는 프레임워크입니다. 현재 AI 개발 생태계에서 사실상의 표준(De facto standard)으로 자리 잡았습니다.


2. 기술적 핵심: 벡터 데이터베이스와 임베딩(Embedding)

RAG 시스템의 심장부는 바로 벡터 데이터베이스(Vector Database)입니다. 컴퓨터는 텍스트의 '의미'를 이해하기 위해 텍스트를 숫자의 나열인 '벡터(Vector)'로 변환합니다. 이 과정을 임베딩(Embedding)이라고 합니다.

2.1. 텍스트를 숫자로? (Embedding의 마법)

예를 들어보겠습니다.

  • "사과"와 "배"는 벡터 공간에서 가까운 위치에 존재합니다. (과일이라는 공통점)
  • "사과"와 "스마트폰"은 아주 먼 거리에 위치합니다.
  • 하지만 "애플"이라는 단어는 문맥에 따라 "사과" 근처에 있을 수도, "스마트폰" 근처에 있을 수도 있습니다.

임베딩 모델(OpenAI의 text-embedding-3-small 등)은 문장의 의미를 다차원 공간의 좌표로 변환해 줍니다.

2.2. Vector DB의 역할

우리가 가진 PDF, Word, 텍스트 파일들을 쪼개서 임베딩한 후, 이 벡터값들을 저장하는 곳이 Vector DB입니다.

  • Pinecone: 클라우드 기반, 관리형 서비스 (대규모 상용 서비스에 적합)
  • ChromaDB: 로컬 설치 가능, 오픈소스 (개인 프로젝트 및 테스트에 적합)
  • FAISS: Meta에서 만든 고속 검색 라이브러리

3. 실전 활용: 10분 만에 구축하는 '내 문서 기반 챗봇'

자, 이제 이론은 충분합니다. nomadlab.kr의 독자라면 직접 코드를 돌려봐야겠죠? 파이썬을 사용하여 로컬 환경에서 작동하는 간단한 RAG 시스템을 만들어 보겠습니다.

준비물:

  • Python 3.8 이상
  • OpenAI API Key
  • 분석하고 싶은 텍스트 파일 (my_data.txt)

Step 1: 환경 설정 및 라이브러리 설치

터미널을 열고 아래 명령어를 입력하여 필요한 라이브러리를 설치합니다.

pip install langchain langchain-openai chromadb tiktoken

Step 2: 문서 로드 및 분할 (Chunking)

LLM은 한 번에 처리할 수 있는 토큰(글자 수)에 제한이 있습니다. 따라서 긴 문서를 적절한 크기로 잘라줘야 합니다. 이를 Chunking이라고 합니다.

import os
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# API 키 설정 (환경변수로 관리하는 것이 안전합니다)
os.environ["OPENAI_API_KEY"] = "sk-당신의_API_키_여기에_입력"

# 1. 문서 로드
loader = TextLoader("my_data.txt", encoding="utf-8")
documents = loader.load()

# 2. 문서 분할 (Chunking)
# chunk_size=1000: 1000자 단위로 자름
# chunk_overlap=200: 문맥 유지를 위해 200자는 겹치게 자름
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000, 
    chunk_overlap=200
)
splits = text_splitter.split_documents(documents)

print(f"총 {len(splits)}개의 청크로 분할되었습니다.")

Step 3: 임베딩 및 벡터 저장소(Vector Store) 생성

이제 쪼개진 텍스트 조각들을 벡터로 변환하여 ChromaDB에 저장합니다. 이 과정이 완료되면 검색 가능한 상태가 됩니다.

from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

# 3. 임베딩 모델 선택 및 벡터 저장소 생성
vectorstore = Chroma.from_documents(
    documents=splits, 
    embedding=OpenAIEmbeddings()
)

# 검색기(Retriever) 생성
retriever = vectorstore.as_retriever()

Step 4: RAG 체인 구성 및 질의응답

마지막으로, 검색된 문서와 사용자의 질문을 합쳐서 LLM에게 전달하는 체인(Chain)을 만듭니다.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 4. LLM 모델 선택 (GPT-3.5-turbo 또는 GPT-4)
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

# 5. 프롬프트 템플릿 작성
# {context}: 검색된 문서 내용이 들어갈 자리
# {question}: 사용자의 질문이 들어갈 자리
template = """
당신은 질문에 대해 주어진 문맥(Context)만을 사용하여 답변하는 AI 비서입니다.
문맥에 없는 내용은 지어내지 말고 "모르겠습니다"라고 답하세요.

문맥:
{context}

질문:
{question}
"""
prompt = ChatPromptTemplate.from_template(template)

# 6. 체인 연결 (LangChain Expression Language - LCEL)
rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# 7. 실행 및 테스트
question = "이 문서에서 언급된 프로젝트의 핵심 목표가 뭐야?"
response = rag_chain.invoke(question)

print(f"질문: {question}")
print(f"답변: {response}")

코드 설명 및 주의사항

  • temperature=0: 답변의 창의성을 낮추고 사실에 입각한 답변을 하도록 설정합니다. RAG에서는 환각을 줄이기 위해 0에 가깝게 설정하는 것이 일반적입니다.
  • LCEL (LangChain Expression Language): | 연산자를 사용하여 데이터의 흐름을 파이프라인처럼 연결하는 랭체인의 최신 문법입니다. 코드가 훨씬 직관적이죠.

4. 결론 및 요약: 나만의 AI 구축, 지금이 기회입니다

지금까지 RAG의 개념부터 LangChain을 이용한 실전 구현까지 살펴보았습니다. 오늘 다룬 내용을 요약하면 다음과 같습니다.

  1. LLM의 한계 극복: 최신 정보 부재와 할루시네이션 문제를 해결하기 위해 RAG가 필수적입니다.
  2. 데이터의 가치: 여러분이 가진 PDF, 회의록, 메모가 AI와 결합될 때 진정한 '개인화 비서'가 탄생합니다.
  3. 접근성의 향상: LangChain과 같은 도구 덕분에 이제 개발자가 아니더라도(혹은 초보 개발자라도) 강력한 AI 애플리케이션을 만들 수 있습니다.

앞으로의 전망은 어떨까요?
단순히 텍스트를 검색하는 것을 넘어, 표나 이미지를 이해하는 멀티모달 RAG, 그리고 스스로 검색 전략을 수정하는 에이전트(Agent) 기반 RAG로 기술은 진화하고 있습니다.

지금 바로 여러분의 하드드라이브에 잠자고 있는 문서들을 꺼내보세요. 그리고 오늘 소개한 코드를 복사해서 실행해 보십시오. 여러분만의 '자비스'를 만드는 첫걸음이 될 것입니다.

궁금한 점이나 코드 실행 중 막히는 부분이 있다면 댓글로 남겨주세요. nomadlab.kr은 언제나 여러분의 성장을 응원합니다.


[참고 자료 및 링크]

  • LangChain 공식 문서
  • OpenAI API Documentation
  • ChromaDB Github

댓글