Step 3 · Scouting Department
The pattern: a ParallelAgent starts its sub-agents at the same time, each writing its own state key. A SequentialAgent around it lets a report writer merge the results afterwards.
One scout covers Gaziantep's attack, one their defence, one cards and the referee. None needs the others' work, so there's no reason to wait:
steps/step3_scouting_dept/agent.py report_writer = LlmAgent(
name="report_writer",
model=MODEL,
instruction="""Merge three scouting reports into one brief for Trabzonspor's coaches.
Attack report: {attack_report}
Defense report: {defense_report}
Discipline report: {discipline_report}
Write four short sections: Threats, Weaknesses to attack, Discipline and referee, Three key takeaways.
Use only facts from the reports; if they disagree, say so.""" + HOUSE_RULES,
output_key="scouting_brief",
)
scouts = ParallelAgent(name="scouts", sub_agents=[attack_scout, defense_scout, discipline_scout])
return SequentialAgent(name=name, description=description, sub_agents=[scouts, report_writer])The scouts' instructions don't name the opponent; each starts with get_match_info to find out. No instruction in this repo hardcodes a fact from the data, so a new fixture is just new JSON.
I asked: "Scout Gaziantep for us."
The three scouts made ten tool calls between them, all at once, and the writer merged their reports in 43 seconds. From the brief, trimmed:
Weaknesses to Attack
- Second-half defensive collapse (last 10 matches – 15 goals conceded, 1.5 avg, 1.63 avg xGA across 9 matches with xG data):
- 10 of 15 goals conceded (67%) came in the second half.
- Vulnerability peaks heavily in 46–60 min (4 conceded, 27%) and 76–90 min (5 conceded, 33%).
Three Key Takeaways
- Exploit the decimated backline: Gaziantep's defensive anchor Myenty Abena is suspended, while starting goalkeeper Kacper Tobiasz and three central defenders (Meleke, Kızıldağ, Sangaré) are doubtful with muscle injuries. …
Use it when you have independent questions about the same thing: three searches, three reviewers, three data sources.
Avoid it when one task needs another's answer, or when the parallel work writes to the same state key.
The gotcha: something has to merge the results. A ParallelAgent gives you three answers in whatever order they finished, not one. Give every parallel agent its own output_key, then add a step that reads them all. Parallel also means more requests per second, which is where a free key starts hitting rate limits.