一条消息的生命周期 · 全景地图
把「你敲一句话 → grok 改完代码回你话」这条端到端链路完整走一遍,标出每一步落在哪个 crate、由后面哪一部分放大讲。这是进入内核前的最后一张全景图。
一条消息的生命周期 · 全景地图
前面几章分别讲了「是什么、怎么跑、怎么分层」。这一章把它们串成一条端到端的链路:从你敲下一句话,到 grok 改完代码、把结果显示回来,中间到底发生了什么、每一步归谁管。后面第 1–6 部分,就是把这条链路上的每一段放大来看。
全链路
逐段拆解
1 · 输入(TUI,第 5 部分)
你在提示框里敲的字,由 xai-grok-pager 的输入层捕获。这里还处理 slash 命令、补全、历史——但如果是普通一句话,它就打包成一条用户消息交给 agent。
2 · 开一轮 turn(Agent 运行时,第 1 部分)
xai-grok-shell 的会话 actor(SessionActor)启动一轮(xai-grok-agent 只负责事先造好 Agent 对象:system prompt、工具桥与各项策略)。「一轮」不等于「一次模型调用」——它可能内部往返模型好几次(每次模型要调工具就得再问一遍),直到模型不再要求工具、给出最终答复。
3 · 组装上下文(第 1 部分)
调模型前,agent 要把「喂给模型的东西」拼齐:system prompt(prompt/template.rs)、项目规则(prompt/agents_md.rs)、相关上下文与提醒(prompt/context.rs、system_reminder.rs),再接上会话历史(xai-chat-state)。这一步决定了模型「看到什么」。
4 · 请求模型(模型接入,第 1 部分)
拼好的请求交给采样器 xai-grok-sampler。它以 actor 方式管理这次请求的并发与取消,底层用自带的共享 HTTP 客户端(shared_http.rs),并按目标模型选择 API 格式(chat completions / messages / responses 三选一)。
5 · 流式回来(第 1 部分) 模型的回复是流式的:文本 token 一边到、一边往 UI 推;如果模型决定调工具,流里会出现结构化的工具调用。采样器把原始字节解析成一串事件。
6 · 路由工具调用(工具系统,第 2 部分)
出现工具调用后,agent 拿着工具名到 xai-grok-tools 的注册表里找对应实现,校验参数,准备执行。
7 · 执行工具(第 2、3 部分)
真正干活:改文件走编辑工具(配 xai-hunk-tracker 追踪 diff、防覆盖),跑命令走 xai-grok-tools 的终端工具(可选套 xai-grok-sandbox),搜代码走搜索与代码库图谱。
8 · 结果回灌(第 1 部分)
工具输出作为新消息写回 xai-chat-state,然后回到第 4 步——把结果喂给模型,让它决定下一步。这个「模型 ↔ 工具」的来回,就是 agent loop 的心跳。
9 · 需要就压缩(第 1 部分)
来回几轮后上下文会变大。当它逼近窗口上限(默认用量达到 85%),xai-grok-shell 触发压缩,由 xai-grok-compaction 把旧内容压成摘要,腾出空间再继续——尽量不丢关键信息。
10 · 渲染(TUI,第 5 部分)
整个过程里的文字、diff、工具状态,实时由 xai-grok-pager-render 画进滚动缓冲,就是你在终端看到的画面。
记住这张图
这十步就是全书的骨架。往后:
- 第 1 部分吃透 2、3、4、5、8、9(运行时内核);
- 第 2 部分吃透 6、7(工具);
- 第 3 部分补 7 里的「代码库理解」那一支;
- 第 5 部分吃透 1、10(TUI);
- 第 4、6 部分处理挂在这条链路周边的扩展与工程。
看完哪一部分,都可以回到这张图,确认它落在哪一段。下一章,我们从第 2 步——那个把一切转起来的主循环——正式进内核。
上一篇:读源码前的准备