Skip to main content

Execution Policies

Execution policies define how an agent carries out its work. Agent Format standardizes the declarative configuration vocabulary for well-known orchestration patterns — ReAct, sequential pipelines, parallel fan-out, loops, batching, and conditional routing — enabling portable agent definitions that any compliant runtime can execute.

For detailed field-level tables for each policy config, see the Execution Policy Catalog.

The Dual-Namespace Convention

Execution policy IDs follow a two-namespace convention:

NamespaceOwnerExamples
agf.*Standard Committeeagf.react, agf.sequential, agf.parallel, agf.loop, agf.batch, agf.conditional
x-<vendor>.*Runtime/Vendorx-contoso.custom-react, x-myruntime.graph-policy

Standard policies (agf.*) are defined by the Standard Committee and have well-known semantics. Any compliant runtime that supports a given agf.* policy must produce equivalent semantic behavior for the same config. This enables portability — an agent using agf.react works on any runtime that implements the standard ReAct policy.

Vendor policies (x-<vendor>.*) are owned by the runtime or vendor. The x- prefix signals "this namespace is runtime-owned, not the standard." Any runtime can define custom policy IDs without coordinating with the Standard Committee. This is borrowed from HTTP headers (X-Request-Id) and API conventions.

Standard vs. Vendor Config Validation

The schema validates execution policy config at two levels:

Standard policies (agf.*) have config structures defined by the standard. The JSON Schema uses conditional validation (allOf with if/then) to apply the correct config schema based on the policy id. For example, when id is agf.react, the schema validates config against ReactConfig; when id is agf.sequential, it validates against SequentialConfig. This ensures that Agent Owners get schema-level validation for all standard policy fields.

Vendor policies (x-<vendor>.*) have opaque config — the schema validates only that config is an object. Vendor config structures are defined by the runtime, not the standard.

This dual-level approach balances portability with extensibility: standard policies are portable and validated; vendor policies are flexible and unconstrained.

Shared Building Blocks

Multi-agent policies (agf.sequential, agf.parallel, agf.loop, agf.batch, agf.conditional) share a set of reusable types that provide consistent patterns across all orchestration strategies.

PolicyStep

A PolicyStep defines a sub-agent invocation within a policy. It references a local_agents[] entry by alias and optionally maps input fields.

FieldTypeRequiredDescription
agentstringYesAlias of the sub-agent to invoke (must match a local_agents[].alias).
input_mappingmap[string->string]NoMaps agent input fields to path expressions referencing parent input or prior step output.

Path expression syntax: <source>.<direction>.<field> where <source> is parent or a step's agent alias, <direction> is input or output, and <field> is a field name.

ExpressionMeaning
parent.input.queryThe parent agent's query input field
researcher.output.findingsThe researcher step's findings output field
parent.input.items.[].valueEach item's value in the parent's items array (Batch only — the .[] operator is valid only in BatchConfig.input_mapping)

OutputFrom

OutputFrom declares how the final output of a multi-agent policy is derived from sub-agent results. It supports a string shorthand or an object form.

String shorthand:

ValueMeaning
An agent alias (e.g., "reviewer")That agent's output becomes the policy output
"last"The last step's output (default for sequential and loop)
"merge"Merge all sub-agent outputs into a single object keyed by agent alias (default for parallel)
"first"The first completed agent's output

Object form — exactly one of agent, strategy, or custom_transform must be set (mutually exclusive):

FieldTypeDescription
agentstringAlias of the sub-agent whose output becomes the policy output.
strategystring (enum: last, merge, first)Built-in output strategy.
custom_transformstringReference to a runtime-registered transformation function. Convention: <org>.<transform-name> (e.g., myorg.summarize_outputs). The runtime passes all sub-agent outputs to this function and uses its return value.
descriptionstringHuman-readable description of the output selection logic. For documentation only.
# String shorthand — last step's output
output_from: "last"

# String shorthand — specific agent
output_from: "reviewer"

# Object form — custom transform
output_from:
custom_transform: "myorg.summarize_pipeline_outputs"
description: "Summarize all step outputs into a single executive report"

Merge Strategy Semantics

The merge strategy produces an object keyed by agent alias, where each key is the alias of a sub-agent and the corresponding value is that agent's complete output (any JSON type). This deterministic algorithm avoids key conflicts and handles non-object outputs uniformly.

For agf.parallel:

// Given parallel agents: food_expert, movie_expert
{
"food_expert": { "recommendation": "Sushi" },
"movie_expert": { "recommendation": "Inception" }
}

For agf.sequential and agf.loop (when output_from: "merge" is explicitly set):

The result includes the output of each step, keyed by alias. For agf.loop, only the final iteration's step outputs are included.

// Given sequential steps: researcher, writer
{
"researcher": { "findings": "..." },
"writer": { "draft": "..." }
}

Normative rules:

  1. The merge result MUST be a JSON object with one key per sub-agent alias.
  2. Each value MUST be the sub-agent's complete output value (object, array, string, number, boolean, or null).
  3. Key order in the result object MUST follow the declaration order in agents[] (parallel) or steps[] (sequential/loop), not completion order.
  4. If two sub-agents share the same alias (which is forbidden by the alias uniqueness rule on action space arrays), the runtime MUST reject the configuration at load time.
