Skip to content

Hgon86/DochiBot

Repository files navigation

DochiBot (도치봇)

라즈베리파이/로컬 환경에서도 구동 가능한 실전형 RAG(Retrieval-Augmented Generation) 운영 백엔드

단순한 문서 검색을 넘어, 데이터 인입부터 하이브리드 검색, 다중 리랭킹, 그리고 답변 검증까지 RAG 파이프라인의 A to Z를 다루는 프로젝트입니다.

  • PRD(무엇을/왜): docs/PRD.md
  • SPEC(어떻게): docs/SPEC.md
  • DB 스키마: docs/db-schema.md
  • 인제션 파이프라인: docs/ingestion-pipeline.md
  • 리트리벌(하이브리드/RRF/리랭크): docs/retrieval.md

🚀 프로젝트 차별점 및 핵심 고찰 (Naive RAG vs Advanced RAG)

일반적인 튜토리얼 수준의 Naive RAG(단순 벡터 검색 후 LLM 주입)는 실무에서 검색 품질 저하(키워드 누락)와 환각(Hallucination) 이라는 치명적인 한계에 부딪힙니다.

DochiBot은 이러한 한계를 극복하기 위해 검색 최적화(Retrieval Optimization)신뢰성 검증(Verification) 공정을 파이프라인에 깊숙이 통합했습니다.

🌊 DochiBot Advanced RAG 파이프라인 흐름도

┌─────────────────────────────────────────────────────────────────────────────┐
│                          User Query (사용자 질의)                           │
└──────────────────────────────────────┬──────────────────────────────────────┘
                                       │
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                      1. Retrieval (하이브리드 검색 & 융합)                  │
│                                                                             │
│  ┌───────────────────────┐                       ┌───────────────────────┐  │
│  │    Dense Retrieval    │                       │   Sparse Retrieval    │  │
│  │ (pgvector / 의미 검색)│                       │ (tsvector / 키워드)   │  │
│  └───────────┬───────────┘                       └───────────┬───────────┘  │
│              │                                               │              │
│              └───────────────────────┬───────────────────────┘              │
│                                      ▼                                      │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                   RRF (Reciprocal Rank Fusion) 병합                   │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────┬──────────────────────────────────────┘
                                       │ (초기 Top-K 후보군)
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                     2. Re-Ranking (문맥 기반 재정렬)                        │
│                                                                             │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                    Reranker Router (질의/상황별 라우팅)               │  │
│  └────────┬──────────────────────────┬─────────────────────────┬─────────┘  │
│           │                          │                         │            │
│           ▼                          ▼                         ▼            │
│  ┌────────────────┐         ┌────────────────┐        ┌────────────────┐    │
│  │ Cross-Encoder  │         │ LLM-as-a-Judge │        │ Heuristic/BM25 │    │
│  │ (고정밀/딥러닝)│         │ (추론 능력 활용)│        │ (빠른 응답속도)│    │
│  └────────┬───────┘         └────────┬───────┘        └────────┬───────┘    │
│           │                          │                         │            │
│           └──────────────────────────┼─────────────────────────┘            │
└──────────────────────────────────────┬──────────────────────────────────────┘
                                       │ (재정렬된 최종 컨텍스트)
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                 3. Generation & Verification (환각 통제)                    │
│                                                                             │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                 Pre-Generation Verify (문서 무관성 필터링)            │  │
│  └───────────────────────────────────┬───────────────────────────────────┘  │
│                                      ▼                                      │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                  LLM Generation (명확한 출처 강제 프롬프팅)           │  │
│  └───────────────────────────────────┬───────────────────────────────────┘  │
│                                      ▼                                      │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                 Post-Generation Verify (환각 및 근거 대조)            │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────┬──────────────────────────────────────┘
                                       │
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                       Final Answer (출처가 포함된 최종 답변)                │
└─────────────────────────────────────────────────────────────────────────────┘

🔍 퀄리티 개선을 위한 3단계 핵심 공정

1. 검색 범위 극대화 및 융합 (Hybrid Search & RRF)

  • 문제점: 기존 Dense Vector 검색은 문맥적 의미는 잘 파악하지만, 고유명사, 품번, 제품명 등 정확한 키워드(Exact Match) 검색에 취약합니다.
  • 해결책: PostgreSQL의 pgvector(Dense)와 tsvector FTS(Sparse)를 동시 수행하는 하이브리드 검색을 구축했습니다.
  • 최적화: 성질이 다른 두 검색 결과의 점수를 공정하게 병합하기 위해 RRF (Reciprocal Rank Fusion) 알고리즘을 적용하여 누락 없는 풍부한 후보군을 구성합니다.

