Files
NetMesh/docs/research/grok-build-context-engineering-source-notes.md
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

32 KiB
Raw Permalink Blame History

Grok Build 上下文工程与 Agent Runtime 源码笔记

研究对象:官方 xai-org/grok-build 本地源码快照,SOURCE_REV=2ec0f0c8488842da03a71eeee3c61154957ca919。 范围提示词与上下文装配、token 预算、历史裁剪/压缩、工具结果、缓存、会话恢复、子 agent、hooks/skills、可观测性与离线评估。 方法:只使用仓库内第一方源码和仓库自带的第三方归属声明,不以 README 宣传文字代替实现证据。

结论先行

Grok Build 最值得 Catty 学的不是某一个 prompt而是以下 8 个机制组成的闭环:

  1. 把上下文做成可检查、可持久化的数据结构,而不是散落的字符串拼接。 PromptContext 明确记录 audience、prompt mode、AGENTS.md、memory、role/persona、运行环境和构建时间再统一渲染父 agent 与子 agent 使用不同模板和目录信息,但项目指令保持一致。prompt/context.rs:79-151 prompt/context.rs:160-171 prompt/context.rs:251-297
  2. 在真正压缩前先做分层、可逆的减负。 超过 50% 才对请求副本裁剪旧工具结果;近 3 轮不动较老大结果保留头尾10 轮以前的结果只留占位;原始事件流仍保留用于重放。request_builder.rs:20-108 request_builder.rs:155-208 types.rs:67-97 mutations.rs:165-205
  3. 把两段式压缩的第一段放到后台提前跑。 达到正式压缩阈值前 10 个百分点时,后台总结约 95% 的历史;真正触发压缩时只需把 NOTE1 与最近约 5% 合并成最终摘要。缓存带前缀指纹与 model 标识,历史编辑、回退、分叉或切模型后自动失效。compaction.rs:34-63 compaction.rs:219-340 compaction.rs:342-429 two_pass.rs:1-20
  4. 压缩不是不可逆删除:摘要之外保留可检索的分段档案。 Summary、原始 transcript、Markdown segments 三种模式可选segments 模式给后继 agent 一个索引和只读恢复路径,摘要不够时再按需读取精确代码、错误和工具输出。compaction_mode.rs:7-20 compaction_mode.rs:51-77 fork.rs:92-106
  5. 压缩后显式重新注入运行状态,而不是赌摘要记住一切。 新上下文重建时单独采集正在运行的终端任务、子 agent、改过的文件、MCP 服务、todo、skills、AGENTS.md、plan mode 和 memory再生成 system reminder这比把所有责任交给总结模型更可靠。compaction.rs:1205-1350 compaction.rs:1381-1499
  6. 所有工具调用历史都做结构完整性修复。 在恢复、下一轮写入和发请求边界去重重复 ToolResult、为悬空 tool call 补合成结果;另有显式 repair 路径移除会导致 provider 400 的孤儿结果。mutations.rs:26-70 mutations.rs:80-109
  7. 子 agent 是独立可恢复会话,不只是一次函数调用。 子 agent 有独立 session id、原始 transcript、tool state、model、cwd、能力与隔离模式支持继续以前的子 agent、后台运行、父轮取消隔离、进度/用量拉取,并把用量按 model 汇总回父账单。task/types.rs:29-68 task/types.rs:84-108 task/types.rs:304-335 usage.rs:100-146
  8. 压缩路径本身是可观测、可离线重放的产品功能。 每次压缩记录触发比例、阈值、输入/输出 token、重试阶段、失败类别、TTFT、流耗时、最大 token 间隔、两段式命中/失效等;同时把“实际送给压缩模型的历史 + 返回摘要/错误”保存成 artifact供离线迭代 prompt。compaction.rs:800-864 session_compact.rs:219-310 persistence.rs:360-374

对 Catty 的优先级建议:先做 压缩后状态再注入 + 工具历史完整性修复 + 压缩 artifact/eval;随后做 可恢复 segments;最后用实验开关验证 后台两段式压缩。这些项的收益与风险边界最清晰。

1. 提示词与上下文装配

1.1 PromptContext 是正式协议

