The round-robin pattern
Distribute tasks evenly across multiple agents using a rotating sequence to ensure fair workload distribution and prevent any single agent from being overloaded.
Distribute incoming tasks evenly across multiple agents in a fixed rotation sequence. Each agent processes tasks in turn, ensuring fair workload distribution and preventing any single agent from being overwhelmed.
When to use this pattern
Section titled “When to use this pattern”The round-robin pattern works well when you need to:
- Distribute high-volume tasks evenly across multiple agents
- Prevent workload concentration on any single agent
- Ensure fair processing where each agent gets equal opportunity
- Maintain diverse perspectives by rotating agents through different tasks
Example use case
Section titled “Example use case”A social media platform receives flagged content for moderation review. Three moderator agents review flagged posts in rotation:
- Agent A reviews posts 1, 4, 7, 10…
- Agent B reviews posts 2, 5, 8, 11…
- Agent C reviews posts 3, 6, 9, 12…
This approach ensures each moderator handles an equal share of reviews, prevents any single moderator from being overloaded, and exposes each moderator to diverse content types. Each agent maintains memory of previous decisions, learning moderation patterns and policy edge cases over time.
How it works
Section titled “How it works”The pattern uses three key components:
- A pool of agents with similar capabilities that process tasks independently.
- A rotation index maintained by the client to track which agent receives the next task.
- Client orchestration that distributes tasks sequentially to agents in the rotation order.
The client orchestrates the workflow:
- The client maintains a list of agents in rotation order.
- For each incoming task, the client sends it to the current agent in the sequence.
- The client advances the rotation index to the next agent.
- When the index reaches the end of the list, it wraps back to the first agent.
Implementation
Section titled “Implementation”Implement a round-robin pattern using the following steps.
Step 1: Create the pool of agents
Section titled “Step 1: Create the pool of agents”Create multiple agents with similar capabilities. These agents will process tasks in rotation:
from letta_client import Lettaimport os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Create three moderator agentsmoderator_a = client.agents.create( name="moderator_a", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I review flagged social media posts for policy violations. I evaluate content against community guidelines and make moderation decisions." }])
moderator_b = client.agents.create( name="moderator_b", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I review flagged social media posts for policy violations. I evaluate content against community guidelines and make moderation decisions." }])
moderator_c = client.agents.create( name="moderator_c", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I review flagged social media posts for policy violations. I evaluate content against community guidelines and make moderation decisions." }])Each agent has the same capabilities but maintains independent memory of their own moderation history.
Step 2: Set up the rotation sequence
Section titled “Step 2: Set up the rotation sequence”Create a list of agents and initialize the rotation index:
# Define rotation ordermoderators = [moderator_a, moderator_b, moderator_c]
# Track current position in rotationcurrent_index = 0The rotation index determines which agent receives the next task.
Step 3: Distribute tasks in rotation
Section titled “Step 3: Distribute tasks in rotation”For each incoming task, send it to the current agent and advance the rotation:
# Example: flagged posts arriving for reviewflagged_posts = [ "Post 1: User shared potentially misleading health information", "Post 2: Comment contains targeted harassment", "Post 3: Image may violate copyright", "Post 4: Spam advertisement posted multiple times", "Post 5: Hate speech reported by users"]
# Distribute posts to moderators in round-robin fashionfor post in flagged_posts: # Get current moderator current_moderator = moderators[current_index]
# Send task to current moderator response = client.agents.messages.create( agent_id=current_moderator.id, messages=[{"role": "user", "content": f"Review this flagged post: {post}"}] )
print(f"{current_moderator.name} reviewed: {post}") print(f"Decision: {response.messages[-1].content}\n")
# Advance to next moderator (with wraparound) current_index = (current_index + 1) % len(moderators)The modulo operation % len(moderators) ensures the index wraps back to 0 after reaching the last agent.
Step 4: Handle agent responses
Section titled “Step 4: Handle agent responses”Each agent processes tasks independently and maintains its own memory:
# Check what each moderator remembersfor moderator in moderators: messages = client.agents.messages.list(agent_id=moderator.id) print(f"{moderator.name} has reviewed {len(messages)} posts")Each agent builds up moderation experience from the posts it reviews.
Minimal working example
Section titled “Minimal working example”Here’s a complete minimal example showing round-robin task distribution:
from letta_client import Lettaimport os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Create three agentsagents = []for i in range(3): agent = client.agents.create( name=f"agent_{i}", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": f"I am agent {i}. I process tasks assigned to me." }] ) agents.append(agent)
# Distribute tasks in round-robintasks = ["Task 1", "Task 2", "Task 3", "Task 4", "Task 5", "Task 6"]current_index = 0
for task in tasks: current_agent = agents[current_index] client.agents.messages.create( agent_id=current_agent.id, messages=[{"role": "user", "content": task}] ) print(f"{current_agent.name} received {task}") current_index = (current_index + 1) % len(agents)Output:
agent_0 received Task 1agent_1 received Task 2agent_2 received Task 3agent_0 received Task 4agent_1 received Task 5agent_2 received Task 6Full example: Content moderation system
Section titled “Full example: Content moderation system”This example demonstrates a complete content moderation system using round-robin distribution:
from letta_client import Lettaimport os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Step 1: Create three moderator agents with shared guidelinesmoderators = []for i in range(3): moderator = client.agents.create( name=f"moderator_{chr(65 + i)}", # A, B, C model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[ { "label": "persona", "value": f"I am Moderator {chr(65 + i)}. I review flagged content and make moderation decisions." }, { "label": "guidelines", "value": """Community Guidelines:- Hate speech: Remove- Harassment: Remove- Misinformation: Flag for fact-check- Spam: Remove- Copyright violations: Flag for review- Minor policy violations: Warn user""" } ] ) moderators.append(moderator)
# Step 2: Simulate incoming flagged contentflagged_content = [ {"id": 1, "content": "User posting spam links repeatedly"}, {"id": 2, "content": "Comment contains targeted harassment"}, {"id": 3, "content": "Potential copyright violation in shared image"}, {"id": 4, "content": "Misleading product claims in advertisement"}, {"id": 5, "content": "Hate speech targeting protected group"}, {"id": 6, "content": "Minor profanity in comment thread"}]
# Step 3: Distribute reviews in round-robin fashioncurrent_index = 0moderation_results = []
for item in flagged_content: # Get current moderator in rotation current_moderator = moderators[current_index]
# Send moderation task response = client.agents.messages.create( agent_id=current_moderator.id, messages=[{ "role": "user", "content": f"Review flagged content ID {item['id']}: {item['content']}. Provide your moderation decision." }] )
# Record result decision = response.messages[-1].content moderation_results.append({ "content_id": item["id"], "moderator": current_moderator.name, "decision": decision })
print(f"Content ID {item['id']} → {current_moderator.name}") print(f"Decision: {decision}\n")
# Advance rotation current_index = (current_index + 1) % len(moderators)
# Step 4: Verify workload distributionprint("Workload distribution:")for moderator in moderators: messages = client.agents.messages.list(agent_id=moderator.id) count = len([m for m in messages if m.role == "user"]) print(f"{moderator.name}: {count} reviews")Expected output:
Content ID 1 → moderator_ADecision: Remove - Spam violation
Content ID 2 → moderator_BDecision: Remove - Harassment policy violation
Content ID 3 → moderator_CDecision: Flag for copyright review
Content ID 4 → moderator_ADecision: Flag for fact-check - Health misinformation
Content ID 5 → moderator_BDecision: Remove - Hate speech violation
Content ID 6 → moderator_CDecision: Warn user - Minor profanity
Workload distribution:moderator_A: 2 reviewsmoderator_B: 2 reviewsmoderator_C: 2 reviewsBest practices
Section titled “Best practices”-
Define clear agent capabilities: Each agent in the pool should have similar capabilities. Round-robin assumes agents are interchangeable. Avoid mixing agents with different specializations in a round-robin pool. Use the supervisor-worker pattern instead for specialized routing.
-
Track rotation state: Maintain the rotation index as part of your application state. If your application restarts, persist the index to resume the rotation.
-
Monitor agent workload: Verify that tasks distribute evenly across agents. Large differences in task counts may indicate an issue with rotation logic.
-
Consider agent capacity: Round-robin assumes all agents have equal processing capacity. If agents process tasks at different speeds, the pattern will still distribute tasks evenly, which may lead to bottlenecks. For scenarios where agents have different capacities or availability, consider alternative patterns like weighted distribution or dynamic load balancing.
-
Use consistent agent ordering: Maintain a consistent rotation order across application restarts to ensure predictable task distribution over time.