Lightweight agent handoffs vs heavyweight multi-agent frameworks
OpenAI Swarm introduces an elegant, minimalist pattern for multi-agent coordination centered on stateless routines and function-based handoffs.
Instead of passing global credentials to a monolithic agent that both reasons about user requests and sends emails, Swarm enables strict separation of concerns: a Front-Line Triage Agent analyzes customer queries and hands off execution to an Outbound Specialist Agent that alone holds scoped credentials.
| Agent Role | Tools Available | Credential Scope | Failure Blast Radius |
|---|---|---|---|
| Triage Agent | transfer_to_email_agent | Zero external credentials | No capability to send mail or touch APIs |
| Research Agent | vector_search, query_db | Read-only document access | Cannot alter state or contact users |
| Outbound Sender | send_transactional_email | Scoped SadaSend key (allowlist locked) | Can only email verified company domains |
Implementing the Swarm Handoff Pattern in Python
Here is how to structure a triage agent that inspects customer questions and transfers control to a dedicated email dispatcher with allowlist validation:
from swarm import Swarm, Agent
import requests
import os
client = Swarm()
def send_transactional_email(to_email: str, subject: str, message: str) -> str:
"""Dispatches email via SadaSend scoped credentials."""
res = requests.post(
"https://api.sadasend.com/emails",
headers={
"Authorization": f"Bearer {os.getenv('SADASEND_AGENT_KEY')}",
"Content-Type": "application/json",
"Idempotency-Key": f"swarm_{hash(to_email + subject)}",
},
json={"to": to_email, "subject": subject, "text": message}
)
return "Dispatched" if res.status_code == 200 else f"Failed: {res.text}"
# Dedicated Outbound Specialist
email_agent = Agent(
name="Outbound Email Agent",
instructions="You are a dedicated sender. Format the email clearly and call send_transactional_email.",
functions=[send_transactional_email]
)
def transfer_to_email_agent():
"""Handoff function for triage agent."""
return email_agent
# Front-line Triage Agent (No email execution tools)
triage_agent = Agent(
name="Triage Agent",
instructions="Determine if the user requires an email notification. If yes, transfer to Outbound Email Agent.",
functions=[transfer_to_email_agent]
)
response = client.run(
agent=triage_agent,
messages=[{"role": "user", "content": "Please send a confirmation email to sam@partner.io about project launch."}]
)
print(response.messages[-1]["content"])Security isolation and defense-in-depth benefits
- Triage and reasoning agents never hold API secrets in their context window.
- Tool execution is localized to leaf agents with explicit recipient allowlists.
- Zero bloat: Python execution finishes in milliseconds without heavyweight background daemons or graph serialization.
Building AI agents that send email?
Scoped API keys, per-key recipient allowlists, approval mode and a hosted MCP server with ten tools — on the free plan, without a card.