# Snow CLI 使用文档——子代理设置

欢迎使用 Snow CLI！在终端中进行 Agentic 编程。

## 更新说明（#194）

| 能力                   | 说明                                                                                              |
| ---------------------- | ------------------------------------------------------------------------------------------------- |
| 项目级 Markdown 子代理 | 扫描 `.snow/agents/**/*.md`（及可选 `~/.snow/agents/**/*.md`），无需改 `sub-agents.json` 即可调度 |
| 合并优先级             | `project .snow/agents` > `global ~/.snow/agents` > `~/.snow/sub-agents.json` > builtin            |
| `ROLE-*.md`            | **不会**注册新的 `agentId`（仍是角色 overlay）                                                    |
| 未知工具 warn          | frontmatter `tools` 中未注册名会 **warn**；声明不静默丢弃，运行时仍按 allowlist 过滤              |
| `beforeSubAgentStart`  | 启动前可通过 Hook 注入/改写 prompt（详见 [Hooks 配置](./07.Hooks配置.md)）                        |

## 什么是子代理

子代理是 Snow CLI 中主流程的分支，专门用于处理特定的单一需求以节约主流程的上下文占用

## 系统自带三个子代理

- Explore Agent——探索代理，用于为主流程搜索代码功能，专注查找代码位置

- Plan Agent——计划代理，用于为主流程制定全面的编码计划与指导

- General Purpose Agent——通用代理，用于为主流程提供通用的编码功能，可用于完成单一但是文件量较大的需求，例如（国际化）

## 子代理的工作流程

```mermaid
graph TB
Start([用户发起任务]) --> MainProcess[主流程 Main Agent]

MainProcess --> Check{是否需要<br/>使用子代理?}

Check -->|否| DirectHandle[主流程直接处理]
DirectHandle --> End([返回结果])

Check -->|是| SelectAgent{选择子代理类型}

SelectAgent -->|代码探索| ExploreAgent[Explore Agent<br/>探索代理]
SelectAgent -->|制定计划| PlanAgent[Plan Agent<br/>计划代理]
SelectAgent -->|通用编码| GeneralAgent[General Purpose Agent<br/>通用代理]

ExploreAgent --> SendTask[主流程发送任务提示词]
PlanAgent --> SendTask
GeneralAgent --> SendTask

SendTask --> SubProcess[子代理接收任务]

SubProcess --> Isolate[独立上下文环境<br/>与主流程隔离]

Isolate --> SpecializedWork{专业方向处理}

SpecializedWork -->|探索代理| SearchCode[搜索代码位置<br/>分析代码结构]
SpecializedWork -->|计划代理| MakePlan[制定编码计划<br/>提供指导方案]
SpecializedWork -->|通用代理| GeneralWork[执行通用编码<br/>处理批量文件]

SearchCode --> Complete[处理完成]
MakePlan --> Complete
GeneralWork --> Complete

Complete --> Return[将结果发送回主流程]

Return --> MainReceive[主流程接收结果]

MainReceive --> End

style MainProcess fill:#e1f5ff
style ExploreAgent fill:#fff4e1
style PlanAgent fill:#ffe1f5
style GeneralAgent fill:#e1ffe1
style Isolate fill:#ffe1e1
style SubProcess fill:#f0f0f0
style Return fill:#e1ffe1
```

### 流程说明

1. **主流程评估**: 主流程接收到用户任务后，首先评估是否需要使用子代理
2. **子代理选择**: 根据任务类型选择合适的子代理：

   - **Explore Agent**: 深度代码探索（5+文件）、复杂依赖追踪
   - **Plan Agent**: 复杂功能拆解、重大重构规划
   - **General Purpose Agent**: 批量修改（5+文件）、系统性重构

3. **任务派发**: 主流程向子代理发送包含完整上下文的任务提示词

4. **独立处理**: 子代理在独立的上下文环境中处理任务，与主流程完全隔离

5. **专业处理**: 每个子代理根据自己的专业方向进行针对性处理

