Guide: Multi-agent pipelines
A pipeline is an ordered list of steps, each running an agent over a templated input. It is the division-of-labour primitive: every step is a separately bound agent, so a pipeline can deliberately run one step on a cheap model and another on a strong one — or on two different models, which is the point of the shipped example. Pipelines run non-interactively, so tool access resolves by policy with no approval prompts.
Run the shipped pipeline
Section titled “Run the shipped pipeline”muaz ships one: code-review. Run it from the UI Pipelines page (live
per-step timeline with tokens, cost, and duration), or the CLI:
muaz pipeline run code-review "the staged changes"It is an adversarial review in three steps. review-proposer reads the change
and reports every defect it can find. review-disputer then attacks that list,
reading the code itself to refute what doesn’t hold. review-arbiter decides
which findings survive and writes the review you actually read.
The dispute step exists because a single model reviewing code reliably produces plausible findings — things that look like defects to a reader who hasn’t checked the guard three lines up. Each false positive sends a developer into code that was fine, and a few of those are enough that people stop reading reviews.
Give the steps different models
Section titled “Give the steps different models”The dispute step works best when the disputer does not share the proposer’s blind
spots, which means running them on different models. Because every step is a
named agent, that is just a binding in ~/.muaz/models.yaml:
agents: "@preset/review-proposer": { profile: anthropic-main } "@preset/review-disputer": { profile: openai-main } # different model, on purpose "@preset/review-arbiter": { profile: anthropic-main }Nothing about the pipeline file changes. This is why steps name an agent rather than carrying an inline prompt: a binding needs something to key on, and an agent’s identity is that key.
Step agents
Section titled “Step agents”review-proposer and friends are marked entrypoint: false — they are built to
be called by a pipeline, not chatted with, so they are kept out of the pickers
that start a new conversation.
They are not lesser agents. They resolve by name, they appear in
muaz agents list, on the UI Agents page, and in the pipeline editor’s agent
picker, and they are bound to models exactly like any other agent. You can still
open a chat with one directly from the Agents page, which is the easiest way to
iterate on its prompt. The flag governs one surface: the new-chat picker, where
a handful of step agents would bury the two you actually start from.
Set it on your own agents with entrypoint: false in the YAML, or the Pipeline
step only checkbox in the UI agent editor.
The shape of a pipeline
Section titled “The shape of a pipeline”name: code-reviewbudget: max_seconds: 1800 # pipeline-wide
steps: - name: propose agent: review-proposer input: | Review this change and report every defect you find.
Review target: ${input} budget: { max_seconds: 600 } retry: { max: 1, backoff_secs: 5 }
- name: dispute agent: review-disputer input: | Attack the findings below.
Review target: ${input}
Proposed findings: ${steps.propose.output}Key pieces:
- Templated input over
${input},${vars.*},${steps.<name>.output}, and${steps.<name>.<field>}(unknown placeholders are hard errors). - Routing is structured output, not free-text scanning: give a step an
output_schemawith aroutefield, then gate later steps withwhen:(equals/not_equals/contains). - Recovery per step:
retry,on_error: fail|continue|fallback. - Budgets (
max_cost_usd/max_tokens/max_seconds) on each step and the pipeline — time budgets hard-timeout an in-flight step. parallel:groups run several agents concurrently.
Author your own
Section titled “Author your own”Create and edit pipelines on the UI Pipelines page (a form-based step-card
editor), or drop a YAML file in ~/.muaz/plugins/local/pipelines/. Plugins can
ship pipelines too — they appear namespaced as @<plugin>/<name>. Full
reference: Pipelines.