파일 변경에서 하이브리드 랭킹까지
쿼리 전 더티 파일을 동기화하고, FTS5 BM25와 선택적 sqlite-vec KNN을 결합합니다. 병합된 점수는 시간 감쇠, 출처 가중치, 접근 부스트를 거치며, 마지막으로 MMR 다양성 재랭킹을 선택적으로 활성화할 수 있습니다.
쿼리 전 동기화
MemoryFileWatcher가 변경된 Markdown 경로를 누적합니다. 백엔드는 검색 시작 시 추가되거나 수정된 파일을 재인덱싱하고, 삭제된 파일의 오래된 chunk를 제거합니다.
BM25 후보
먼저 표준 FTS를 실행하고, global 및 workspace 소스 쿼리로 보완하여 세션 수 과다로 인한 밀어내기를 줄입니다.
선택적 KNN
sqlite-vec와 provider가 사용 가능할 때만 쿼리를 임베딩합니다. Embedding 오류는 warning으로 기록되며, None을 전달하여 FTS-only를 계속합니다.
정규화 및 병합
BM25 점수와 벡터 L2 거리를 각각 정규화합니다. 이중 경로 히트 시 가중치로 병합하되, 결과가 해당 chunk의 FTS 점수보다 낮지 않도록 보장합니다.
시간 및 소스
세션은 반감기로 지수 감쇠하며, global 및 workspace 소스는 evergreen으로 처리합니다. 이후 source weight와 적절한 access boost를 곱합니다.
선택적 MMR
활성화 시 관련성과 snippet의 Jaccard 다양성으로 그리디 재정렬을 수행합니다. 마지막으로 max_results로 잘라냅니다.
Embedding 실패
벡터 경로가 중단되지만 FTS 결과는 hybrid_search_merge에 계속 들어갑니다. 페이지나 호출자는 embedding 장애를 전체 검색 실패로 처리할 필요가 없습니다.
MMR 기본 상태
MmrConfig::default()는 enabled: false와 lambda: 0.7로 설정합니다. 0.7 값은 MMR이 명시적으로 활성화된 경우에만 적용됩니다.
pub async fn hybrid_search(
index: &MemoryIndex,
embedding_provider: Option<&dyn EmbeddingProvider>,
query: &str,
config: &MemorySearchConfig,
) -> Result<Vec<SearchResult>, Box<dyn std::error::Error>> {
let candidate_limit = config.max_results * 3;
let mut fts_results =
index.search_fts(query, candidate_limit).unwrap_or_default();
/* evergreen FTS 후보를 보완하는 소스 코드가 여기에 있음 */
let vec_available = index.vec_available();
let query_embedding = if vec_available {
if let Some(provider) = embedding_provider {
match provider.embed_batch(&[query]).await {
Ok(embeddings) if !embeddings.is_empty() =>
Some(embeddings.into_iter().next().unwrap()),
Ok(_) => None,
Err(e) => {
tracing::warn!(error = %e,
"embedding query failed, falling back to FTS-only");
None
}
}
} else { None }
} else { None };
hybrid_search_merge(index, fts_results, query_embedding.as_deref(), config)
}
crates/codegen/xai-grok-memory/src/backend.rs: search() — watcher 동기화 및 쿼리 실행
crates/codegen/xai-grok-memory/src/watcher.rs: MemoryFileWatcher
crates/codegen/xai-grok-memory/src/mmr.rs: mmr_rerank
crates/codegen/xai-grok-config-types/src/memory.rs: MmrConfig 기본값
grok-build-main 기준, 검증일 2026-07-17. 코드 블록은 실제 함수와 분기를 보존하며, 유일하게 접힌 부분은 주석으로 설명됩니다. 흐름도는 명시적으로 교육용 구조 다이어그램으로 표시됩니다.다운그레이드 쿼리 추적하기
watcher가 수정된 파일을 감지하고, query embedding이 실패하며, MMR이 기본 설정으로 유지된다고 가정합니다. 인덱스 업데이트, 후보 생성, 가중치 정렬, 최종 잘라내기를 순서대로 작성하고, 발생하지 않은 두 단계를 표시하세요.