PromptContext 是可序列化的第一等对象,而不是最终 prompt 的临时参数。它包含 schema version、prompt mode、父/子 audience、可覆盖的基础模板、AGENTS.md 列表、memory 路径、role/persona、OS/shell/cwd/date 和 non-interactive 状态。prompt/context.rs:79-151

渲染统一走 ToolBridge 的模板引擎,因此工具名不是写死在 prompt 中,换工具集或兼容模式时仍能解析正确名称;Extend 支持基础模板 + 自定义 bodyFull 支持完全替换。prompt/context.rs:233-297

父/子 agent 的差异被显式建模:子 agent 用紧凑模板、不接收 persona catalog但仍接收完整 AGENTS.md避免验证型子任务绕过项目约束。prompt/context.rs:68-77 prompt/context.rs:160-170 prompt/context.rs:205-220

Catty 可借鉴: 给现有 system prompt/context manager 增加一个可 dump、可版本化的 PromptContextSnapshot,让问题排查能回答“这轮究竟注入了什么、来自哪里、为何出现”。

1.2 项目规则有顺序、来源和幂等性

AGENTS.md/rules 的查找顺序是 global → repo root → cwd越深的文件越晚出现、冲突时优先兼容 Claude/Cursor 规则目录,并受 gitignore 过滤,最终按 canonical path 去重。agents_md.rs:66-77 agents_md.rs:87-168

每段规则保留源文件路径rules frontmatter 被剥离;恢复会话时通过结构标签或 legacy 前缀识别已有项目指令,避免重复注入。agents_md.rs:186-229 prompt_build.rs:65-90

1.3 大用户输入采用“内联摘要 + 文件指针”

首轮大 prompt 超过 25 KB 时,不直接粗暴截掉尾部:会把全文写到 session 文件,内联内容按 query 80%、context 余量、skills 独立 4 KB 预算分配,并保留 head + tail确保结尾真正问题仍在写盘失败则改成无路径的诚实提示避免模型追逐不存在的文件。prompt_build.rs:185-202 prompt_build.rs:203-276 prompt_build.rs:278-309

这和 Catty 已有的 tool output handle 思路相似,但 Grok 把同一模式也用于用户输入。值得统一成通用的“上下文外置对象”:有稳定 handle、摘要、大小、来源、读取工具和生命周期。

2. Token 预算与上下文计量

Grok 把 bytes/4 估算、图片固定成本、百分比、剩余量和阈值判断放在共享 crate所有 UI、预检和自动压缩使用同一套整数语义阈值是 >=,边界行为有测试固定。xai-token-estimation/src/lib.rs:1-32 xai-token-estimation/src/lib.rs:35-104 xai-token-estimation/src/lib.rs:188-207

运行时不是只信模型上次返回的 usageget_estimated_total_tokens 会把上次模型总量与之后新增的工具结果估算相加,用于下一次请求前的 overflow 检查。handle.rs:403-419 mutations.rs:112-127

工具 schema 本身也进入压缩预算;输入溢出时采用 verbatim → fitted verbatim → lossy 的降级阶梯fitted 为摘要预留 32,768 token再扣除工具 schema tokenlossy 最多使用窗口 70%。compaction.rs:879-890 compaction.rs:931-946 compaction.rs:1062-1116

Catty 可借鉴: 统一 tokenEstimator、UI context 指示、step pruning 与 413 预检的边界语义;把 tool schema、pending tool output、图片字节都纳入“下一请求成本”而不是只看上一响应 usage。

3. 历史裁剪、压缩与可恢复性

3.1 三层减负

第一层是工具本身输出限额:一般工具默认 40 KB终端结果默认 20,000 字符;完整终端输出写文件,模型收到头尾预览和文件路径。xai-grok-tools/src/lib.rs:5-16 types/output.rs:413-432 types/output.rs:1217-1238

第二层是请求副本 pruning只在窗口超过 50% 后运行,近 3 个用户轮不动;较老且超过 4,000 字符的结果保留头尾各 1,50010 轮以前只留 placeholder。request_builder.rs:155-208 types.rs:67-97

第三层才是整段 compaction。默认阈值 85%可配模型、memory flush、5 分钟 wall-clock backstop并可启用两段式模式。xai-grok-agent/src/compaction.rs:3-44

