Skip to content

Multi-Strategy Example

Compare different reasoning strategies on the same task.

Complete Code

import asyncio
from reactive_agents import ReactiveAgentBuilder, tool, ReasoningStrategies

@tool()
async def search(query: str) -> str:
    """Search for information.

    Args:
        query: The search query
    """
    # Simulated search results
    return f"Search results for '{query}': Found 3 relevant articles."


@tool()
async def analyze(data: str) -> str:
    """Analyze data and extract insights.

    Args:
        data: The data to analyze
    """
    return f"Analysis of '{data}': Key insight - positive trend detected."


async def create_agent(strategy: ReasoningStrategies, name: str):
    """Create an agent with a specific strategy."""
    return await (
        ReactiveAgentBuilder()
        .with_name(name)
        .with_model("ollama:llama3")
        .with_role("Research Analyst")
        .with_instructions(
            "You are a research analyst. Use available tools to gather "
            "information and provide thorough analysis."
        )
        .with_reasoning_strategy(strategy)
        .with_enable_dynamic_strategy_switching(False)  # Lock strategy
        .with_custom_tools([search, analyze])
        .with_max_iterations(15)
        .build()
    )


async def run_with_strategy(strategy: ReasoningStrategies, task: str):
    """Run a task with a specific strategy and report results."""
    name = f"{strategy.value}Agent"
    print(f"\n{'='*60}")
    print(f"Strategy: {strategy.value.upper()}")
    print(f"{'='*60}")

    agent = await create_agent(strategy, name)

    iteration_count = 0
    tools_used = []

    def on_iteration(e):
        nonlocal iteration_count
        iteration_count = e["iteration"]
        print(f"  Iteration {e['iteration']}: {e['strategy']}")

    def on_tool(e):
        tools_used.append(e["tool_name"])
        print(f"    -> Tool: {e['tool_name']}")

    agent.on_iteration_started(on_iteration)
    agent.on_tool_called(on_tool)

    async with agent:
        result = await agent.run(task)

        print(f"\nResults:")
        print(f"  Status: {result.status.value}")
        print(f"  Iterations: {iteration_count}")
        print(f"  Tools used: {', '.join(tools_used) or 'None'}")
        print(f"  Success: {result.was_successful()}")
        print(f"\nAnswer:\n{result.final_answer}")

    return {
        "strategy": strategy.value,
        "iterations": iteration_count,
        "tools_used": tools_used,
        "success": result.was_successful()
    }


async def main():
    task = (
        "Research the current trends in renewable energy and provide "
        "a brief analysis with key insights."
    )

    print(f"Task: {task}")

    # Test each strategy
    strategies = [
        ReasoningStrategies.REACTIVE,
        ReasoningStrategies.REFLECT_DECIDE_ACT,
        ReasoningStrategies.PLAN_EXECUTE_REFLECT,
    ]

    results = []
    for strategy in strategies:
        result = await run_with_strategy(strategy, task)
        results.append(result)

    # Summary comparison
    print(f"\n{'='*60}")
    print("STRATEGY COMPARISON SUMMARY")
    print(f"{'='*60}")
    print(f"{'Strategy':<25} {'Iterations':>10} {'Tools':>10} {'Success':>10}")
    print("-" * 60)
    for r in results:
        print(
            f"{r['strategy']:<25} "
            f"{r['iterations']:>10} "
            f"{len(r['tools_used']):>10} "
            f"{'Yes' if r['success'] else 'No':>10}"
        )


if __name__ == "__main__":
    asyncio.run(main())

Strategy Behaviors

REACTIVE Strategy

  • Approach: Direct prompt-response
  • Iterations: Usually 1-3
  • Best for: Simple, straightforward tasks
  • Behavior: Makes quick decisions, calls tools immediately if needed

REFLECT_DECIDE_ACT Strategy

  • Approach: Think before acting
  • Iterations: Usually 3-7
  • Best for: Tasks requiring careful consideration
  • Behavior: Reflects on progress, considers alternatives

PLAN_EXECUTE_REFLECT Strategy

  • Approach: Plan first, then execute
  • Iterations: Usually 5-15
  • Best for: Complex multi-step tasks
  • Behavior: Creates explicit plan, executes step by step

Expected Output

Task: Research the current trends in renewable energy...

============================================================
Strategy: REACTIVE
============================================================
  Iteration 1: reactive
    -> Tool: search
  Iteration 2: reactive
    -> Tool: analyze

Results:
  Status: complete
  Iterations: 2
  Tools used: search, analyze
  Success: Yes

Answer:
Based on my research, renewable energy trends show...

============================================================
Strategy: REFLECT_DECIDE_ACT
============================================================
  Iteration 1: reflect_decide_act
  Iteration 2: reflect_decide_act
    -> Tool: search
  Iteration 3: reflect_decide_act
  Iteration 4: reflect_decide_act
    -> Tool: analyze

Results:
  Status: complete
  Iterations: 4
  Tools used: search, analyze
  Success: Yes

Answer:
After careful reflection and research, here's my analysis...

============================================================
Strategy: PLAN_EXECUTE_REFLECT
============================================================
  Iteration 1: plan_execute_reflect
  Iteration 2: plan_execute_reflect
    -> Tool: search
  Iteration 3: plan_execute_reflect
  Iteration 4: plan_execute_reflect
    -> Tool: analyze
  Iteration 5: plan_execute_reflect
  Iteration 6: plan_execute_reflect

Results:
  Status: complete
  Iterations: 6
  Tools used: search, analyze
  Success: Yes

Answer:
Following my research plan:
1. Initial search revealed...
2. Analysis shows...
3. Key insights include...

============================================================
STRATEGY COMPARISON SUMMARY
============================================================
Strategy                  Iterations      Tools    Success
------------------------------------------------------------
reactive                           2          2        Yes
reflect_decide_act                 4          2        Yes
plan_execute_reflect               6          2        Yes

Choosing the Right Strategy

Use REACTIVE when:

  • Tasks are simple and well-defined
  • Quick responses are important
  • Tool calls are straightforward

Use REFLECT_DECIDE_ACT when:

  • Tasks require careful thought
  • Mistakes would be costly
  • You want more deliberate reasoning

Use PLAN_EXECUTE_REFLECT when:

  • Tasks have multiple steps
  • Order of operations matters
  • You need structured output

Use ADAPTIVE when:

  • Task complexity is unknown
  • You want the framework to decide
  • Tasks vary significantly