【免费下载链接】firstmate
Talk to one agent. Ship with a crew.
Grok Build(xAI 的grokTUI)是 Firstmate 舰队中一个经过完整验证的 harness:它以 Claude-Code 兼容形态工作,被用作 crewmate/secondmate 运行时,也可作为 primary 挂载 turn-end 守卫。本文基于 .agents/skills/harness-adapters/references/harness/grok.md 整理出完整的操作事实表、启动/提交/信任门/隐私边界处理方案,并结合bin/下可执行所有者与tests/中的回归用例,解释每条规则背后的源码级依据。读完你可以按 Firstmate 的既有规范可靠地 spawn、发送、中断、恢复与验证 Grok 工作进程,并在 primary 模式下正确接线 turn-end 钩子。
一、Grok Build 的适配定位与验证基线
Grok Build 是 xAI 的grokTUI 程序,被 Firstmate 判定为Claude-Code 兼容(Claude-Code-compatible)。这意味着它的很多行为(项目设置加载、hook 机制、composer 交互)与 Claude 高度相似,但又有自己独立的差异点,因此需要单独一份 harness 参考记录。
适配器经过多轮实机验证,时间线如下:
- 2026-06-29:验证于
0.2.73 - 2026-07-03:slash 提交验证于
0.2.82 - 2026-07-13:effort 参数验证于
0.2.99 - 2026-07-19:退出行为验证于
0.2.103 - 2026-07-28:primary 集成验证于
0.2.112(同时保留对原生 pre-native0.2.73的验证) - 2026-09-24:文件夹信任、训练 opt-in、未发送 composer 投递验证于
1.0.0/1.0.41
启动形态(launch shape)固定为:
grok --always-approve "$(cat <brief>)"其中<brief>是任务简报文件路径,--always-approve提供无人值守的自主性。这个启动形态与 Firstmate 的bin/fm-spawn.sh对 worker 的启动约定保持一致。
该参考文件属于.agents/skills/harness-adapters/SKILL.md技能路由体系(SKILL.md),按其中给出的harness-adapter-routing-v1矩阵,grok被登记为独立 harness 条目,任何涉及 spawn、recovery、primary 集成、model/effort 选择的操作都会按需加载本参考与references/common/下的公共参考。
二、操作事实表(Operating Facts)
原文档用一张事实表固化了 Grok harness 的关键交互语义,这是任何自动化脚本(busy 判定、生命周期控制、发送)的输入依据:
| Fact | Value |
|---|---|
| Busy state | 使用"最后渲染尾部回退"(last rendered-tail fallback),并隔离到 Grok 专用语义:ASCII 形式的回合中提示Ctrl+c:cancel;空闲栏中无Shift+Tab:mode │ Ctrl+.:shortcuts;绝不使用对 locale 敏感的 braille 旋转器 |
| Exit | /exit打印Resume this session with: grok --resume <session-id>;回退方式是 1000ms 内连按两次Ctrl+Q;在 VS Code 系终端中Ctrl+D退出;Ctrl+C中断 |
| Interrupt | 单次Ctrl+C;Escape 只滚动 scrollback |
| Skill | /<skill>形式,例如/no-mistakes,具备端到端的用户技能发现、调用与真实no-mistakes axi run证据;popup 可能吞掉 Enter 并填充一个参数占位符,需要真实的第二次 Enter |
| Autonomy | --always-approve,footer 显示· always-approve,已实测无人值守可用;--permission-mode bypassPermissions是更强的等价项 |
| Marker | 0.2.73的 child/tool 进程带GROK_AGENT=1且无CLAUDECODE;而1.0.0的 hook 进程带GROK_HOOK_EVENT、GROK_HOOK_NAME、GROK_SESSION_ID、GROK_WORKSPACE_ROOT却没有GROK_AGENT,因此判定身份必须看进程祖先链(ancestry) |
| Resume | grok --resume <session-id>;grok -c/--continue恢复 cwd 最近会话;--fork-session创建新 id |
| Model | --model <model>;用grok models发现当前账号可用模型 |
| Effort | --reasoning-effort <low\|medium\|high>,别名--effort;0.2.99会拒绝xhigh和max,报错use one of: high, medium, low |
这里的关键点在于busy 判定与 marker 都是版本演进的:旧版(0.2.73)只在 child 进程注入GROK_AGENT,新版(1.0.0)的 hook 进程改注入GROK_HOOK_*系列变量。任何"只看单一环境变量"的守卫都会在升级后失效(详见第七节)。
Effort 的兜底与非法值处理由公共参考 references/common/model-and-effort.md 拥有:若请求的 effort 超出适配器接受集合,spawn 只在任务元数据里记录effort=而不下发该 flag,从而保住启动成功而不是传入已知非法值;max永远不允许通过 fallback 选择,只有显式的 per-task 或常驻 captain 偏好才允许。
三、身份标记契约:为什么 hook marker 与 child 快路径都要管
Grok 的可靠规则必须同时覆盖两类进程:hook 进程的 marker与child 进程的快路径。两者注入的环境变量不同(GROK_AGENTvsGROK_HOOK_EVENT/GROK_HOOK_NAME/GROK_SESSION_ID/GROK_WORKSPACE_ROOT),所以"marker 命名了 harness,但结构祖先才是证明谁拥有进程树"的原则在此尤为重要——一个 marker 只是普通环境状态,可能被子进程或多路复用器保留,而祖先链才能证明进程归属。
marker 契约由 docs/turnend-guard.md 的 "Harness integrations" 一节拥有。该文档记录了这样一个真实事故:grok 1.0.0的 hook 进程不再带GROK_AGENT,一个只按GROK_AGENT键控的守卫因此停止触发,导致 Claude-only 的 auto-arm 在 Grok 下同步运行。由于 Grok 没有 Claude 的asyncRewake,它会在前台等待 watcher 长达声明的 28800 秒超时,Grok 回合永远不结束。因此:
- 守卫必须同时接受
GROK_AGENT与GROK_HOOK_EVENT两个标记; - 不得把守卫扩大到
GROK_SESSION_ID——Grok 把它注入每个 child 进程,它可能存续到 Grok 启动的 Claude 会话里,静默禁用 Claude 自身的连续性。
四、技能调用与自主性
技能调用:使用/<skill>形式,例如/no-mistakes。验证证据链完整:技能发现(discovery)→ 调用(invocation)→ 真实的no-mistakes axi run输出证据。有一个交互陷阱:技能 popup 可能吞掉第一次 Enter 并填充一个参数占位符(如/no-mistakes的可选任务参数、/compact的 compaction 指令),此时并没有真正提交,需要补发第二次真实的 Enter。
自主性(autonomy):--always-approve是经过无人值守实测的授权方式,footer 会显示· always-approve;更强的等价项是--permission-mode bypassPermissions。两者可按部署要求选择,但都需要在 spawn 时作为具体 flag 传入(Firstmate 的bin/fm-spawn.sh只接受具体轴值,从不解析自然语言规则)。
五、提交与启动的三个真实陷阱
5.1 Slash 自动补全吞掉 Enter
斜杠自动补全可能把第一次 Enter 变成"选择 + 参数提示",并不构成提交。2026-07-03 的一次真实事故中,两个 Grok 0.2.82 的 Herdr worker 把/no-mistakes留在输入框里数分钟,而 send 却返回了成功——旧 Herdr 逻辑把任何 pane 增量都当成提交(包括 popup 关闭和占位符填充)。
修复后,Tmux 与 Herdr 的采集都经过 bin/fm-composer-lib.sh 的共享分类器,在每条"已证明内容行"上分类真实文本;边界由 docs/herdr-backend.md 拥有,回归覆盖在 tests/fm-backend-herdr.test.sh。
5.2 发送成功 ≠ 送达
2026-09-24 在 Grok 加入舰队后的首次派发中,一条指令落到了 Grok 1.0.41 的 composer 里而未发送,pane 显示Enter:send now,文本保持 pending。教训:对任何时间敏感的内容,必须 peeking pane 验证投递,而不是信任 send 的返回值——一个"静默未送达"的 hold 是最糟的消息丢失。这也呼应了公共参考 references/common/control-and-recovery.md 的原则:发送或按键返回成功不是提交的证据,必须要求工具特定的后置条件。
5.3 项目选择器与文件夹信任门
- "Run Grok Build in a project directory?" 选择器只在项目目录之外(home、Desktop、Downloads、
/tmp)出现。spawn 总是从隔离的 git 根启动,因此该选择器不会出现、无需按键;无法避免的非项目启动场景,可用~/.grok/config.toml中的[hints] project_picker_disabled = true抑制。项目选择器与文件夹信任门是两个独立对话框。 - 文件夹信任门:2026-09-24 的首次派发中,Grok 1.0.41 在 linked git worktree 里弹出了信任门。对话框打印的是 primary checkout 路径(linked worktree 的 git root 解析到主 checkout),因此文本读起来像是"隔离被破坏",而隔离实际完好。正确做法是:用
/proc/<pid>/cwd检查 worker 真实位置,绝不信对话框打印的路径。 - 用 bin/fm-send.sh 以按键路径 Enter 应答该门(
fm-send.sh <target> --key Enter)。fm-send.sh只携带 Escape、Enter、C-c 三种键,字面y没有合规投递途径。 - 信任决策持久化到
~/.grok/trusted_folders.toml,键是对话框打印的路径。这正是bin/fm-spawn.sh故意不写、称之为"高爆炸半径写入"的同一存储:在 linked worktree 里信任会落在 primary checkout 而非一次性副本,并对之后每次 Grok 运行持续生效,等于静默开启该 checkout 的 Grok 项目 hooks。应答信任门仍是合规途径(因为fm-send.sh没有其他办法清除它),这是对"避免写该存储"立场的知情例外,因此该文件出现新条目是预期行为,不是疏忽。
六、训练 Opt-in:必须保持关闭的隐私边界
2026-09-24 的首次派发中,Grok 1.0.41 弹出了 "Help improve Grok" 训练 opt-in。该 opt-in 会把 prompts、traces 和 metrics 保留用于训练。
- 它默认关闭,必须保持关闭;
- 理由:本舰队对外发布的客户隐私声明承诺客户数据和音频不用于训练。一边向第三方 provider 发送自己的 prompts/traces 用于训练,一边对外发布这样的声明,不是可以悄悄做的交易。
这是把 harness 适配落到合规事实的一节:适配一个外部 TUI 不只是按键与状态机,还包括对隐私边界的事前决策。
七、Composer 状态识别:TRUECOLOR 幽灵文本
Grok 的 composer 输入框带边框,新会话占位符Type a message...用暗色 24-bit TRUECOLOR渲染(而非主题无关的 SGR-2)。这让旧的"按 SGR-2 剥离幽灵文本"逻辑失效——Grok 的占位符走的是38;2;...真彩色序列。
Firstmate 的解法集中在 bin/fm-composer-lib.sh 的fm_composer_strip_ghost:它是全舰队唯一 ANSI 感知的"真实键入文本"提取器,丢弃 dim/faint 以及亮度低于FM_COMPOSER_GHOST_LUMA_MAX(默认 128)的 TRUECOLOR 文本。实测数据(Grok 0.2.93):
- 真实输入
38;2;224;222;244亮度约 225,被保留; - 边框与占位符
38;2;50;47;70至38;2;110;106;134,亮度约 51–110,被丢弃。
代价是这条真彩色规则假设舰队使用深色主题(SGR-2 才是主题无关的);提高FM_COMPOSER_GHOST_LUMA_MAX不是免费的——例如 muse 的⟩提示符亮度可能跨过阈值。回归覆盖在 tests/fm-composer-ghost.test.sh 与 tests/fm-backend-herdr.test.sh(后者包含 "grok dark-truecolor placeholder reads empty" 与 "grok bright real text reads pending" 两个用例)。
Tmux 侧还有一点:#{cursor_y}可能指向干净 composer 的底部边框,但共享分类器定位完整边框盒与所有内容行,所以边框光标与多行 composer 都不需要适配器偏移。
八、Worker Turn-End Hook:回合结束的可靠落盘
Grok 每个回合都会触发Stop事件。但项目级 hooks 需要~/.grok/trusted_folders.toml中的文件夹信任(spawn 不编辑该文件,不过应答上面那个信任门会写入它);全局~/.grok/hooks/则始终受信任。
因此 spawn 安装的是受守卫的全局fm-turn-end.json与fm-turn-end.sh:
- 它们只在 workspace 的
.fm-grok-turnend与~/.grok/hooks/fm-turn-end.d/下的注册表匹配时行动; - 然后通过始终设置的
GROK_WORKSPACE_ROOT(等于 worktree)触摸任务的state/<id>.turn-ended; - 整个机制留在 worktree 之外、无需信任授予、只写 Firstmate 自己的文件。
bin/fm-teardown.sh会在池化前移除 gitignored 的指针;secondmate 跳过该 hook,因为 idle 是健康状态且普通 stale-pane 检测不适用。
九、Primary 集成:Turn-End 守卫与 Claude 设置兼容
Primary 模式验证于 2026-07-28(0.2.112,同时保留对 pre-native 0.2.73 的验证)。.grok/hooks/fm-primary-turnend-guard.json调用 bin/fm-turnend-guard-grok.sh。
9.1 Native 能力选择与 legacy 回退
该脚本用精确的正在运行的 Stop payload选择路径(源码见 bin/fm-turnend-guard-grok.sh):
- payload 中出现
stopHookActive(或 snake_casestop_hook_active)且为布尔值 →native路径:直接把 payload 交给共享守卫bin/fm-turnend-guard.sh,并把退出码(0 或 2)原样传回该 Grok 进程(0.2.112具备的同进程继续能力); - 无该字段 →
legacy路径(0.2.73缺少 native 能力):当共享守卫返回 2("回合不能盲结束")时,编码一条 operational input,执行一次受守卫的grok --resume "$SESSION_ID" --cwd "$ROOT" --output-format plain -p "$PROMPT"作为回退; - payload 无效或不可读时两条路径都不启动;Camel case 优先于旧的 snake_case 拼写。
bin/fm-turnend-guard.sh存在且可执行、ROOT取自GROK_WORKSPACE_ROOT(回退CLAUDE_PROJECT_DIR)等前置条件都在脚本内逐条校验,任何一步不满足就静默退出。自适应与畸形输入行为由 docs/turnend-guard.md 拥有。
9.2 Claude 设置加载与标记守退
Grok 也加载 Claude 的项目设置(.claude/settings.json),所以被 Grok 覆盖的 Claude 事件条目在GROK_AGENT或GROK_HOOK_EVENT出现时必须stand down(守退),否则会产生第二条继续路径。两个 marker 都要检查,因为 Grok 不会给每种进程注入相同的变量。被守退的集合是:两个Stop条目、SessionStart条目、两个PreToolUseBash 条目;唯一刻意不守退的例外是bin/fm-subagent-pretool-check.sh——没有任何 Grok 注册覆盖 subagent-spawn 事件,见 docs/subagent-guard.md 的 "Known residual gap"。tests/fm-turnend-guard.test.sh固定了这个清单,任何一方都不能静默变化。
9.3 信任授予、守卫告警与 watcher 监督
- 项目级 hooks 需要启动时的
--trust;没有它,守卫让位,下一命令告警由 bin/fm-guard.sh 承担。 - Watcher 监督保持"跟踪的后台通知"形态,围绕 bin/fm-watch-arm.sh,不是 Pi 风格的扩展所有权。
- 在启用了
config/supervision-host的 home 里,session-start 块把这个后台调用渲染为bin/fm-supervision-host.sh park,以 Claude 的 print mode 作为无头引擎;宿主由 docs/supervision-host.md 拥有。 - PreToolUse 直接阻塞,但 hook 命令里的每个
$VAR都需要内联:-default默认值,否则 Grok 拒绝该 hook——这是写 Grok hook JSON 时必须遵守的硬性语法约束。
十、配套验证与回归证据
- 发送能力边界:
bin/fm-send.sh只携带 Escape、Enter、C-c(无字面y路径),对应公共参考 references/common/control-and-recovery.md 的"生命周期动作只能走控制面"原则。 - busy 语义:
bin/fm-busy-lib.sh是语义 busy 的唯一所有者;Grok 的Ctrl+c:cancel/Shift+Tab:mode │ Ctrl+.:shortcuts判定是记录在该工具参考中的经验事实。 - 测试覆盖:tests/fm-backend-herdr.test.sh 固定了 Grok 暗色 TRUECOLOR 占位符读作
empty、亮色真实输入读作pending的判定;tests/fm-arm-pretool-check.test.sh 固定了 Grok 形态的 PreToolUse 拒绝(toolInput.commandschema 拒绝、Grok 形态 stdout JSON);tests/fm-afk-launch.test.sh 覆盖了 grok 等 harness 在 away 模式下不启动 daemon;tests/fm-agy-harness.test.sh 断言harness=grok绝不借用 agy 的 esc token,反之亦然。
十一、结语:把 Grok 当"Claude 兼容但不是 Claude"来对待
Grok Build 的适配经验可以浓缩为三条原则:兼容不等于相同(Claude 设置会加载,但 marker、asyncRewake、信任门、composer 渲染各自不同);投递必须验证(send 成功不代表送达,pane 里的真实状态才是证据);身份看祖先(GROK_AGENT与GROK_HOOK_EVENT因版本而异,结构祖先链才是进程归属的证明)。围绕这些事实,.agents/skills/harness-adapters/references/harness/grok.md 与bin/、tests/、docs/中的所有者共同构成一个可复制、可回归、可升级验证的 harness 适配闭环。
【免费下载链接】firstmate
Talk to one agent. Ship with a crew.
相关推荐
Wazuh 5.x 引擎迁移指南:从 XML 解码器到 YAML 解码器树的架构变革
Wazuh 5.x 引擎迁移指南:从 XML 解码器到 YAML 解码器树的架构变革 本文基于 Wazuh 仓库 docs/guide/migration/en
@ai-sdk/harness-grok-build 演进全解析:AI SDK 中基于 ACP 的 Grok Build Harness 适配器
@ai sdk/harness grok build 演进全解析:AI SDK 中基于 ACP 的 Grok Build Harness 适配器 本篇文章以仓库
人工智能AI 应用AI Agent工具调用MCP ClientsDeepSeek Harness 回合尾部操作栏修复:以 `turn/end` 完成事实为唯一挂载依据
DeepSeek Harness 回合尾部操作栏修复:以 turn/end 完成事实为唯一挂载依据 导读 本文以仓库中已实施的 Agent Note《Turn
人工智能AI AgentAgent 框架DeepSeek
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考