Uma estrutura educacional que explora orquestração ergonômica e leve de multi-agente.
Aviso
Atualmente, o Swarm é uma estrutura de amostra experimental destinada a explorar interfaces ergonômicas para sistemas multi-agentes. Não se destina a ser usado na produção e, portanto, não tem apoio oficial. (Isso também significa que não estaremos revisando os PRs ou problemas!)
O objetivo principal do enxame é mostrar os padrões de transferência e rotinas explorados nos agentes orquestradores: transferência e rotinas de livro de receitas. Não se significa como uma biblioteca independente e é principalmente para fins educacionais.
Requer 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?
O Swarm se concentra em tornar a coordenação e a execução do agente leve, altamente controlável e facilmente testável.
Ele realiza isso através de duas abstrações primitivas: Agent
e transferências . Um Agent
abrange instructions
e tools
e, a qualquer momento, pode escolher entregar uma conversa a outro Agent
.
Esses primitivos são poderosos o suficiente para expressar dinâmica rica entre ferramentas e redes de agentes, permitindo que você construa soluções escaláveis e do mundo real, evitando uma curva de aprendizado acentuada.
Observação
Os agentes de enxame não estão relacionados aos assistentes na API de assistentes. Eles são nomeados da mesma forma por conveniência, mas, de outra forma, não são completamente relacionados. O Swarm é totalmente alimentado pela API de conclusão de bate -papo e, portanto, está sem estado entre as chamadas.
Swarm explora padrões leves, escaláveis e altamente personalizáveis por design. Abordagens semelhantes ao enxame são mais adequadas para situações que lidam com um grande número de recursos e instruções independentes que são difíceis de codificar em um único prompt.
A API de assistentes é uma ótima opção para desenvolvedores que procuram threads totalmente hospedados e gerenciamento e recuperação de memória incorporados. No entanto, o Swarm é um recurso educacional para os desenvolvedores curiosos para aprender sobre orquestração multi-agente. As corridas de enxame (quase) inteiramente no cliente e, assim como a API de conclusão de bate -papo, não armazena o estado entre as chamadas.
Confira /examples
para obter inspiração! Saiba mais sobre cada um em seu readme.
basic
: exemplos simples de fundamentos como configuração, chamada de função, transferência e variáveis de contextotriage_agent
: exemplo simples de configurar uma etapa básica de triagem para o agente certoweather_agent
: exemplo simples de chamada de funçãoairline
: uma configuração multi-agente para lidar com diferentes solicitações de atendimento ao cliente em um contexto de companhia aérea.support_bot
: um bot de atendimento ao cliente que inclui um agente de interface do usuário e um agente do centro de ajuda com várias ferramentaspersonal_shopper
: um agente de compras pessoais que pode ajudar a fazer vendas e reembolso de pedidos Comece instantando um cliente de enxame (que internamente apenas instancia um cliente OpenAI
).
from swarm import Swarm
client = Swarm ()
client.run()
A função run()
swarm () é análoga à função chat.completions.create()
na API de conclusão de bate -papo - ela recebe messages
e retorna messages
e não salva nenhum estado entre as chamadas. É importante ressaltar que, no entanto, também lida com a execução da função do agente, as transferências, as referências variáveis de contexto e pode fazer várias voltas antes de retornar ao usuário.
Na sua essência, o swarm's client.run()
implementa o seguinte loop:
Argumento | Tipo | Descrição | Padrão |
---|---|---|---|
agente | Agent | O agente (inicial) a ser chamado. | (obrigatório) |
mensagens | List | Uma lista de objetos de mensagem, idênticos para conclusões de bate -papo messages | (obrigatório) |
context_variables | dict | Um dicionário de variáveis de contexto adicionais, disponíveis para funções e instruções do agente | {} |
max_turns | int | O número máximo de voltas conversacionais permitidas | float("inf") |
Model_Override | str | Uma sequência opcional para substituir o modelo que está sendo usado por um agente | None |
execute_tools | bool | Se False , interrompa a execução e retorna imediatamente a mensagem tool_calls quando um agente tenta chamar uma função | True |
fluxo | bool | Se True , permite respostas de streaming | False |
depurar | bool | Se for True , permite o log de depuração | False |
Depois que client.run()
for concluído (após potencialmente várias chamadas para agentes e ferramentas), ele retornará uma Response
que contém todo o estado atualizado relevante. Especificamente, as novas messages
, o último Agent
a ser chamado e o mais atualizado context_variables
. Você pode passar esses valores (além de novas mensagens do usuário) para sua próxima execução do client.run()
para continuar a interação onde ele parou - bem como chat.completions.create()
. (A função run_demo_loop
implementa um exemplo de um loop de execução completo em /swarm/repl/repl.py
.)
Response
Campo | Tipo | Descrição |
---|---|---|
mensagens | List | Uma lista de objetos de mensagem gerados durante a conversa. Muito parecido com messages de conclusão de bate -papo, mas com um campo sender indicando de qual Agent a mensagem se originou. |
agente | Agent | O último agente a lidar com uma mensagem. |
context_variables | dict | O mesmo que as variáveis de entrada, além de quaisquer alterações. |
Um Agent
simplesmente encapsula um conjunto de instructions
com um conjunto de functions
(além de algumas configurações adicionais abaixo) e tem a capacidade de entregar a execução a outro Agent
.
Embora seja tentador personificar um Agent
como "alguém que faz x", ele também pode ser usado para representar um fluxo de trabalho ou etapa muito específico definido por um conjunto de instructions
e functions
(por exemplo, um conjunto de etapas, uma recuperação complexa e única de etapa de transformação de dados, etc). Isso permite que Agent
sejam compostos em uma rede de "agentes", "fluxos de trabalho" e "tarefas", todos representados pelo mesmo primitivo.
Agent
Campo | Tipo | Descrição | Padrão |
---|---|---|---|
nome | str | O nome do agente. | "Agent" |
modelo | str | O modelo a ser usado pelo agente. | "gpt-4o" |
instruções | str ou func() -> str | Instruções para o agente, podem ser uma string ou uma chamada retornando uma string. | "You are a helpful agent." |
funções | List | Uma lista de funções que o agente pode ligar. | [] |
Tool_choice | str | A escolha da ferramenta para o agente, se houver. | None |
instructions
Agent
são convertidas diretamente no prompt do system
de uma conversa (como a primeira mensagem). Somente as instructions
do Agent
ativo estarão presentes a qualquer momento (por exemplo, se houver uma transferência Agent
, o prompt system
mudará, mas o histórico de bate -papo não será.)
agent = Agent (
instructions = "You are a helpful agent."
)
As instructions
podem ser um str
regular ou uma função que retorna um str
. A função pode opcionalmente receber um parâmetro context_variables
, que será preenchido pelo context_variables
passados para o 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
de enxames podem chamar as funções do Python diretamente.str
(os valores serão tentados para serem fundidos como um str
).Agent
, a execução será transferida para esse Agent
.context_variables
, ela será preenchida pelos context_variables
passados para 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
tiver um erro (função ausente, argumento errado, erro), uma resposta de erro será anexada ao bate -papo para que o Agent
possa se recuperar graciosamente.Agent
, elas serão executadas nessa ordem. Um Agent
pode entregar a outro Agent
retornando -o em uma 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
Ele também pode atualizar o context_variables
retornando um objeto Result
mais completo. Isso também pode conter um value
e um agent
, caso você queira uma única função retornar um valor, atualizar o agente e atualizar as variáveis de contexto (ou qualquer subconjunto dos três).
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'}
Observação
Se um Agent
chamar várias funções para entregar a um Agent
, apenas a última função de transferência será usada.
O Swarm converte automaticamente as funções em um esquema JSON que é passado em tools
de conclusão de bate -papo.
description
da função.required
.type
do parâmetro (e padrão para 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 )
Usa os mesmos eventos que o streaming de API de conclusão de bate -papo. Consulte process_and_print_streaming_response
em /swarm/repl/repl.py
como exemplo.
Dois novos tipos de eventos foram adicionados:
{"delim":"start"}
e {"delim":"end"}
, para sinalizar cada vez que um Agent
lida com uma única mensagem (resposta ou chamada de função). Isso ajuda a identificar interruptores entre Agent
s.{"response": Response}
retornará um objeto Response
no final de um fluxo com a resposta agregada (completa), por conveniência. As avaliações são cruciais para qualquer projeto e incentivamos os desenvolvedores a trazer suas próprias suítes de avaliação para testar o desempenho de seus enxames. Para referência, temos alguns exemplos de como avaliar exemplos de enxames na airline
, weather_agent
e triage_agent
QuickStart. Veja os Readmes para obter mais detalhes.
Use o run_demo_loop
para testar seu enxame! Isso executará um REPL na sua linha de comando. Suporta streaming.
from swarm . repl import run_demo_loop
...
run_demo_loop ( agent , stream = True )