6. **结果返回**: 处理完成后，子代理将结果发送回主流程

7. **主流程继续**: 主流程接收结果并继续后续工作

### 关键特点

- **上下文隔离**: 子代理拥有独立的上下文，不会影响主流程的对话历史
- **单向通信**: 主流程 → 发送任务 → 子代理 → 返回结果 → 主流程
- **专业分工**: 每个子代理专注于特定领域，提高处理效率
- **资源节约**: 避免主流程上下文被大量探索或计划信息占用

## 项目级 Markdown 子代理

除了配置界面与 `~/.snow/sub-agents.json`，还可以把子代理定义成 Markdown 文件，提交到仓库后即可被发现与调度（无需改 `sub-agents.json`）。

### 扫描路径

- 项目：`.snow/agents/**/*.md`
- 全局（可选）：`~/.snow/agents/**/*.md`

### 合并优先级（高覆盖低）

```
project .snow/agents > global ~/.snow/agents > ~/.snow/sub-agents.json > builtin
```

### Markdown 格式

```markdown
---
id: trellis-implement
name: trellis-implement
description: Implement features from Trellis task
tools:
  - filesystem-read
  - filesystem-edit
  - terminal-execute
  - ace-search
---

You implement the active Trellis task using project specs.
```

字段说明：

- `id`：可选；缺省用文件名（不含扩展名）
- `name`：可选；缺省用 `id`
- `description`：描述
- `tools`：工具列表（数组或单字符串）
- `role`：可选 frontmatter；缺省用正文 body 作为 role

注意：

- 无效 md 会跳过并打 warn，不崩溃
- 项目根目录 / `~/.snow` 下的 `ROLE-*.md` **不会**注册为新的 `agentId`（仍是角色 overlay）
- 发现后即可用 `#agentId` / 选择器调度
- frontmatter `tools` 中未注册的工具名会 **warn**（不静默丢弃声明；执行时仍按 allowlist 过滤）

## 子代理配置管理

### 新增子代理

通过配置界面可以创建自定义子代理，满足特定的业务需求。

#### 操作步骤

1. **进入配置界面**

   - 在主菜单中选择"子代理配置"选项
   - 选择"新增子代理"

2. **基础信息配置**

   按照界面提示依次填写以下字段：

   - **代理名称** (必填)

     - 输入子代理的名称
     - 建议使用描述性名称，如 "代码审查代理"、"测试代理" 等
     - 按 Enter 确认进入下一字段

   - **描述** (必填)

     - 输入子代理的功能描述
     - 详细说明该子代理的用途和应用场景
     - 按 Enter 确认进入下一字段

   - **角色定义** (必填)
     - 定义子代理的角色和行为规范
     - 这是子代理的核心系统提示词，决定其工作方式
     - 示例：
       ```
       你是一个专业的代码审查助手。
       你的职责是：
       1. 检查代码质量和规范性
       2. 发现潜在的bug和安全问题
       3. 提供改进建议和最佳实践
       ```
     - 按 Enter 确认进入下一字段

3. **高级配置选项**

   **重要提醒**: 子代理不再单独选择「系统提示词」和「自定义请求头」。子代理的系统提示词与请求头会跟随所选的**配置文件**（Profile），配置文件本身已经包含这两项配置。

   - **配置文件** (可选)

     - 为子代理指定专属的 API 配置文件
     - 用途：让子代理使用不同的 API 端点、不同的 AI 模型，以及该配置文件内定义的系统提示词与请求头
     - 操作：
       - 使用 ↑/↓ 方向键浏览可用的配置文件
       - 按 Space 键选中/取消选中
       - 按 ←/→ 方向键在配置选项间快速切换
       - 标记说明：`❯` 表示光标位置，`[✓]` 表示已选中
     - 应用场景：
       - 让子代理使用更强大的模型
       - 让子代理使用不同的 API 提供商
       - 为不同子代理分配不同的计费账户
       - 为不同子代理绑定不同的系统提示词/请求头

   选择子代理可以使用的工具：

   - 使用 ↑/↓ 方向键在工具类别间导航
   - 使用 ←/→ 方向键在工具类别间切换
   - 按 Space 键选中/取消选中工具
   - 工具类别包括：
     - 文件系统工具 (filesystem-read, filesystem-create, filesystem-edit 等)
     - ACE 代码搜索工具（`ace-search`，通过 action 选择 find_definition / find_references / semantic_search / file_outline / text_search）
     - 代码库工具 (codebase-search)
     - 终端工具 (terminal-execute)
     - TODO 管理工具
     - Web 搜索工具
     - MCP 工具（如已配置）

   **建议**: 只授予子代理完成其任务所需的最小权限集

