내가 싱가포르 법률을 위해 RAG 엔진을 구축한 방법
Source: Dev.to

안녕하세요, 여러분!
저는 학생 개발자입니다. 최근에 Explore Singapore 라는 RAG 기반 검색 엔진을 만들었는데, 이는 싱가포르 정부의 법령과 규정을 약 20,000 페이지에 걸쳐 스크래핑합니다.
MVP를 공개한 뒤, 환각 현상과 질의 깊이에 대한 중요한 피드백을 받았습니다. 그 피드백을 반영해 개선에 집중했고, 이제 Version 2 를 방금 출시했습니다.
디자인 및 UI
지루한 정부 웹사이트를 피하고자 했습니다.
디자인: Apple의 미니멀리즘 스타일에서 크게 영감을 받음.
기술: Python 백엔드와 상호작용하는 커스텀 프론트엔드.
V2 엔지니어링 전면 개편
커뮤니티가 세 가지 주요 포인트를 지적했습니다. 각각에 대한 해결 방법은 다음과 같습니다:
1. “퍼스낼리티” 수정
문제: 저는 세 모델을 백업으로 두는 “Triple Failover” 시스템을 사용합니다. 메인 모델이 실패하면 백업 모델들이 전혀 다른 어조를 내보냈습니다.
해결: Dynamic System Instructions 를 추가했습니다. 백엔드가 Model B 로 전환될 때, Model B 의 특성에 맞춘 프롬프트를 사용해 기본 모델과 동일한 구조와 어조를 흉내 내게 합니다. 사용자는 변화를 전혀 느끼지 못합니다.
2. “딥 서치” 수정
문제: “Starting a business” 라는 간단한 의미 검색만으로는 “Tax” 혹은 “Labor” 법령과 같은 연관 법을 놓칩니다.
해결: Multi‑Query Retrieval (MQR) 을 구현했습니다. LLM이 사용자의 질의를 가로채어 하위 의도(예: “Business Registration”, “Corporate Tax”, “Employment Rules”) 로 분해하고, 이를 동시에 검색한 뒤 결과를 결합합니다.
결과: 훨씬 풍부하고 맥락을 고려한 답변을 제공합니다.
3. “환각” 수정
문제: Garbage In, Garbage Out. FAISS 가 잘못된 문서를 가져오면 LLM 이 부정확한 정보를 생성합니다.
해결: Cross‑Encoder Re‑Ranking 레이어를 추가했습니다.
- FAISS 가 상위 10개 결과를 가져옵니다.
- 특화된 Cross‑Encoder 모델이 관련성을 평가합니다.
- 관련성이 낮은 부분은 Chat LLM 에 전달되기 전에 제거됩니다.
기술 스택
- 임베딩: BGE‑M3 (로컬 실행)
- 벡터 DB: FAISS
- 백엔드: Python + Custom Triple‑Model Failover (Hugging Face 상에서 실행)
- 로직: Multi‑Query + Re‑Ranking (V2에서 새롭게 도입)
직접 사용해 보기
저는 아직 배우는 중입니다. 새로운 로직에 대한 여러분의 의견을 듣고 싶습니다.
- 실시간 데모: Explore Singapore
- GitHub 저장소: adityaprasad-sudo/Explore-Singapore
플랫폼에 대한 피드백—특히 장애 조치 속도에 관한—을 언제든 환영합니다! 👇