본문 바로가기

개발 자동화 & 생산성 도구

4편 사내 문서 요약/검색 자동화 시스템 구축기 (RAG·vLLM·FastAPI 기반)

반응형

 

🟦 개발 생산성 & 자동화 시리즈 — 4편

사내 문서 요약/검색 자동화 시스템 구축기 (RAG·vLLM·FastAPI 기반)

사내에는 수십~수백 개의 문서가 존재한다.
보고서, 제안서, 회의록, 기술 문서, 정책 문서, 시스템 스펙…
문제는 찾아야 할 때 절대 안 보인다는 거다.

매번 “그 문서 어디 있지?”, “이 내용 누가 정리했지?”라는 혼돈 속에서
‘정작 내용 읽기 전에 검색에 시간을 다 써버리는’ 일이 반복됐다.

그래서 직접 사내 RAG 기반 문서 요약/검색 자동화 시스템을 구축했다.
30초면 문서요약이 되고, 질문하면 정확하게 문서에 근거한 답변이 나온다.

이 글은 구축 과정을 실제 코드·아키텍처·문제 해결 경험 포함
현업에서 바로 참고할 수 있도록 구성했다.


🟩 1. 우리가 해결하고 싶었던 진짜 문제들

프로젝트를 시작한 이유는 명확했다.

🔥 1) 문서가 너무 많아서 검색이 불가능

보통 회사에 문서 저장소가 3~6개씩 흩어져 있다:

  • 공유폴더
  • Notion / Confluence
  • 이메일 첨부파일
  • Jira
  • 메신저 파일함
  • 개인 PC

문서명도 뒤죽박죽이라 검색으로 못 찾는다.

🔥 2) 문서 읽는데 시간이 너무 오래 걸림

사내 문서는 대부분 길다.
대부분 30~200페이지.

"요약본 좀 주세요"만 하루에 10번 나온다.

🔥 3) 신입/타부서가 업무 문서를 빠르게 이해하기 어려움

특히 신규 투입자나 외부 협력사는
RAG 기반 문서 검색 시스템이 없으면 onboarding 자체가 느려진다.

그래서 다음 목표를 잡았다.


🟦 2. 시스템 목표 정의

🎯 1) 모든 문서를 자동으로 요약하고 검색 인덱스 구성

PDF/한글(hwp)/PPT/Word/텍스트, 이미지 OCR까지 모두 처리.

🎯 2) 문서 기반 ‘정확한 답변’ 제공 — 헛소리(할루시네이션) 최소화

LLM이 뇌피셜이 아니라 문서에 근거한 답변만 해야 한다.

🎯 3) 내부망 환경에서도 동작해야 한다

은행/공공기관처럼 인터넷 차단된 환경 지원.

🎯 4) 문서 변경 시 자동 인덱싱

신규 문서 업로드 → 자동 요약 + 자동 임베딩 생성.

🎯 5) FastAPI 기반 단일 API로 제공

사내 다른 시스템에서 쉽게 붙일 수 있도록.


🟦 3. 전체 아키텍처 구성

아키텍처는 아래 흐름으로 구성했다.

[문서 수집 → 변환 → 요약 → Chunk → Embedding → Vector DB → 검색/QA]

🔷 1) 문서 수집 모듈

  • 공유폴더 스캔
  • S3 / NAS 연동
  • 메신저 첨부파일 webhook 수집(선택)

🔷 2) 문서 변환

  • PDF → 텍스트
  • HWP → 텍스트 (아래아한글 API or hwp5txt)
  • PPT → 텍스트
  • 이미지 → OCR (Tesseract or PaddleOCR)

🔷 3) 요약 엔진

  • vLLM 로컬 모델 or Azure OpenAI GPT-4o-mini
  • Draft Summary / Key Points / Table of Contents 생성

🔷 4) Chunking

  • 문단 단위 분리
  • 의미 기반 문장 분리
  • 토큰 단위 최적화 처리

🔷 5) Embedding 생성

  • nomic-embed-text
  • or bge-m3
  • 로컬 vLLM embedding도 가능

🔷 6) Vector DB

  • Milvus
  • Qdrant
  • Chroma(개발용)

🔷 7) 검색/QA API

  • FastAPI 기반
  • Retrieval → Rerank → LLM Answering
  • 신뢰도 점수 + 출처 링크 제공

🟦 4. 실제 구현 코드 (핵심 부분만)

