Skip to content

fix(handoff): prevent infinite router loop in HANDOFF multi-agent strategy#1279

Closed
shaileshpadave wants to merge 5 commits into
agentspan_updatefrom
fix/handoff-loop-termination
Closed

fix(handoff): prevent infinite router loop in HANDOFF multi-agent strategy#1279
shaileshpadave wants to merge 5 commits into
agentspan_updatefrom
fix/handoff-loop-termination

Conversation

@shaileshpadave

@shaileshpadave shaileshpadave commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What was the problem?

When running a HANDOFF multi-agent setup (like 13_hierarchical_agents.py), the router LLM would keep re-calling agents that had already responded instead of saying DONE — causing the workflow to loop indefinitely until it hit the 100-turn hard cap.

Two things caused this:

  1. The router had no memory of who already spoke. Nothing in the prompt told the LLM that an agent it already routed to had responded. So it would happily route to the same agent again and again.

  2. The default turn limit was too high. The default max turns was 100, so even with a bad router decision the loop would grind through all 100 iterations before stopping. For a 3-agent team, the loop should stop after at most 4 turns — not 100.

How we fixed it

  • Router prompt rewritten — the router is now told each agent may be called at most once. Agents that have already responded leave a visible marker in the conversation history, and the router is instructed to say DONE once all needed agents have replied.

  • Smarter default turn limit — the default max turns for HANDOFF is now number of agents + 1 instead of 100. This means a 2-agent team caps at 3 turns, a 5-agent team at 6, and so on. Explicit maxTurns settings still override this.

Verified

Ran 13_hierarchical_agents.py (CEO → Engineering Lead → Backend Dev) against the fixed server — completed cleanly with no looping.

…ategy

Two changes stop the HANDOFF loop from running indefinitely:

1. AgentConfig.maxTurns default changed from 100 to 0 (unset sentinel)
   All compiler strategy defaults now activate correctly — HANDOFF uses
   agents.size() + 1 turns (one per agent plus one final DONE check),
   single-agent loops default to 25, swarm loops to 100. Previously the
   default of 100 caused every strategy to effectively ignore its
   natural cap.

2. Router system prompt rewritten to prevent re-delegation
   The router is now told each agent may be called AT MOST ONCE, that a
   responded agent is marked with "[agent_name]:" in conversation history,
   and to respond DONE once all needed agents have replied. Previously the
   prompt encouraged re-routing to agents that had already responded.

Tests added:
- testHandoffDefaultMaxTurnsIsNumAgentsPlusOne: 3-agent HANDOFF → loop < 4
- testHandoffExplicitMaxTurnsIsRespected: .maxTurns(10) → loop < 10
- testHandoffRouterPromptPreventsReDelegation: prompt contains AT MOST ONCE
@shaileshpadave

Copy link
Copy Markdown
Contributor Author

The SDK default is 25, but users can pass any value they want:

ceo = Agent(
name="ceo",
instructions="...",
max_turns=5,
)

so lets not have pr for this

@shaileshpadave
shaileshpadave deleted the fix/handoff-loop-termination branch July 13, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant