Skip to main content

Version Actions

Version actions generate multiple action instances from a single configuration, enabling parallel processing with different parameters.

Configuration

actions:
- name: extract_raw_qa
versions:
range: [1, 3] # Inclusive range - creates _1, _2, _3
mode: parallel # or "sequential"
prompt: |
Extract questions using strategy {{ i }}

Parameters

ParameterTypeDefaultDescription
rangearrayRequired[start, end] - inclusive range
modestringparallelparallel or sequential

Template Variables

Version variables are available in both inline prompts and prompt store references:

VariableTypeDescriptionExample
{{ i }}intCurrent iteration value1, 2, 3
{{ idx }}intZero-based index0, 1, 2
{{ version.length }}intTotal iterations3
{{ version.first }}boolTrue on first iterationtrue/false
{{ version.last }}boolTrue on last iterationtrue/false
{{ custom_param }}intCustom param value (when param is set)1, 2, 3

Custom Parameter Names

When using a custom param name, it's available as a top-level variable:

versions:
param: classifier_id
range: [1, 3]
{# Both work: #}
Classifier {{ classifier_id }}
Classifier {{ i }}

Using with Prompt Store

Version variables work with prompt store references, enabling reusable versioned prompts:

# In workflow config
- name: classify_severity
versions:
range: [1, 3]
mode: parallel
prompt: $incident_triage.Classify_Severity
{# In prompt_store/incident_triage.md #}

{prompt Classify_Severity}
You are classifier {{ i }} of {{ version.length }}.

{% if version.first %}
Be conservative in your assessment.
{% elif version.last %}
Be comprehensive and thorough.
{% else %}
Balance precision and recall.
{% endif %}

Analyze the incident and provide your classification.
{end_prompt}

This renders as:

  • Classifier 1: "You are classifier 1 of 3. Be conservative..."
  • Classifier 2: "You are classifier 2 of 3. Balance precision..."
  • Classifier 3: "You are classifier 3 of 3. Be comprehensive..."

Version Consumption

Downstream actions consume outputs from all version iterations. The version_consumption block controls how versioned outputs are collected.

FieldTypeDescription
sourcestringName of the upstream versioned action to consume
patternstringmerge — combine all version outputs into one record (fan-in); match — pair each version output 1:1 with the consumer

merge (Fan-In)

The most common pattern. All version outputs are collected into a single record, keyed by version name (e.g., extract_raw_qa_1, extract_raw_qa_2). Use this for aggregation, voting, and consensus:

- name: extract_raw_qa
versions:
range: [1, 3]

- name: flatten_questions
dependencies: [extract_raw_qa]
version_consumption:
source: extract_raw_qa
pattern: merge
context_scope:
observe:
- extract_raw_qa.* # Wildcard reference

Outputs are merged as nested namespaces:

{
"extract_raw_qa_1": {"questions": ["Q1a", "Q1b"]},
"extract_raw_qa_2": {"questions": ["Q2a", "Q2b"]},
"extract_raw_qa_3": {"questions": ["Q3a", "Q3b"]}
}

Access in prompts:

prompt: |
Strategy 1: {{ extract_raw_qa_1.questions }}
Strategy 2: {{ extract_raw_qa_2.questions }}

Common Patterns

Multi-Strategy Extraction

- name: extract_with_strategies
versions:
range: [1, 3]
prompt: |
{% if i == 1 %}Focus on explicit statements
{% elif i == 2 %}Focus on implicit meanings
{% else %}Focus on contextual clues{% endif %}

Extract from: {{ source.text }}

- name: combine_extractions
dependencies: [extract_with_strategies]
version_consumption:
source: extract_with_strategies
pattern: merge

Sequential Refinement

- name: refine_iteration
versions:
range: [1, 3]
mode: sequential
dependencies:
- "{% if i == 1 %}draft_content{% else %}refine_iteration_{{ i-1 }}{% endif %}"

Parallel Model Comparison

- name: model_comparison
versions:
range: [1, 3]
model_vendor: |
{% if i == 1 %}openai{% elif i == 2 %}anthropic{% else %}google{% endif %}

Execution Modes

Parallel (default): All iterations run simultaneously. Use when iterations are independent.

Sequential: Iterations run one at a time. Use when later iterations depend on earlier ones or to control API rate limits.

Context Scope with Versions

- name: extract_variants
versions:
range: [1, 3]

- name: analyze
dependencies: [extract_variants]
context_scope:
observe:
- extract_variants.* # Expands to all version namespaces

Reference specific iterations:

context_scope:
observe:
- extract_variants_1.specific_field
- extract_variants_2.specific_field

Debugging

Inspect expanded version actions:

agac inspect -a workflow_name

Enable prompt debug to see rendered prompts per iteration:

- name: extract_variants
versions:
range: [1, 3]
prompt_debug: true

See Also