这种分层优于“每轮都压缩工具结果”:它刻意保护稳定前缀,避免频繁改写旧消息导致 KV cache miss。request_builder.rs:64-85

3.2 两段式后台预压缩

两段式先按估算 token 权重切分约 95%/5%,且切点会避开 assistant tool_calls 与对应 ToolResult保证结构合法。two_pass.rs:29-50 two_pass.rs:52-139

NOTE1 最多 12,000 字符;优先取完整、足够长的 <summary>,否则使用原始输出。正式压缩前缓存必须同时满足 prefix_len、model slug、前缀 fingerprint 三项,任何不一致都退回单段压缩。two_pass.rs:14-20 two_pass.rs:141-187 compaction.rs:379-415

它还区分“后台已经完成的延迟”和“用户实际等待的延迟”,只有后者计入最终 TTFT这是评估 speculative work 是否真的降低用户等待的正确方法。compaction.rs:342-355 compaction.rs:416-428

风险: 后台 pass1 会额外花 token且 prefix fingerprint 目前只 hash item 类型和 text_content没有显式 hash tool call arguments如果 tool calls 的参数不在 text_content()理论上可能出现缓存误命中。Catty 若实现,应使用完整 canonical serialization fingerprint并先用命中率、浪费 token、同步等待下降三项实验数据验证。

3.3 压缩后恢复精确细节

CompactionMode 提供 summary-only、指向原始 updates.jsonl、以及 clean Markdown segment store 三种模式。后两者在摘要尾部告诉后继 agent 如何用 read/grep 找回精确内容。compaction_mode.rs:7-20 compaction_mode.rs:51-77

segment 有独立索引、关键词、turn/tool/file/error 统计和不同细节级别fork 时连同 segments 一起复制,因此子分支不会因为父会话压缩失去早期证据。compaction_transcript.rs:75-140 compaction_transcript.rs:184-267 fork.rs:92-106

Catty 可借鉴: ToolOutputStore 解决的是大工具输出segments 解决的是“摘要后整个旧对话”。两者可共用 handle/read 基础设施:压缩摘要携带结构化 archive manifest按 segment/turn/tool/file 查询,而非只给一个巨大 transcript 路径。

3.4 压缩后重新建立“工作现场”

压缩成功后Grok 不直接只留下 system + summary。它重新构造 AGENTS.md、skills、memory、计划模式、运行中的后台命令、活跃子 agent、改过的文件、MCP 和 todo再对 compacted history 做 orphan ToolResult 清理与验证;若仍不合法,退回更小的安全历史。compaction.rs:1205-1350 compaction.rs:1425-1499 compaction.rs:1504-1548

这是对 Catty 最直接的改进点:现有 SessionState reinjection 可以扩展为正式的 ContinuationState,明确包含 active jobs、subagents、todo/plan、edited files、MCP/tool catalog version、skills/AGENTS snapshot、外置输出 handles并有 schema/version 和恢复测试。

4. 工具结果与缓存

