Skip to content

Chain Format

lacause edited this page Mar 29, 2026 · 2 revisions

Chain Format Reference

Chains are YAML files stored in the chains/ directory. This page covers every field available.

Minimal Chain

name: my-chain
steps:
  - id: step1
    prompt: "Do something"
    output_var: result
output: result

Complete Structure

name: my-chain                    # Required. kebab-case identifier.
description: "What this does"     # Optional. Shown in list_chains.
version: "1.0"                    # Optional. Semantic version.

inputs:                           # Optional. Chain-level parameters.
  - name: topic                   # Input variable name.
    description: "The topic"      # Optional. Shown to users.
    optional: false               # Default: false. If true, can be omitted.

steps:                            # Required. At least 1 step.
  - id: step_one                  # Required. Unique ID (kebab-case).
    type: agent                   # Optional. Default: "agent".
    label: "Human-readable name"  # Optional. Shown in SSE events.
    model: claude-sonnet-4-6      # Optional. Override default model.
    prompt: "..."                 # Required. Supports {variables}.
    output_var: result            # Required. Variable name for output.
    depends_on: [other_step]      # Optional. Steps that must complete first.
    tools: [Read, Write, Bash]    # Optional. Claude tools this step can use.
    cwd: "/path/to/dir"           # Optional. Working directory for Claude.
    condition: '{var} == "value"'  # Optional. Skip step if condition is false.
    timeout_ms: 300000            # Optional. Per-step timeout (default: 5min).
    pre_tools: [...]              # Optional. Data injection before execution.
                                   # Each pre-tool supports on_error: "inject" | "skip" | "fail"
    retry: { ... }                # Optional. Retry configuration.
    fallback_models: [...]        # Optional. Models to try if primary fails.
    cache: { ... }                # Optional. Result caching.
    guardrails: [...]             # Optional. Output validation rules.
    context_strategy: { ... }     # Optional. How to compress dependencies.
    early_exit_if: '...'          # Optional. Stop chain if condition is true.

output: result                    # Required. output_var to return as final result.

Variable Interpolation

Variables are referenced with {name} syntax in prompts and pre-tool configs:

Variable Source Example
{input.topic} Chain input User-provided value
{step_output} Step output_var Output from a previous step
{search_results} Pre-tool inject_as Data injected before the step
{item} Loop iteration Current item in a loop step

Variables resolve at execution time. Undefined variables remain as literal {name} in the prompt.

Dependency Graph

Steps without depends_on run in parallel (same wave). Steps with depends_on wait for their dependencies.

steps:
  # Wave 1 (parallel)
  - id: a
    prompt: "..."
    output_var: out_a
  - id: b
    prompt: "..."
    output_var: out_b

  # Wave 2 (waits for a and b)
  - id: c
    depends_on: [a, b]
    prompt: "Combine {out_a} and {out_b}"
    output_var: out_c

Circular dependencies are detected at load time and rejected with a clear error message.

Retry & Fallback

retry:
  max: 3                    # Max attempts (default: 1 = no retry)
  delay_ms: 2000            # Initial delay between retries
  backoff: 2                # Multiply delay by this factor each retry

fallback_models:             # Try these models if the primary fails
  - claude-opus-4-6
  - claude-sonnet-4-6

Retry order: attempt with primary model → retry with primary → fallback model 1 → fallback model 2.

Output Validation (Guardrails)

guardrails:
  - type: min_length
    value: 500
  - type: max_length
    value: 5000
  - type: must_contain
    value: "## Summary"
  - type: must_not_contain
    value: "I don't know"
  - type: regex_match
    value: "^#{1,3} "
  - type: json_valid

# Legacy fields (still supported)
output_must_contain: ["## Summary"]
output_must_not_contain: ["TODO"]
output_max_length: 5000
output_schema: json          # "json", "markdown", or "text"

If guardrails fail and retry is configured, the step re-runs automatically.

Caching

cache:
  enabled: true
  ttl_minutes: 60            # Cache expires after 60 minutes

Cache key = hash of (step ID + resolved prompt + model). Identical inputs skip the LLM entirely.

Context Strategy

Control how dependency outputs are compressed before injection:

context_strategy:
  research: "full"              # Pass full output (default)
  raw_data: "summarize"         # LLM-summarize before injection
  big_output: "truncate:2000"   # Truncate to 2000 characters

Conditional Execution

condition: '{codebase_type} == "frontend"'

Supported operators: ==, !=, contains, >, <.

If condition is false, the step is skipped and its output_var is set to empty string.

Early Exit

early_exit_if: '{answer_found} == "true"'

If the condition evaluates to true after this step completes, remaining waves are skipped.

See Also

Clone this wiki locally