Agent 2.0 exdev 서버 배포 스택

- server-dev start/stop/deploy 및 Gitea push 자동 배포
- local-dev 로컬 개발 환경

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Macbook
2026-07-21 22:57:30 +09:00
commit 4b86b2a660
344 changed files with 45787 additions and 0 deletions
@@ -0,0 +1,92 @@
"""
설정 관리 모듈
────────────
환경 변수 기반 설정 관리
"""
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 '아니오'}")