4. **保存配置**

   - 按 Ctrl+S 保存配置
   - 系统会自动验证配置的完整性
   - 保存成功后返回主菜单

#### 配置继承说明

新建子代理时，如果未指定 **配置文件**（Profile），子代理将自动跟随当前主流程激活的配置文件。这意味着：

- 子代理将使用与主流程相同的 API 配置与模型
- 子代理将使用该配置文件内定义的系统提示词与请求头（再叠加自身的角色定义）

### 编辑子代理

可以编辑现有的子代理配置，包括系统内置的三个代理。

#### 操作步骤

1. **进入编辑界面**

   - 在主菜单中选择"子代理配置"选项
   - 选择要编辑的子代理

2. **编辑限制说明**

   **系统内置代理**（Explore Agent、Plan Agent、General Purpose Agent）：

   - 名称、描述、角色定义为只读，不可修改
   - 界面会显示"(系统内置 - 不可修改)"提示
   - 可以修改：工具权限、配置文件

   **自定义代理**：

   - 所有字段均可修改

3. **修改配置**

   导航和操作方式与新增代理相同：

   - 使用 ↑/↓ 方向键在字段间导航
   - 使用 ←/→ 方向键在配置选项间切换
   - 按 Space 键选中/取消选中
   - 在文本字段中直接输入修改内容

4. **保存更改**

   - 按 Ctrl+S 保存更改
   - 系统会验证修改后的配置
   - 保存成功后返回主菜单

#### 编辑配置继承说明

编辑已有子代理时：

- 如果子代理已有自定义配置，界面会显示并加载这些配置
- 如果子代理没有自定义配置：
  - 编辑系统内置代理的副本时，会自动继承当前主流程的配置作为默认值
  - 编辑已有的自定义代理时，不会自动填充配置（保持未选中状态）

### 配置最佳实践

1. **角色定义要明确**

   - 清楚描述子代理的职责范围
   - 提供具体的工作步骤或检查清单
   - 说明输出格式和质量标准

2. **合理分配工具权限**

   - 遵循最小权限原则
   - 只读任务不授予写入工具
   - 探索任务不授予执行工具

3. **善用配置隔离**

   - 为不同类型的任务配置不同的子代理
   - 使用不同的配置文件（Profile）控制成本与模型选择
   - 使用不同的配置文件（Profile）绑定不同的系统提示词与请求头

4. **测试配置效果**
   - 创建后先进行小规模测试
   - 观察子代理的行为是否符合预期
   - 根据实际效果调整角色定义和工具权限

### 键盘快捷键

- **↑/↓**: 在选项间导航或滚动列表
- **←/→**: 在字段间切换（配置选项、工具类别）
- **Space**: 选中/取消选中（工具、配置选项）
- **Enter**: 确认输入并移至下一字段
- **Ctrl+S**: 保存配置
- **Ctrl+C** 或 **ESC**: 取消并返回

## 快速选择子代理

除了使用 `/agent-` 指令打开子代理选择面板外，您还可以直接在输入框中使用 `#` 符号快速触发子代理选择器：

### 使用方法

1. **触发选择器**: 在输入框中输入 `#`，会自动弹出子代理选择面板
2. **搜索过滤**: 输入 `#关键字` 可以根据子代理的 ID、名称或描述进行过滤
3. **选择子代理**: 使用方向键选择子代理，按 Enter 确认，系统会自动插入 `#子代理ID ` 到输入框

