第 15 章:工程地图与继续阅读方法
前 14 章建立了系统模型。本章不再引入新子系统,而是提供“真正开始改代码时”的定位表、调用链、测试策略和排障入口。
15.1 主要 Crate 地图
产品与编排
| Crate | 一句话职责 | 首读文件 |
|---|---|---|
xai-grok-pager-bin | 可执行文件组合根与命令分派 | src/main.rs |
xai-grok-pager | TUI client、Action/Effect、scrollback | src/app/mod.rs |
xai-grok-shell | Agent/Session/Leader 应用编排 | src/lib.rs、session/acp_session.rs |
xai-grok-agent | agent preset、prompt/tool 构建 | src/config.rs、src/builder.rs、src/agent.rs |
xai-acp-lib | ACP transport、gateway、消息边界 | src/lib.rs |
模型与上下文
| Crate | 一句话职责 | 首读文件 |
|---|---|---|
xai-grok-sampling-types | 供应商无关的 conversation/request/response | src/conversation.rs |
xai-grok-sampler | 后端网络流、转换、重试、取消 | src/lib.rs、actor/request_task.rs |
xai-chat-state | conversation actor、token/pruning/request | src/types.rs、src/actor/* |
xai-grok-compaction | transport-agnostic 压缩流水线 | src/code_compaction/mod.rs |
xai-grok-memory | Markdown 记忆、索引、检索、Dream | src/lib.rs |
工具与执行环境
| Crate | 一句话职责 | 首读文件 |
|---|---|---|
xai-tool-types | 工具与任务的规范数据 | src/lib.rs |
xai-tool-protocol | 工具服务器 JSON-RPC contract | src/lib.rs |
xai-tool-runtime | Tool、ToolDyn、流式终态 | src/tool.rs |
xai-grok-tools | 内置工具、registry、bridge、reminder | src/lib.rs、registry/types.rs |
xai-grok-workspace-types | 本地/代理共享 op 类型 | src/lib.rs |
xai-grok-workspace-client | Workspace RPC client | src/lib.rs |
xai-grok-workspace | 文件、VCS、权限、session storage | src/lib.rs |
xai-grok-sandbox | OS 级进程约束 | src/lib.rs |
长任务与扩展
| Crate | 一句话职责 | 首读文件 |
|---|---|---|
xai-grok-subagent-resolution | 子代理角色/context/resume 解析 | src/lib.rs |
xai-workflow | Rhai 引擎、host contract、journal | src/lib.rs、engine.rs |
xai-grok-mcp | MCP transport/OAuth/server lifecycle | src/lib.rs |
xai-grok-hooks | Hook 执行与事件 | src/lib.rs |
xai-hooks-plugins-types | 扩展跨层 DTO | src/lib.rs |
xai-grok-plugin-marketplace | 插件市场/安装数据 | src/lib.rs |
15.2 六条最有用的调用链
链 1:用户发 prompt
text
TUI Action
-> ACP session/prompt
-> MvpAgent::prompt
-> SessionHandle mailbox
-> SessionActor prompt task
-> process_conversation_turn1
2
3
4
5
6
2
3
4
5
6
入口:
pager/src/app/actions.rsshell/src/agent/mvp_agent/acp_agent.rs约 2144 行shell/src/session/acp_session_impl/turn.rs
链 2:请求模型
text
SessionActor
-> ChatState::build_request
-> ConversationRequest
-> SamplerHandle::submit
-> request_task::run_one_attempt
-> backend client
-> SamplingEvent
-> sampler_turn::submit_and_collect1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
链 3:执行工具
text
Assistant tool calls
-> execute_tool_calls
-> prepare_tool_call
-> ToolBridge parse
-> Hook + Permission
-> ToolDyn
-> typed Tool
-> WorkspaceOp / MCP
-> ToolResult
-> ChatState1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
链 4:更新 UI
text
Sampling/Tool event
-> SessionActor update
-> PersistenceMsg + ACP gateway
-> Leader route (optional)
-> pager ACP handler
-> Action/dispatch
-> AgentView/Scrollback block
-> render1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
链 5:恢复 session
text
session/load
-> resolve storage path
-> read summary + updates + checkpoints
-> reducer rebuild
-> restore ChatState
-> full/delta replay
-> Leader replay/live barrier
-> Client projection1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
链 6:自动压缩
text
ChatState token check / backend context error
-> Session compaction gate
-> xai-grok-compaction prompt + sample
-> validate + assemble
-> persistence checkpoint
-> ChatState full replace
-> reset reminder/token state
-> continue original turn1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
15.3 按改动目标定位
| 你要改什么 | 首要位置 | 必须联查 |
|---|---|---|
| 新增 CLI command | pager-bin/main.rs、pager CLI | shell app、help/tests |
| 新增模型后端 | sampler client/transform | sampling-types conversion、retry、usage |
| 新增内置工具 | xai-grok-tools implementation/registry | agent preset、permission、render/tests |
| 改工具并发 | tool_calls.rs | per-file lock、cancel、Hook、result order |
| 改权限规则 | workspace permission | Bash parser、managed config、UI prompt |
| 改系统提示 | xai-grok-agent templates/context | compaction head、subagent audience、cache |
| 改 context pruning | xai-chat-state | token ledger、persistence/replay、provider tests |
| 改 compaction | xai-grok-compaction + shell integration | checkpoint、rewind、memory reinjection |
| 改 session 文件格式 | storage/persistence | reducer、migration、torn-write tests |
| 改 TUI 完成状态 | pager turn_completion/ACP handler | driver/viewer、replay、cancel-now |
| 改 subagent | task tool/coordinator/resolution | usage fold、permissions、storage tree |
| 改 Goal | goal_tracker/orchestrator/evaluator | persistence、tool gate、token budget |
| 改 Workflow | xai-workflow + session manager | journal compatibility、limits、child ownership |
| 改 MCP | xai-grok-mcp + session dispatcher | dynamic registry、OAuth、reload |
| 改 Plugin/Hook | shell plugin/extensions | folder trust、containment、permission |
15.4 修改一个工具时的检查清单
- 参数和输出是否为强类型,并生成正确 schema?
- internal id 与 client-visible name 是否稳定?
- registry preset 是否真的启用它?
- Plan/Explore/readonly 模式是否应看到它?
AccessKind与权限展示是否正确?- Hook payload 是否包含 canonical 参数且受大小限制?
- 并发调用时是否需要 path/resource lock?
- 取消是否产生恰好一个 terminal?
- 错误是 ToolResult 还是系统失败?
- ACP/TUI 是否有对应 display/progress?
- 结果是否可能撑爆上下文,需要 truncate/reminder?
- 本地与 Proxy Workspace 是否都支持?
15.5 修改消息/事件时的检查清单
新增一个事件字段时,沿下面所有投影检查:
text
producer
-> in-memory type
-> serde/wire compatibility
-> persistence
-> replay reducer
-> Leader routing/buffer
-> ACP client
-> TUI state
-> render/tests1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
尤其要回答:
- 旧日志缺少字段时默认什么?
- 新客户端读旧日志是否正常?
- 旧客户端遇到新 update 是否能忽略?
- full replay 与 live update 是否幂等?
- 事件是否需要 event/prompt/request id?
- 是否可 coalesce,还是必须逐条保留?
15.6 并发不变量
改异步代码前先写下不变量:
| 子系统 | 关键不变量 |
|---|---|
| SessionActor | 单 session 业务状态只有 actor 所有 |
| Sampler | 每个 request 恰好一个 terminal;cancel 可观测 |
| ToolStream | 任意 progress 后恰好一个 terminal |
| Tool batch | 预检顺序稳定;结果保持 call identity |
| Persistence | append 顺序稳定;ack 语义明确 |
| Leader load | replay 完成前 live 不越过屏障 |
| Workflow journal | request order/hash 与记录对应 |
| Dream | 新 MEMORY 原子提交后才删除素材 |
如果修改破坏其中一项,即使 happy path 测试通过,也很可能在取消、重连或崩溃时出错。
15.7 测试层级
纯函数/类型测试
适合:
- provider conversion;
- schema/registry validation;
- permission parser;
- reducer;
- ranking/MMR;
- path containment;
- goal state machine。
Actor 测试
适合:
- command/ack;
- cancellation;
- persistence commit/unknown;
- token ledger;
- sampler retry;
- workflow pause/resume。
E2E/协议测试
适合:
- ACP prompt/load/replay;
- MCP handshake/call/restart;
- goal planner/verifier;
- subagent completion;
- rewind cross-compaction;
- TUI driver/viewer completion。
故障注入
至少覆盖:
- 流在最后 token 前断开;
- terminal 到达但 consumer 未 drained;
- JSONL 最后一行 torn;
- persistence 写成功但 ack 丢失;
- replay 时 live update 到达;
- permission modal client 消失;
- Hook timeout;
- MCP server 在调用中退出;
- compaction summary 无效;
- workflow journal 尾行损坏;
- Dream 写回前失败。
15.8 建议测试命令
当前环境应在安装 Rust toolchain 后执行。按风险从小到大:
bash
cargo test -p xai-grok-sampling-types
cargo test -p xai-tool-runtime
cargo test -p xai-chat-state
cargo test -p xai-grok-compaction
cargo test -p xai-grok-memory
cargo test -p xai-workflow
cargo test -p xai-grok-tools
cargo test -p xai-grok-workspace
cargo test -p xai-grok-shell
cargo test -p xai-grok-pager1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
先运行受影响 crate,再运行直接集成方。全 workspace 体积很大,不适合把一次微小改动的第一反馈交给全量测试。
15.9 静态定位命令
bash
# 找 workspace member
sed -n '/^members = \[/,/^\]/p' Cargo.toml
# 找类型与实现
rg -n 'struct SessionActor|impl .*SessionActor' crates/codegen/xai-grok-shell
# 找某个 ACP method
rg -n 'session/prompt|session/load' crates/codegen
# 找工具注册与调用
rg -n 'ToolRegistryBuilder|prepare_tool_call|execute_tool_calls' crates
# 找 update 的所有投影
rg -n 'SomeUpdateType' crates/codegen/xai-grok-shell crates/codegen/xai-grok-pager
# 找测试而忽略快照噪声时可继续限定目录
rg -n '#\[.*test\]|tokio::test' path/to/crate/src1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
15.10 读测试比读注释更有价值的地方
以下语义应优先读 tests:
- ChatState persistence 的 indeterminate commit;
- TUI turn completion 的 driver/viewer;
- rewind 穿越 compaction;
- Goal restore 与 pause;
- plugin trust/config path;
- MCP coalescing/restart;
- permission shell parser;
- workflow journal torn tail;
- Leader replay/live ordering。
注释说明意图,测试列出了已经遇到过的边界。
15.11 观察与诊断
排障时按 ownership 定位:
| 症状 | 首查 |
|---|---|
| 模型不返回/反复 retry | sampler event、retry classifier、auth |
| 模型看不到工具 | AgentBuilder、registry finalize、MCP init |
| 工具显示批准却未执行 | Hook、permission decision、Workspace error |
| TUI 丢尾 token | stream-drained、ACP chunk、completion ordering |
| 重连后重复内容 | cursor/full replay、Leader live buffer、handler idempotence |
| session 能显示但下一轮上下文错 | chat_history/reducer/ChatState |
| compact 后忘记规则 | head rebuild、reminder reset、project instructions |
| rewind 回错轮 | compaction checkpoint、prompt checkpoint |
| child 完成但 parent 不知道 | coordinator owner、background completion drain |
| workflow 重复花费 | journal request hash/order |
| 插件被发现但不执行 | folder trust、activation、path containment |
15.12 架构取舍总结
| 取舍 | 收益 | 代价 |
|---|---|---|
| 多 actor 状态所有权 | 并发边界明确 | 调用链分散、需事件相关性 |
| ACP 作为稳定边界 | 多 Client/Leader/重连 | 协议与 replay 复杂 |
| 规范 sampling types | 多后端共享主循环 | 转换层需要大量兼容测试 |
| 类型 Tool + 动态擦除 | 实现安全、模型动态 | registry/finalize 更复杂 |
| 决策串行、执行并发 | 权限可理解且保留性能 | 需要 call identity 与锁 |
| Updates 事实源 | 可重建、可重放 | reducer/版本兼容成本 |
| Full-replace compaction | 新上下文干净合法 | checkpoint/rewind 复杂 |
| Markdown-first Memory | 可审计、可恢复 | 需要索引同步与 Dream |
| Goal 独立验证 | 降低虚假完成 | 额外 token 与状态机 |
| Workflow journal | 可重复恢复 | host call 必须可哈希/重放 |
| Plugin trust 分层 | 可发现但不盲执行 | 配置与解释面增加 |
15.13 当前文档的验证记录
本拆解完成时执行了:
- workspace/源码目录静态盘点;
- 核心类型、函数、常量与模块注释交叉核对;
- 关键测试文件和错误分支抽样;
- 文档内部链接与路径检查;
- 结论按源码事实/设计归纳区分。
当前执行环境没有可用的 cargo/rustc,因此未运行 Rust 编译与测试。本文描述的是提交 6e386420... 的静态源码行为;后续仓库升级时,应优先复核本章六条调用链和各章“源码阅读卡”。
15.14 当前快照的关键符号索引
| 符号 | 位置 | 阅读价值 |
|---|---|---|
main | pager-bin/src/main.rs:1654 | 进程级初始化 |
async_main | pager-bin/src/main.rs:1735 | 顶层命令分派 |
run_agent_command | pager-bin/src/main.rs:1004 | Agent 运行模式汇合 |
run_stdio_agent | shell/src/agent/app.rs:306 | ACP stdio 入口 |
run_headless | shell/src/agent/app.rs:426 | 无头入口 |
run_leader | shell/src/agent/app.rs:933 | 常驻 Leader 入口 |
MvpAgent | shell/src/agent/mvp_agent/mod.rs:605 | session registry 与共享服务 |
SessionActor | shell/src/session/acp_session.rs:581 | 单会话状态所有权 |
spawn_session_actor | acp_session_impl/spawn.rs:95 | actor 装配 |
spawn_session_on_thread | acp_session_impl/spawn.rs:2039 | OS thread 与 LocalSet 边界 |
run_session | acp_session_impl/run_loop.rs:120 | 外层 session event loop |
process_conversation_turn | acp_session_impl/turn.rs:1880 | 内层模型—工具循环 |
run_turn_via_sampler | acp_session_impl/sampler_turn.rs:1118 | 采样收集与 drained barrier |
execute_tool_calls | acp_session_impl/tool_calls.rs:284 | 批量工具执行 |
prepare_tool_call | acp_session_impl/tool_calls.rs:754 | 解析、Hook、权限预检 |
ConversationRequest | sampling-types/src/conversation.rs:551 | 规范模型请求 |
ConversationResponse | sampling-types/src/conversation.rs:732 | 规范模型响应 |
SamplingEvent | sampler/src/events.rs:28 | 流式协议 |
Tool / ToolDyn | tool-runtime/src/tool.rs:36 / 306 | 强类型与动态边界 |
ToolRegistryBuilder | grok-tools/src/registry/types.rs:528 | 工具注册与 finalize |
PruningConfig | chat-state/src/types.rs:72 | 上下文修剪阈值 |
GoalStatus | shell/src/session/goal_tracker.rs:64 | Goal 生命周期 |
WorkflowManager | shell/src/session/workflow/manager.rs:55 | 工作流运行与恢复 |
行号只对本文记录的提交快照有效;升级后优先按符号名检索。
15.15 最终心智模型
用一句话收束全书:
Grok Build 是一个以 SessionActor 为业务核心、以 ACP 为交互边界、以规范事件和持久更新连接模型、工具、UI 与长期任务的多进程/多 actor 编码代理系统。