Skip to content

Repository files navigation

librAIan 🏛️

도서관 맥락 기반 AI 도서 큐레이션 시스템

멀티턴 대화로 사용자의 독서 의도를 파악하고, 하이브리드 검색 → 리랭킹 → 실시간 대출 가능 여부 확인을 거쳐 "지금 이 도서관에서 빌릴 수 있는 책"을 추천합니다.

4인 팀 프로젝트(6주)의 개인 포트폴리오 스냅샷입니다. 본 문서는 제가 담당한 평가 골드셋 구축리랭커 모델 선정·운영 전환을 중심으로 정리했습니다.


추천 파이프라인

flowchart TD
    A["멀티턴 대화<br/>슬롯 추출 · CLOVA HCX"] --> B["RAG 쿼리 생성<br/>keyword · semantic · filters · constraints · score_boost"]
    B --> C["Hybrid 검색 (Elasticsearch)<br/>BM25 0.3 + Dense 0.7 · KURE 임베딩"]
    C --> D["★ BGE Cross-Encoder 리랭킹<br/>Score Fusion (retrieval 0.2 + rerank 0.8)"]
    D --> E["대출 가능 여부 조회<br/>정보나루 API"]
    E --> F["최종 추천 + 추천 사유"]
    style D fill:#ffe0b2,stroke:#e65100,stroke-width:2px
    style C fill:#e3f2fd,stroke:#1565c0
Loading

기술 스택: FastAPI · React(Vite) · Elasticsearch · PostgreSQL · CLOVA Studio(HCX) · sentence-transformers(PyTorch) · Docker / k8s


🙋 담당 파트 1 — 평가 골드셋 구축

"검색·리랭킹의 성능을 측정하려면 '이 질의에 어떤 도서가 실제로 적합한가'라는 정답이 있어야 한다"는 문제를 해결.

라벨링 방식 선택 (핵심 설계 결정)

방식 장점 한계
사람만 신뢰도 높음 80권 × 42시나리오 = 3,360건, 비용·시간 과다
LLM만 빠르고 저렴 일관성·정확도 불확실
LLM × 3 + 다수결 단일 LLM 오류 완화, 효율·신뢰 균형 불일치 케이스만 사람 검수로 보완

구축 흐름

flowchart LR
    A["① 시나리오 작성<br/>다양한 RAG 쿼리 설계"] --> B["② 검색기로 후보 추출<br/>Top-K 후보군"]
    B --> C["③ 관련도 라벨링<br/>LLM-judge × 3회 (0~3점)"]
    C --> D["④ 다수결 합의"]
    D --> E["⑤ 불일치 케이스만<br/>사람(사서) 검수"]
    E --> F["최종 GoldSet"]
Loading
  • 리랭킹 평가셋: 42개 시나리오 → 품질 검수 후 최종 39개, 시나리오당 후보 20권(관련 5 · 비관련 15), final_grade ≥ 2 = 관련
  • 평가 지표 유틸 직접 구현: Hit@K · Recall@K · MRR@K · NDCG@K · HardNegative@K (metrics.py)

관련 코드: 01a_goldset_retrieval · 01b_goldset_llm_judge · 03_goldset_consensus_grading


🙋 담당 파트 2 — 리랭커 모델 선정 및 운영 전환

외부 API 의존(비용·지연·제어 불가) 리랭커를 자체 호스팅 Cross-Encoder로 교체.

평가 설계: 39개 시나리오 · 시나리오당 후보 20권 · Primary NDCG@10 / Secondary MRR@10 · Hit@3

실험 ① — Book-Text Variant Ablation (어떤 필드를 넣을까?)

1. Variant 구성

Variant 포함 필드 설계 의도
A 도서명 + 책소개 (baseline) 카테고리 제거 baseline. “카테고리 없어도 충분한가?”
B A + 카테고리 카테고리 포함 시 효과 비교
C B + 목차 목차가 도움되는가?
BD B + 리뷰 (추가실험 진행) 목차가 도움이 되지 않는가?
D B + 목차 + 리뷰 리뷰가 도움되는가?
E D + 저자 + 출판연도 + 페이지 전체 필드