### 示例

```
#explore     → 选择 explore 子代理
#plan        → 选择 plan 子代理
#general     → 选择 general 子代理
```

### 注意事项

- `#` 符号前面不能有 `@` 符号（如 `@#` 或 `@@#` 不会触发子代理选择器，而是触发文件选择器）
- 输入 `#` 后如果继续输入空格或换行，选择器会自动关闭
- 按 ESC 键可以关闭子代理选择面板

## 向运行中的子代理发送消息

当子代理正在运行时，您可以使用 `>>` 指令向特定的运行中子代理发送消息，实现与主流程的实时交互。

### 使用方法

1. **触发选择器**: 在输入框开头输入 `>>`（可以带前导空格），会弹出当前运行中的子代理列表
2. **选择子代理**:
   - 使用 `↑/↓` 方向键选择子代理
   - 使用 `Space` 键选中/取消选中子代理（支持多选）
   - 如果没有显式选择任何子代理，当前高亮项会在按 Enter 时自动被选中
3. **发送消息**: 按 `Enter` 确认选择，输入消息内容后发送

### 视觉标签说明

选择子代理后，输入框中会显示视觉标签：

```
[»Explore Agent#abcd: 调查项目架构和结构...] 你好，请继续分析
```

- `»` 符号（U+00BB）：用于避免重新触发选择器
- `Explore Agent`：子代理名称
- `#abcd`：实例 ID 后 4 位（保证唯一性）
- `调查项目架构和结构...`：任务提示词的简短摘要

### 消息路由机制

实际发送的消息中会包含特殊标记：

```
# SubAgentTarget:instanceId:agentName
消息内容
```

系统会根据这些标记将消息路由到对应的子代理。

### 使用场景

- **追问细节**：子代理正在探索代码时，您想询问某个具体函数的实现
- **纠正方向**：发现子代理理解有误，及时发送纠正信息
- **补充上下文**：突然想起某些重要信息，需要告知正在工作的子代理
- **批量指令**：同时向多个运行中的子代理发送相同指令

### 注意事项

- `>>` 必须出现在输入框**开头**（忽略前导空格）才能触发
- 如果子代理已完成或退出，它将不会出现在选择列表中
- 按 `ESC` 键可以关闭选择面板
- 删除 `>>` 后，选择面板会自动关闭

### 常见问题

**Q: 为什么我输入 `#` 没有弹出选择器？**

A: 请检查以下几点：

- 确认 `#` 前面没有 `@` 符号（如 `@#` 会触发文件选择器而非子代理选择器）
- 确认 `#` 后面没有输入空格或换行
- 检查是否已配置子代理

**Q: 子代理可以使用主流程的上下文吗？**

A: 不可以。子代理与主流程的上下文完全隔离。主流程需要在调用子代理时，在提示词中提供所有必要的上下文信息。

**Q: 如何让子代理使用更强大的模型？**

A: 在配置文件选项中，为子代理指定一个使用更强大模型的 API 配置文件即可。
**Q: 配置文件里的系统提示词和子代理的角色定义有什么区别？**

A: 角色定义是子代理自身的行为规范（配置子代理时填写/编辑），用于描述这个子代理要怎么工作。配置文件（Profile）中的系统提示词是该 Profile 的全局约束，会同时影响主流程与选择了该 Profile 的子代理。子代理执行时会以所选 Profile 的系统提示词为基础，再叠加子代理的角色定义。

**Q: 编辑系统内置代理会影响原始配置吗？**
A: 不会。系统内置代理的核心定义（名称、描述、角色）是只读的。您只能修改其工具权限和配置文件（Profile），这些修改只影响您的使用，不会改变系统预设。

**Q: 如何删除自定义子代理？**

A: 在子代理列表中选择要删除的子代理，按 Delete 键或选择删除选项即可。系统内置代理无法删除。
