""" 설정 관리 모듈 ──────────── 환경 변수 기반 설정 관리 """ import os from dataclasses import dataclass from typing import Optional @dataclass class Config: """RAG 시스템 설정""" # 벡터 검색 설정 top_k: int threshold: float threshold_rewrite: float hybrid_search_enabled: bool sparse_top_k: int hybrid_merge_top_k: int # 재랭킹 설정 rerank_candidates: int rerank_batch_size: int top_n_for_llm: int # 리랭커 1위 점수 미만 → 제안 문구·Full Context Rewriting (Qwen3-Reranker sigmoid 0~1) low_confidence_threshold: float # low 이상이면 medium, 이상이면 high (MongoDB answer_confidence) high_confidence_threshold: float # LLM 설정 llm_max_tokens: int # Query Rewriting 설정 query_rewrite_enabled: bool # 대화 이력 설정 chat_history_enabled: bool chat_history_limit: int chat_history_hours: int chat_history_always_include: bool @classmethod def from_env(cls, chat_history_enabled: bool = False) -> "Config": """환경 변수에서 설정 로드""" return cls( # 벡터 검색 top_k=int(os.getenv("FAISS_TOP_K", "30")), threshold=float(os.getenv("FAISS_THRESHOLD", "0.55")), threshold_rewrite=float(os.getenv("FAISS_THRESHOLD_REWRITE", "0.50")), hybrid_search_enabled=os.getenv("HYBRID_SEARCH_ENABLED", "false").lower() == "true", sparse_top_k=int(os.getenv("SPARSE_TOP_K", "30")), hybrid_merge_top_k=int(os.getenv("HYBRID_MERGE_TOP_K", "40")), # 재랭킹 rerank_candidates=int(os.getenv("RERANK_CANDIDATES", "20")), rerank_batch_size=int(os.getenv("RERANK_BATCH_SIZE", "16")), top_n_for_llm=int(os.getenv("TOP_N_FOR_LLM", "5")), low_confidence_threshold=float(os.getenv("LOW_CONFIDENCE_THRESHOLD", "0.65")), high_confidence_threshold=float(os.getenv("HIGH_CONFIDENCE_THRESHOLD", "0.75")), # LLM llm_max_tokens=int(os.getenv("LLM_MAX_TOKENS", "2048")), # Query Rewriting query_rewrite_enabled=os.getenv("QUERY_REWRITE_ENABLED", "true").lower() == "true", # 대화 이력 chat_history_enabled=chat_history_enabled, chat_history_limit=int(os.getenv("CHAT_HISTORY_LIMIT", "10")), chat_history_hours=int(os.getenv("CHAT_HISTORY_HOURS", "24")), chat_history_always_include=os.getenv("CHAT_HISTORY_ALWAYS_INCLUDE", "true").lower() == "true" ) def print_summary(self): """설정 요약 출력""" print(f"[Config] Query Rewriting: {'활성화' if self.query_rewrite_enabled else '비활성화'}") print(f"[Config] FAISS Threshold: 1차={self.threshold}, 2차(Rewrite)={self.threshold_rewrite}") print( f"[Config] Hybrid Search: {'활성화' if self.hybrid_search_enabled else '비활성화'} " f"(sparse_top_k={self.sparse_top_k}, merge_top_k={self.hybrid_merge_top_k})" ) print( f"[Config] Reranker 신뢰도: low<{self.low_confidence_threshold}, " f"high>={self.high_confidence_threshold}" ) print(f"[Config] 대화 이력: {'활성화' if self.chat_history_enabled else '비활성화'}") if self.chat_history_enabled: print(f"[Config] - 최근 {self.chat_history_limit}개 / {self.chat_history_hours}시간") print(f"[Config] - 정상 질문 포함: {'예' if self.chat_history_always_include else '아니오'}")