# 一条消息的生命周期 · 全景地图

> 把「你敲一句话 → grok 改完代码回你话」这条端到端链路完整走一遍，标出每一步落在哪个 crate、由后面哪一部分放大讲。这是进入内核前的最后一张全景图。

- 作者：David（道雾轩）
- 专栏：Grok Build 源码解读（https://daiw.org/manual/grok-build.md）
- 最后更新：2026-09-15
- 原文：https://daiw.org/manual/grok-build/message-lifecycle
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 一条消息的生命周期 · 全景地图

前面几章分别讲了「是什么、怎么跑、怎么分层」。这一章把它们**串成一条端到端的链路**：从你敲下一句话，到 grok 改完代码、把结果显示回来，中间到底发生了什么、每一步归谁管。后面第 1–6 部分，就是把这条链路上的每一段放大来看。

## 全链路

```mermaid
flowchart TB
  IN["1 · 输入<br/>xai-grok-pager 输入层"]
  TURN["2 · 开一轮 turn<br/>xai-grok-shell 会话 actor"]
  PROMPT["3 · 组装上下文<br/>prompt/* + chat-state"]
  SAMPLE["4 · 请求模型<br/>xai-grok-sampler → http"]
  STREAM["5 · 流式回来<br/>token / 工具调用"]
  ROUTE["6 · 路由工具调用<br/>xai-grok-tools registry"]
  EXEC["7 · 执行工具<br/>编辑 / shell / 搜索"]
  FEED["8 · 结果回灌<br/>写回 chat-state"]
  COMPACT["9 · 需要就压缩<br/>xai-grok-compaction"]
  RENDER["10 · 渲染<br/>pager-render scrollback"]
  IN --> TURN --> PROMPT --> SAMPLE --> STREAM
  STREAM -->|有工具调用| ROUTE --> EXEC --> FEED --> SAMPLE
  STREAM -->|无更多工具| RENDER
  FEED -.上下文变大.-> COMPACT -.压缩后继续.-> SAMPLE
```

## 逐段拆解

**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 步——那个把一切转起来的**主循环**——正式进内核。

---

上一篇：[读源码前的准备](https://daiw.org/manual/grok-build/reading-the-source)
