Guides

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.

On this page

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/:

{
  "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:

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:

{
  "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:

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.

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.

Last updated October 27, 2026

Type to search the documentation.