Custom agents

Muse Code can run subagents that work on parts of a task in parallel. By default, a subagent runs on the same model as your main session, the lead. To run subagents on a different model, such as a lower-cost one, ask the lead for that model in your prompt, or define named agents that always run the way you set them up.

Ask the lead for a model

The lead doesn't switch its subagents to a lower-cost model on its own: Muse Code tells it to keep them on its own model unless a task clearly needs a different capability or cost. For a one-off request, name the model in your prompt. The lead starts those subagents as a workflow and sets the model on each one, so this works when workflows are available in your build:

text
Split the test suite into four parts and run each part in a subagent using muse-ember-1.0. If that model isn't available, stop and tell me.
  • Use the exact model ID, such as muse-ember-1.0. With only the model's name, the lead guesses an ID, and Muse Code rejects a wrong one.
  • The model must be in your /models list. Muse Code rejects a subagent on a model your account doesn't offer.
  • Say what to do when the model isn't available. Otherwise the lead can rerun the work on its own model, which costs more.
  • Check which model ran in the session record. The lead's reply relies on what the subagents say about themselves. muse export records the model ID each subagent ran on.

Asking works for a single request. For repeated runs, or when the cost split matters, define agents instead. A definition applies to every spawn without depending on the lead getting the ID right, and it can carry its own instructions and tool list.

Define agents for a run

An agent definition names a type of subagent and sets its instructions, model, reasoning effort and tools. The lead reads each definition's name and description, and chooses one when it spawns a subagent.

Write your definitions as one JSON object. Each key is an agent name, and each value is that agent's definition. This agents.json defines a subagent on Muse Ember for a lead that plans the work on Muse Wonder:

json
{
"subagent": {
"description": "Executes one well-defined coding part of a larger plan, such as implementing a module, adding tests or fixing a bug.",
"prompt": "You receive one part of a larger plan from the lead. Complete that part as the task describes, creating or changing the files it needs. Run the checks the task names. Reply with what you changed and whether the checks pass.",
"model": "muse-ember-1.0",
"effort": "medium"
}
}

Write the prompt for what you want the subagent to do. This one keeps the subagent on its part of the plan and asks for a short report. A subagent that reviews code, writes tests or researches an API needs different guidance, such as what to look for and how to report it.

Pass the file's contents with --agents every time you start Muse Code. Muse Code doesn't save the definitions, so they apply only to the session or run you pass them to:

  • Interactive session: the definitions last until you quit.

    bash
    muse --model muse-wonder-1.0 --reasoning-effort high --agents "$(cat agents.json)"
  • Headless run: each muse exec is a separate run, so each one needs the flag, including a run that continues a session with --session-id.

    bash
    muse exec --model muse-wonder-1.0 --reasoning-effort high --agents "$(cat agents.json)" \
    "Plan the work in PLAN.md, hand each well-defined part to a subagent, and check every result."
  • Resumed session: pass the flag again when you resume.

    bash
    muse resume --last --agents "$(cat agents.json)"

The flag can appear only once per command, so put every definition in the one object.

Name the agents in your prompt. The lead chooses an agent from its description, and a prompt that says which agent does which step gives you a predictable split.

Agent names use lowercase letters, with words separated by single hyphens, such as subagent or test-writer. Muse Code refuses to start when the JSON is malformed, when the top-level value isn't an object, when a name breaks that rule, or when two keys repeat a name.

Set the fields

FieldRequiredValue
descriptionYesWhen to use this agent. The lead reads it to choose an agent, so say what the agent does and what to give it. Up to 4,096 bytes.
promptYesThe agent's standing instructions, applied to every task it receives. This is where you shape the agent for its objective: what to focus on, what to produce and how to report back. The task the lead writes at spawn time arrives as the agent's input.
modelNoThe model ID the agent runs on. Omit it to use the lead's model.
effortNoThe agent's reasoning effort: none, minimal, low, medium, high, xhigh, max or ultra. The Meta provider doesn't accept none. Omit it to use the lead's effort.
toolsNoAn array of the tool names the agent can use. Omit it to give the agent every tool the lead has.
disallowedToolsNoAn array of tool names to remove from the agent's tools.

An agent can narrow the lead's toolset, but it can't expand it. The permission boundary that applies to the lead also applies to every agent it spawns.

A definition with a missing description or prompt, a field of the wrong type, or an unrecognized key is invalid. Muse Code still starts, but the lead can't spawn that agent. Check the spelling of every key, including the case of disallowedTools.

Choose a model for each agent

Put the most capable model where judgment is made once, and a lower-cost model where work repeats. Run the lead on Muse Wonder to plan the work, write each subagent's brief and check the results. Define the subagents on Muse Ember for the many well-defined parts.

