Un cadre éducatif explorant une orchestration multi-agents ergonomique et légère.
Avertissement
Swarm est actuellement un cadre d'échantillon expérimental destiné à explorer les interfaces ergonomiques pour les systèmes multi-agents. Il n'est pas destiné à être utilisé en production et n'a donc aucun soutien officiel. (Cela signifie également que nous ne réviserons pas les PR ou les problèmes!)
L'objectif principal de l'essaim est de présenter les modèles de transfert et de routines explorés dans le livre de cuisine des agents orchestrants: Handoffs & Routines. Il ne s'agit pas de bibliothèque autonome et est principalement à des fins éducatives.
Nécessite Python 3.10+
pip install git+ssh://[email protected]/openai/swarm.git
ou
pip install git+https://github.com/openai/swarm.git
from swarm import Swarm , Agent
client = Swarm ()
def transfer_to_agent_b ():
return agent_b
agent_a = Agent (
name = "Agent A" ,
instructions = "You are a helpful agent." ,
functions = [ transfer_to_agent_b ],
)
agent_b = Agent (
name = "Agent B" ,
instructions = "Only speak in Haikus." ,
)
response = client . run (
agent = agent_a ,
messages = [{ "role" : "user" , "content" : "I want to talk to agent B." }],
)
print ( response . messages [ - 1 ][ "content" ])
Hope glimmers brightly,
New paths converge gracefully,
What can I assist?
Swarm se concentre sur la coordination et l'exécution des agents légers, hautement contrôlables et facilement testables.
Il accomplit cela à travers deux abstractions primitives: Agent
et les transferts . Un Agent
englobe instructions
et tools
, et peut à tout moment choisir de remettre une conversation à un autre Agent
.
Ces primitives sont suffisamment puissantes pour exprimer une dynamique riche entre les outils et les réseaux d'agents, vous permettant de construire des solutions évolutives et réelles tout en évitant une courbe d'apprentissage abrupte.
Note
Les agents d'essaim ne sont pas liés aux assistants de l'API assistants. Ils sont nommés de la même manière pour plus de commodité, mais sont autrement complètement sans rapport. Swarm est entièrement alimenté par l'API de complétion de chat et est donc apatride entre les appels.
Swarm explore des modèles légers, évolutifs et hautement personnalisables par conception. Des approches similaires à Swarm sont les mieux adaptées aux situations traitant d'un grand nombre de capacités et d'instructions indépendantes difficiles à coder en une seule invite.
L'API Assistants est une excellente option pour les développeurs à la recherche de threads entièrement hébergés et de gestion et de récupération de la mémoire intégrées. Cependant, Swarm est une ressource éducative pour les développeurs curieux de se renseigner sur l'orchestration multi-agents. Swarm fonctionne (presque) entièrement sur le client et, tout comme l'API de complétion de chat, ne stockait pas l'état entre les appels.
Découvrez /examples
pour l'inspiration! En savoir plus sur chacun de son lecture.
basic
: Exemples simples de fondamentaux comme la configuration, les appels de fonction, les transferts et les variables de contextetriage_agent
: Exemple simple de la mise en place d'une étape de triage de base à remettre au bon agentweather_agent
: exemple simple d'appel de fonctionairline
: une configuration multi-agents pour gérer différentes demandes de service client dans un contexte de compagnie aérienne.support_bot
: un bot de service client qui comprend un agent d'interface utilisateur et un agent de centre d'aide avec plusieurs outilspersonal_shopper
: un agent de magasinage personnel qui peut aider à passer des commandes de vente et de remboursement Commencez par instancier un client Swarm (qui instancie simplement en interne un client OpenAI
).
from swarm import Swarm
client = Swarm ()
client.run()
La fonction run()
de Swarm est analogue à la fonction chat.completions.create()
dans l'API de complétion de chat - il prend messages
et renvoie messages
et n'enregistre aucun état entre les appels. Surtout, cependant, il gère également l'exécution de la fonction d'agent, les transferts, les références de variables de contexte et peut prendre plusieurs tours avant de revenir à l'utilisateur.
À la base, client.run()
implémente la boucle suivante:
Argument | Taper | Description | Défaut |
---|---|---|---|
agent | Agent | L'agent (initial) à appeler. | (requis) |
messages | List | Une liste d'objets de message, identiques aux messages de complétion de chat | (requis) |
context_variables | dict | Un dictionnaire de variables de contexte supplémentaires, disponibles pour les fonctions et les instructions d'agent | {} |
max_turns | int | Le nombre maximum de virages conversationnels autorisés | float("inf") |
Model_override | str | Une chaîne facultative pour remplacer le modèle utilisé par un agent | None |
exécuter_tools | bool | En cas False , interrompre l'exécution et renvoie immédiatement le message tool_calls lorsqu'un agent essaie d'appeler une fonction | True |
flux | bool | Si True , permet les réponses en streaming | False |
déboguer | bool | Si c'est True , permet la journalisation de débogage | False |
Une fois que client.run()
est terminé (après des appels potentiellement multiples aux agents et aux outils), il renverra une Response
contenant tout l'état mis à jour pertinent. Plus précisément, les nouveaux messages
, le dernier Agent
à appeler et le context_variables
le plus à jour. Vous pouvez transmettre ces valeurs (plus de nouveaux messages utilisateur) dans votre prochaine exécution de client.run()
pour continuer l'interaction où elle s'était arrêtée - un peu comme chat.completions.create()
. (La fonction run_demo_loop
implémente un exemple de boucle d'exécution complète dans /swarm/repl/repl.py
.)
Response
Champ | Taper | Description |
---|---|---|
messages | List | Une liste d'objets de message générés lors de la conversation. Très similaire aux messages de complétion de chat, mais avec un champ sender indiquant de quel Agent le message est originaire. |
agent | Agent | Le dernier agent à gérer un message. |
context_variables | dict | Identique aux variables d'entrée, plus toutes les modifications. |
Un Agent
encapsule simplement un ensemble d' instructions
avec un ensemble de functions
(plus quelques paramètres supplémentaires ci-dessous), et a la capacité de remettre l'exécution à un autre Agent
.
Bien qu'il soit tentant de personnifier un Agent
comme "quelqu'un qui fait X", il peut également être utilisé pour représenter un flux de travail ou un pas très spécifique défini par un ensemble d' instructions
et functions
(par exemple, un ensemble d'étapes, une récupération complexe, une seule étape de pas de pas de transformation des données, etc.). Cela permet à Agent
S d'être composé dans un réseau d '"agents", "workflows" et "tâches", tous représentés par la même primitive.
Agent
Champ | Taper | Description | Défaut |
---|---|---|---|
nom | str | Le nom de l'agent. | "Agent" |
modèle | str | Le modèle à utiliser par l'agent. | "gpt-4o" |
instructions | str ou func() -> str | Les instructions pour l'agent peuvent être une chaîne ou un renvoi de la chaîne. | "You are a helpful agent." |
fonctions | List | Une liste de fonctions que l'agent peut appeler. | [] |
tool_choice | str | Le choix de l'outil pour l'agent, le cas échéant. | None |
instructions
Agent
sont directement converties en invite system
d'une conversation (comme premier message). Seules les instructions
de l' Agent
actif seront présentes à un moment donné (par exemple s'il y a un transfert Agent
, l'invite system
changera, mais l'historique du chat ne le fera pas.)
agent = Agent (
instructions = "You are a helpful agent."
)
Les instructions
peuvent être soit une str
régulière, soit une fonction qui renvoie un str
. La fonction peut éventuellement recevoir un paramètre context_variables
, qui sera peuplé par le context_variables
transmis dans client.run()
.
def instructions ( context_variables ):
user_name = context_variables [ "user_name" ]
return f"Help the user, { user_name } , do whatever they want."
agent = Agent (
instructions = instructions
)
response = client . run (
agent = agent ,
messages = [{ "role" : "user" , "content" : "Hi!" }],
context_variables = { "user_name" : "John" }
)
print ( response . messages [ - 1 ][ "content" ])
Hi John, how can I assist you today?
Agent
Swarm peuvent appeler directement les fonctions Python.str
(les valeurs seront tentées d'être jetées sous forme de str
).Agent
, l'exécution sera transférée à cet Agent
.context_variables
, il sera peuplé par le context_variables
transmis dans client.run()
. def greet ( context_variables , language ):
user_name = context_variables [ "user_name" ]
greeting = "Hola" if language . lower () == "spanish" else "Hello"
print ( f" { greeting } , { user_name } !" )
return "Done"
agent = Agent (
functions = [ greet ]
)
client . run (
agent = agent ,
messages = [{ "role" : "user" , "content" : "Usa greet() por favor." }],
context_variables = { "user_name" : "John" }
)
Hola, John!
Agent
a une erreur (fonction manquante, mauvais argument, erreur), une réponse d'erreur sera annexée au chat afin que l' Agent
puisse récupérer gracieusement.Agent
, elles seront exécutées dans cet ordre. Un Agent
peut transmettre à un autre Agent
en le renvoyant dans une function
.
sales_agent = Agent ( name = "Sales Agent" )
def transfer_to_sales ():
return sales_agent
agent = Agent ( functions = [ transfer_to_sales ])
response = client . run ( agent , [{ "role" : "user" , "content" : "Transfer me to sales." }])
print ( response . agent . name )
Sales Agent
Il peut également mettre à jour le context_variables
en renvoyant un objet Result
plus complet. Cela peut également contenir une value
et un agent
, au cas où vous souhaitez qu'une seule fonction renvoie une valeur, mettez à jour l'agent et mettez à jour les variables de contexte (ou tout sous-ensemble des trois).
sales_agent = Agent ( name = "Sales Agent" )
def talk_to_sales ():
print ( "Hello, World!" )
return Result (
value = "Done" ,
agent = sales_agent ,
context_variables = { "department" : "sales" }
)
agent = Agent ( functions = [ talk_to_sales ])
response = client . run (
agent = agent ,
messages = [{ "role" : "user" , "content" : "Transfer me to sales" }],
context_variables = { "user_name" : "John" }
)
print ( response . agent . name )
print ( response . context_variables )
Sales Agent
{'department': 'sales', 'user_name': 'John'}
Note
Si un Agent
appelle plusieurs fonctions à transmettre à un Agent
, seule la dernière fonction de transfert sera utilisée.
STALM convertit automatiquement les fonctions en un schéma JSON qui est transmis en tools
de complétion de chat.
description
de la fonction.required
.type
du paramètre (et par défaut en string
). def greet ( name , age : int , location : str = "New York" ):
"""Greets the user. Make sure to get their name and age before calling.
Args:
name: Name of the user.
age: Age of the user.
location: Best place on earth.
"""
print ( f"Hello { name } , glad you are { age } in { location } !" )
{
"type" : "function" ,
"function" : {
"name" : "greet" ,
"description" : "Greets the user. Make sure to get their name and age before calling.nnArgs:n name: Name of the user.n age: Age of the user.n location: Best place on earth." ,
"parameters" : {
"type" : "object" ,
"properties" : {
"name" : { "type" : "string" } ,
"age" : { "type" : "integer" } ,
"location" : { "type" : "string" }
} ,
"required" : [ "name" , "age" ]
}
}
}
stream = client . run ( agent , messages , stream = True )
for chunk in stream :
print ( chunk )
Utilise les mêmes événements que le streaming API complétion de chat. Voir process_and_print_streaming_response
dans /swarm/repl/repl.py
comme exemple.
Deux nouveaux types d'événements ont été ajoutés:
{"delim":"start"}
et {"delim":"end"}
, pour signaler chaque fois qu'un Agent
gère un seul message (réponse ou appel de fonction). Cela aide à identifier les commutateurs entre Agent
s.{"response": Response}
Renvoie un objet Response
à la fin d'un flux avec la réponse agrégée (complète), pour plus de commodité. Les évaluations sont cruciales pour tout projet, et nous encourageons les développeurs à apporter leurs propres suites d'évaluation pour tester les performances de leurs essaims. Pour référence, nous avons quelques exemples pour évaluer l'essaim dans les exemples de la airline
, weather_agent
et triage_agent
. Voir les ReadMes pour plus de détails.
Utilisez le run_demo_loop
pour tester votre essaim! Cela exécutera un REP sur votre ligne de commande. Prend en charge le streaming.
from swarm . repl import run_demo_loop
...
run_demo_loop ( agent , stream = True )