Grok Build · 工具配置

進程級外部 Toolset Preset 註冊表

config.rs 允許 crate 外的擴展程式碼在當前進程內註冊按名稱解析的工具集構建函式,並用 Public 與 Internal 控制是否進入公開枚舉。

課程目標讀懂 registry 保存什麼、Public 與 Internal 的邊界,以及晚註冊對「已解析配置」和「後續解析」的不同影響。
核心視覺 · 教學化結構圖
註冊 APIregister_toolset_presetregister_internal_toolset_preset TOOLSET_PRESETSOnceLock<Mutex<HashMap<...>>>name → (builder, visibility)builder: fn() → ToolServerConfig Public可枚舉,也可按名解析 Internal僅按名解析,不公開枚舉 registered_toolset_preset(name)取出函式並立即構建新配置
教學化結構圖:節點與連綫用於解釋源碼關係,內容經過課程化整理。
三個必須分清的事實
Builder 是函式指針

ToolsetPresetBuilder = fn() -> ToolServerConfig。註冊表保存構建函式,查詢時調用函式生成配置。

Visibility 只管枚舉

Public 會進入 preset_names 與公開 preset 集合。Internal 不進入公開枚舉,但仍能被 toolset_for_preset 按名稱解析。

Registry 屬於進程

OnceLockMutex 包住全局 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 的核心差異是公開枚舉範圍。晚註冊不會改變已解析配置,後續解析仍能查詢到新條目。