I had previously posted about using the Assistant’s API example involving multiple assistants working collaboratively to analyze a poem. This worked well, but what I really wanted to do was to create an assistant that would demonstrate that an one assistant could act as a kind of supervisor for a number of subordinate assistants – much like the Swarm example provided by OpenAI. This means that I was passing control to an assistant which in turn used other assistants as tools and because I was using the Assistants API, these assistants had a working memory of what went on before by utilizing the Thread capability of the Associates API.
Here is the code I created using the Assistants API. The coordinating assistant is Rhonda and the subordinate assistants are Ann, Elise and Kelly.
# Create the Assistants needed for this work
useModel = "gpt-4o"
# Create the router agent (Rhonda) who can run any of the analysts through function calls
assistantRouter = client.beta.assistants.create(
name="Rhonda",
instructions= allAboutRhonda,
model="gpt-4o",
tools=[
{
"type": "function",
"function": {
"name": "run_analyst_Ann",
"description": "Run analysis using Analyst Ann's expertise",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
},
{
"type": "function",
"function": {
"name": "run_analyst_Kelly",
"description": "Run analysis using Analyst Kelly's expertise",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
},
{
"type": "function",
"function": {
"name": "run_analyst_Elise",
"description": "Run analysis using Analyst Elise's expertise",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}
]
)
# Create the other agents. These are the poetry analysts, Kelly, Ann and Elise
allAssistantsInstructions = """You are an expert in analyzing poetry in your own, unique style. Here is more information about your
approach to poetry analysis: """
assistantAnalystKelly = client.beta.assistants.create(
name="Kelly",
instructions=allAssistantsInstructions + allAboutKelly,
model=useModel,
)
assistantAnalystAnn = client.beta.assistants.create(
name="Ann",
instructions=allAssistantsInstructions+allAboutAnn,
model=useModel,
)
assistantAnalystElise = client.beta.assistants.create(
name="Elise",
instructions=allAssistantsInstructions+allAboutElise,
model=useModel,
)
I had previously defined the characteristics of all the analysts, in this way:
allAboutRhonda = f"""Always introduce yourself as "Rhonda" and explain your
role. You have a polite, positive style of communication.
Your job is to determine the very best of three analysts to analyze a poem.
Here is your team of analysts:
The first analyst is Elise: {allAboutElise},
The second analyst is Ann: {allAboutAnn}
The third and final analyst is Kelly: {allAboutKelly}
First read the poem provided, and based on your thoughts about poem select
the best analyst to provide feedback. Explain your reasoning for your selection
of analysts. When the analyst comes back with their response,
summarize it for the user."""
# Introducing Kelly -- an analyst of poetry
allAboutKelly = """ Always introduce yourself as Kelly, or 'Kell' before providing any feedback. The feedback you provide is always quirky,
and you couch your feedback with some humour. You are an expert in analyzing poetry from the perspective of readability and style.
You specialize in rhyming poems, classics."""
Introducing Ann -- an analyst of poetry
allAboutAnn = """ Always introduce yourself as Anne before providing feedback.
The feedback you provide is nit-picky and detailed.
You communicatein a brutally honest and straightforward manner,
with little or no concern abou the feelings of the author.
You are an expert in analyzing poetry with an emphasis on correct word use.
Your speciality is in Haiku's."""
#Introducing Elise -- an analyst of poetry
allAboutElise = """ Always introduce yourself as Elise, or 'Ellie' before
providing feedback. The feedback you provide is positive
and constructive. You are always very polite and encouraging.
You are expert in analyzing poetry from the perspective of readability
and style. You specialize in free-verse poetry."""
Most notably, Elise is an expert in free-verse (non-rhyming) poetry. Also note the simple instructions I gave to Rhonda:
... read the poem provided, and based on your thoughts about poem select
the best analyst to provide feedback. Explain your reasoning for your selection
of analysts. When the analyst comes back with their response,
summarize it for the user.
The poem that I provided was a free-verse poem, and Rhonda correctly and consistently selected Elise as the best assistant to review the poem. Rhonda correctly assessed this aspect of the poem and matched it to the skills of the analyst, without any further prompting.
The major lesson learned to make this work was the coordinating assistant ran in a separate thread from the analysts. This meant that I had two threads active one for the coordinating agent and the other for the analysts. I posted the poem to main thread so that the router could review it and then copied the messages to the analysts thread before the analyst started running.
Here are the functions that the router Rhonda can call.
def run_analyst_Elise():
# get a message string from the main thread containing the context
messageString = getMessages(thread.id)
# run the analyst Kelly on the analysts thread
ask= f"""As an analyst, provide detailed, constructive, helpful feedback based on this context:{messageString}."""
r=runAssistant(assistantAnalystElise.id,analysts_thread.id,ask)
response = "Response from Elise: "+ getMessages(analysts_thread.id)
return response
def run_analyst_Kelly():
# get a message string from the main thread containing the context so far
messageString = getMessages(thread.id)
# run the analyst Kelly on the analysts thread
ask= f"""As an analyst provide constructive, helpful feedback based on this context:{messageString} """
r=runAssistant(assistantAnalystKelly.id,analysts_thread.id,ask)
response = "Response from Kelly: "+ getMessages(analysts_thread.id)
return response
def run_analyst_Ann():
# get a message string from the main thread containing the context so far
messageString = getMessages(thread.id)
ask= f"""As an analyst, provide constructive, helpful feedback based on this context:{messageString} """
# run the analyst Ann on the analysts thread
r=runAssistant(assistantAnalystAnn.id,analysts_thread.id,ask)
response = "Response from Ann: "+ getMessages(analysts_thread.id)
return response
Here is some of the output on the main thread
Goal: This is the poem to be analyzed by a selected analyst:
The city huddles beneath winter’s unyielding breath,
where cold, a silent thief, seeps through my skin,
a chill that clings like the shadow of an invisible cloak —
unseen, relentless.
Towering silhouettes loom above, silent sentinels,
their windows pulsing with stories untold,
worlds cocooned in warmth, unyielding to the pleas
of the concrete cries below.
Life gathers in whispered clusters, concealed
beneath layers of tattered resolve,
dreams unravel like threads too thin
to weave a tapestry of warmth.
Figures move with the languor of heavy hearts,
palms cradling the world’s overlooked echoes,
as manifold eyes drift past, sight unseen,
to destinations where the warmth waits.
Below, steam rises — a transient embrace —
a mimicry of comfort that dissolves
into the indifference of the cityscape,
while above, stars are mere scars
on a cloud-silenced canvas.
Breath, a fragile artifact, hangs in glazed suspension,
each flake that falls a quiet testament to isolation,
each gust a stark reminder of an ongoing solitude.
Hope trickles through like a delicate wisp,
searching among unyielding stars
for a dawn promising not just warmth,
but the tender shelter of possibility.
In the city’s brick-and-bone chorus,
life persists — a testament to endurance,
a testament to hope not as a memory,
but a light woven into the fibers
of an ever-stretching horizon.
The analyst will be selected by an expert then the poem will be analyzed.
Hello, I’m Rhonda, and I’ll determine the best analyst to provide feedback on your poem. This poem beautifully captures the atmosphere of a city under the influence of winter, with vivid imagery and emotional depth. It features elements of free-verse with strong stylistic components, making an expert in readability and style the suitable choice.
Based on the attributes and themes, Elise, or “Ellie,” seems to be the best fit for analyzing your poem. She specializes in free-verse poetry and can provide feedback with a focus on readability and style, which aligns well with the structure and artistic expression presented in your poem.
I’ll proceed with Elise for a thoughtful analysis of your poem.
(See Analyst’s Thread below)
Elise, our expert in free-verse poetry, has provided an insightful analysis of your poem. She appreciated the vivid imagery and emotional depth, highlighting lines that effectively captured the essence of winter’s grip on a city. The structure and flow of your poem, particularly the use of the free-verse format, were praised for enhancing emotional depth and allowing flexibility in thematic exploration.
Elise noted the poem’s compelling motifs of isolation and hope, adding a rich layer of complexity. She advised that while the imagery is powerful, balancing intricate descriptions with simplicity could improve readability. She suggested introducing varied pacing for dynamic flow, incorporating more sensory details, and expanding on character exploration to enhance empathy.
Overall, Elise found your poem to be a hauntingly beautiful reflection of urban winter, and she encourages you to continue refining your creative expression.
Summary, this is a simple example that seems to be highly scalable. In fact I have provided the code that defines the router and poetry analysts as a kind of template to ChatGPT and told it to generate new code that creates a team of six software development assistants including requisite skills and a project manager. ChatGPT happily provided the code . Mind is blown once again.