Execution Strategies

A strategy controls how an agent reasons and produces its final answer. Pass a strategy to any agent's strategy parameter to change its reasoning loop. The default ReActStrategy works for most tool-calling tasks; the options below cover more demanding scenarios.

Prerequisites: Agents · Next: Workflows · Directives

ReActStrategy

The default strategy. It runs a Reasoning + Acting loop:

  1. Call the LLM with the current messages and available tools
  2. If the LLM returns tool calls, execute them and add the results to the conversation
  3. Repeat until the LLM returns a text response with no tool calls
from sagewai import UniversalAgent, ReActStrategy

agent = UniversalAgent(
    name="react-agent",
    model="gpt-4o",
    strategy=ReActStrategy(),
    max_iterations=10,
)

ReAct covers most tool-calling use cases:

  • Question-answering with tool access
  • Data retrieval and processing
  • Single-step or low-complexity tasks

TreeOfThoughtsStrategy

Generates multiple candidate reasoning paths, scores them, and picks the best one. Use this when the first approach the LLM takes is often not the right one.

from sagewai import UniversalAgent, TreeOfThoughtsStrategy

strategy = TreeOfThoughtsStrategy(
    num_branches=3,
    max_depth=3,
    evaluation_model=None,  # Use the same model for evaluation
)

agent = UniversalAgent(
    name="creative-agent",
    model="gpt-4o",
    strategy=strategy,
)

How It Works

  1. Generate num_branches candidate reasoning paths
  2. Score each path with the LLM
  3. Continue with the highest-scoring path
  4. Repeat up to max_depth levels

Good fit for:

  • Creative writing where quality matters more than speed
  • Problems with several plausible approaches
  • Tasks where you want the LLM to consider alternatives before committing

LATSStrategy

Monte Carlo Tree Search adapted for LLM agents. It balances exploration (trying new paths) and exploitation (deepening promising ones) through simulated rollouts.

from sagewai import UniversalAgent, LATSStrategy

strategy = LATSStrategy(
    num_simulations=5,
    exploration_weight=1.4,
    max_depth=4,
)

agent = UniversalAgent(
    name="lats-agent",
    model="gpt-4o",
    strategy=strategy,
)

How It Works

  1. Select — Pick the most promising node using UCB1
  2. Expand — Generate a new child reasoning step
  3. Simulate — Roll out to a terminal state
  4. Backpropagate — Update scores up the tree

Good fit for:

  • Mathematical reasoning
  • Code generation where you can validate correctness
  • Problems with clear success/failure criteria

SelfCorrectionStrategy

After the agent produces output, validate it against rules you define. If the output fails validation, inject the error and an exemplar as feedback, then re-run. Repeat up to max_corrections times.

from sagewai import UniversalAgent, SelfCorrectionStrategy
from sagewai.core.self_correction import OutputValidator, ExemplarStore, FailureExemplar

validator = OutputValidator()
validator.add_json_validator(required_fields=["title", "body", "tags"])
validator.add_length_validator(min_length=100, max_length=5000)

exemplar_store = ExemplarStore()
exemplar_store.add(FailureExemplar(
    error_type="missing_required_fields",
    bad_output='{"title": "Test"}',
    correction_prompt="Output is missing 'body' and 'tags' fields.",
    corrected_output='{"title": "Test", "body": "Content here.", "tags": ["test"]}',
))

strategy = SelfCorrectionStrategy(
    max_corrections=3,
    validator=validator,
    exemplar_store=exemplar_store,
)

agent = UniversalAgent(
    name="structured-agent",
    model="gpt-4o",
    strategy=strategy,
)

How It Works

  1. Run the agent's normal reasoning loop
  2. Validate output against your rules
  3. If invalid, add the error message and a matching exemplar to the conversation
  4. Re-run the agent with that feedback
  5. Repeat up to max_corrections times

Good fit for:

  • Structured output (JSON, XML, CSV)
  • Schema compliance where a partial response is not acceptable

PlanningStrategy

Break the goal into explicit steps, then execute them in sequence. Optionally reflect after each step to revise the remaining plan.

from sagewai import UniversalAgent, PlanningStrategy

# Plan once, execute all steps
strategy = PlanningStrategy(
    mode="plan_then_act",
    max_steps=5,
)

# Or plan, act, reflect, and revise as you go
strategy = PlanningStrategy(
    mode="plan_act_reflect",
    max_steps=10,
)

agent = UniversalAgent(
    name="planner",
    model="gpt-4o",
    strategy=strategy,
)

Modes

ModeBehavior
plan_then_actGenerate the full plan upfront, then execute each step in order
plan_act_reflectPlan, execute step 1, reflect on the result, optionally revise remaining steps, continue

Good fit for:

  • Multi-step research tasks
  • Report generation
  • Tasks where writing out a plan first improves output quality

RoutingStrategy

Route user messages to different specialist agents based on intent. Supports keyword heuristics (no extra LLM call) or LLM-based classification.

from sagewai import UniversalAgent, RoutingStrategy

greeter = UniversalAgent(name="greeter", system_prompt="You greet users warmly.")
researcher = UniversalAgent(name="researcher", system_prompt="You research topics.")
coder = UniversalAgent(name="coder", system_prompt="You write code.")
fallback = UniversalAgent(name="fallback", system_prompt="General assistant.")

# Keyword routing — fast, no extra LLM call
strategy = RoutingStrategy(
    routes={"greet": greeter, "research": researcher, "code": coder},
    fallback=fallback,
    method="heuristic",
    keywords={
        "greet": ["hello", "hi", "hey"],
        "research": ["find", "search", "look up"],
        "code": ["write code", "implement", "function"],
    },
)

# LLM routing — the host agent classifies intent
strategy = RoutingStrategy(
    routes={"greet": greeter, "research": researcher, "code": coder},
    fallback=fallback,
    method="llm",
)

Good fit for:

  • Customer support bots (route to billing, technical, general)
  • Multi-domain assistants
  • Reducing latency by sending simple queries to cheaper models

Tip: For deterministic condition-based routing without a strategy, use ConditionalAgent instead.


Choosing a Strategy

StrategySpeedQualityUse Case
ReActStrategyFastGoodGeneral tool-calling tasks
TreeOfThoughtsStrategySlowHighCreative, multi-path reasoning
LATSStrategySlowHighestMathematical, code with validation
SelfCorrectionStrategyMediumHighStructured output, schema compliance
PlanningStrategyMediumHighMulti-step research, report generation
RoutingStrategyFastVariesMulti-domain, intent-based routing

Strategies compose. For example, you can put RoutingStrategy at the top level to route to specialist agents that each use SelfCorrectionStrategy for structured output.


Custom Strategies

Implement the ExecutionStrategy protocol to write your own strategy:

from sagewai import ExecutionStrategy, BaseAgent, ChatMessage
from sagewai.models.tool import ToolSpec

class MyStrategy:
    async def execute(
        self,
        agent: BaseAgent,
        messages: list[ChatMessage],
        tools: list[ToolSpec],
        max_iterations: int,
    ) -> ChatMessage:
        # Your custom reasoning loop here.
        # _call_llm is a protected API for strategy subclasses —
        # application code should use agent.chat() instead.
        response = await agent._call_llm(messages, tools)
        return response

_call_llm is part of the execution contract for strategy subclasses. Call it from strategy code; use agent.chat() from application code.


What's Next

  • Workflows — Durable multi-step execution with checkpointing and human approval
  • Agents — Agent types and composition patterns
  • Directives — Prompt preprocessing with model-aware formatting