> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 子 Agent

子 Agent 是主会话可以临时委派出去的专门角色。Qoder Agent SDK Python 版支持两类子 Agent：

* **内置子 Agent**：由 qodercli 提供，例如通用搜索、代码探索、规划等。
* **自定义子 Agent**：由 SDK 使用者通过 `QoderAgentOptions.agents` 定义，适合业务审查、测试执行、安全分析等专门角色。

本文重点讲如何在 Python SDK 中使用内置子 Agent，以及如何按需自定义子 Agent。完整类型定义见 [Agents Reference](/zh/cli/sdk/python/references#agents-reference)。

除非特别说明，本文里的“Agent”都指可以被主会话委派的子 Agent；`QoderAgentOptions.agent` 是把某个 Agent 定义作为主会话角色运行的特殊用法。

<div id="内置子-agent" />

<div id="内置子agent" />

## 内置子 Agent

使用内置子 Agent 时，你不需要自己写子 Agent 定义，只需要知道它的名称，并在 SDK 中引用它。

当前 qodercli 常见内置子 Agent：

| 名称                | 用途                                  |
| ----------------- | ----------------------------------- |
| `general-purpose` | 通用子 Agent，适合搜索代码、研究复杂问题和执行多步骤任务     |
| `Explore`         | 只读代码探索子 Agent，适合快速查找文件、搜索关键字、理解代码结构 |
| `Plan`            | 只读规划子 Agent，适合设计实现方案、识别关键文件和分析架构取舍  |

内置子 Agent 列表会随 qodercli 版本和当前配置变化。交互式 CLI 中可以输入 `/agents` 查看当前发现的子 Agent；命令行也可以运行：

```bash theme={null}
qodercli agents list
```

SDK 会话初始化后，可以用 `QoderSDKClient.supported_agents()` 读取当前会话实际可用的子 Agent：

```python theme={null}
from qoder_agent_sdk import QoderSDKClient, QoderAgentOptions


client = QoderSDKClient(options=QoderAgentOptions())
await client.connect("List available agents.")
agents = client.supported_agents()
await client.disconnect()
```

`supported_agents()` 返回的列表会包含 SDK 通过 `agents` 注册的子 Agent，也可能包含当前 CLI 已发现的内置、用户、项目和插件子 Agent。返回结构见 [AgentInfo](/zh/cli/sdk/python/references#agentinfo)。

<div id="使用内置子-agent" />

<div id="使用内置子agent" />

## 使用内置子 Agent

<div id="作为主会话角色运行" />

### 作为主会话角色运行

如果希望整个会话都按某个内置子 Agent 的角色运行，可以直接把内置子 Agent 名称传给 `QoderAgentOptions.agent`，不需要在 `agents` 里重复定义。

```python theme={null}
from qoder_agent_sdk import QoderAgentOptions, query


options = QoderAgentOptions(agent="general-purpose")

async for message in query(
    prompt="Summarize this project architecture and identify the most important modules.",
    options=options,
):
    print(message)
```

`agent` 可以引用 SDK 注册的子 Agent，也可以引用当前 CLI 已发现的内置 / 用户 / 项目 / 插件子 Agent。

<div id="作为子-agent-委派" />

<div id="作为子agent委派" />

### 作为子 Agent 委派

子 Agent 委派通过内置 `Agent` 工具完成。主会话的可用工具集中必须包含 `Agent`，模型才有入口发起委派；在 SDK 里常见做法是预授权这条工具调用路径，然后在 prompt 里点名。

```python theme={null}
options = QoderAgentOptions(
    allowed_tools=["Agent"],
)

async for message in query(
    prompt="Use the Explore agent to find where authentication is implemented.",
    options=options,
):
    print(message)
```

`allowed_tools=["Agent"]` 表示放行 / 预授权这类工具调用；如果你同时使用 `tools` 收窄主会话可用工具白名单，也要把 `Agent` 放进 `tools`。不要把 `Agent` 放进 `disallowed_tools`。

子 Agent 名称需要和当前发现结果一致，包括大小写。例如当前内置名称里有 `Explore`、`Plan`、`general-purpose`。不确定时先调用 `client.supported_agents()`。

<div id="自定义子-agent" />

<div id="自定义子agent" />

## 自定义子 Agent

当内置子 Agent 不够贴合你的业务或项目约束时，可以通过 `QoderAgentOptions.agents` 自定义子 Agent。例如：

* 只读代码审查子 Agent：只能读文件和搜索，不能改代码。
* 测试执行子 Agent：能运行测试命令并分析失败原因。
* 安全审查子 Agent：只关注认证、授权、注入、敏感信息泄露等风险。
* 业务支持子 Agent：只能调用指定 MCP 工具，例如订单查询、工单检索、内部知识库搜索。

自定义子 Agent 通常分三步：

1. 在 `agents` 中定义子 Agent 名称、用途描述和系统提示词。
2. 用 `tools` 或 `disallowedTools` 收口它能使用的工具。
3. 让主会话通过 `Agent` 工具委派给它，或用 `agent` 让它直接驱动主会话。

> **必须包含 `Agent` 工具**：自定义子 Agent 需要主会话通过内置 `Agent` 工具发起委派，因此 `allowed_tools` 中必须包含 `Agent` 工具。

<div id="使用-agents-自定义子-agent" />

<div id="使用agents自定义子agent" />

## 使用 agents 自定义子 Agent

最小示例：注册一个只读代码审查子 Agent。

```python theme={null}
import asyncio

from qoder_agent_sdk import AgentDefinition, QoderAgentOptions, query


async def main():
    options = QoderAgentOptions(
        allowed_tools=["Agent"],
        agents={
            "code-reviewer": AgentDefinition(
                description=(
                    "Reviews code for correctness, security issues, and "
                    "maintainability problems."
                ),
                prompt="""You are a code review specialist.
Review the requested code and report concrete findings.
Sort findings by severity and include file paths when possible.""",
                tools=["Read", "Grep", "Glob"],
            ),
        },
    )

    async for message in query(
        prompt="Use the code-reviewer agent to review the authentication module.",
        options=options,
    ):
        print(message)


asyncio.run(main())
```

这个例子里有三个关键点：

* `QoderAgentOptions.agents` 注册本次会话可用的自定义子 Agent。
* 子 Agent 委派通过 `Agent` 工具发生；这里必须用 `allowed_tools=["Agent"]` 预授权这条调用路径。
* 子 Agent 自己的 `tools` 只允许读和搜索，所以它不能改文件，也不能执行命令。

<div id="agents-入参" />

<div id="agents入参" />

### `agents` 入参

`agents` 是子 Agent 名称到 `AgentDefinition` 的映射。完整类型见 [AgentDefinition](/zh/cli/sdk/python/references#agentdefinition)。

| 字段                | 类型                                     | 必填 | 怎么填                                    | 说明                               |
| ----------------- | -------------------------------------- | -- | -------------------------------------- | -------------------------------- |
| `description`     | `str`                                  | 是  | 一句话说明什么时候使用这个子 Agent                   | 给模型看的路由说明，影响是否会调用它               |
| `prompt`          | `str`                                  | 是  | 子 Agent 的角色、边界、输出要求                    | 该子 Agent 的系统提示词                  |
| `tools`           | `list[str]`                            | 否  | 如 `["Read", "Grep", "Glob"]`           | 工具白名单，配置后只能使用列出的工具               |
| `disallowedTools` | `list[str]`                            | 否  | 如 `["Bash", "Write"]`                  | 工具黑名单，适合只排除少数工具                  |
| `model`           | `str`                                  | 否  | 如 `"inherit"`、`"auto"` 或完整模型 ID        | 子 Agent 的模型配置                    |
| `maxTurns`        | `int`                                  | 否  | 如 `8`                                  | 限制子 Agent 最多执行多少轮                |
| `effort`          | `"low" \| "medium" \| "high" \| "max"` | 否  | 如 `"high"`                             | 控制推理努力级别                         |
| `permissionMode`  | `PermissionMode`                       | 否  | 如 `"default"`、`"acceptEdits"`、`"plan"` | 控制子 Agent 内部工具调用的权限模式            |
| `skills`          | `list[str]`                            | 否  | 如 `["review"]`                         | 预加载到子 Agent 上下文的 skill           |
| `mcpServers`      | `list[str \| dict[str, Any]]`          | 否  | 如 `["orders"]` 或 `[{"kb": {...}}]`     | 给子 Agent 限定或增加 MCP server        |
| `initialPrompt`   | `str`                                  | 否  | 首轮自动输入                                 | 仅当该子 Agent 通过 `agent` 成为主会话角色时生效 |

Python SDK 的 `AgentDefinition` 字段名使用协议风格 camelCase，例如 `disallowedTools`、`maxTurns`、`initialPrompt`、`permissionMode`，不是 `disallowed_tools`、`max_turns`。

<div id="配置子-agent-角色" />

<div id="配置子agent角色" />

## 配置子 Agent 角色

`description` 和 `prompt` 是自定义子 Agent 最重要的两个字段。

<div id="description" />

### `description`

`description` 描述“什么时候应该使用这个子 Agent”。模型会根据它决定是否委派。

```python theme={null}
description="Runs project tests, analyzes failing output, and suggests fixes."
```

好的 `description` 应该具体说明任务边界。不要只写 `A helpful agent`、`Helper` 这类泛化描述。

<div id="prompt" />

### `prompt`

`prompt` 定义子 Agent 的角色、边界和输出方式。Python `AgentDefinition` 构造函数要求传入该字段。

```python theme={null}
prompt="""You are a code review specialist.
Only review the requested code; do not edit files.
Return findings sorted by severity, with file paths and suggested fixes."""
```

建议 `prompt` 至少说明三件事：

| 要说明什么  | 示例                                                     |
| ------ | ------------------------------------------------------ |
| 负责什么任务 | `Review code for security and maintainability issues.` |
| 不该做什么  | `Do not edit files. Do not run commands.`              |
| 如何返回结果 | `Return findings sorted by severity with file paths.`  |

<div id="配置子-agent-模型和推理" />

<div id="配置子agent模型和推理" />

## 配置子 Agent 模型和推理

先把 `description` 和 `prompt` 写清楚，再考虑 `model`、`effort` 和 `maxTurns`。前者决定子 Agent 会不会被正确调用、调用后是否知道边界；后者主要用于在角色已经清楚后调效果、速度和成本。

| 配置         | 控制什么                 | 什么时候优先调整                         |
| ---------- | -------------------- | -------------------------------- |
| `model`    | 选择子 Agent 使用的模型或模型别名 | 这个子 Agent 长期承担某类固定任务，需要稳定控制能力和成本 |
| `effort`   | 控制同一模型下愿意花多少推理预算     | 同一个子 Agent 偶尔遇到更复杂、更需要仔细推理的任务    |
| `maxTurns` | 限制最多执行多少轮            | 任务可能探索过深、跑太久，或你希望给成本设置硬上限        |

Python 类型层面 `model` 是 `str | None`。常见写法包括 `"inherit"`、`"auto"`、模型别名，或当前 CLI / 后端支持的完整模型 ID。实际可用值取决于 qodercli 和后端配置。

示例：给不同子 Agent 配不同策略。

```python theme={null}
agents = {
    "explorer": AgentDefinition(
        description="Quickly searches code and summarizes relevant files.",
        prompt="Find relevant files and return a concise summary. Do not edit.",
        tools=["Read", "Grep", "Glob"],
        model="inherit",
        effort="low",
        maxTurns=5,
    ),
    "architect": AgentDefinition(
        description="Designs complex implementation plans across modules.",
        prompt="Analyze tradeoffs carefully and return an implementation plan with risks.",
        tools=["Read", "Grep", "Glob"],
        model="auto",
        effort="high",
        maxTurns=10,
    ),
}
```

字段完整参考见 [Agents Reference - model](/zh/cli/sdk/python/references#agentdefinition-model)、[Agents Reference - maxTurns](/zh/cli/sdk/python/references#agentdefinition-maxturns) 和 [Agents Reference - effort](/zh/cli/sdk/python/references#agentdefinition-effort)。

<div id="控制子-agent-工具" />

<div id="控制子agent工具" />

## 控制子 Agent 工具

自定义子 Agent 和主会话使用同一套工具名。内置工具名如 `Read`、`Grep`、`Glob`、`Bash`；自定义 MCP 工具名使用完整格式 `mcp__{serverName}__{toolName}`。

<div id="主会话侧的-agent-工具" />

<div id="主会话侧的agent工具" />

### 主会话侧的 `Agent` 工具

`agents` 只注册子 Agent，不会自动替模型调用它。模型要委派任务，主会话工具集中必须存在 `Agent`。如果你设置 `QoderAgentOptions.tools` 限定主会话可用工具，记得包含 `Agent`；如果设置 `disallowed_tools=["Agent"]`，委派会被禁用。

<div id="工具白名单tools" />

### 工具白名单：`tools`

`tools` 是子 Agent 的工具白名单。配置后，这个子 Agent 只能使用列出的工具。

```python theme={null}
tools=["Read", "Grep", "Glob"]
```

常用工具组合：

| 场景     | 推荐工具                                    | 说明             |
| ------ | --------------------------------------- | -------------- |
| 只读分析   | `Read`, `Grep`, `Glob`                  | 能看代码，不能修改或执行命令 |
| 跑测试    | `Bash`, `Read`, `Grep`                  | 能执行测试命令并分析输出   |
| 写代码    | `Read`, `Edit`, `Write`, `Grep`, `Glob` | 能读写文件，但不能直接跑命令 |
| 调用业务工具 | `mcp__server__tool`                     | 只允许调用指定自定义工具   |

<div id="工具黑名单disallowedtools" />

### 工具黑名单：`disallowedTools`

`disallowedTools` 适合“允许大部分工具，只排除少数工具”的场景。

```python theme={null}
disallowedTools=["Bash", "Write"]
```

通常不要同时设置 `tools` 和 `disallowedTools`，除非你明确知道最终工具集合。

<div id="与主会话工具配置的关系" />

### 与主会话工具配置的关系

子 Agent 的 `tools` / `disallowedTools` 只作用于自己，不继承主会话的工具白名单或黑名单裁剪。即使主会话侧只预授权 `Agent` 这条委派路径，子 Agent 仍可以使用自己配置的 `Read`、`Grep` 等工具。

```python theme={null}
options = QoderAgentOptions(
    allowed_tools=["Agent"],
    agents={
        "analyst": AgentDefinition(
            description="Reads and summarizes code structure.",
            prompt="Inspect relevant files and return a concise summary. Do not edit files.",
            tools=["Read", "Grep", "Glob"],
        ),
    },
)
```

<div id="控制子-agent-权限" />

<div id="控制子agent权限" />

## 控制子 Agent 权限

工具集合决定子 Agent “能调用哪些工具”，权限配置决定这些工具调用“如何审批或阻断”。可以在子 Agent 上单独配置 `permissionMode`，控制它内部工具执行的权限行为。

```python theme={null}
AgentDefinition(
    description="Plans implementation work without making changes.",
    prompt="Read relevant files and return an implementation plan. Do not edit files.",
    tools=["Read", "Grep", "Glob"],
    permissionMode="plan",
)
```

`permissionMode` 的完整可选值和语义见 [Agents Reference - permissionMode](/zh/cli/sdk/python/references#agentdefinition-permissionmode)。如果宿主需要逐次审批工具调用，可以使用会话级 `can_use_tool` 回调；回调收到的 `context.agent_id` 可用于识别是否来自子 Agent。

<div id="为子-agent-加载-skills" />

<div id="为子agent加载skills" />

## 为子 Agent 加载 skills

`skills` 用来给某个子 Agent 预加载专项技能。它适合把特定工作流、团队规范或工具使用方式绑定到一个子 Agent 上，而不是塞进每次调用的 prompt。

```python theme={null}
AgentDefinition(
    description="Reviews pull requests using the team review workflow.",
    prompt="Review the requested changes and return actionable findings.",
    tools=["Read", "Grep", "Glob"],
    skills=["review"],
)
```

子 Agent 的 `skills` 只影响该子 Agent 的上下文，不等同于主会话的 `QoderAgentOptions.skills`。会话级 skill 行为见 [Skills](/zh/cli/sdk/python/skills)。

<div id="配置子-agent-的-mcpservers" />

<div id="配置子agent的mcpservers" />

## 配置子 Agent 的 mcpServers

`mcpServers` 用来给子 Agent 限定或增加 MCP server。它适合把业务工具只暴露给需要它的子 Agent，例如订单查询、工单检索、内部知识库搜索等。

可以引用会话里已经配置好的 MCP server：

```python theme={null}
options = QoderAgentOptions(
    mcp_servers={
        "orders": {
            "command": "python",
            "args": ["servers/orders.py"],
        },
    },
    allowed_tools=["Agent"],
    agents={
        "support": AgentDefinition(
            description="Answers customer support questions using order tools.",
            prompt="Use order tools when needed and return a concise answer.",
            mcpServers=["orders"],
            tools=["mcp__orders__lookup_order"],
        ),
    },
)
```

也可以给某个子 Agent 配专属 MCP server：

```python theme={null}
options = QoderAgentOptions(
    allowed_tools=["Agent"],
    agents={
        "knowledge": AgentDefinition(
            description="Searches the internal knowledge base.",
            prompt="Search the knowledge base and cite the relevant entries.",
            mcpServers=[
                {
                    "kb": {
                        "command": "python",
                        "args": ["servers/kb.py"],
                    },
                },
            ],
            tools=["mcp__kb__search"],
        ),
    },
)
```

使用建议：

| 场景                         | 怎么配                                                                           |
| -------------------------- | ----------------------------------------------------------------------------- |
| 多个子 Agent 共用同一个 MCP server | 在会话级 `QoderAgentOptions.mcp_servers` 配置 server，再在子 Agent 的 `mcpServers` 中引用名称 |
| 只有某个子 Agent 需要业务工具         | 把 server 放到该子 Agent 的 `mcpServers`，并用 `tools` 限定可调用工具                         |
| 只想调用某个 MCP 工具              | 同时配置 `tools=["mcp__server__tool"]`，避免暴露整个 server 的所有工具                        |

完整字段状态见 [Agents Reference - mcpServers](/zh/cli/sdk/python/references#agentdefinition-mcpservers)。

<div id="调用子-agent" />

<div id="调用子agent" />

## 调用子 Agent

子 Agent 有三种常见调用方式。

<div id="自动调用" />

### 自动调用

模型会根据任务和每个子 Agent 的 `description` 自动决定是否调用。写清楚 `description` 能提升命中准确性。

<div id="显式点名调用" />

### 显式点名调用

如果你希望模型使用某个子 Agent，可以在 prompt 里点名。

```python theme={null}
async for message in query(
    prompt="Use the tester agent to run the unit tests and summarize failures.",
    options=QoderAgentOptions(
        allowed_tools=["Agent"],
        agents={
            "tester": AgentDefinition(
                description="Runs tests and analyzes failures.",
                prompt="Run the requested tests and explain failures clearly.",
                tools=["Bash", "Read", "Grep"],
            ),
        },
    ),
):
    print(message)
```

### 作为主会话角色运行

`QoderAgentOptions.agent` 让主会话直接以某个子 Agent 身份运行。

```python theme={null}
options = QoderAgentOptions(
    agents={
        "planner": AgentDefinition(
            description="Plans implementation work before code changes.",
            prompt="Break the task into clear steps, risks, and validation checks.",
            tools=["Read", "Grep", "Glob"],
            model="inherit",
        ),
    },
    agent="planner",
)
```

`agent` 可以引用 `agents` 里的自定义子 Agent，也可以引用当前 CLI 已发现的内置 / 用户 / 项目 / 插件子 Agent。

<div id="子-agent-上下文与结果" />

<div id="子agent上下文与结果" />

## 子 Agent 上下文与结果

子 Agent 在独立上下文中运行。它会收到自己的系统提示词和委派 prompt，但不会直接继承父会话完整历史。

| 子 Agent 能看到                  | 子 Agent 看不到     |
| ---------------------------- | --------------- |
| 自己的 `prompt`                 | 父会话的完整对话历史      |
| 主会话通过 `Agent` 工具传入的任务 prompt | 父会话的中间工具结果      |
| 自己可用的工具定义                    | 未传给它的父会话私有推理过程  |
| 按配置预加载的 skills               | 其他 Agent 的中间上下文 |

父会话传信息给子 Agent 的主要通道，是调用 Agent 工具时传入的任务 prompt。因此，如果子 Agent 需要特定文件路径、错误信息或业务背景，应该让主会话在委派时明确传过去。

子 Agent 完成后，父会话收到的是它的最终返回，而不是它内部每一步工具调用的全部上下文。

<div id="组合示例" />

## 组合示例

<div id="多角色协作" />

### 多角色协作

注册多个角色不同的子 Agent，主会话根据任务需要决定是否调用、何时调用。

```python theme={null}
options = QoderAgentOptions(
    allowed_tools=["Agent"],
    agents={
        "researcher": AgentDefinition(
            description="Reads existing code to understand patterns and constraints.",
            prompt="Research relevant files and report implementation constraints. Do not edit.",
            tools=["Read", "Grep", "Glob"],
            maxTurns=8,
        ),
        "implementer": AgentDefinition(
            description="Implements code changes following existing project conventions.",
            prompt="Implement the requested change with minimal, idiomatic edits.",
            tools=["Read", "Edit", "Write", "Grep", "Glob"],
            maxTurns=12,
        ),
        "tester": AgentDefinition(
            description="Runs tests and explains failures.",
            prompt="Run relevant tests, summarize results, and identify failing cases.",
            tools=["Bash", "Read", "Grep"],
            maxTurns=6,
        ),
    },
)
```

<div id="启动后自动执行首轮任务" />

### 启动后自动执行首轮任务

`initialPrompt` 只在该子 Agent 通过 `agent` 成为主会话角色时生效：

```python theme={null}
options = QoderAgentOptions(
    agents={
        "auditor": AgentDefinition(
            description="Audits code for security risks.",
            prompt="Scan code for security risks and produce a concise report.",
            initialPrompt="Start with the authentication and session management code.",
            tools=["Read", "Grep", "Glob"],
            effort="high",
        ),
    },
    agent="auditor",
)

async for message in query(prompt="", options=options):
    print(message)
```

如果 `auditor` 是被主会话通过 `Agent` 工具当作子 Agent 调用，`initialPrompt` 会被忽略。

<div id="常见踩坑" />

## 常见踩坑

* 直接使用内置子 Agent 时，不要在 `agents` 里重复定义同名子 Agent；除非你明确想覆盖它。
* 调用子 Agent 依赖主会话的 `Agent` 工具。`allowed_tools=["Agent"]` 是预授权；如果使用 `tools` 限定主会话可用工具，也要包含 `Agent`。
* 子 Agent 名称大小写要匹配当前发现结果，例如 `Explore` 和 `Plan` 是大写开头。
* `description` 负责告诉模型何时调用；`prompt` 负责告诉子 Agent 被调用后怎么做。
* 子 Agent 不能再生成自己的子 Agent。不要把 `Agent` 放进子 Agent 的 `tools`。
* `initialPrompt` 只对 `agent` 指定的主会话角色生效，作为子 Agent 被委派时会被忽略。
* `AgentDefinition` 字段名是 camelCase，不是 snake\_case。
* `background`、`memory`、`criticalSystemReminder_EXPERIMENTAL` 等字段类型存在，但 SDK 注册链路当前不会通过它们改变运行时行为；写入前先看 [Agents Reference](/zh/cli/sdk/python/references#agentdefinition)。

<div id="继续阅读" />

## 继续阅读

* [Agents Reference](/zh/cli/sdk/python/references#agents-reference)：`AgentDefinition`、`AgentInfo`、`agent`、`agents` 的完整参考。
* [Tools](/zh/cli/sdk/python/tools)：内置工具、自定义工具和工具权限。
* [权限控制](/zh/cli/sdk/python/permissions)：`permissionMode`、`allowed_tools`、`can_use_tool`。
* [Skills](/zh/cli/sdk/python/skills)：会话级和子 Agent 级 skill 配置。
