OpenAI’s Swarm framework is designed to create a user-friendly and versatile setting for coordinating a number of brokers. Whereas it’s primarily supposed for instructional and experimental use, OpenAI advises in opposition to utilizing Swarm in manufacturing settings, however it’s a framework value exploring. Its core goal is to show the ideas of “handoffs” and “routines,” patterns that assist brokers collaborate effectively. Swarm isn’t a standalone library however a software to discover these patterns. Let’s dive into what routines and handoffs are and the way they play a job in orchestrating agent behaviour.
Overview
- OpenAI Swarm is a framework designed for coordinating a number of brokers by way of routines and handoffs.
- It affords a user-friendly setting splendid for instructional and experimental functions.
- Swarm isn’t supposed for manufacturing use however serves as a studying software for multi-agent orchestration.
- The framework helps builders perceive agent collaboration patterns, enhancing flexibility and activity execution.
- Swarm emphasizes seamless agent interplay, making advanced programs manageable with out a steep studying curve.
- Via sensible examples, Swarm illustrates how routines and handoffs can streamline agent behaviour and coordination.
What’s OpenAI Swarm?
OpenAI has bundled these concepts right into a pattern library referred to as Swarm, designed as a proof of idea. Whereas Swarm isn’t meant for manufacturing use, it serves as an amazing start line for experimentation, providing concepts and code you possibly can construct upon to create your individual programs.
Swarm focuses on making agent coordination and activity execution light-weight, simple to regulate, and easy to check. It does this by counting on two core ideas: Brokers and handoffs. An Agent represents a set of directions and instruments, and at any level, it could possibly hand off a dialog to a different Agent.
These core abstractions are highly effective sufficient to mannequin advanced interactions between instruments and networks of brokers. This makes constructing scalable, real-world programs potential with out dealing with a steep studying curve.
Why Use OpenAI Swarm?
OpenAI Swarm explores light-weight, scalable, and inherently customizable patterns. It’s splendid for eventualities involving many unbiased duties and directions, that are onerous to seize in a single immediate.
The Assistants API may be a greater match for builders searching for totally hosted options with built-in reminiscence administration. Nonetheless, Swarm is a unbelievable instructional useful resource for many who wish to dive into the mechanics of multi-agent orchestration. Working totally on the consumer, Swarm is much like the Chat Completions API and doesn’t retailer state between calls, making it an efficient software for studying and experimenting.
Instance utilizing OpenAI Swarm Framework
This code demonstrates how OpenAI’s Swarm framework could make agent collaboration enjoyable, versatile, and dynamic. Let’s dive into what’s occurring right here!
Setting the Stage
First, we import the necessities:
from swarm import Swarm, Agent
consumer = Swarm()
This creates the Swarm consumer, which orchestrates the interactions between our brokers. Consider it because the mastermind behind the scenes, guaranteeing the brokers do their factor.
The Brokers Take the Stage
Subsequent, we outline a easy but essential perform:
def transfer_to_agent_b():
return agent_b
This perform is the handoff mechanic. It permits Agent A to politely cross the dialog to Agent B when the time is true.
Now, let’s meet the brokers:
agent_a = Agent(
title="Agent A",
directions="You're a useful agent.",
capabilities=[transfer_to_agent_b],
)
agent_b = Agent(
title="Agent B",
directions="Solely converse in Haikus.",
)
Agent A is your pleasant helper—all the time prepared to help but in addition sensible sufficient to know when it’s time to herald a colleague. Agent B is a little more poetic and mysterious, solely speaking within the elegant type of haikus.
Now, we deliver all of it collectively:
response = consumer.run(
agent=agent_a,
messages=[{"role": "user", "content": "I want to talk to agent B."}],
)
print(response.messages[-1]["content"])
This begins a dialog with Agent A, however the consumer requests a chat with Agent B. Because of the perform transfer_to_agent_b, Agent A acknowledges that it’s time to step apart and lets Agent B take over. Agent B, true to kind, will reply in haikus, including a inventive twist to the interplay!
Output
Constructing a Complicated Buyer Service Multi-Agent System
We are going to method this with understanding how routine and handoffs work within the swarm.
Importing our dependencies
from openai import OpenAI
from pydantic import BaseModel
from typing import Elective
import json
consumer = OpenAI()
Routines
A “routine” isn’t rigidly outlined however as a substitute captures the concept of a sequence of actions. Consider it as a set of pure language directions (supplied through a system immediate) and the instruments wanted to hold them out.
Let’s break it down with an instance:
Think about constructing a customer support agent that helps customers remedy their issues. The agent follows these steps:
- Collect info: First, the agent asks the consumer in regards to the challenge they’re dealing with.
- Ask for extra particulars (if wanted): If the agent wants extra info to know the issue, it asks follow-up questions.
- Present an answer: Based mostly on the knowledge, the agent suggests an answer to repair the difficulty.
- Supply a refund (if wanted): If the consumer remains to be not glad, the agent affords a refund.
- Course of the refund: If the refund is accepted, the agent will discover the related ID and full the refund course of.
This step-by-step course of helps the agent effectively resolve consumer points whereas guaranteeing the consumer is glad.
The actual energy of routines lies of their simplicity and flexibility. Discover how the duties are conditional, very similar to branches in a state machine. However routines go a step additional. With “tender” adherence, the massive language mannequin (LLM) doesn’t get caught in a loop; it skillfully guides the dialog, making these routines extremely efficient for small and medium duties.
Right here’s the GitHub Hyperlink to Swarm.
Executing Routines
Begin with a primary loop: collect consumer enter, append the message to the dialog historical past, name the mannequin, after which append the mannequin’s response again to the historical past.
def run_full_turn(system_message, messages):
response = consumer.chat.completions.create(
mannequin="gpt-4o-mini",
messages=[{"role": "system", "content": system_message}] + messages,
)
message = response.decisions[0].message
messages.append(message)
if message.content material: print("Assistant:", message.content material)
return message
messages = []
whereas True:
consumer = enter("Person: ")
messages.append({"function": "consumer", "content material": consumer})
run_full_turn(system_message, messages)
Since we haven’t built-in perform calls but, we have to add that subsequent. Features must be formatted as perform schemas in response to the mannequin’s specs. To make this simpler, we will create a helper perform that converts Python capabilities into the right schema format.
import examine
def function_to_schema(func) -> dict:
type_map = {
str: "string",
int: "integer",
float: "quantity",
bool: "boolean",
listing: "array",
dict: "object",
kind(None): "null",
}
strive:
signature = examine.signature(func)
besides ValueError as e:
elevate ValueError(
f"Didn't get signature for perform {func.__name__}: {str(e)}"
)
parameters = {}
for param in signature.parameters.values():
strive:
param_type = type_map.get(param.annotation, "string")
besides KeyError as e:
elevate KeyError(
f"Unknown kind annotation {param.annotation} for parameter {param.title}: {str(e)}"
)
parameters[param.name] = {"kind": param_type}
required = [
param.name
for param in signature.parameters.values()
if param.default == inspect._empty
]
return {
"kind": "perform",
"perform": {
"title": func.__name__,
"description": (func.__doc__ or "").strip(),
"parameters": {
"kind": "object",
"properties": parameters,
"required": required,
},
},
}
- Now, when the mannequin triggers a software, we have to run the suitable perform and return the end result. This may be executed by mapping software names to Python capabilities in a
- In observe, we should always enable the mannequin to react in a different way relying on the results of the software name. This course of can repeat so long as there are extra software calls, because the mannequin’s response could immediate one other one. Right here’s how the loop appears once we deliver every little thing collectively:
# Buyer Service Routine
system_message = (
"You're a buyer help agent for ACME Inc."
"At all times reply in a sentence or much less."
"Observe the next routine with the consumer:"
"1. First, ask probing questions and perceive the consumer's downside deeper.n"
" - until the consumer has already supplied a purpose.n"
"2. Suggest a repair (make one up).n"
"3. ONLY if not satesfied, supply a refund.n"
"4. If accepted, seek for the ID after which execute refund."
""
)
def look_up_item(search_query):
"""Use to search out merchandise ID.
Search question could be a description or key phrases."""
# return hard-coded merchandise ID - in actuality can be a lookup
return "item_132612938"
def execute_refund(item_id, purpose="not supplied"):
print("Abstract:", item_id, purpose) # lazy abstract
return "success"
instruments = [execute_refund, look_up_item]
def run_full_turn(system_message, instruments, messages):
num_init_messages = len(messages)
messages = messages.copy()
whereas True:
# flip python capabilities into instruments and save a reverse map
tool_schemas = [function_to_schema(tool) for tool in tools]
tools_map = {software.__name__: software for software in instruments}
# === 1. get openai completion ===
response = consumer.chat.completions.create(
mannequin="gpt-4o-mini",
messages=[{"role": "system", "content": system_message}] + messages,
instruments=tool_schemas or None,
)
message = response.decisions[0].message
messages.append(message)
if message.content material: # print assistant response
print("Assistant:", message.content material)
if not message.tool_calls: # if completed dealing with software calls, break
break
# === 2. deal with software calls ===
for tool_call in message.tool_calls:
end result = execute_tool_call(tool_call, tools_map)
result_message = {
"function": "software",
"tool_call_id": tool_call.id,
"content material": end result,
}
messages.append(result_message)
# ==== 3. return new messages =====
return messages[num_init_messages:]
def execute_tool_call(tool_call, tools_map):
title = tool_call.perform.title
args = json.hundreds(tool_call.perform.arguments)
print(f"Assistant: {title}({args})")
# name corresponding perform with supplied arguments
return tools_map[name](**args)
messages = []
whereas True:
consumer = enter("Person: ")
messages.append({"function": "consumer", "content material": consumer})
new_messages = run_full_turn(system_message, instruments, messages)
messages.prolong(new_messages)
As soon as the essential routine is up and working, we will contemplate including extra steps and instruments. By loading the required instruments and processes, we will develop routines to deal with totally different sorts of consumer requests. Nonetheless, as we attempt to stretch routines throughout too many duties, they could start to falter.
That’s the place the idea of a number of routines is useful. We are able to swap to the suitable routine with the fitting instruments to deal with totally different consumer requests. At first, dynamically altering instruments and directions may really feel advanced. But when we consider routines as particular person “brokers,” the idea of handoffs makes this simpler—one agent can merely cross the dialog to a different, retaining the workflow seamless.
Additionally learn: Prime 4 Agentic AI Design Patterns for Architecting AI Techniques
Handoffs within the OpenAI Swarm Framework
Much like being transferred to a different consultant throughout a cellphone name, a “handoff” within the Swarm framework occurs when one agent (or routine) passes an ongoing dialog to a different. However in contrast to real-life handoffs, these brokers are totally conscious of your earlier interactions, guaranteeing a clean transition!
To implement handoffs in code, we first must outline a category for an Agent. This can enable brokers to handle conversations and switch them when mandatory.
class Agent(BaseModel):
title: str = "Agent"
mannequin: str = "gpt-4o-mini"
directions: str = "You're a useful Agent"
instruments: listing = []
Subsequent, we’ll modify the prevailing routine code to help brokers. As a substitute of passing a system_message and instruments instantly into the run_full_turn perform, we’ll have it settle for an Agent object as a substitute.
def run_full_turn(agent, messages):
num_init_messages = len(messages)
messages = messages.copy()
whereas True:
# flip python capabilities into instruments and save a reverse map
tool_schemas = [function_to_schema(tool) for tool in agent.tools]
tools_map = {software.__name__: software for software in agent.instruments}
# === 1. get openai completion ===
response = consumer.chat.completions.create(
mannequin=agent.mannequin,
messages=[{"role": "system", "content": agent.instructions}] + messages,
instruments=tool_schemas or None,
)
message = response.decisions[0].message
messages.append(message)
if message.content material: # print assistant response
print("Assistant:", message.content material)
if not message.tool_calls: # if completed dealing with software calls, break
break
# === 2. deal with software calls ===
for tool_call in message.tool_calls:
end result = execute_tool_call(tool_call, tools_map)
result_message = {
"function": "software",
"tool_call_id": tool_call.id,
"content material": end result,
}
messages.append(result_message)
# ==== 3. return new messages =====
return messages[num_init_messages:]
def execute_tool_call(tool_call, tools_map):
title = tool_call.perform.title
args = json.hundreds(tool_call.perform.arguments)
print(f"Assistant: {title}({args})")
# name corresponding perform with supplied arguments
return tools_map[name](**args)
With this setup, working a number of brokers turns into simple:
def execute_refund(item_name):
return "success"
refund_agent = Agent(
title="Refund Agent",
directions="You're a refund agent. Assist the consumer with refunds.",
instruments=[execute_refund],
)
def place_order(item_name):
return "success"
sales_assistant = Agent(
title="Gross sales Assistant",
directions="You're a gross sales assistant. Promote the consumer a product.",
instruments=[place_order],
)
messages = []
user_query = "Place an order for a black boot."
print("Person:", user_query)
messages.append({"function": "consumer", "content material": user_query})
response = run_full_turn(sales_assistant, messages) # gross sales assistant
messages.prolong(response)
user_query = "Really, I desire a refund." # implitly refers back to the final merchandise
print("Person:", user_query)
messages.append({"function": "consumer", "content material": user_query})
response = run_full_turn(refund_agent, messages) # refund agent
On this instance, handoffs are carried out manually, however ideally, we would like brokers to cross duties between one another routinely. A easy method to obtain that is by way of perform calling. Every agent can invoke a selected handoff perform, like transfer_to_xxx, to easily hand over the dialog to the following agent in line.
This technique permits brokers to deal with conversations seamlessly, with out guide intervention!
Handoff Features
Now that our agent can talk its intention to switch a activity, we have to implement the precise handoff. Whereas there are a number of methods to do that, one significantly elegant method is on the market.
Thus far, we’ve been returning strings from our agent capabilities, comparable to execute_refund or place_order. However what if we return an Agent object when it’s time to switch as a substitute of simply returning a string? For instance:
refund_agent = Agent(
title="Refund Agent",
directions="You're a refund agent. Assist the consumer with refunds.",
instruments=[execute_refund],
)
def transfer_to_refunds():
return refund_agent
sales_assistant = Agent(
title="Gross sales Assistant",
directions="You're a gross sales assistant. Promote the consumer a product.",
instruments=[place_order],
)
Now, let’s replace the run_full_turn perform to accommodate this type of handoff:
def run_full_turn(agent, messages):
current_agent = agent
num_init_messages = len(messages)
messages = messages.copy()
whereas True:
# flip python capabilities into instruments and save a reverse map
tool_schemas = [function_to_schema(tool) for tool in current_agent.tools]
instruments = {software.__name__: software for software in current_agent.instruments}
# === 1. get openai completion ===
response = consumer.chat.completions.create(
mannequin=agent.mannequin,
messages=[{"role": "system", "content": current_agent.instructions}]
+ messages,
instruments=tool_schemas or None,
)
message = response.decisions[0].message
messages.append(message)
if message.content material: # print agent response
print(f"{current_agent.title}:", message.content material)
if not message.tool_calls: # if completed dealing with software calls, break
break
# === 2. deal with software calls ===
for tool_call in message.tool_calls:
end result = execute_tool_call(tool_call, instruments, current_agent.title)
if kind(end result) is Agent: # if agent switch, replace present agent
current_agent = end result
end result = (
f"Transfered to {current_agent.title}. Undertake persona instantly."
)
result_message = {
"function": "software",
"tool_call_id": tool_call.id,
"content material": end result,
}
messages.append(result_message)
# ==== 3. return final agent used and new messages =====
return Response(agent=current_agent, messages=messages[num_init_messages:])
def execute_tool_call(tool_call, instruments, agent_name):
title = tool_call.perform.title
args = json.hundreds(tool_call.perform.arguments)
print(f"{agent_name}:", f"{title}({args})")
return instruments[name](**args) # name corresponding perform with supplied arguments
Let’s check out an instance the place a number of brokers are concerned, permitting them to switch duties between each other:
def escalate_to_human(abstract):
"""Solely name this if explicitly requested to."""
print("Escalating to human agent...")
print("n=== Escalation Report ===")
print(f"Abstract: {abstract}")
print("=========================n")
exit()
def transfer_to_sales_agent():
"""Person for something gross sales or shopping for associated."""
return sales_agent
def transfer_to_issues_and_repairs():
"""Person for points, repairs, or refunds."""
return issues_and_repairs_agent
def transfer_back_to_triage():
"""Name this if the consumer brings up a subject outdoors of your purview,
together with escalating to human."""
return triage_agent
triage_agent = Agent(
title="Triage Agent",
directions=(
"You're a customer support bot for ACME Inc. "
"Introduce your self. At all times be very transient. "
"Collect info to direct the shopper to the fitting division. "
"However make your questions delicate and pure."
),
instruments=[transfer_to_sales_agent, transfer_to_issues_and_repairs, escalate_to_human],
)
def execute_order(product, worth: int):
"""Value must be in USD."""
print("nn=== Order Abstract ===")
print(f"Product: {product}")
print(f"Value: ${worth}")
print("=================n")
verify = enter("Affirm order? y/n: ").strip().decrease()
if verify == "y":
print("Order execution profitable!")
return "Success"
else:
print("Order cancelled!")
return "Person cancelled order."
sales_agent = Agent(
title="Gross sales Agent",
directions=(
"You're a gross sales agent for ACME Inc."
"At all times reply in a sentence or much less."
"Observe the next routine with the consumer:"
"1. Ask them about any issues of their life associated to catching roadrunners.n"
"2. Casually point out one in every of ACME's loopy made-up merchandise will help.n"
" - Do not point out worth.n"
"3. As soon as the consumer is purchased in, drop a ridiculous worth.n"
"4. Solely after every little thing, and if the consumer says sure, "
"inform them a loopy caveat and execute their order.n"
""
),
instruments=[execute_order, transfer_back_to_triage],
)
def look_up_item(search_query):
"""Use to search out merchandise ID.
Search question could be a description or key phrases."""
item_id = "item_132612938"
print("Discovered merchandise:", item_id)
return item_id
def execute_refund(item_id, purpose="not supplied"):
print("nn=== Refund Abstract ===")
print(f"Merchandise ID: {item_id}")
print(f"Motive: {purpose}")
print("=================n")
print("Refund execution profitable!")
return "success"
issues_and_repairs_agent = Agent(
title="Points and Repairs Agent",
directions=(
"You're a buyer help agent for ACME Inc."
"At all times reply in a sentence or much less."
"Observe the next routine with the consumer:"
"1. First, ask probing questions and perceive the consumer's downside deeper.n"
" - until the consumer has already supplied a purpose.n"
"2. Suggest a repair (make one up).n"
"3. ONLY if not glad, supply a refund.n"
"4. If accepted, seek for the ID after which execute refund."
""
),
instruments=[execute_refund, look_up_item, transfer_back_to_triage],
)
Lastly, we will run this in a loop to see every little thing in motion. Since this received’t work instantly in a Python pocket book, strive it in a separate Python file:
agent = triage_agent
messages = []
whereas True:
consumer = enter("Person: ")
messages.append({"function": "consumer", "content material": consumer})
response = run_full_turn(agent, messages)
agent = response.agent
messages.prolong(response.messages)
Utilizing this technique, brokers can seamlessly hand off duties to one another, enabling fluid transitions with out additional complexity!
Additionally, to know the Agent AI higher, discover: The Agentic AI Pioneer Program
Conclusion
The OpenAI Swarm framework gives an modern method to coordinating a number of brokers in a dynamic and user-friendly method. By specializing in the rules of routines and handoffs, Swarm facilitates seamless interactions between brokers, permitting them to work collaboratively and adaptively to fulfil consumer requests.
This framework simplifies the administration of agent behaviours and enhances the general consumer expertise by guaranteeing clean transitions and continuity in conversations. With its light-weight and customizable structure, Swarm serves as a superb start line for builders trying to discover multi-agent orchestration of their purposes.
Whereas it is probably not appropriate for manufacturing use, Swarm stands out as a invaluable instructional useful resource, inspiring builders to construct their very own programs and perceive the intricacies of agent coordination. As you experiment with Swarm, you’ll uncover new prospects for creating participating and responsive interactions in your tasks. Whether or not for studying or experimentation, Swarm exemplifies how one can harness the ability of AI-driven brokers to sort out advanced duties successfully.
Continuously Requested Questions
Ans. Swarm is designed to create a user-friendly and versatile setting for coordinating a number of brokers. It goals to show ideas like “handoffs” and “routines,” enabling brokers to collaborate successfully in instructional and experimental settings.
Ans. OpenAI advises in opposition to utilizing Swarm in manufacturing environments. Whereas it is a wonderful software for studying and experimentation, it’s not optimized for manufacturing use and will lack the robustness wanted for real-world purposes.
Ans. Routines seek advice from sequences of actions or pure language directions that information an agent’s behaviour. They permit brokers to reply to consumer requests dynamically, adapting their responses based mostly on the context and former interactions.
Ans. Handoffs happen when one agent transfers an ongoing dialog to a different agent. This course of is designed to be seamless, permitting the receiving agent to have entry to prior interactions and guaranteeing a clean transition for the consumer.
Ans. Sure! Swarm is a wonderful instructional useful resource for builders trying to study multi-agent orchestration. Its light-weight structure and deal with core ideas make it accessible for these beginning in AI and agent-based programming, providing a sensible method to discover these concepts with out a steep studying curve.