Grok Build · 記憶檢索
從檔案變更到混合排序
查詢前先同步髒檔案,再結合 FTS5 BM25 與可選的 sqlite-vec KNN。合併分數經過時間衰減、來源權重與存取增益,最後可選擇啓用 MMR 多樣性重排。
課程目標按真實順序複述 sync-on-search、FTS、embedding、KNN、合併加權與 MMR,並能説明 embedding 失敗和 MMR 關閉時各自發生什麼。
核心視覺 · 完整檢索路徑
教學化結構圖:失敗分支回到 FTS-only;MMR 是 opt-in,預設不會重排。
流水綫中的真實機制
01 · SYNC
查詢前同步
MemoryFileWatcher 累積變化的 Markdown 路徑。backend 在 search 開始時重新索引新增或修改檔案,並刪除已移除檔案的舊 chunk。
02 · FTS
BM25 候選
先執行普通 FTS,再補充 global 與 workspace 來源查詢,降低 session 數量過多造成的擠出。
03 · VECTOR
可選 KNN
僅在 sqlite-vec 與 provider 可用時嵌入 query。embedding 報錯會記錄 warning,並傳入 None 繼續 FTS-only。
04 · SCORE
歸一化與合併
BM25 分數與向量 L2 距離分別歸一化。雙路命中時按權重合並,同時保證結果不低於該 chunk 的 FTS 分數。
05 · WEIGHT
時間與來源
session 按半衰期指數衰減,global 與 workspace 視為 evergreen。隨後乘 source weight 與適度的 access boost。
06 · DIVERSITY
可選 MMR
開啓後按相關性與 snippet 的 Jaccard 差異做貪心重排。最後截斷到 max_results。
兩個容易誤讀的開關
Embedding 失敗
向量路徑停止,FTS 結果仍進入 hybrid_search_merge。頁面或調用方無需把 embedding 故障當成整次搜索失敗。
MMR 預設狀態
MmrConfig::default() 設定 enabled: false 與 lambda: 0.7。0.7 只在顯式開啓 MMR 後生效。
真實源碼證據
crates/codegen/xai-grok-memory/src/search.rs · 第 146 至 190 行節選
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。程式碼塊保留真實函式與分支,唯一的摺疊處已用註釋説明;流程圖明確標為教學化結構圖。課堂練習
06
推演一次降級查詢
假設 watcher 發現一個檔案被修改,query embedding 隨後失敗,MMR 保持預設配置。請按順序寫出索引更新、候選生成、加權排序與最終截斷,並標出沒有發生的兩個步驟。
Takeaway:記憶檢索具備可降級與可同步兩條關鍵保障。FTS 始終提供基礎候選,向量搜索按可用性增強;時間衰減和來源權重調整排序;MMR 需要顯式開啓;watcher 讓外部 Markdown 修改在下一次查詢前進入索引。