Sift: 인프라 부담 없이 로컬 하이브리드 검색
Source: Dev.to
위 링크에 포함된 전체 텍스트를 제공해 주시면, 해당 내용을 한국어로 번역해 드리겠습니다.
(코드 블록, URL, 마크다운 형식 및 기술 용어는 그대로 유지됩니다.)
개요
sift는 문서 검색을 위한 로컬 Rust CLI입니다. 디렉터리를 지정하고 질문을 하면 전체 하이브리드 검색 파이프라인—BM25, 밀집 벡터, 퓨전, 선택적 재순위 지정—을 실행하고 순위가 매겨진 결과를 반환합니다. 데몬도 없고, 백그라운드 인덱서도 없으며, 클라우드도 없습니다. 하나의 바이너리입니다.
이는 인프라를 별도로 구축하지 않고도 원시 코드베이스, 문서, 혼합 형식 코퍼스에 대해 신뢰할 수 있고 반복 가능한 검색이 필요한 에이전트와 개발자를 위해 만들어졌습니다.
지금 macOS, Windows, Linux에서 설치하기 할 수 있습니다.
검색 파이프라인
모든 쿼리는 네 단계로 진행됩니다:
- Expansion – 검색을 시작하기 전에 리콜을 넓히기 위해 쿼리 변형을 생성합니다.
- Retrieval – BM25(키워드), 구문 매치, 그리고 밀집 벡터 검색이 코퍼스에 대해 실행됩니다. 각 방법은 서로 다른 신호를 포착합니다.
- Fusion – 결과는 Reciprocal Rank Fusion(RRF)을 사용해 병합되며, 수동 가중치 조정 없이 검색 방법 간 신호를 균형 있게 조정합니다.
- Reranking – 선택적인 로컬 LLM 재정렬은 Qwen을 통해 융합된 후보 집합에 의미적 구분을 적용합니다.
각 단계는 독립적으로 튜닝할 수 있습니다. BM25 속도만 필요하면 벡터 단계를 건너뛰세요. 최고의 정밀도를 원한다면 전체 스택을 실행하세요.
아키텍처
구현은 domain과 adapters로 나뉩니다:
- Domain objects는 검색 계획, 후보, 그리고 점수 출력 모델을 담당합니다.
- Adapters는 구체적인 BM25, phrase, vector, 그리고 재정렬 백엔드를 구현합니다.
공유 검색 서비스는 CLI, 벤치마크, 평가 흐름 모두에 동일한 전략 모델을 실행합니다—개발 실행과 CI 평가 패스 사이에 변화가 없습니다.
성능 하이라이트
- CPU 집약적인 작업에서 벡터 점수를 위한 SIMD‑accelerated dot‑product.
- Zig 영감을 받은 증분 캐시 – Zig 빌드 시스템에서 차용한 2계층 설계. 매니페스트 스토어는 파일 시스템 메타데이터(inode, mtime, size)를 추적하고 이를 BLAKE3 콘텐츠 해시와 매핑하여
sift가 파일이 변경되었는지 정확히 알 수 있게 하며 다시 읽을 필요가 없습니다. 콘텐츠 주소 지정 블롭 스토어는 사전 추출된 텍스트, 사전 계산된 BM25 용어 빈도, 사전 임베딩된 밀집 벡터를 보관합니다—즉, 반복 쿼리는 신경망을 전혀 호출하지 않습니다. 서로 다른 프로젝트의 동일한 파일은 하나의 블롭 엔트리를 공유합니다. - 다단계 파이프라인 전반에 걸친 Per‑query embedding reuse.
- 대규모 코퍼스에서 지연 시간을 낮게 유지하기 위한 Mapped I/O and tight tokenization hot loops.
개발 중에 구체적인 트레이드오프 하나: 임베딩 max_length를 48에서 40으로 낮추어 지연 시간 예산을 회복하면서도 품질을 BM25 기준선보다 높게 유지했습니다—증거 기반 튜닝이 추측보다 효과적이라는 좋은 예시입니다.
전체 내부 구조는 ARCHITECTURE.md에서 문서화되어 있습니다.
평가
AMD Ryzen Threadripper 3960X에서 5,185개의 SciFact 문서(~7.8 MB)를 대상으로 수행한 비교 전략:
| 전략 | nDCG@10 | MRR@10 | Recall@10 | p50 (ms) |
|---|---|---|---|---|
| bm25 | 0.7262 | 0.7000 | 0.8000 | 5.41 |
| legacy‑hybrid | 0.7893 | 0.7250 | 1.0000 | 50.29 |
| page‑index | 0.7000 | 0.6667 | 0.8000 | 16.79 |
| page‑index‑hybrid | 0.5701 | 0.4367 | 1.0000 | 41.09 |
| page‑index‑llm | 0.7893 | 0.7250 | 1.0000 | 41.28 |
| page‑index‑qwen | 0.7893 | 0.7250 | 1.0000 | 41.18 |
| vector | 0.8262 | 0.7667 | 1.0000 | 25.94 |
주요 요점
- BM25는 5.41 ms p50으로, 지연 시간이 제한된 상황에서 키워드 회수가 충분한 경우 적절한 기본값입니다.
- 벡터는 nDCG@10(0.8262)에서 최고 점수를 기록하고 25.94 ms에 완벽한 회수를 달성하여 대부분의 워크로드에 가장 균형 잡힌 전략입니다.
- LLM 재정렬(page‑index‑llm, page‑index‑qwen)은 비슷한 속도에서 legacy‑hybrid와 동일한 품질을 제공하여 로컬 Qwen 경로가 무거운 하이브리드 파이프라인에 대한 실용적인 대안임을 검증합니다.
- page‑index‑hybrid는 nDCG에서 BM25보다 성능이 낮은 유일한 전략으로, 복잡성을 추가한다고 해서 품질이 반드시 향상되는 것은 아니라는 점을 상기시킵니다.
캐시 적중률(100/0/100 %)은 모든 전략에서 캐시 계층이 올바르게 작동함을 확인합니다. 자세한 출력(-v, -vv)은 CLI에서 캐시 적중률, 단계 시간 및 순위 메타데이터를 직접 표시합니다.
에이전트에게 중요한 이유
에이전트에게는 지연 시간과 신뢰성이 선택 사항이 아니라 필수 조건입니다. 검색이 느리거나 컨텍스트가 사라지거나, 이용할 수 없는 서비스에 의존할 경우 툴링 루프가 크게 실패합니다.
sift는 이러한 마찰을 제거합니다: 검색이 로컬에서 이루어지고, 결정적이며, 반복해도 비용이 저렴합니다. 건강 검사를 위한 데몬이 없습니다. 속도 제한을 적용할 임베딩 서비스가 없습니다. 관리할 클라우드 의존성이 없습니다. 이 바이너리는 Homebrew와 정적 Linux 아티팩트 지원과 함께 제공되므로, 에이전트는 환경 변동 없이 고정된 버전에 의존할 수 있습니다.
어떻게 구축되었는가
프로젝트는 집중된, 거의 중단 없는 24시간 푸시로 배포되었습니다—구현, 평가 설계, 벤치마킹, 성능 최적화, 패키징, 그리고 릴리스 준비를 하나의 지속적인 흐름으로 진행했습니다. 모든 주요 단위는 완료로 표시되기 전에 수용 기준과 측정 가능한 증거가 부착되었습니다.
그러한 속도를 가능하게 만든 요인은 아직 자세히 논의할 준비가 되지 않았습니다. 하지만 sift는 실제 제약 하에서 속도를 유지하며, 절차를 생략하지 않고 작동한다는 첫 번째 실질적인 증거입니다. 곧 더 자세히 알려드리겠습니다.
시작하기
- README — 설치 및 기본 사용법
- CONFIGURATION — 전략 및 모델 설정
- EVALUATION — 자체 코퍼스 평가 실행
- ARCHITECTURE — 내부 구조 심층 탐구
- 코드: