Multi-agent orchestration

Run many agents. Let a controller decide the order.

Some work has an order you cannot write down in advance. Set `type: controller`, declare what must be true when the run ends, and Dagu lets a model choose which agent step to run next as findings come back. Every action stays an ordinary workflow step with logs, retries, approvals, and audit history.

Two reviewers, one reviser, no depends
# code-review.yaml
type: controller

llm:
  provider: anthropic
  model: claude-opus-5
  system: |
    Get top_n.py past both reviews. When a review fails, pass its finding
    to revise, then ask that same reviewer again. A revision made for one
    reviewer can break the other.

steps:
  - name: review_simplicity
    description: Judge simplicity. Prints PASS, or FAIL with what to change.
    action: harness.run
    with:
      provider: opencode
      prompt: Read top_n.py. Print "PASS" or "FAIL: <what to change>".

  - name: review_correctness
    description: Judge correctness. Prints PASS, or FAIL with the bug.
    action: harness.run
    with:
      provider: codex
      prompt: Read top_n.py. Print "PASS" or "FAIL: <the bug>".

  - name: revise
    description: Edit top_n.py to resolve one review finding.
    action: dag.run
    with: { dag: revise }

tasks:
  - name: simplicity_passed
    description: The latest simplicity review returned PASS on the current file.
  - name: correctness_passed
    description: The latest correctness review returned PASS on the current file.

Declare completion criteria, not step order

Every action is a real agent CLI: Claude, Codex, Gemini, OpenCode

Tasks settle as completed, skipped, or failed

Durable pauses for human answers, with no process left running

At a glance

Controller workflows vs. agent frameworks

Termination
Dagu

You declare completion criteria. The run ends when no task is left open.

Agent framework

The model decides it is finished, or every path is drawn in advance and maintained by hand.

Durability
Dagu

A waiting run exits its process and resumes on a new one.

Agent framework

Long waits usually mean a process to keep alive and a state store to operate.

Operations
Dagu

Schedules, queues, retries, artifacts, and audit history come from the DAG run.

Agent framework

Rebuilt per project, or delegated to a hosted control plane.

Blast radius
Dagu

The set of steps in the workflow file.

Agent framework

Whatever the tool definitions allow.

In depth

Where each tool fits

01

Order is the part you cannot write down

A graph can branch on an exit code. It cannot branch on what a review actually said. A controller workflow keeps the actions fixed and hands over only the ordering.

  • Steps become a catalog of actions, so there is no `depends` to maintain.
  • A `tasks` list declares what must be true when the run is over.
  • The controller carries one agent's finding into the next agent's parameters.
02

The model chooses the order, never the capability

The controller picks among the steps you declared. It cannot invent a step, write its own shell command, or reach anything the file does not name, so the blast radius is the workflow definition.

  • Run each agent on the host or in a container sandbox with explicit mounts and egress rules.
  • Give each role its own provider and model, so no single model grades its own work.
  • Move anything you come to trust into a sub-workflow and it stops being a decision.
03

Production controls come from the run, not a framework

A controller run is a DAG run. Schedules, queues, retries, artifacts, and audit history apply unchanged, and the limits that cap an agent's spend are engine settings rather than prompt instructions.

  • `ask_user` suspends the run durably: the process exits and the worker slot is released.
  • A person answers hours later and the run resumes on a fresh process.
  • Turn, action-attempt, and question limits fail the run instead of spending without a bound.
04

Reconstruct any run afterwards

A controller has no dependency edges, so the run is presented as the sequence of decisions it actually made rather than as a graph.

  • A decision timeline: one row per turn, with attempt counts, durations, and the child run each action produced.
  • A task view showing why the controller settled each goal as completed, skipped, or failed.
  • The full transcript, including every tool result the model saw.

FAQ

Practical questions before adopting Dagu

How is a controller workflow different from an agent loop?

A bare loop lets the model decide when it is finished. A controller keeps the loop but takes the termination condition back: you declare the tasks and what done means, and the run ends when no task is open.

What happens when a task turns out to be unnecessary?

The controller marks it skipped and records why, and the run still succeeds. Skipped and failed are separate states because 'there was nothing to do' and 'this could not be done' are different outcomes in an audit log.

Can different steps use different models?

Yes. Each Agent Harness step names its own provider and model, and the controller's own model is configured separately, so a cheap model can drive expensive specialists or two providers can check each other.

How do I stop a run from spending without a bound?

Limits are enforced by the engine. An action runs at most five times per run, a run asks at most five questions, and the turn limit defaults to fifty and can be lowered. Hitting a limit fails the run and names what was left open.

When should I still use a plain graph?

If you can draw the graph, draw the graph. `type: graph` stays the default because it is faster, cheaper, and reproducible. Reach for a controller only when the order genuinely depends on what earlier steps produced.

Next step

Start with one workflow.

Install Dagu, move one fragile script or agent task into YAML, and decide from a real run history.