Understanding RAG Before Applying It to ERP Systems

2 분 소요

Beginning

최근 회사 ERP 솔루션에서 LLM을 활용해 번역, CHATBOT, RAG를 통합 지원하는 AI 서비스를 제공하고자 하며 ERP 내부 DB 정보는 LLM이 알 수 없기 때문에 RAG 기반 검색 서비스를 도입하여 정확한 최신 답변을 제공하려 합니다.
이번 프로젝트를 진행하며 공부하고 적용한 내용을 정리하고자 합니다.



Index

  1. RAG(Retrieval-Augmented Generation)
  2. Process
  3. Initial Tech Stack


RAG (Retrieval-Augmented Generation)

  • Issue : LLM은 훈련 데이터 이후의 최신 정보나 회사 특화 지식을 항상 알지 못한다
  • Solution : RAG(LLM이 알지 못하는 정보를 외부지식 저장소에서 실시간으로 검색해 LLM에게 제공) → 응답에 근거하여 답변 생성

Conecption

  • RAG는 검색(retrieval)생성(generation) 을 결합해 특정 도메인 지식을 LLM 답변에 반영하는 패턴 → LLM + 검색 기반 정보 보강
  • LLM은 학습하지 않은 최신 정보나 도메인 특화 지식에 취약 → 외부 문서/DB 검색 후 동적으로 참조하여 정보 보강 후 답변 생성
  • 단순 LLM 호출보다 신뢰성과 정확성 향상
  • 사용시 이점 : 최신성 확보, 모델 재학습 불필요, 정확도 향상


Process

  • Document Loader → Preprocessing → Chunking → Embeddings → Vector DB → Retriever+QA

Document Loader (Data → Document)

  • 다양한 형태의 데이터(Markdown, PDF, HTML, DB)를 Document(text + metadata) 표준으로 통일 및 전달
  • 모든 Document에 일관된 metadata(source, path, sha256, last_modified, doc_type) 필요
    • 원본의 section/header/table/code 같은 구조 정보를 최대한 보존
  • 데이터에 맞는 적절한 Loader 선택 필요
    • PDF/HTML는 단순 텍스트 추출할 경우 섹션 구조, 표, 캡션 정보가 유실될 수 있음

Library/Usage

  • langchain.document_loaders, TextLoader, MarkdownLoader, PyPDFLoader: LangChain 생태계 내 통합 Loader
  • unstructured: 복잡한 PDF/문서 레이아웃 추출
  • pdfplumber, PyMuPDF(fitz): 정밀 PDF 텍스트/테이블 추출
  • BeautifulSoup, lxml`: HTML 파싱/클린징
  • pymssql, psycopg2, mysql-connector-python, sqlalchemy: DB → 텍스트
  • python-frontmatter`: Markdown front-matter 파싱

Preprocessing

  • Dcoument Loader가 만든 Document 객체의 page_content를 Embedding에 적합한 포맷으로 정리
  • 텍스트 정규화(줄바꿈, 공백, 인코딩) → HTML 태그 제거 → PII 탐지·마스킹

Library/Usage

  • 기본 정규화: re, html
  • HTML 클린징: BeautifulSoup, bleach
  • NER/전처리: spaCy, NLTK, stanza
  • PII 탐지/익명화: presidio
  • 테스트용 더미 데이터: Faker

Chunking / Tokenization

  • 문서를 LLM Context(Token) 한계에 맞는 검색 단위(Chunk)로 분해
    • Chunk : 기본 단위(Token 기준 지향 / 문자 수 지양)
  • tiktoken을 Token 수를 계산 해서 적당한 Chunk Size 및 Chunk Overlap 지정
    • Overlap : Chunk의 10% 권장(문맥 유실 완화용)
  • 각 청크에 meta를 남긴다
    • Chunk Meta : chunk_id, start_offset, end_offset, parent_section
  • 섹션 헤더 우선 분할 → 섹션 내 토큰 분할

Library/Usage

  • tiktoken: 모델별 Tokenizer(정확한 토큰 수 계산)
  • langchain.text_splitter.RecursiveCharacterTextSplitter: 빠른 Prototype
  • spaCy, nltk.sent_tokenize: 문장 경계 보조

Embeddings (모델)

  • 각 Chunk를 고차원 Vector로 변환하여 의미 기반 검색(semantic search) 지원
  • Query와 Chunk 간 유사도 계산의 기초

Library/Usage

  • OpenAIEmbeddings (langchain_openai): 관리형(품질 편의성)
  • sentence-transformers (Hugging Face): 로컬/GPU 실행(프라이버시/비용절감)
  • Cohere, Anthropic 등: 대체 상용 제공자
  • tenacity/backoff: 안정적인 재시도 구현

Vector DB (검색 인덱스)

목적

  • Embedding Vector와 Meta를 저장/인덱싱해 빠른 ANN 검색 제공
  • 검색 결과와 함께 원문 및 META를 LLM에 제공

Library/Usage

  • FAISS: 로컬/POC용(단일 머신)
  • Chroma: 로컬 친화적 벡터 스토어
  • Qdrant: 페이로드 관리가 쉽고 프로덕션에 적합
  • Milvus, Weaviate: 분산/대규모 환경
  • Pinecone: 매니지드 서비스

Retriever + QA Chain(LLM)

목적

  • 쿼리를 임베딩 → vector DB에서 후보 검색 → LLM Chain에 문맥 전달 → 답 생성 + 출처 포함 반환
  • 어떻게 검색결과를 정제하고 LLM에 주느냐가 최종 신뢰도/정확도를 결정

Library/Usage

  • langchain: RetrievalQA, load_qa_chain, PromptTemplate 등 체인 구성
  • LlamaIndex (GPT Index): 인덱스·질의 고수준 도구(대체/보완)
  • Haystack: 엔터프라이즈 파이프라인(리트리버+리더)
  • sentence-transformers.CrossEncoder: re-ranker
  • LLM: OpenAI, Anthropic, Llama 등

Chain Type

  • stuff: 모든 문맥을 LLM에 넣어 처리(단순하지만 토큰·비용 이슈)
  • map_reduce: 문서별 요약 → 합성(긴 컨텍스트에 유리)
  • refine: 초안 응답을 반복 보완


Initial Tech Stack

  • Backend/Frontend : FastAPI(Python) & React
  • WAS: Uvicorn
  • WebServer: Nginx
  • DevOps: Docker(FastAPI, Nginx Container)
  • Python Framework: LangChain
  • DB Format: Markdown, VectorDB
  • LLM: ChatGPT-4
  • MCP: Translator, RAG, Chatbot 통합 제공