2. 문맥 기반 정밀 재정렬 (Dynamic Re-Ranking)

  • 문제점: 1단계에서 찾은 Top-K 후보군 중 상위권 문서가 실제 질문에 대한 '정답'을 담고 있다는 보장이 없습니다. (Lost in the middle 현상 발생 가능성)
  • 해결책: 검색된 문서들과 사용자 질의 간의 진짜 연관성을 깊게 계산하는 리랭킹(Re-ranking) 단계를 추가했습니다.
  • 최적화: 시스템 리소스와 질문의 난이도에 따라 Cross-Encoder, LLM-as-a-Judge, Heuristic 등 다양한 리랭커를 동적으로 선택하는 Reranker Router 구조를 설계하여 속도와 정확도의 트레이드오프를 제어합니다.

3. 환각 통제 및 신뢰성 검증 (Verify Pipeline)

  • 문제점: 검색된 문서 내용이 부족하거나 무관해도 LLM이 그럴싸한 거짓말(Hallucination)을 지어낼 수 있습니다.
  • 해결책: LLM의 응답 생성 전후로 개입하는 자체 Verify 파이프라인을 구축했습니다.
  • 최적화: 주어진 문서 목록이 질문에 답할 수 있는지 사전 평가하고, 최종 답변에는 사용자가 직접 정보의 출처를 눈으로 검증할 수 있도록 원문 스니펫(Snippet)과 메타데이터(Citation)를 강제로 포함시킵니다.

⚙️ 안정적인 비동기 인제션(Ingestion) 아키텍처

  • Presigned URL 기반 안전한 업로드: 대용량 파일 업로드 시 백엔드 병목을 없애기 위해 클라이언트가 S3(SeaweedFS)로 직접 업로드하는 패턴을 채택했습니다.
  • Ingestion Job Worker: 무거운 문서 청킹(Chunking) 및 임베딩 로직을 메인 스레드에서 분리하여 비동기 Job으로 관리합니다. 실패 시 재처리(Retry) 및 상태 추적(Queued, Running, Failed)이 가능한 실무적 파이프라인을 구축했습니다.

🍃 Edge 환경을 고려한 리소스 최적화

  • 로컬 LLM 지향: 라즈베리파이 등 제한된 엣지 환경에서도 외부 API 의존 없이 동작할 수 있도록 Ollama 기반으로 아키텍처를 구성했습니다.
  • 100% Non-Blocking I/O: 적은 스레드로 높은 동시성을 확보하기 위해 Spring WebFlux와 Kotlin Coroutines 기반의 Reactive Programming을 적용했습니다.

🛠 Tech Stack

  • Backend: JDK 21, Kotlin 2.0, Spring Boot 3.4 (WebFlux) + Coroutines, Spring AI
  • Database: PostgreSQL 17 (R2DBC) + Flyway (JDBC)
  • Search Engine: PostgreSQL + pgvector (Dense) + FTS(tsvector, GIN) (Sparse)
  • Cache: Redis 7
  • AI/LLM: Ollama (Chat/Embedding)
  • Storage: SeaweedFS (S3 Gateway; S3 호환, Presigned URL 용도)

⚙️ 로컬 실행(권장 흐름)

1) 인프라 기동 (Postgres/Redis/Ollama/SeaweedFS)

# 필요 시 docker-dev/.env 값을 수정하세요.
docker compose -f docker-dev/compose.yaml --env-file docker-dev/.env up -d

2) 백엔드 빌드/실행

./gradlew clean build
./gradlew bootRun

🐳 올도커(옵션)

API 컨테이너까지 함께 올리려면 api profile을 사용합니다.

docker compose -f docker-dev/compose.yaml --env-file docker-dev/.env --profile api up -d --build

💡 설정 메모

  • 로컬 프로필의 채팅 LLM은 기본적으로 OpenAI 호환 제공자를 사용하며, 기본 엔드포인트는 NVIDIA NIM입니다. NVIDIA_API_KEY만 채우면 바로 사용할 수 있습니다.
  • 필요하면 AI_CHAT_PROVIDER=ollama로 로컬 Ollama 채팅 모델로 되돌릴 수 있습니다.
  • 문서 업로드는 현재 PDF(.pdf)Markdown(.md, .markdown)만 지원합니다.
  • 임베딩 모델은 OLLAMA_EMBEDDING_MODEL로 바꿀 수 있습니다(기본: bge-m3). bge-m3는 100개 이상의 언어를 지원하는 multilingual 임베딩이라 한글 질문과 영어 섹션명/기술명이 섞인 RAG에 더 적합합니다.

📚 문서

  • API 상세: docs/phase1-api.md
  • DB 스키마: docs/db-schema.md
  • S3/SeaweedFS: docs/s3-config.md
  • 인증(JWT): docs/auth-jwt.md
  • 대화 메모리 전략: docs/chat-memory-strategy.md

About

단순 검색을 넘어선 실전형 Advanced RAG 백엔드. 하이브리드 검색(RRF), 동적 리랭킹, 그리고 환각(Hallucination) 제어 파이프라인을 구축한 RAG 프로젝트입니다

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors