← Back to Whitepapers Architecture

Whitepaper 09: Orchestrator Design Patterns for AI Security Agents

Author: Khushal Suthar Date: June 2026 Series: Autonomous Penetration Testing with AI Agents Category: Systems Design — Coordination Patterns


Executive Summary

The orchestrator is the brain of an autonomous pentesting system. It does not find vulnerabilities or run exploits; it decides what to work on next, which agent should do it, how to combine results, and when to stop. A well-designed orchestrator multiplies the effectiveness of its sub-agents; a poorly-designed one creates contention, wasted work, and missed correlations. This paper catalogs the design patterns that have proven effective for orchestrating AI security agents, drawn from production autonomous pentesting systems and adjacent multi-agent literature. Each pattern is presented with its structure, strengths, failure modes, code structure, example scenario, and guidance on when to apply it.

We catalog eight orchestration patterns — Sequential Pipeline, Parallel Fan-Out, Event-Driven, Hierarchical, Hybrid, Planner-Executor, Blackboard, and Competitive — along with four anti-patterns that consistently fail in production. A selection matrix maps engagement characteristics to recommended patterns. Cross-cutting concerns — error handling, state management, observability, budget enforcement, and conflict resolution — are examined in detail. Finally, we show how the Custom Orchestrator introduced in Whitepaper 03 (wp03) implements a Hybrid pattern, combining pipeline flow, parallel dispatch, and event-driven triggers into a single adaptive coordinator.


1. The Orchestrator's Job

Before cataloging patterns, we must define the orchestrator's responsibilities precisely. The orchestrator is the executive function of the system. Its job is:

  • Goal decomposition: Translate engagement objectives ("assess the security of this /24 and the web app on 10.0.0.5") into phase-level and task-level sub-goals.
  • Resource allocation: Decide which sub-agent works on which target, in what order, with what model tier and context budget.
  • Flow control: Determine when to move from one phase to the next, when to parallelize, when to wait, when to escalate.
  • Synthesis: Combine findings from multiple sub-agents into a coherent world model and attack chains.
  • Termination: Decide when the engagement is complete — when enough of the attack surface has been explored, enough chains have been attempted, and the marginal value of continued work is low.
  • The orchestrator does not interpret tool output, select specific exploits, or write findings. That is the sub-agents' job. The orchestrator operates at a higher level of abstraction — phases, targets, agents — and its context is correspondingly small (engagement state, not tool output).

    This separation is deliberate: an orchestrator that also does detailed reasoning becomes a single-agent system with extra steps, inheriting all the context-window and cost problems of single-agent design (Whitepapers 06, 07). The orchestrator's context budget should be measured in hundreds of findings, not thousands of tool outputs. It reasons over summaries and structured state, not raw packets and command output.

    Design Principles

    All patterns in this catalog adhere to four design principles:

    This adaptive switching is controlled by a strategy policy function that evaluates engagement state (budget remaining, findings produced, phase progress, time elapsed) and selects the appropriate pattern configuration.

    Concrete Implementation Sketch

    class CustomOrchestrator(HybridOrchestrator):
    

    """The wp03 Custom Orchestrator — a Hybrid pattern implementation."""

    def __init__(self, config): super().__init__( world_model=WorldModel(config.world_model_config), agent_factory=AgentFactory(config.agent_configs), budget_ledger=BudgetLedger(config.total_budget), triggers=self.build_triggers(config.triggers), ) self.strategy_policy = StrategyPolicy(config.strategy_config) self.current_strategy = "hybrid_aggressive"

    def build_triggers(self, trigger_configs): triggers = [] for tc in trigger_configs: triggers.append(Trigger( condition=tc.condition, agent_type=tc.agent_type, priority=tc.priority, budget_cap=tc.budget_cap, cooldown=tc.cooldown, concurrency_limit=tc.concurrency_limit, )) return triggers

    async def run(self, engagement): while not self.termination_condition(): # Adaptive strategy selection new_strategy = self.strategy_policy.evaluate( budget=self.budget.remaining(), phase=self.current_phase, findings=self.world_model.finding_count(), time_elapsed=engagement.elapsed(), ) if new_strategy != self.current_strategy: self.switch_strategy(new_strategy)

    # Dispatch from priority queue await self.dispatch_available_tasks()

    # Check phase advancement if self.exit_criteria_met(self.current_phase): self.advance_phase()

    # Check progress (deadlock/livelock detection) status = self.progress_monitor.check() if status == ProgressStatus.DEADLOCKED: self.handle_deadlock() elif status == ProgressStatus.LIVELOCKED: self.handle_livelock()

    await asyncio.sleep(POLL_INTERVAL)

    def switch_strategy(self, new_strategy): self.telemetry.log_pattern_switch( from_pattern=self.current_strategy, to_pattern=new_strategy, reason=self.strategy_policy.last_reason, ) self.current_strategy = new_strategy self.apply_strategy_config(new_strategy)

    def apply_strategy_config(self, strategy): config = STRATEGY_CONFIGS[strategy] self.max_concurrency = config.max_concurrency self.trigger_filter = config.trigger_filter # which triggers are active self.budget.per_agent_cap = config.per_agent_cap

    This implementation shows how the Hybrid pattern is not a single rigid design but a configurable framework. The Custom Orchestrator uses the same priority-queue, phase-based, trigger-driven core throughout the engagement, but tunes its parameters (concurrency, trigger filter, budget caps) based on the current strategy. This is pattern-aware orchestration in practice.


    6. Anti-Patterns

    Several orchestration designs are temptingly simple but consistently fail in practice. Each anti-pattern is presented with its failure mode and a fix.

    Anti-Pattern 1: Mega-Orchestrator

    Description: The orchestrator does all reasoning itself, using sub-agents only as "tool runners" with no autonomy. The orchestrator reads tool output, decides what tool to run next, and sends commands to sub-agents who merely execute.

    Failure mode: The orchestrator's context grows unboundedly as it ingests every tool output from every sub-agent. It becomes the bottleneck — all work serializes through it. The system collapses to a single-agent system with the context and cost problems of single-agent design (Whitepapers 06, 07), but with additional coordination overhead. Budget is consumed by the orchestrator's reasoning, not by sub-agent work.

    Fix: Sub-agents should make decisions, not just execute. The orchestrator delegates objectives ("enumerate this host and identify vulnerabilities"), not instructions ("run nmap with these flags, then run nikto, then check for CVE-2023-XXXX"). The orchestrator's context contains summaries and findings, not tool output.

    Anti-Pattern 2: Free-For-All Blackboard

    Description: All agents read and write to a shared blackboard with no coordination layer. Each agent monitors the blackboard and acts autonomously on what it finds. There is no orchestrator deciding what to work on next.

    Failure mode: Agents duplicate work (two agents both enumerate the same host because both saw it on the blackboard and neither knew the other was working on it). Agents miss obvious attack chains because each agent sees only its piece of the puzzle — no agent has the global view needed to connect a credential from agent A with a service from agent B. The system never terminates because no agent is responsible for deciding when the engagement is done.

    Fix: The blackboard is a substrate, not an orchestrator. Add an explicit coordination layer — any of Patterns 1–6 or the Hybrid pattern. The coordinator assigns work units, prevents duplication, runs synthesis, and decides termination. Agents write to the blackboard but do not self-dispatch; the coordinator dispatches based on blackboard state and engagement objectives.

    Anti-Pattern 3: Perpetual Re-Planning

    Description: The planner re-plans after every task completion, producing a new plan each time. The system spends more time planning than executing, and the plan is never stable enough to execute fully.

    Failure mode: Each re-plan is a large LLM call that consumes budget and time. By the time the new plan is ready, several tasks have completed and the plan is already stale, triggering another re-plan. The system enters a planning loop where execution never gains momentum. In the worst case, the planner produces a different plan each time even when the engagement state hasn't meaningfully changed, leading to inconsistent and unpredictable behavior.

    Fix: Re-plan only on failure or on significant assumption violation — not on every task completion. Define explicit re-plan triggers: (1) a task failed in a way that invalidates the plan's assumptions, (2) a finding was discovered that opens a significantly better path, (3) the budget is running low and the plan needs to be prioritized. Between re-plans, execute the plan as-is. If the plan becomes stale, let executors adapt within their delegated scope rather than triggering a global re-plan.

    Anti-Pattern 4: Budgetless Parallelism

    Description: The orchestrator dispatches unlimited parallel agents without budget enforcement. Each agent is free to make as many calls as it wants, for as long as it wants.

    Failure mode: One cascade — a subnet that expands into thousands of findings, or an event-driven trigger that fires repeatedly — spawns thousands of agent calls, exhausting the engagement budget in the first hour. The system has no mechanism to stop runaway agents. In the worst case, the API rate limit is hit and all agents fail simultaneously, producing a burst of errors and no useful findings. The operator discovers that 90% of the budget was spent on a single subnet that turned out to be uninteresting, while the critical target was never assessed.

    Fix: Per-agent budget caps and a global concurrency limit. No agent is dispatched without an allocated budget. The budget is checked before every LLM call, and the agent terminates gracefully when exhausted. The global concurrency limit prevents resource exhaustion (API rate limits, memory, CPU). The orchestrator monitors aggregate budget burn rate and reduces concurrency or triggers strategy-switching if burn rate is too high.


    7. Conclusion

    Orchestration is the art of coordinating multiple cognitive agents toward a shared objective. In autonomous pentesting, the objective is complex (find and exploit vulnerabilities across a network), the agents are imperfect (LLMs that hallucinate, misjudge, and miss), and the environment is adversarial (the target does not cooperate). The orchestrator's job is to produce a coherent, thorough assessment despite these imperfections.

    The eight patterns in this paper are not theoretical constructs — they are the patterns that work. They have been validated in systems that run real engagements against real infrastructure. The choice among them is not aesthetic; it is driven by the engagement's structure, the system's budget, and the acceptable level of risk.

    The four anti-patterns are the patterns that do not work, despite their apparent simplicity. They are worth naming explicitly because every team that builds an autonomous pentesting system is tempted by at least one of them. The Mega-Orchestrator seems like the "obvious" design — let the smartest model do the thinking. The Free-For-All Blackboard seems elegant — let agents self-organize. Perpetual Re-Planning seems thorough — always have the best plan. Budgetless Parallelism seems powerful — throw everything at the problem. Each fails for specific, predictable reasons, and each has a known fix.

    The most important design principle is this: the orchestrator should be adaptive, not fixed. Engagements vary. A fixed orchestration strategy will be optimal for some and disastrous for others. The mature system recognizes this and adapts its strategy as the engagement unfolds — faster on simple targets, more deliberate on complex ones, aggressive when a critical finding demands immediate follow-up, and conservative when the budget is running low.

    The Hybrid pattern, as implemented by the Custom Orchestrator (wp03), is the recommended default for production systems. It combines the predictability of the pipeline, the speed of parallel dispatch, and the responsiveness of event-driven triggers in a single adaptive framework. Its priority-queue dispatch, configurable concurrency, and strategy-switching policy provide the flexibility to handle the full range of engagement conditions — from a single-host assessment to a multi-domain enterprise engagement — without changing the core architecture.

    In the final paper of this series, we look forward: where is AI pentesting headed, and what does the trajectory mean for defenders, attackers, and the practice of security assessment itself?


    This whitepaper is part of a series on autonomous penetration testing with AI agents. For the full series index and related work, see the accompanying documentation.