---
title: "harness - 子代理定义与任务委派"
---

主代理（main）在处理复杂任务时，可以把子任务委派给"专项子代理"执行。子代理拥有独立的上下文与工具权限，互不污染。

### 1、内置子代理

`solon-ai-harness` 内置了几个常用子代理（开箱即用），定义文件位于 `META-INF/solon/ai/harness/` 目录下：

| 名称 | 说明 | 工具集 |
|------|------|--------|
| `general` | 通用全能专家。其它子代理不匹配时优先选它 | `*`（全部公有工具） |
| `explore` | 全域信息探索专家（本地文件 + 全网检索，无写权限） | `list, read, grep, glob, skill, webfetch, websearch, codesearch` |
| `plan` | 规划与计划专家（制定逻辑路径与执行步骤，无写权限） | `list, read, grep, glob, skill, webfetch, websearch, codesearch` |
| `bash` | Bash 命令执行专家（git、命令行操作，无写权限） | `list, read, bash` |
| `git-summary` | Git 提交摘要生成专家（隐藏代理，内部使用） | 无工具（hidden） |

### 2、子代理定义文件（Markdown）

子代理通过 Markdown 文件定义：YAML Front Matter 描述元数据，正文即系统提示词。文件放在 `{harnessHome}/agents/` 或挂载的 `AGENTS` 目录下。

```markdown
---
name: "code_reviewer"
description: "代码评审专家，定位风险并给出改进建议"
tools: ["read", "grep", "glob"]
model: "deepseek-v4-flash"
---

你是一位严谨的代码评审专家。

输出规范：
- 按"风险等级"分组列出问题。
- 每条问题须标注文件路径与行号。
```

元数据字段（Front Matter）：

| 字段 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `name` | `String` | / | 代理唯一标识 |
| `description` | `String` | / | 职能描述（供主代理识别调度） |
| `tools` | `List<String>` | / | 允许的工具（见《配置参考》工具权限表） |
| `disallowedTools` | `List<String>` | / | 禁用的工具 |
| `model` | `String` | / | 指定模型（不指定则用会话选中或主模型） |
| `skills` | `List<String>` | / | 绑定的技能标识 |
| `mcpServers` | `List<String>` | / | 绑定的 MCP 服务 |
| `memory` | `String` | / | 记忆作用域（`user` / `project` / `local`） |
| `permissionMode` | `String` | / | 权限模式（如 `plan`） |
| `enabled` | `boolean` | `true` | 是否启用 |
| `hidden` | `boolean` | `false` | 是否隐藏（不出现在可用代理列表） |
| `primary` | `boolean` | `false` | 是否为主代理 |
| `background` | `boolean` | `false` | 是否为后台任务代理 |
| `isolation` | `String` | / | 隔离配置（如 `worktree`） |
| `teamName` | `String` | / | 所属团队名称（用于团队成员管理） |
| `hooks` | `Object` | / | 钩子配置（保留字段，暂不解析） |

> 注：`tools` 工具名大小写均可解析，`ls` 与 `list` 等价，`task` 与 `subagent` 等价。

### 3、用代码动态定义子代理

无文件时，也可用代码构建子代理（详见 [《harness - 进一步扩展定制参考》](/article/1439)）：

```java
AgentDefinition definition = new AgentDefinition();
definition.setSystemPrompt("你是一位代码评审专家...");
definition.getMetadata().setName("code_reviewer");
definition.getMetadata().setDescription("代码评审专家");
definition.getMetadata().addTools(ToolName.TOOL_READ, ToolName.TOOL_GREP);

ReActAgent subagent = engine.createSubagent(definition).build();
subagent.prompt("评审 src 目录").session(session).call();
```

### 4、任务委派（task / multitask）

当主代理拥有 `task` 工具权限时，模型可自主把任务委派给子代理。马具内部由 `TaskTalent` 暴露两个能力：

* `task`：委派单一任务给某个子代理（串行）。
* `multitask`：并行执行多个互不依赖的子任务（无资源竞争时优先用它以省时）。

每个子任务都是无状态的（上下文隔离），因此委派时必须在 prompt 中提供完成任务所需的全部背景。委派结果会以结构化片段（含 `agent_name`、`result_status`、`result_content`）回传给主代理。

> 注：`task` 工具在 `AgentFactory.toolAddDo` 中同时接受 `task` 和 `subagent` 两个名称。`todoread` 和 `todowrite` 则是 `todo` 的别名。

### 5、动态生成子代理（generate）

当主代理拥有 `generate` 工具权限（且 `subagentEnabled=true`）时，模型可在运行中"即时创建"一个垂直领域的专家子代理。若 `saveToFile=true`，定义会持久化到 `{workspace}/{harnessHome}/agents/{name}.md`，后续可复用。

生成的子代理基于内置 `general` 代理定义复制修改，继承其全部公有工具权限。生成后的代理会注册到 `AgentManager`，可通过 `getAgent(name)` 获取。

### 6、AgentManager 管理接口

```java
// 获取所有可用子代理（不含隐藏的）
Collection<AgentDefinition> agents = engine.getAgentManager().getAgents();

// 按名称获取子代理（不存在则抛出异常）
AgentDefinition def = engine.getAgentManager().getAgent("bash");

// 检查是否存在
boolean exists = engine.getAgentManager().hasAgent("explore");

// 动态添加（覆盖同名）
engine.getAgentManager().addAgent(customDefinition);

// 动态添加（仅不存在时）
engine.getAgentManager().addAgentIfAbsent(customDefinition);

// 清除所有自定义代理（保留内置）
engine.getAgentManager().clearCustomAgents();
```