Grok Build 源码拆解
这是一份面向“想真正理解并改造 Grok Build”的源码课程。它参考
refs/dg-ai-notes对pi-0.82.0的拆解方式:先建立全局心智模型,再沿一条真实请求逐层下钻;每章都回答“它是什么、如何工作、为什么这样设计”,并给出可继续追踪的源码入口。
这套文档研究的是什么
Grok Build 不是一个“把消息发给模型,再执行几个工具”的薄壳。以一次用户请求为中心,它至少同时包含:
- 终端 UI、无头模式和 ACP 客户端等多个入口;
- 可选的常驻 Leader 进程与多个客户端连接;
- 每个会话独立的
SessionActor; - 独立的采样 actor、流式事件和多后端协议转换;
- 类型化工具、动态 MCP 工具、权限策略、Hook 与沙箱;
- 上下文修剪、全量压缩、跨会话记忆;
- 子代理、持久目标和可恢复工作流;
- 事件日志、派生聊天历史、断线重放和文件回退。
因此,最合适的阅读单位不是“某个 crate”,而是下面这条端到端链路:
快照与结论边界
本文基于当前工作区快照:
| 项目 | 值 |
|---|---|
| Git 提交 | 6e386420825bd44ae648c63e7c8cba12fcec9401 |
| 提交说明 | Synced from monorepo |
| 上游源码修订 | 9b8d35b46d959c042ea9aa31cbbebbd1f0c5c527,见根目录 SOURCE_REV |
| 工作区规模 | 80 个 Cargo workspace members |
| 主要语言 | Rust 2024 edition |
文中使用三种语气:
- 源码事实:可直接由类型、控制流、常量或测试确认;
- 设计解释:由多个源码事实归纳出的工程意图;
- 阅读建议:为了理解系统而给出的阅读顺序,不代表运行时依赖顺序。
统计数字只描述这个快照。仓库约有 2,360 个 Rust 源文件、约 147 万行 Rust(包含测试与生成内容),不应把它们当作稳定 API 指标。
与现有用户指南的关系
现有用户指南 回答“怎样使用 Grok Build”;本套文档回答“它为什么能这样工作,以及修改时要跨过哪些边界”。因此这里不重复快捷键和命令说明,而把用户可见行为映射回 Agent、Session、Sampler、Tool、Workspace 与 Persistence 源码。
课程地图
| 章 | 主题 | 你会回答的问题 |
|---|---|---|
| 01 | 产品与总览 | Grok Build 到底是什么?一次请求跨过哪些边界? |
| 02 | Workspace 架构 | 80 个 crate 如何分层?哪些是主干,哪些是适配层? |
| 03 | 启动、ACP 与 Leader | TUI、无头、stdio、常驻服务如何共用同一套 Agent? |
| 04 | SessionActor 与 Agent Loop | 一轮对话如何调度模型、工具、插话、压缩与停止条件? |
| 05 | 模型与采样 | 三种模型协议如何被归一为同一套流式事件? |
| 06 | 工具系统 | 类型化工具怎样注册、裁剪、授权、并发执行? |
| 07 | 权限与工作区 | “允许执行”由谁决定?本地、代理、沙箱如何组合? |
| 08 | 消息与上下文 | 系统提示、规则、技能、提醒和历史如何进入请求? |
| 09 | 事件与 TUI | 后端流怎样变成可恢复、可渲染的用户界面状态? |
| 10 | 会话与重放 | 什么是事实源?如何应对崩溃、断线、重连和 rewind? |
| 11 | 压缩与修剪 | 长会话如何控制上下文,又不破坏工具调用语义? |
| 12 | 跨会话记忆 | Markdown、FTS、向量检索和 Dream 如何协作? |
| 13 | 子代理、目标与工作流 | 三套长任务机制分别解决什么问题? |
| 14 | MCP、插件、Hook 与技能 | 外部能力如何接入,信任边界在哪里? |
| 15 | 工程地图 | 如何继续读源码、改功能、找测试和定位故障? |
三条推荐阅读路线
路线 A:先抓主链
01 → 03 → 04 → 05 → 06 → 08 → 10
适合第一次接触 Agent 工程的人。读完后,你应该能从 session/prompt 一直追到模型响应、工具执行和落盘更新。
路线 B:准备改代码
02 → 04 → 06 → 07 → 09 → 15
适合要新增工具、修改权限、增加运行模式或修复 UI/后端竞态的人。
路线 C:研究长任务能力
08 → 11 → 12 → 13 → 14
适合研究上下文工程、长期记忆、多代理编排和扩展平台的人。
与 pi-agent 拆解的对应关系
| pi-agent 课程主题 | Grok Build 对应章节 | 关键差异 |
|---|---|---|
| Agent Loop | 04 | Grok Build 是 SessionActor + SamplerActor 两级 actor,并有 goal/workflow/插话等控制面 |
| 模型调用 | 05 | 同时归一 Chat Completions、Responses、Anthropic Messages |
| 工具系统 | 06、07 | 除工具抽象外,还有策略权限、Hook、工作区代理和 OS 沙箱 |
| 消息转换 | 08 | 消息中显式标记多类 synthetic reason,并有动态规则、技能、记忆注入 |
| 事件驱动 | 09、10 | ACP 既是客户端协议,也是 Leader 与 UI 的稳定边界;事件日志可重放 |
| 上下文工程 | 08 | 提示渲染、规则发现、技能优先级、工具提醒共同参与 |
| 自动压缩 | 11 | 采用全会话替换,并为派生历史写入 compaction checkpoint |
| 会话管理 | 10 | updates.jsonl 是事实源,chat_history.jsonl 是可重建缓存 |
| 无直接对应 | 12—14 | Grok Build 额外提供记忆、子代理、目标、工作流、MCP、插件与 Hook |
文档中最重要的阅读约定
- Actor 不是业务层的同义词。 它表示状态所有权与并发边界。
MvpAgent、SessionActor、ChatState、SamplerActor各自拥有不同状态。 - ACP 更新不是模型原始流。 模型事件先经过采样归一、会话组装和持久化,再变成客户端可消费的更新。
- 工具拒绝通常也是正常对话数据。 权限拒绝、Hook 拒绝和部分错误会被包装成工具结果,让模型有机会调整。
- 聊天历史不是唯一事实源。 会话恢复首先要理解
updates.jsonl与 reducer。 - “自动模式”不等于绕过边界。 Plan gate、托管策略和强制提示仍可能覆盖 yolo/auto 的快速路径。
从哪里开始看源码
如果只打开六个文件,建议依次看:
这六处形成一条最短的“入口—会话—模型—工具”主链。其余章节都是围绕这条主链解释状态、安全、持久化和扩展能力。