2. 입력데이터 조합에 따른 리랭커 모델별 성능

Variant BGE GTE Jina
A (baseline) 0.7199 0.7196 0.6858
B (+카테고리) 0.7503 0.7385 0.7012
BD (+리뷰) 0.7883 0.7609 0.6944
C (+목차) 0.7494 0.7354 0.7089
D (+목차+리뷰) 0.7735 0.7702 0.7039
E (+메타) 0.7733 0.7644 0.7242

모델별 성능이 좋은 입력 데이터 조합이 다름

실험 ② — 전체 모델 비교 (어떤 리랭커가 좋은가?)

xychart-beta
    title "리랭커 모델별 NDCG@10 (best variant)"
    x-axis ["BGE", "GTE", "Jina", "CLOVA", "EXAONE"]
    y-axis "NDCG@10" 0 --> 1
    bar [0.788, 0.770, 0.724, 0.653, 0.644]
Loading
모델 유형 Best Variant NDCG@10 MRR@10
BGE Cross-encoder BD 0.788 0.912
GTE Cross-encoder D 0.770 0.858
Jina Cross-encoder E 0.724 0.793
CLOVA LLM (RAG API) D 0.653 0.795
EXAONE LLM (Listwise) BD 0.644 0.709

가설 기각: LLM 리랭커가 Cross-Encoder를 능가하지 못함. CLOVA는 RAG API 구조상 20개 후보 중 1~2개만 인용(나머지 0점 이진분포), EXAONE은 프롬프트 무시(파싱 실패). 후보 수(20개)가 적어 listwise 이점도 희석.

실험 ③ — Score Fusion (retrieval 신호를 얼마나 섞을까?)

final = 0.2 × norm(retrieval) + 0.8 × norm(BGE)α=0.2가 최적.

Retrieval baseline 대비 최종 성능:

지표 Retrieval BGE(BD) 향상
NDCG@10 0.7365 0.7883 +0.07
MRR@10 0.8329 0.9124 +0.079
Hit@3 0.8718 0.9744 +0.103

운영 반영 (bge_reranker.py): BAAI/bge-reranker-v2-m3 + BD variant, GPU 자동 감지(CPU fallback), 모델 싱글턴 로딩, 의존성 부재 시 hybrid 결과로 graceful fallback. 실험 상세는 experiments/rerank/ 참고.


참고 — 검색기(Retriever) 선정 결과

팀 공동 작업이지만, 위 골드셋이 검색기 선정에도 사용되었습니다 (39개 시나리오, Recall@20 기준):

실험 선정 Recall@20
Embedding KURE(한국어 특화) > CLOVA 0.383 > BGE-M3-KO 0.317 0.400
Chunking strategy0 0.311
Hybrid 가중치 BM25 0.3 / Dense 0.7 0.351
Retriever Hybrid > Dense 0.332 > BM25 0.236 0.351

프로젝트 구조

├── backend/           # FastAPI 서버, 검색·리랭킹·대출조회 파이프라인
├── frontend/          # React UI
├── data_pipeline/     # 서지·리뷰 데이터 ETL, 임베딩/인덱싱
├── evaluation/        # ★ 평가 프레임워크: 골드셋, 메트릭, 평가 노트북
├── experiments/       # ★ 리랭커 모델 선정 실험 (ablation, 최종 비교)
└── docker-compose.yml

★ = 본인 주도 영역. 상세 설계는 evaluation/README.md, experiments/rerank/README.md 참고.


설치 및 실행

1. 환경 준비

  • Python 3.11+
  • Node.js 18+
  • Docker & Docker Compose

2. 백엔드 설치

cd backend
pip install -r ../requirements.txt

3. 프론트엔드 설치

cd frontend
npm install

4. 환경 변수 설정

cp .env.example .env
# 필요한 키 입력

5. Docker로 서비스 실행

docker-compose up -d

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages