02

Workflows

Declarative YAML pipelines that turn multi-step agent tasks into repeatable, validated, resumable sequences.

Why Workflows?

The supervisor pattern with assign() is powerful — it lets a creative agent decompose problems on the fly, delegate to workers in parallel, and adapt to unexpected results. But sometimes you do not want creativity. You want a fixed pipeline that runs the same steps, in the same order, every time.

Workflows give you exactly that: a declarative YAML spec that defines each step, its inputs, its outputs, and how data flows between them. No improvisation, no skipped steps, no variation between runs.

Supervisor + assign()

Flexible and creative. The supervisor decides what to do next based on results. Great for novel, open-ended tasks.

Workflows

Deterministic and repeatable. Steps are fixed in advance. Inputs are typed (string, int, bool, path) and step outputs can declare a JSON Schema. Runs are journaled and resumable.

Anatomy of a Workflow

A workflow spec is a flat YAML file with top-level metadata and a list of steps. Specs live in ~/.aws/cli-agent-orchestrator/workflows/.

workflow spec (YAML)
name: code-review-pipeline
description: Automated PR review pipeline
inputs:
  pr_url:
    type: string
    required: true
steps:
  - id: fetch-diff
    provider: claude_code
    agent: developer
    prompt: "Fetch the diff from {{workflow.inputs.pr_url}} and summarize"
    output_schema:
      type: object
      properties:
        summary: {type: string}

  - id: review-security
    provider: claude_code
    agent: reviewer
    prompt: "Review for security issues: {{steps.fetch-diff.output.summary}}"

  - id: review-quality
    provider: kiro_cli
    agent: reviewer
    prompt: "Review for code quality: {{steps.fetch-diff.output.summary}}"
Plain English
name: — workflow identifier used to run it
description: — human-readable summary
inputs: — dictionary of typed parameters
Each input key has type and required fields
 
 
steps: — sequential list of steps to execute
id: — unique step identifier used to reference outputs
provider: — which AI CLI runs this step (required)
agent: — agent profile for this step
prompt: — message sent to the agent; supports {{}} interpolation
output_schema: — required if later steps reference this step's output; the agent returns it via workflow_return
 
Step 2: id: gives it a unique name for later reference
provider: can differ per step (here claude_code)
{{steps.fetch-diff.output.summary}} — references a field from a previous step's output (full path required: {{steps.STEP_ID.output.FIELD}})
 
Step 3: uses a different provider (kiro_cli)
Same agent profile but different provider
Template syntax: {{workflow.inputs.NAME}} for inputs, {{steps.STEP_ID.output.FIELD}} for step outputs

Running a Workflow

From authoring to monitoring — the lifecycle of a workflow run:

1
Validate the spec

cao workflow validate my-pipeline.yaml — catches grammar errors, duplicate step ids, and constraint violations (max 100 steps, 256KB limit) before you run anything. Template references are resolved at run time, so validate will not catch a typo in {{steps.…}}.

2
Start the run

cao workflow run code-review-pipeline --input pr_url=https://... — launches the workflow with the required inputs. This blocks until the run finishes, then prints the run id and per-step results. Pass --run-id to pre-assign an id you can poll from another shell.

3
Steps execute sequentially

Each step launches an agent via run_agent_step (same substrate as handoff). Steps run one at a time, each with a 600-second timeout and up to 3 retries.

4
Data flows between steps

Step outputs are captured and available to later steps via {{steps.STEP_ID.output.FIELD}} template expressions (the full path is required: {{workflow.inputs.NAME}} for inputs, {{steps.STEP_ID.output.FIELD}} for step outputs). Outputs are validated against JSON Schema if defined.

5
Monitor progress

cao workflow status RUN_ID — see which step is currently executing, which have completed, and the overall run state.

Resume from crash

CAO journals every step completion. If a run is interrupted — process killed, machine reboots, network drops — cao workflow resume RUN_ID keeps every completed step and re-runs the interrupted step and anything after it on a fresh terminal.

Check Your Understanding

1. When would you choose a workflow over a supervisor with assign()?