String Ambiguity Resolution

When output_from is a string, it is resolved as follows: first check if the value matches a strategy keyword (last, merge, first); if it does, apply that strategy. Otherwise, treat it as an agent alias. This means agent aliases MUST NOT be named last, merge, or first — the strategy keywords take priority. Use the object form ({ agent: "last" }) if an agent alias conflicts with a keyword.

ConditionGroup

The ConditionGroup type is reused by execution policies for exit_condition (Loop) and when (Conditional). Conditions can be a single ConditionGroup (AND semantics) or an array of ConditionGroups (OR-of-ANDs). Path expressions in field names reference the execution context (e.g., parent.input.* or step outputs).

Standard Policy Catalog

The standard defines six execution policies under the agf.* namespace. All compliant runtimes MUST implement agf.react. The remaining standard policies (agf.sequential, agf.parallel, agf.loop, agf.batch, agf.conditional) are RECOMMENDED — runtimes SHOULD implement them for full portability. A runtime that receives a standard policy it does not implement MUST return a clear error identifying the unsupported policy.

ReAct (agf.react)

The agent iterates through reasoning and acting cycles, using tools to gather information before producing a final response.

execution_policy:
id: agf.react
config:
instructions: |
You are a helpful assistant with access to tools.
provider: google
model: gemini-2.5-pro
temperature: 0.3
max_steps: 10
tool_choice: auto

Preferences vs. Constraints

ReactConfig fields fall into two semantic categories:

CategoryFieldsRuntime obligation
Constraintsmax_stepsThe runtime MUST honor these values. They are hard limits that bound agent behavior.
Preferencesprovider, model, temperature, top_p, top_k, max_output_tokens, stop_sequences, tool_choice, user_prompt_templateThe runtime SHOULD honor these when possible, but MAY override them based on deployment policy, model availability, or organizational rules. They express the Agent Owner's intent, not a binding requirement.

The instructions field is neither — it is the agent's core identity and MUST be passed to the underlying model verbatim (the runtime MUST NOT modify it, though governance policies may augment it).

This distinction aligns with the WHAT vs. HOW principle: the Agent Owner declares desired behavior (preferences) and safety bounds (constraints); the Runtime Owner decides how to fulfill them. It is analogous to Kubernetes requests (preferences) vs. limits (constraints) — the scheduler honors requests when feasible but guarantees limits.

Sequential (agf.sequential)

Steps execute in order. Each step is a PolicyStep sub-agent invocation. Output from one step can be mapped as input to the next via input_mapping. The output_from field determines the policy's final output (default: last step).

execution_policy:
id: agf.sequential
config:
steps:
- agent: writer
input_mapping:
topic: "parent.input.topic"
- agent: editor
input_mapping:
draft: "writer.output.draft"
output_from: "editor"

Parallel (agf.parallel)

Multiple sub-agents execute concurrently. All results are combined when all complete. The output_from field determines the policy's final output (default: merge all outputs).

execution_policy:
id: agf.parallel
config:
agents:
- agent: food_expert
input_mapping:
mood: "parent.input.mood"
- agent: movie_expert
input_mapping:
mood: "parent.input.mood"
output_from: "merge"

Loop (agf.loop)

Steps repeat each iteration until exit_condition is satisfied or max_iterations is reached. The exit_condition uses ConditionGroup matchers. When max_iterations is reached without the exit_condition being satisfied, the runtime MUST stop the loop and return the output from the most recent iteration. The runtime SHOULD emit a warning indicating the loop was terminated by the iteration limit rather than the exit condition.

execution_policy:
id: agf.loop
config:
steps:
- agent: writer
input_mapping:
topic: "parent.input.topic"
- agent: quality_checker
input_mapping:
draft: "writer.output.draft"
max_iterations: 5
exit_condition:
args_match:
quality_checker.output.score: { gte: 0.8 }
output_from: "writer"

Batch (agf.batch)

A single sub-agent processes each item from an input collection independently. The input_mapping must contain at least one field with [] array iteration syntax. The policy output is always an array of per-item results.

execution_policy:
id: agf.batch
config:
agent: item_processor
input_mapping:
item: "parent.input.items.[].value"
max_batch_count: 100

Conditional (agf.conditional)

Evaluates conditions in order and routes to the first matching sub-agent. Conditions use ConditionGroup matchers. A default_agent handles the fallback when no route matches.

execution_policy:
id: agf.conditional
config:
routes:
- when:
args_match:
parent.input.language: { in: ["zh", "ja", "ko"] }
agent: cjk_translator
input_mapping:
text: "parent.input.text"
- when:
args_match:
parent.input.language: "en"
agent: english_processor
default_agent: generic_handler

Registering Custom Policies

Any SDK can register custom execution policies. The convention is:

  1. Choose an id with the x-<vendor> prefix (e.g., x-myruntime.custom-policy)
  2. Implement the policy in the SDK's execution engine
  3. Document the config structure for Agent Owners

The Standard Committee does not gate custom policies. The x-<vendor>.* namespace ensures no naming collisions with standard-defined policies (agf.*).