The model value must be a model your Muse Code account offers. If it isn't available, the agent runs on the lead's model by default instead of failing, and Muse Code tells the lead which model ran. Before a long run, check that each model ID in your definitions appears in the /models list, so the work doesn't move to the lead's more expensive model.

Set effort on each agent when it should reason more or less than the lead. A subagent that follows a complete brief often needs less reasoning than the lead that wrote it.

Replace the default subagent

Agent definitions apply only to the subagents the lead spawns. The lead is your main session, and its model comes from --model.

When the lead spawns a subagent without naming one of your agents, Muse Code uses its built-in general-purpose subagent. Written as an agent definition, the built-in one is:

json
{
"general-purpose": {
"description": "General-purpose agent for complex, multi-step tasks that require exploration and action.",
"prompt": "Complete the delegated task using only the effective capabilities supplied for this agent. Return a concise result to the parent."
}
}

It sets no model or effort, so it runs on the lead's model at the lead's effort: a part meant for a Muse Ember subagent runs on Muse Wonder instead and costs more. It sets no tools either, so it gets every tool the lead has. Workflow children use the built-in workflow-subagent the same way, unless the workflow sets a model or effort for that child, which overrides any definition.

To keep those subagents on Muse Ember too, add your own general-purpose and workflow-subagent to agents.json. A definition you pass with --agents takes the place of the built-in subagent with the same name for that run. This file keeps the built-in instructions and adds a model and effort:

json
{
"subagent": {
"description": "Executes one well-defined coding part of a larger plan, such as implementing a module, adding tests or fixing a bug.",
"prompt": "You receive one part of a larger plan from the lead. Complete that part as the task describes, creating or changing the files it needs. Run the checks the task names. Reply with what you changed and whether the checks pass.",
"model": "muse-ember-1.0",
"effort": "medium"
},
"general-purpose": {
"description": "General-purpose agent for complex, multi-step tasks that require exploration and action.",
"prompt": "Complete the delegated task using only the effective capabilities supplied for this agent. Return a concise result to the parent.",
"model": "muse-ember-1.0",
"effort": "medium"
},
"workflow-subagent": {
"description": "Workflow child agent for one delegated Workflow task.",
"prompt": "Complete the delegated Workflow task using only the effective capabilities supplied for this agent. Return a concise result to the Workflow owner.",
"model": "muse-ember-1.0",
"effort": "medium"
}
}

Pass it the same way as before:

bash
muse --model muse-wonder-1.0 --reasoning-effort high --agents "$(cat agents.json)"

By default, Muse Code runs up to eight agents at once, counting the lead, or 64 when the lead runs at max or ultra effort. To run more subagents in parallel, raise agents.execution_capacity for the run, from 1 to 64. For example, -c agents.execution_capacity=17 runs the lead and up to 16 subagents at once.

Keep definitions in files

Save a definition you reuse as a Markdown file. The YAML frontmatter holds name, description and the optional fields, and the body is the prompt:

markdown
---
name: subagent
description: Executes one well-defined coding part of a larger plan, such as implementing a module, adding tests or fixing a bug.
model: muse-ember-1.0
effort: medium
---
​
You receive one part of a larger plan from the lead. Complete that part as the task
describes, creating or changing the files it needs. Run the checks the task names.
Reply with what you changed and whether the checks pass.

Muse Code loads .md definition files from two places:

  • Project: .agents/agents/ in the directory where you start Muse Code. Commit them to share the agents with your team. Project definitions load only after you trust the workspace.
  • User: ~/.config/muse/agents/, or $XDG_CONFIG_HOME/muse/agents/ when XDG_CONFIG_HOME is set, available in every project.

Muse Code loads the definitions from these folders and from --agents together. When two sources define the same name, the first of these wins: definitions your organization manages, --agents, project files, user files, plugins, and the built-in agents. A managed definition can't be replaced: if your organization manages a general-purpose definition, the one you pass with --agents has no effect.

See custom agents in a recipe

These Meta Model Cookbook recipes run Muse Code with an --agents definition file:

  • Port Python to Rust with Muse Wonder and Muse Ember: a Muse Wonder planner dispatches the Muse Ember port-workers defined in the recipe's agents/agents.json, and they port 16 lexers in parallel, one language each. The file also gives general-purpose the worker's definition, so every child runs on Muse Ember.
  • Organize a photo library with parallel subagents: a Muse Wonder lead writes a photo pipeline, and 16 Muse Ember workers run it. The recipe also replaces general-purpose, so every worker runs on Muse Ember.

Next steps