Subagents 与 personas · 并行的隔离子任务
grok 能派生并行的 subagent 各自干活。这一章看它的解析(内置 general-purpose/explore/plan + 角色 + persona 的优先级)、能力模式如何真的裁掉工具、fork 上下文怎么塑形,以及协调器怎么在独立线程上并行跑、后台轮询。
Subagents 与 personas · 并行的隔离子任务
接下来看并行扩展。grok 能派生 subagent——独立上下文、可并行的子会话,需要时还能放进隔离 worktree 里干活(默认 isolation 是 none,和父会话共享工作区;显式要求或角色默认才开 worktree)。解析逻辑在纯 crate xai-grok-subagent-resolution。
内置三种 + 角色 + persona
内置 subagent 有 general-purpose、explore、plan,提示词是 MiniJinja 模板(${{ tools.by_kind.read }} 那套),其中 explore/plan 带 === READ-ONLY MODE ===,而且不只靠提示词:它们拿到的是专用工具集(只有读文件、列目录、grep,plan 再加 todo),没有 shell,也没有编辑工具。除此之外你还能定义:
- 角色(role):
.grok/roles/*.toml——description、default_capability_mode、model、reasoning_effort、prompt_file、default_isolation。 - persona:
.grok/personas/*.toml——instructions(或instructions_file)、inputs/outputs,也能带model、default_isolation等默认值。 - 另外还认 Claude 风格的 agent 定义:
.grok/agents/、.claude/agents/下的*.md(frontmatter + 提示词)。
派生一个 subagent 时,模型、推理强度的优先级是一条清晰的链:显式 spawn 覆盖 > 角色默认 > persona 默认 > 继承父会话;隔离方式也走同样的前三级,都没设就是 none。能力模式例外:它取显式请求和角色默认的交集(更严者胜),再与 agent 定义自己的能力模式交一次。persona 指令读文件出错是致命的(中止派生),角色 prompt 读不到只是软降级(警告后继续)——按「这个字段错了要不要命」区别对待。
能力模式真的裁掉工具
SubagentCapabilityMode(ReadOnly/ReadWrite/Execute/All)不是摆设:filter_tool_config 会按 ToolKind 把工具集裁一遍——一个 read-only 的 subagent,注册表里根本没有编辑工具,不是「有但不让用」,是压根给不到。这比「靠 prompt 叮嘱它别改」硬得多。两个细节:没有 kind 的工具(MCP、自定义工具)不受裁剪;能力模式也不是模型可传的 spawn 参数,只由角色、agent 定义等 harness 侧配置决定。
fork 上下文的塑形
子会话的初始上下文分三种(shell 侧的 InitialContextSource):
- New:全新;
- Forked:从父会话 fork——只供 harness 内部使用,模型调工具派生时拿不到。条件允许(估算 token 不超过子会话窗口的 80% 等)时直接逐字镜像父对话;否则由
normalize_forked_context把它塑成[System 占位, User(<background_context>)],最近 3 轮保留(工具参数和结果会截短)、更早的只留摘要,还strip_fork_noise剥掉 system-reminder、git_status 等噪声; - Resumed:恢复之前的 subagent(
validate_resume_identity校验类型 + persona 匹配)。
协调器:真并行
SubagentCoordinator 是 xai-grok-tools 里一个泛型的单写者 actor,各宿主通过 ChannelBackend 驱动它,shell 只提供具体的 ChildRunner。每个 subagent spawn 到自己的会话线程上(独立 OS 线程 + 自己的 runtime,真并行),结果经 oneshot 通道回来。派生默认在后台(run_in_background = true,模型看到的工具叫 spawn_subagent、参数叫 background)——派了就返回,不阻塞你继续;后台 subagent 由 get_task_output 轮询、kill_task 取消(对模型分别叫 get_command_or_subagent_output / kill_command_or_subagent),和后台命令一套。根会话还能用 send_subagent_message 给自己名下的 subagent 插话或排队追加任务。
防失控靠两道上限:嵌套深度默认 1(只有主会话能派生,可用 [subagents] max_depth 调大),每个会话最多 32 个并发 subagent,超出默认排队。
和《从 LLM 到 Coding Agent》对照
对照 subagents:最小实现里 subagent 是「再开一个上下文窗口跑子任务」。grok 的增量是把它做成完整的产品能力:内置角色 + 自定义 role/persona 的分层解析、能力模式硬裁工具、fork 上下文塑形、独立线程并行 + 后台轮询、可选的 worktree 隔离、深度与并发上限。这是「并行 agent」从概念到工程的全部落地。下一章看 Part 4 的最后一块:自定义模型。