🔵 문서 → 텍스트 변환

import docling

def extract_text(file_path):
    return docling.convert_document(file_path).text

Docling이 진짜 성능이 미쳤다.
PDF/워드/엑셀/hwp까지 거의 원터치로 된다.


🔵 텍스트 청킹

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,
    chunk_overlap=150,
    separators=["\n\n", "\n", ".", " "]
)

chunks = splitter.split_text(text)

chunk_size 800 + overlap 150 조합이 가장 정확도가 높았다.


🔵 임베딩 & 저장

from langchain_community.embeddings import HuggingFaceEmbeddings
from qdrant_client import QdrantClient

embed = HuggingFaceEmbeddings(model_name="BAAI/bge-m3")
db = QdrantClient("localhost", port=6333)

vectors = embed.embed_documents(chunks)

Milvus도 써봤지만 작은 규모는 Qdrant가 빠르고 관리도 쉬웠다.


🔵 검색 + 답변 생성 API

@app.post("/search")
def search(query: str):
    query_vector = embed.embed_query(query)
    result = db.search(collection="docs", query_vector=query_vector, limit=5)

    context = "\n".join([r.payload["text"] for r in result])
    prompt = f"다음 문서 내용을 기반으로만 답변해라:\n{context}\n\n질문: {query}"

    answer = llm.generate(prompt)
    return {"answer": answer, "references": result}

핵심은 문서 기반으로만 답변하도록 프롬프트를 강하게 제어하는 것.


🟦 5. 구축 과정에서 실제로 맞닥뜨린 문제들

1) PDF→텍스트 추출이 잘 안 되는 문제

특히 표/레이아웃이 많은 문서들이 문제였다.

해결:

  • Docling + PDFPlumber + PyMuPDF 조합 사용
  • OCR fallback 경로 추가
  • 표는 별도 JSON 추출 후 요약 단계에서 재수합

2) 문서 내용이 너무 길어서 LLM이 요약 중간에 끊어짐

100~200페이지 문서 요약 시 자주 발생.

해결:

  • 1차 chunk summary → 2차 global summary 방식 적용
  • 요약을 2단계 파이프라인으로 분리

3) 검색 결과가 엉뚱한 문서를 가져옴

Embedding 모델의 품질 문제.

해결:

  • bge-m3로 변경
  • rerank 단계 추가 (Cross Encoder)
rerank = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")

정확도 체감이 확 올라갔다.


4) LLM이 문서에 없는 내용을 말함 (할루시네이션)

가장 심각했던 문제.

해결: Grounded Answering 강제

프롬프트에 아래 규칙을 강하게 걸었다.

문서에 없는 내용은 “문서에 해당 내용이 없습니다”라고 반드시 답하세요.
추가적인 추론을 하지 마세요.

🟦 6. 실제 사내 적용 후 변화

문서 검색 시간 20분 → 10초

검색 정확도가 “구글급”이 되어버렸다.

신규 직원 온보딩 기간 2주 → 3일

기존 문서 읽기 절반이 자동 요약으로 해결.

보고서 작성 속도 50% 단축

‘요약 + 핵심 정리’가 자동 생성되니
기획/보고 문서 흐름이 빨라졌다.

사내 질문 70% 감소

“이거 어디 있어요?”, “이 내용 뭐예요?” 같은 질문이 사라졌다.

제안서·기획서 작업 효율 대폭 증가

유사 문서를 기반으로 바로 서론/배경/핵심 요약이 나온다.


🟦 7. 실전 팁 3개

① Chunking이 정확도의 절반을 결정한다

문서마다 chunk 규칙을 달리해야 한다.
— 표 많은 문서
— 기술 매뉴얼
— 제안서
는 모두 따로 튜닝해야 한다.

② Rerank는 필수다 (정답률이 20~40% 상승)

Embedding만으로는 정확한 문장/문단을 못 찾을 때가 많다.
CrossEncoder Rerank를 넣으면 정확도가 압도적으로 좋아진다.

③ 요약은 2단계 구조가 가장 안정적

  • Chunk Summary
  • Global Summary

한 번에 요약하면 길이 제한으로 정확도가 떨어진다.


🟦 추천 태그

#RAG #문서요약 #AI검색 #개발자동화 #Docling #vLLM #FastAPI  
#Embedding #Qdrant #Milvus #OCR #사내시스템 #AI개발 #업무자동화

 

반응형