# Subagents

> Run clai workers in parallel from one lead agent: async_cmd starts each worker as its own clai process, and the clai-subagents Hub skill tells the lead how to brief, wait for, check and merge them.

Canonical URL: https://www.clai.chat/docs/guides/subagents/ · Version: 1.0 · Updated: 2026-10-27

Full site index: https://www.clai.chat/llms.txt

A subagent, or worker, is a separate `clai` process that a lead agent
starts, waits for and reads. clai has no special tool for this. The lead
gets `async_cmd`, which runs a program in the background, and it runs
`clai`. Every worker has its own model, its own tools and its own context,
and they all run at once. This page is the one pattern every subagent
example on this site uses.

## How it works

1. You ask the lead a question, through an alias like any other profile.
2. The lead loads the `clai-subagents` skill from the Hub, which tells it
   how to run workers, and reads `clai help` and `clai q -h` so it uses
   the flags of the clai you have.
3. It splits the work into independent pieces and starts one worker per
   piece with `async_cmd`, all before it waits for any. Each start returns
   an id straight away.
4. It waits for every id at once with `async_cmd_await` and reads each
   worker's answer with `async_cmd_logs`.
5. It checks one point of each answer against the source, reruns a bad
   worker once, and merges what is left into one reply.

A worker sees nothing of the lead's conversation. Everything it needs is in
its brief: the goal, the exact scope, what it must not touch, and the shape
of the answer.

## The lead profile

This is `lead.json`, in `~/.config/.clai/profiles/`:

```json
{
  "name": "lead",
  "model": "gpt-6.1-sol",
  "use_tools": true,
  "tools": [
    "async_cmd",
    "async_cmd_await",
    "async_cmd_logs",
    "async_cmd_status",
    "async_cmd_cancel",
    "rg",
    "cat",
    "ls"
  ],
  "skills": [
    "cchub:clai/clai-subagents@1#sha256=bf52c25be2989453e5fec1ad7528560f7b2999a9df86572e7ed168ba33947283"
  ],
  "prompt": "Split the task into independent pieces. Before the first worker, call load_skill with skill clai-subagents and follow it. Start one worker per piece with -t rg,cat,ls, then check and merge their answers. Use async_cmd only to run clai."
}
```

- `tools` holds the five `async_cmd` tools, which start, wait for, read,
  check and cancel workers, plus three read tools so the lead can check
  answers itself.
- `skills` names the `clai-subagents` skill on the Hub, pinned to one
  version by its hash. Naming a skill turns skills on for the profile, and
  the pin is what lets it run where no terminal can ask you to trust it.
- `prompt` only says what to split and to load the skill first. How to run
  workers lives in the skill, so every lead that uses it gets the same,
  tested instructions.

Give it two aliases, as with any profile, and ask:

```sh
alias lead='clai -p lead q' rlead='clai -p lead -dre q'
lead 'Why does go test fail, and does api/ need the same fix? Two lines.'
rlead 'And the smallest fix? One line.'
```

## What the skill tells the lead

The skill is a short `SKILL.md`. Its rules, in brief:

- **Read the help first.** Run `clai help` and `clai q -h` and trust their
  output over the skill, since flags change between versions.
- **Start a worker with `async_cmd`.** The command is always `clai`. The
  arguments are the flags, then `q`, then the brief as one argument.
- **Always pass `-ro` and `-summarize=false`.** `-ro` (`-reply-only`)
  keeps the worker's tool calls and reasoning on stderr, so its standard
  output is its answer alone. `-summarize=false` skips a summary the worker
  does not need.
- **Start every worker of a round before awaiting any,** at most eight at
  once, then call `async_cmd_await` once with all their ids. Cancel a
  worker still running at the timeout.
- **Treat each answer as a claim.** Check one concrete point of it, rerun a
  bad worker once with a sharper brief, then merge.
- **Use `async_cmd` only to run `clai`.**

## Three kinds of worker

The flags before `q` decide what a worker is. The lead picks one per piece:

| Worker                 | Arguments to `clai`                                                             |
| ---------------------- | ------------------------------------------------------------------------------- |
| Chosen model and tools | `-ro -summarize=false -cm <model> -t rg,cat,ls q '<brief>'`                     |
| A local profile        | `-ro -summarize=false -p <profile> q '<brief>'`                                 |
| A Hub agent, pinned    | `-ro -summarize=false -prp cchub:<handle>/<agent>@<n>#sha256=<hex> q '<brief>'` |

A worker profile is an ordinary profile. Give it only the tools its piece
needs, and set `"save-reply-as-conv": false`, so a worker's run never
replaces the conversation `-re` or `-dre` replies to:

```json
{
  "name": "investigator",
  "model": "gpt-6.1-sol",
  "prompt": "Read-only investigator. Use the tools to find the cause, then reply in two plain lines.",
  "use_tools": true,
  "tools": ["cat", "git", "go", "ls"],
  "save-reply-as-conv": false
}
```

A Hub agent that is not pinned with `#sha256=`, and that this machine has
not trusted, is refused with exit code 3, because a worker has no terminal
to ask you in.

## Guard rails

- **A tool list is a wall.** A worker without write tools cannot write,
  whatever its brief says. Give write tools only to a worker whose piece is
  an edit, and never let two workers edit the same file.
- **Bans carry over.** A lead profile's `cmd-ban` entries apply to what
  `async_cmd` starts, and the worker inherits them. The brief of a direct
  `clai` call is not matched against them.
- **One program.** The lead's prompt and the skill both say to use
  `async_cmd` only to run `clai`, so the lead cannot drift into running
  other programs in the background.

## Agents on the Hub that use it

Three published agents run workers this way. Run one from a repository
root:

```sh
clai -prp cchub:clai/upgrade-scout@4 q
clai -prp cchub:clai/reviewer@5 q 'Review the staged diff.'
clai -prp cchub:baalimago/swarm-lead@2 q 'Find every place we parse dates and check each for time zone bugs.'
```

`upgrade-scout` starts one worker per central dependency, each one itself
`upgrade-scout` focused on one library, and merges their migration plans.
`reviewer` fans the review out over several workers and then has others
verify their findings. Install one with `clai profiles install` to read its
profile, or see [Share and rate configs](/docs/guides/community-hub/).

## The older worker tools

Earlier versions ran workers through the `clai_run`, `clai_check`,
`clai_result`, `clai_wait_for_workers` and `clai_help` tools. They are
hidden now: a profile that names one exactly still gets it, but nothing
offers them, and new profiles use `async_cmd` with the skill as above.

## Related

- [Putting it all together](/docs/guides/putting-it-all-together/) uses a
  lead in daily work and for a large change.
- [Agent Skills and shell context](/docs/guides/skills-and-shell-context/)
  explains skills and `load_skill`.
- The [tools reference](/docs/reference/tools/) lists the `async_cmd`
  tools.
