Parallel Fanout
When the user task is clearly decomposable into 2+ truly independent sub-tasks, the agent has two choices:
- Serialize: do them one by one, holding the conversation hostage.
- Fan out: dispatch them concurrently, aggregate the results.
This Skill is about knowing when to choose (2) and how to dispatch + aggregate cleanly so the user gets the parallel speedup without losing correctness.
mcode 0.2.4 surface
Each sub-task is a separate task() call:
task(
description: string, // 3-5 word label, required
prompt: string, // the brief, required
agent_name: "explore" | "worker" | "verifier", // required
run_in_background?: boolean // optional; usually false for fan-out
)
The agent dispatches all the calls in a single response; mcode executes them concurrently subject to the host's per-session buffer-unordered limit (8 by default in 0.2.4; check the runtime config if unsure). The agent then waits for all to complete before aggregating.
agent_name is the canonical mcode spelling. agent_name= is accepted as
a runtime alias but the Skills prefer canonical. mavis is the root agent
not a sub-agent; do not pass it as agent_name.
When to use
Activate when any of these is true:
- The user task is clearly decomposable into 2+ independent sub-tasks.
- The sub-tasks touch independent files / directories / systems (so there is no shared state to corrupt).
- The user explicitly said "in parallel" / "并行" / "fan out" / "同时".
- You would otherwise serialize work that has no real dependency.
When NOT to use
- The sub-tasks have a hard data dependency (output of A is the input of B).
- The user explicitly said "sequential" / "one at a time" / "按顺序".
- There is only one sub-task (no fan-out to do).
- The sub-tasks would all touch the same file (race condition risk).
Process
- Decompose explicitly. Write the list of sub-tasks in the brief header before dispatching anything. "Sub-tasks: A, B, C" is the single most important line.
- For each sub-task, decide context size (see
fork-context-decisionSkill):- Self-contained sub-task?
none(just the brief inprompt). - Needs prior context?
Norall→ inline the prior content intoprompt.
- Self-contained sub-task?
- Check mcode's per-session buffer-unordered limit. Default in 0.2.4 is 8
concurrent
taskcalls. If you have more sub-tasks, the host will queue or fail — split the batch or userun_in_background: trueand polltask_outputlater. - Dispatch the batch in a single response. mcode runs them concurrently subject to the buffer-unordered limit.
- Wait for all to complete. The aggregator MUST verify each sub-task's
output before declaring success (use
completion-audit). - Surface the parallelism in the user-facing message. "I dispatched 3 sub-agents in parallel; here are their results." The user should know fan-out actually happened (vs serial).
Output contract
After activating this Skill, the agent's next message MUST include:
- The list of sub-tasks dispatched (one per
taskcall). - The chosen context level per sub-task.
- The aggregation result (per-sub-task outcome + overall verdict).
- A completion audit step (each sub-task verified).
Common pitfalls
- Fanning out for the sake of it — parallelism is a tool, not a goal. If two sub-tasks are easier to do serially, do them serially.
- Missing the data dependency — the most common bug. Always check: does sub-task B actually need sub-task A's output? If yes, serialize.
- Hitting mcode's buffer-unordered limit silently — the host will queue or fail. Check the limit first; if you have more than 8, run them in waves.
- Aggregating without verification — one sub-task may have silently failed. Always read each output.
- Using
agent_name="mavis"— mavis is the root, not a sub-agent. Useexplore/worker/verifier. - Writing the sub-task brief in a separate
brief=field — mcode 0.2.4 has nobrieffield. The brief goes inprompt.
Example
The example below is MiniMax Code 0.2.4 task tool syntax. The fan-out
is 3 sub-tasks, all none context, all dispatched in one response, mcode
runs them concurrently.
# Sub-tasks: A, B, C
# Concurrency cap: 8 (mcode 0.2.4 default)
# Context level: none (all sub-tasks are self-contained)
# Aggregation: read each output, run completion-audit, then summarize
> task(
description="Look up X in repo 1",
agent_name="explore",
prompt="""
Task name: lookup-X-repo1
Task: Find every file in <repo1> that imports `X`.
Return: List of <repo1>/<path> files, one per line.
"""
)
> task(
description="Look up Y in repo 2",
agent_name="explore",
prompt="""
Task name: lookup-Y-repo2
Task: Find every file in <repo2> that imports `Y`.
Return: List of <repo2>/<path> files, one per line.
"""
)
> task(
description="Look up Z in repo 3",
agent_name="explore",
prompt="""
Task name: lookup-Z-repo3
Task: Find every file in <repo3> that imports `Z`.
Return: List of <repo3>/<path> files, one per line.
"""
)
# (Agent waits for all three.)
# Aggregator reads each output, audits per `completion-audit`.
The decision (3 sub-tasks, none context, wait-for-all) is the same; the
call shape is what mcode 0.2.4 actually exposes.
Verification checklist
- Did you write the sub-task list in the brief header before dispatching?
- Did you stay under mcode's per-session buffer-unordered limit (default 8)?
- Did you choose the right context level per sub-task (via
fork-context-decision)? - Did you wait for all sub-tasks to complete before aggregating?
- Did you verify each sub-task's output (via
completion-audit)? - Did you use
agent_namefrom{explore, worker, verifier}(notmavis)? - Did you put the sub-task brief in the
promptfield (not a separatebrief)?