# Subagents 与 personas · 并行的隔离子任务

> grok 能派生并行的 subagent 各自干活。这一章看它的解析（内置 general-purpose/explore/plan + 角色 + persona 的优先级）、能力模式如何真的裁掉工具、fork 上下文怎么塑形，以及协调器怎么在独立线程上并行跑、后台轮询。

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

# Subagents 与 personas · 并行的隔离子任务

接下来看并行扩展。grok 能派生 **subagent**——独立上下文、可并行的子会话，需要时还能放进[隔离 worktree](https://daiw.org/manual/grok-build/fast-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`)，和[后台命令](https://daiw.org/manual/grok-build/shell-and-pty)一套。根会话还能用 `send_subagent_message` 给自己名下的 subagent 插话或排队追加任务。

防失控靠两道上限：嵌套深度默认 1(只有主会话能派生，可用 `[subagents] max_depth` 调大)，每个会话最多 32 个并发 subagent，超出默认排队。

```mermaid
flowchart LR
  P[主会话:spawn_subagent] --> C[SubagentCoordinator]
  C -->|spawn 独立会话线程| S1[subagent 1]
  C -->|spawn| S2["subagent 2(可选 worktree 隔离)"]
  S1 -->|oneshot 结果| C
  S2 -->|后台?轮询 get_task_output| C
```

## 和《从 LLM 到 Coding Agent》对照

对照 [subagents](https://daiw.org/manual/llm-to-agent/subagents)：最小实现里 subagent 是「再开一个上下文窗口跑子任务」。grok 的增量是把它做成完整的产品能力：内置角色 + 自定义 role/persona 的分层解析、**能力模式硬裁工具**、fork 上下文塑形、独立线程并行 + 后台轮询、可选的 worktree 隔离、深度与并发上限。这是「并行 agent」从概念到工程的全部落地。下一章看 Part 4 的最后一块：自定义模型。

---

上一篇：[插件市场](https://daiw.org/manual/grok-build/plugins-marketplace) · 下一篇：[自定义模型](https://daiw.org/manual/grok-build/custom-models)
