コンテンツにスキップ
Developer Preview — APIs and language features may change before 1.0

Flows

このコンテンツはまだ日本語訳がありません。

Most machines have a single linear sequence of steps. For those, you place steps directly under behaves and the runtime executes them in order. When a machine needs multiple execution paths, parallel processing stages, or reusable step groups, you use named flows.

For single-flow machines, put steps directly under behaves:

behaves
ask classify, using: "anthropic:claude-haiku-4-5"
with task "Classify this text"
returns
category as text
assuming
category: "general"
compute format
{result: steps.classify.category}

No flow keyword needed. This is the implicit main flow.

When you need multiple execution paths, wrap them in a flows container:

behaves
flows
flow extract
ask fetch, from: "@mashin/actions/http/get"
url: input.source_url
assuming
body: {records: []}
status: 200
flow transform
compute normalize
{cleaned: steps.fetch.body.records.filter(r => r != null)}
flow load
ask store, from: "@myorg/data/writer"
records: normalize.cleaned
assuming
written: true
compute result
{status: "complete", count: normalize.cleaned.length}

Each flow is a named group of steps. Flows execute in the order they are declared unless you use run or goto to control the sequence.

run (name) calls a flow and returns to the current position (like a function call). goto flow(name) jumps to a flow and does not return (tail call).

behaves
compute check
{needs_retry: input.attempt < 3}
decide route
when check.needs_retry
run (process)
otherwise
run (fallback)
flows
flow process
ask analyze, using: "anthropic:claude-sonnet-4-6"
with task "Analyze this data"
returns
result as text
assuming
result: "Analysis complete"
flow fallback
compute default_response
{result: "Max retries exceeded", status: "failed"}

Use run when you need to return and continue execution. Use goto when the current flow is done and execution should continue in another flow.

The most common pattern: use a decide step to route to different flows.

machine order_handler
accepts
order_type as text, is required
amount as number, is required
responds with
status as text
handler as text
behaves
decide route_order
when input.order_type == "subscription"
run handle_subscription
when input.amount > 10000
run handle_enterprise
otherwise
run handle_standard
flows
flow handle_subscription
compute result
{status: "processed", handler: "subscription_team"}
flow handle_enterprise
compute result
{status: "pending_review", handler: "enterprise_sales"}
flow handle_standard
compute result
{status: "processed", handler: "auto"}
verifies
test "subscriptions go to the subscription team"
given {order_type: "subscription", amount: 50}
expect {status: "processed", handler: "subscription_team"}
test "large orders wait for enterprise review"
given {order_type: "one_off", amount: 50000}
expect {status: "pending_review", handler: "enterprise_sales"}

Each flow can have its own on failure block:

behaves
flows
flow fetch
ask get_data, from: "@mashin/actions/http/get"
url: input.url
assuming
body: {}
status: 200
on failure
compute fetch_error
{status: "fetch_failed", error: error.message}
flow process
ask analyze, using: "anthropic:claude-sonnet-4-6"
with task "Analyze: ${steps.get_data.body}"
returns
result as text
assuming
result: "OK"
on failure
compute process_error
{status: "analysis_failed", error: error.message}

If a step in fetch fails, only the fetch flow’s error handler runs. The process flow’s error handler is independent.

Use named flows when:

  • A decide step routes to different multi-step paths
  • An ETL pipeline has distinct extract, transform, and load stages
  • You want independent error handling for different parts of the machine
  • Steps are logically grouped and the grouping aids readability

Keep a single implicit flow when:

  • Steps execute linearly from top to bottom
  • There are fewer than 6 steps
  • There is no branching or error isolation needed

Build an ETL machine with three named flows: extract (fetch data via HTTP), transform (clean and reshape with compute), and load (store via a machine call). Add on failure to each flow with different error responses.