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