Building dynamic workflows with Claude: a pattern for adaptive automation

· claude, ai, serverless, platform-engineering, workflows

A pattern I’ve been exploring: instead of hardcoding every branch and condition in a workflow, let Claude decide what happens next based on the context at runtime. The workflow becomes a loop — observe, reason, act — where Claude’s job is to pick the next action and the orchestrator’s job is to execute it safely.

This isn’t about replacing Step Functions or Temporal with an LLM. It’s about using Claude as a decision layer in workflows where the right path isn’t knowable until you see the data.

The core idea

A traditional workflow looks like this:

Start → Check condition A → if true: Task 1 → Check condition B → ...

Every branch is pre-defined. That works beautifully when the logic is stable, but breaks down when you’re dealing with:

A dynamic workflow flips it:

Start → Observe state → Ask Claude: "what should happen next?" → Execute that → Loop

Claude gets the current state as context, a list of available actions, and returns a structured decision. The orchestrator validates it, runs it, and feeds the result back in.

A concrete example: incident triage

Say you’re building an on-call helper. An alert fires, and you want to:

  1. Classify severity
  2. Decide whether to page immediately, gather more data, or auto-remediate
  3. If gathering data: pick which diagnostic commands to run
  4. Synthesize the findings and decide next steps

You could write nested if statements for every alert type and every metric pattern. Or you could give Claude:

Claude reasons through it and returns something like:

{
  "action": "run_diagnostic",
  "parameters": {
    "command": "check_disk_usage",
    "target": "prod-db-01"
  },
  "reasoning": "High memory alert but disk at 95% — check if logs are filling disk before paging."
}

The orchestrator runs that command, appends the output to the context, and asks Claude again. Maybe this time it pages. Maybe it auto-remediates. The workflow is static — it’s a loop — but the path through it is dynamic.

The shape I’ve landed on

Here’s the loop:

  1. Observe — gather the current state (alert data, previous actions taken, tool outputs)
  2. Reason — call Claude’s Messages API with:
    • System prompt defining the role and available actions
    • The state as a message
    • response_format set to JSON mode (or tool use, depending on the SDK version)
  3. Validate — parse Claude’s response; ensure the action exists and parameters are sane
  4. Execute — run the action via a Lambda, an API call, a script — whatever the action maps to
  5. Record — append the action and its result to the state
  6. Decide — is this terminal (resolved, escalated, max-loops hit)? If not, loop back to Observe

The orchestrator itself can be a Step Function, a simple Lambda loop with a DynamoDB table for state, or even a long-running container. The key is that Claude never executes anything directly — it only returns a decision, and the orchestrator is responsible for safety, retries, and observability.

What goes in the system prompt

The system prompt is where you define the contract:

You are an incident triage assistant. Your job is to analyze the current state
and decide the next action.

Available actions:
- page_oncall: page the on-call engineer (use sparingly)
- run_diagnostic: run a diagnostic command
- auto_restart: restart a service
- escalate: escalate to a human
- resolve: mark the incident as resolved

Respond with valid JSON:
{
  "action": "<action_name>",
  "parameters": { ... },
  "reasoning": "<why you chose this>"
}

If you're unsure, prefer gathering more data over paging.

Be explicit about the output format, the available actions, and any guardrails. Claude is good at following structured instructions — the clearer you are, the fewer validation errors you’ll see.

Guardrails

A few things that matter:

Why I like this shape

What this isn’t

This is not:

Things I’d still like to add

A few extensions I’m thinking about:

If you’re building automation that deals with ambiguity — support tickets, incident triage, data pipelines with messy input — giving Claude a structured menu of actions and letting it reason through the context is a shape worth trying.

← All posts