Grok Build · 工具配置
進程級外部 Toolset Preset 註冊表
config.rs 允許 crate 外的擴展程式碼在當前進程內註冊按名稱解析的工具集構建函式,並用 Public 與 Internal 控制是否進入公開枚舉。
課程目標讀懂 registry 保存什麼、Public 與 Internal 的邊界,以及晚註冊對「已解析配置」和「後續解析」的不同影響。
核心視覺 · 教學化結構圖
教學化結構圖:節點與連綫用於解釋源碼關係,內容經過課程化整理。
三個必須分清的事實
Builder 是函式指針ToolsetPresetBuilder = fn() -> ToolServerConfig。註冊表保存構建函式,查詢時調用函式生成配置。
Visibility 只管枚舉Public 會進入 preset_names 與公開 preset 集合。Internal 不進入公開枚舉,但仍能被 toolset_for_preset 按名稱解析。
Registry 屬於進程OnceLock 與 Mutex 包住全局 HashMap,生命週期覆蓋當前進程,並支持受鎖保護的讀寫。
註冊時序的準確含義
配置 A 已經解析
隨後註冊的新 preset 不會回寫到配置 A。現有 ToolServerConfig 保持原樣。
配置 B 之後解析
後續調用會重新查詢全局 registry,因此能看到晚註冊的 preset。源碼註釋仍要求儘量在第一次解析前完成註冊,以保證啓動行為一致。
真實源碼證據
crates/codegen/xai-grok-agent/src/config.rs第 38 至 81 行節選
pub type ToolsetPresetBuilder = fn() -> ToolServerConfig;
enum PresetVisibility {
Public,
Internal,
}
pub fn register_toolset_preset(name: &str, builder: ToolsetPresetBuilder) {
toolset_preset_registry().lock().expect("toolset preset registry poisoned")
.insert(name.to_string(), (builder, PresetVisibility::Public));
}
pub fn register_internal_toolset_preset(name: &str, builder: ToolsetPresetBuilder) {
toolset_preset_registry().lock().expect("toolset preset registry poisoned")
.insert(name.to_string(), (builder, PresetVisibility::Internal));
}
fn registered_toolset_preset(name: &str) -> Option<ToolServerConfig> {
toolset_preset_registry().lock().expect("toolset preset registry poisoned")
.get(name).map(|(f, _)| f())
}
源碼快照説明:依據本地倉庫
grok-build-main,核對檔案 crates/codegen/xai-grok-agent/src/config.rs,核對日期 2026-07-17。程式碼塊保留所展示字段、函式與字串的源碼原文。課堂練習
01
設計一個僅供測試 harness 使用的 preset
寫出應調用的註冊函式、builder 的完整類型,以及它能否出現在 preset_names() 中。再説明:若會話配置已經解析,註冊後該會話是否自動變化。
Takeaway:外部 preset registry 保存「名稱到構建函式與可見性」的映射。Public 與 Internal 的核心差異是公開枚舉範圍。晚註冊不會改變已解析配置,後續解析仍能查詢到新條目。