Grok 明确区分 ToolRunResult.output(干净、协议/序列化/追踪用)和 prompt_text(可附 reminder、专供模型避免 UI/协议数据被模型提示加工污染。types/output.rs:128-145

对话完整性修复发生在确定的写边界,不在任意读取时运行,避免把仍在执行中的并行工具误判为悬空;修复会持久化,因而恢复后不会重复撞 provider 400。mutations.rs:26-43 mutations.rs:47-70

图片处理也考虑 cache只有请求体接近 50 MB 才批量移除最旧图片,并一次降到 25 MB形成迟滞区避免每轮移一张、每轮破坏 KV 前缀;占位文案明确告诉模型图片已不可见,避免凭“记忆”幻觉描述。request_builder.rs:215-265

Catty 可借鉴: 所有会改写历史前缀的策略都应有 cache-cost 意识;用 high-water/low-water 批处理,而不是刚过线就做最小改写。并将“干净工具结果”和“给模型看的文本”拆为两个字段,防止 reminder、裁剪标记污染恢复/审计数据。

5. 会话恢复与分叉

本地会话只有存在 summary.json 才算可恢复,避免只有 images 的残缺目录劫持 resume远端恢复会寻找同 cwd 下最新的本地 child避免重复恢复。persistence.rs:395-419 persistence.rs:422-453

分叉会复制 chat、updates、plan state 和 compaction segments记录 parent_session_id并可指定 prompt index/model/cwd磁盘复制放到 blocking pool后台注册服务端不阻塞本地 fork 的关键路径。fork.rs:64-113 fork.rs:115-163

恢复/子 agent spawn 对 system prompt 的策略不同:顶层 resume 保留历史 system子 agent resume 继承 raw transcript 和 tool state但用当前定义重新渲染 system避免旧 persona/工具目录永久冻结。prompt_build.rs:92-110 task/types.rs:44-47

6. 子 agents

子 agent channel protocol 把身份、parent prompt、resume_from、cwd、runtime overrides、是否后台、是否向父模型展示完成事件、是否 fork parent context 都作为明确字段。task/types.rs:29-68

能力不是简单的“全工具/无工具”,而是 ReadOnly、ReadWrite、Execute、All 四档,并在移除所有能产生后台任务的工具时同步移除无意义的 get/kill 生命周期工具。task/types.rs:139-174 task/types.rs:189-300

父子共享 filesystem、terminal backend、memory、scheduler、hunk tracker、hooks 等运行资源,但子会话有独立的 model/context threshold/usage/session signals背景子 agent 在父轮取消时继续,前台子 agent 才按 parent_prompt_id 取消。subagent/mod.rs:135-214 task/types.rs:39-58

用量账本区分 main-loop calls 与 subagent calls能按 model 汇总 input/output/cached/reasoning/cost并显式标记 incomplete后台仍在跑时不伪造精确账单。usage.rs:1-26 usage.rs:31-89 usage.rs:100-146

Catty 可借鉴: 将 subagent completion 从一段自由文本提升为结构化结果status、session id、turn/tool count、duration、tokens、worktree、archive handles父上下文仅保留短摘要细节通过 resume/read 获取。

7. Hooks 与 Skills

Hook 生命周期覆盖 session、turn stop/failure、pre/post tool、permission denied、prompt submit、notification、subagent 和 pre/post compactenvelope 包含 session/cwd/workspace/transcript/prompt idtool payload 限制为 128 KB。event.rs:3-49 event.rs:152-172 event.rs:201-240 event.rs:322-340

只有 PreToolUse 是阻塞决策hook 超时/崩溃采取 fail-open并把失败展示与记录而不是默默吞掉。event.rs:127-149 dispatcher.rs:15-35

Skills 采用渐进披露:启动时仅列名称/说明/路径,单条说明上限 400 bytes整个 listing 预算由 context window 推导;实际 body 调用时再载入。skill_discovery_tracker/listing.rs:1-20 skill_discovery_tracker/listing.rs:79-120

运行期还会根据 read/list/edit/apply_patch 实际触达路径发现或激活 skillsI/O 在资源锁外执行checked_dirs 回写避免重复 stat公告由 session 统一排队去重。skill_discovery.rs:27-45 skill_discovery.rs:109-155 skill_discovery.rs:159-218

Catty 可借鉴: hook 应进入统一 AgentEvent traceskill announcement 需要预算和去重,并在压缩后恢复“已宣布/已激活”状态,避免每次 compaction 后重复灌入。

8. 可观测性与离线评估

压缩 span 记录 trigger、使用比例、阈值、tokens before、attempts、degenerate/input-overflow/deterministic/transient rejection、TTFT、stream time、delta count、最大 inter-token gap、两段式是否使用、prefire hit/wait/stale 和 prefix release。compaction.rs:800-864 compaction.rs:1150-1202

compaction streaming timing 是 O(1) accumulator不保存每 token 时间戳;能直接算 TTFT、流持续时间、delta 数和最大间隔。session_compact.rs:256-310

更关键的是持久化 compaction_requests/{id}.json:包含精确输入 ConversationItem、工具定义、模型、用户额外上下文、摘要或错误和每次尝试细节注释明确说用于 offline prompt iteration。persistence.rs:360-368

这使“摘要质量”可以离线回放而不是靠线上主观反馈。Catty 应补一套固定 eval

  • continuation state recallactive task/subagent/todo/edited file 是否完整;
  • exact-detail recovery摘要缺失时能否从 archive 找回具体错误、命令、路径;
  • tool-call integrity压缩/取消/恢复后无 dangling/orphan/duplicate
  • instruction retention用户约束、AGENTS.md、skill 触发在多次压缩后仍有效;
  • latency/cost同步压缩等待、prefire 命中率、浪费 token、cached input 比例;
  • continuation success后继 agent 在不看原始 transcript 时能否完成下一步。

9. 原创实现与移植部分的边界

仓库的正式归属声明非常明确:从 OpenAI Codex 移植的是 xai-grok-tools/src/implementations/codex/ 下的 apply_patch、grep_files、list_dir、read_file从 sst/opencode 移植的是 implementations/opencode/ 下 bash、edit、glob、grep、read、skill、todowrite、write。THIRD_PARTY_NOTICES.md:1-12 THIRD_PARTY_NOTICES.md:14-42

因此本笔记讨论的 PromptContext、chat-state actor、分层 pruning、图片迟滞、两段式 prefire compaction、segment archive、ContinuationState 重建、session fork/resume、subagent coordinator、usage ledger、hook runtime、compaction telemetry/artifacts均不在声明的 Codex/OpenCode 移植目录中,应视为 Grok Build 自己的 runtime/context-engineering 实现。这里的“原创”只表示仓库归属证据显示不是那两组移植文件,不主张它在思想史上从未受其他 agent 产品启发。

需要特别避免误判Grok 可以配置 Codex prompt profile也能组合 OpenCode 工具集;这表示兼容/复用工具行为,不等于它的上下文 runtime 来自 Codex/OpenCode。prompt/context.rs:15-29 xai-grok-agent/src/config.rs:518-528

10. 给 Catty 的落地计划建议

P0先补正确性与评估底座

  1. 定义版本化 ContinuationState,压缩后确定性重注入 active jobs、subagents、todo/plan、edited paths、MCP、skills/AGENTS、tool-output handles。
  2. 在开始新轮、取消完成、恢复、压缩替换四个边界运行 conversation integrity repair并记录修复数与原因。
  3. 保存每次 compaction 的精确输入、输出、模型、token、重试与错误 artifact建立 2050 条真实长会话的离线 continuation eval。

P1增加可恢复的压缩档案

  1. 在现有 ToolOutputStore 上增加 conversation segment handles 和索引;摘要只带 manifest/恢复提示,不塞回全文。
  2. 对工具结果采用“近轮保护、旧结果头尾裁剪、极旧占位”的分层策略,并保证原始 trace 仍可重放。
  3. 给大用户输入使用同一套外置 handle不让首轮超长需求在进入 agent 前就丢失尾部。

P2在实验开关下优化延迟与缓存

  1. 实现带完整 canonical fingerprint 的后台两段式 compaction记录 hit/stale/wasted tokens/sync wait saved。
  2. 对会破坏 prompt cache 的历史改写采用 high-water/low-water 批处理,并比较 cached input tokens 的变化。
  3. 将 skill listing、tool catalog、MCP announcement 都纳入独立预算和持久化去重状态。

不建议直接照搬

  • 不应直接采用 bytes/4 作为唯一 token 估算器Catty 已有模型相关估算基础,应保留实际 tokenizer/usage 校正,只统一边界语义。
  • 不应未经 eval 就开启后台 pass1它可能增加费用且缓存失效会造成纯浪费。
  • 不应把 50%/85%/95%、40 KB、10 轮等常数照抄;这些是 Grok 的模型和服务约束,应由 Catty 的 trace 分布校准。
  • Hook 的 fail-open 是 Grok 明示的威胁模型选择不适合作为所有安全策略的默认值Catty 需要按 hook 类型区分“工作流扩展”和“安全门禁”。

最终判断

Catty 现有架构已经有 pre-turn compaction、step pruning、413 retry、SessionState reinjection、ToolOutputStore 和统一 AgentEvent方向是对的。Grok Build 显示下一阶段最有价值的不是再加一种总结 prompt而是把这些模块连成一个可恢复、可验证、可观测的上下文生命周期:压缩前分层减负,压缩时保存证据,压缩后重建现场,细节按需恢复,所有路径都能离线重放和量化。