728x90
왜 문서 기반 챗봇인가?
오늘날 대부분의 기업 정보는 아래와 같은 형태로 존재합니다.
- 📄 PDF 제품 매뉴얼
- 📊 Excel 실적 보고서
- 📑 내부 정책 문서 (Word)
- 🖼️ 이미지 포함된 PPT 발표자료
300x250
이러한 비정형 문서들은 단순 텍스트가 아니기 때문에, AI가 직접 이해하기 어렵습니다.
→ 그래서 문서 → 정제된 텍스트 → 벡터화 → 검색 기반 AI 응답이라는 전체 파이프라인이 필요합니다.
전체 파이프라인 구성도
문서 업로드 → LlamaParser 파싱 → LangChain 분할 → 임베딩 → 벡터 DB 저장 → 질문 임베딩 → 벡터 검색 → RAG 응답 생성
1️⃣ 문서 업로드
└── PDF, PPT, Word, Excel 등 다양한 포맷의 비정형 문서
↓
2️⃣ 문서 파싱 (LlamaParser)
└── 문서 레이아웃 유지, 표/이미지/계층 구조 정제
└── 자연어 명령으로 요약, 필터링 등 가능
↓
3️⃣ 텍스트 분할 (LangChain TextSplitter)
└── 문단 또는 토큰 기준으로 텍스트를 Chunk(청크) 단위로 나눔
└── 각 청크는 문맥을 유지하며 잘게 쪼개짐
↓
4️⃣ 텍스트 임베딩 (Embedding Model)
└── 각 청크를 의미 기반 벡터(Vector)로 변환
└── OpenAI, HuggingFace, Cohere 등 임베딩 모델 활용 가능
↓
5️⃣ 벡터 DB 저장
└── FAISS, Weaviate, Qdrant, Chroma 등 사용
└── 유사도 기반 검색을 위한 벡터 인덱싱 처리
↓
6️⃣ 사용자 질문 처리
└── 사용자 질문도 벡터화 후 벡터 DB에 유사도 검색 요청
└── 가장 관련 있는 문서 청크 반환
↓
7️⃣ RAG 기반 응답 생성 (LLM)
└── 검색된 문서 청크 + 질문을 함께 LLM(GPT 등)에 입력
└── 맥락 기반 정확한 답변 생성
LlamaParser로 문서 파싱하기
🪄 역할
- 다양한 포맷(PDF, DOCX, PPTX, XLSX)을 정제된 텍스트로 추출
- 표, 이미지, 계층 구조까지 이해
- 자연어로 "요약해줘", "표는 따로 추출해줘" 등 지시 가능
✅ 실무 팁
- 문서마다 일관성 없는 구조를 가진 경우, 사용자 정의 Rule을 포함해 후처리해야 함
- 문서별 출처 태그 (
metadata.source
) 추가 → 나중에 출처 기반 필터링 가능
🔧 예시 코드
from llama_parse import LlamaParse
parser = LlamaParse()
parsed = parser.parse("매뉴얼.pdf")
text = parsed.to_text()
LangChain으로 텍스트 분할하기
🧐 왜 분할이 필요한가?
- LLM은 한번에 수천 개의 토큰(Token)만 처리 가능
- 긴 문서를 그대로 주면 처리 불가 → 청크(Chunk) 단위로 잘라야 함
✂️ 주요 옵션
분할기 | 특징 | 사용 추천 |
---|---|---|
CharacterTextSplitter |
\n\n 등 문자 기준 |
문단 기반 문서 |
TokenTextSplitter |
토큰 수 기준 | 정확한 컨텍스트 유지 필요 시 |
from langchain.text_splitter import CharacterTextSplitter
splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = splitter.split_text(text)
🎯 청크 크기(chunk_size)는 임베딩 모델과 LLM의 토큰 제한 기준으로 조정하세요.
텍스트 임베딩 및 벡터 DB 저장
📌 임베딩이란?
- 텍스트 → 숫자 벡터(Vector)로 변환
- 의미적으로 가까운 텍스트끼리 벡터 공간에서 거리 가까움
⚙️ LangChain + OpenAI 임베딩 예시
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
embedding = OpenAIEmbeddings()
db = FAISS.from_texts(chunks, embedding)
db.save_local("faiss_index")
💾 이 과정에서 생성된 벡터들은 벡터 DB(FAISS, Weaviate, Qdrant 등)에 저장됩니다.
벡터 DB 연동 및 검색
🧭 실시간 검색 흐름
- 사용자가 "작년 A제품 매출이 낮았던 이유?" 질문
- 질문을 임베딩 → 벡터로 변환
- 벡터 DB에서 가장 유사한 문서 조각 반환
- 이 문서 조각 + 질문 → LLM에 전달
- LLM이 맥락 기반 응답 생성
🔍 검색 예시
retriever = db.as_retriever()
docs = retriever.get_relevant_documents("작년 A제품 매출이 낮았던 이유?")
RAG 시스템 적용 방법
RAG 구조
- Retrieval (검색): 질문과 관련된 문서 조각 검색
- Augmentation (증강): LLM 입력에 문서를 함께 포함
- Generation (생성): 문서 내용을 반영한 응답 생성
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(),
retriever=retriever,
return_source_documents=True
)
response = qa_chain.run("B 제품의 AS 문의가 많았던 이유는?")
print(response)
보안 관점 체크리스트
항목 | 설명 |
---|---|
문서 접근 통제 | 내부 계정 기반 인증 필요, ACL 적용 |
로그 기록 | 질문 및 응답 로그, 검색 키워드 로그화 |
개인정보 마스킹 | 고객 정보 포함 문서는 파싱 시 익명처리 |
원본 보존 | 추후 재임베딩을 위한 원본 보관 |
임베딩 버전 관리 | 모델 교체 시 전체 재임베딩 필요 → 원문 필수 |
업무 적용 예시
① 고객지원 챗봇
- 문서 유형: 제품 매뉴얼, FAQ, 기능 가이드
- 활용 방법: 고객 질문 → 관련 문서 검색 → 자동 응답
② 내부 지식 Q&A 시스템
- 문서 유형: 보안 정책, 인사 지침, 회의록
- 활용 방법: "재택근무시 VPN 필수인가요?" 질문에 문서 기반 응답
③ 보안 이벤트 해석
- 문서 유형: Wazuh, EDR, SIEM 설정 가이드
- 활용 방법: "이 alert 의미가 뭐야?" → 파서 + 검색 기반 설명
배포/운영 시 고려사항
항목 | 체크포인트 |
---|---|
🎯 프롬프트 설계 | RAG 프롬프트에 문서 출처 포함 (e.g., "다음 출처에 따르면...") |
🧩 벡터 DB 선택 | 로컬이면 FAISS, 확장성이 필요하면 Weaviate 또는 Qdrant |
🏷️ 문서 메타데이터 | source , date , type 등 검색 필터에 활용 |
📈 성능 모니터링 | 검색 정확도, 답변 품질, LLM 응답 시간 측정 |
구성 요약 도식
[PDF/PPT/DOC]
↓ LlamaParser
[정제된 텍스트]
↓ LangChain Splitter
[청크]
↓ 임베딩
[벡터]
↓ 벡터 DB 저장
사용자 질문 → 임베딩 → 검색 → 문서 + 질문 → LLM → 응답 생성
문서를 똑똑하게 파싱하고, 의미를 벡터로 이해시켜, 질문에 맥락 있게 답변하는 AI 챗봇.
이것이 바로 LlamaParser + LangChain + RAG 파이프라인의 힘입니다.
728x90
그리드형(광고전용)
댓글