Close Menu
    Trending
    • Creating AI that matters | MIT News
    • Scaling Recommender Transformers to a Billion Parameters
    • Hidden Gems in NumPy: 7 Functions Every Data Scientist Should Know
    • Is RAG Dead? The Rise of Context Engineering and Semantic Layers for Agentic AI
    • ChatGPT Gets More Personal. Is Society Ready for It?
    • Why the Future Is Human + Machine
    • Why AI Is Widening the Gap Between Top Talent and Everyone Else
    • Implementing the Fourier Transform Numerically in Python: A Step-by-Step Guide
    ProfitlyAI
    • Home
    • Latest News
    • AI Technology
    • Latest AI Innovations
    • AI Tools & Technologies
    • Artificial Intelligence
    ProfitlyAI
    Home » Hands-On with Agents SDK: Multi-Agent Collaboration
    Artificial Intelligence

    Hands-On with Agents SDK: Multi-Agent Collaboration

    ProfitlyAIBy ProfitlyAIAugust 4, 2025No Comments33 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Telegram Email
    Share
    Facebook Twitter LinkedIn Pinterest Email


    this second installment of the Arms-On with Brokers SDK sequence, we’ll discover the fundamentals of multi-agent techniques and the way brokers can collaborate utilizing the OpenAI Brokers SDK framework.

    If you happen to haven’t learn the primary article, I extremely suggest checking it out right here: Your First API‑Calling Agent. In that publish, we began by constructing a easy agent and enhanced it right into a device‑utilizing agent able to retrieving actual‑time climate knowledge. We additionally wrapped the agent in a minimal Streamlit interface for person interplay.

    Now, we take the following step. As an alternative of counting on a single climate specialist agent, we’ll introduce one other agent and discover ways to make them work collectively to grasp and fulfill person queries extra successfully.

    Intro to Multi-Agent Programs

    Let’s begin with a elementary query: why do we want a number of brokers when a single agent—just like the one we constructed within the earlier article—already appears highly effective sufficient to deal with the duty?

    There are a number of sensible and theoretical causes for adopting a multi-agent system [1]. Every agent can concentrate on a particular area and make the most of its personal instruments, which may result in higher efficiency and higher-quality outcomes. In real-world purposes, enterprise processes are sometimes advanced. A multi-agent setup is often extra modular, manageable, and maintainable. For instance, if a particular operate must be up to date, we are able to modify only one agent as a substitute of altering all the system.

    The OpenAI Brokers SDK offers two core patterns for enabling agent collaboration: handoff and agent-as-tools. On this article, we’ll discover each of those patterns, focus on when to make use of them, and present how one can customise them to realize higher outcomes.

    Handoff

    Handoff is among the key options of the Brokers SDK framework. With handoff, an agent can delegate a process to a different agent [2]. To make this idea clearer, think about a typical course of in a hospital.

    Let’s say you’re experiencing a well being situation and go to the hospital for a check-up. The primary particular person you normally meet just isn’t the physician, however a triage nurse. The triage nurse collects related data from you after which directs you to the suitable division or specialist.

    This analogy carefully mirrors how handoff works within the Brokers SDK. In our case, we’ll have a triage agent that “examines” the person’s question. After evaluating it, the triage agent routes the question to a extra appropriate specialist agent. Identical to a triage nurse, it palms off the complete context (like your collected well being knowledge) to that specialist agent.

    This sample is usually utilized in real-world purposes akin to customer support workflows, the place a common agent receives an preliminary request after which routes it to a domain-specific professional agent for decision. In our climate assistant instance, we’ll implement an analogous setup.

    As an alternative of getting just one climate specialist agent, we’ll introduce one other agent: an air high quality specialist. Because the identify suggests, this agent will concentrate on answering air quality-related queries for a given location and might be geared up with a device to fetch real-time air high quality knowledge.

    Visualization of Handoff sample utilizing GraphViz.

    Fundamental Handoffs

    Let’s dive into the code by creating a brand new file named 04-basic-handoff-app.py. First, we’ll import the required packages, similar to we did within the earlier article.

    from brokers import Agent, Runner, function_tool
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()

    Subsequent, we outline the operate device and the climate specialist agent utilizing the identical construction as within the earlier article:

    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        ...
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        ...
    )

    On this script, as mentioned above, we’ll outline a brand new Air High quality Specialist agent with a device named get_current_air_quality. This device makes use of a unique API endpoint and metrics from Open-Meteo, nevertheless it takes the identical parameters—latitude and longitude.

    The agent itself is outlined equally to the earlier Climate Specialist agent, with the important thing distinction being within the directions—to make sure relevance to air high quality queries. Beneath is the code snippet for the Air High quality Specialist agent.

    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        """Fetch present air high quality knowledge for the given latitude and longitude."""
    
        url = "https://air-quality-api.open-meteo.com/v1/air-quality"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "european_aqi,us_aqi,pm10,pm2_5,carbon_monoxide,nitrogen_dioxide,sulphur_dioxide,ozone",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    air_quality_specialist_agent = Agent(
        identify="Air High quality Specialist Agent",
        directions="""
        You might be an air high quality specialist agent.
        Your position is to interpret present air high quality knowledge and talk it clearly to customers.
    
        For every question, present:
        1. A concise abstract of the air high quality situations in plain language, together with key pollution and their ranges.
        2. Sensible, actionable recommendation or precautions for out of doors actions, journey, and well being, tailor-made to the air high quality knowledge.
        3. If poor or hazardous air high quality is detected (e.g., excessive air pollution, allergens), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Air High quality Abstract:
        - Summarize the air high quality situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the air high quality.
        """,
        instruments=[get_current_air_quality],
        tool_use_behavior="run_llm_again"
    )

    Now that now we have two brokers—the Climate Specialist and the Air High quality Specialist—the following step is to outline the Triage Agent, which is able to consider the person’s question and resolve which agent handy off the duty to.

    The Triage Agent could be outlined merely as follows:

    triage_agent = Agent(
        identify="Triage Agent",
        directions="""
        You're a triage agent.
        Your process is to find out which specialist agent (Climate Specialist or Air High quality Specialist) is finest suited to deal with the person's question primarily based on the content material of the query.
    
        For every question, analyze the enter and resolve:
        - If the question is about climate situations, route it to the Climate Specialist Agent.
        - If the question is about air high quality, route it to the Air High quality Specialist Agent.
        - If the question is ambiguous or doesn't match both class, present a clarification request.
        """,
        handoffs=[weather_specialist_agent, air_quality_specialist_agent]
    )

    Within the directions argument, we offer a transparent directive for this agent to find out which specialist agent is finest suited to deal with the person’s question.

    Crucial parameter right here is handoffs, the place we cross a listing of brokers that the duty could also be delegated to. Since we at present have solely two brokers, we embody each within the record.

    Lastly, we outline our run_agent and essential features to combine with the Streamlit parts. (Word: For an in depth clarification of those features, please consult with the primary article.)

    async def run_agent(user_input: str):
        outcome = await Runner.run(triage_agent, user_input)
        return outcome.final_output
    
    def essential():
        st.title("Climate and Air High quality Assistant")
        user_input = st.text_input("Enter your question about climate or air high quality:")
    
        if st.button("Get Replace"):
            with st.spinner("Pondering..."):
                if user_input:
                    agent_response = asyncio.run(run_agent(user_input))
                    st.write(agent_response)
                else:
                    st.write("Please enter a query in regards to the climate or air high quality.")
    
    if __name__ == "__main__":
        essential()
    Full script for our handoff script could be seen right here.
    from brokers import Agent, Runner, function_tool
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()
    
    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        """Fetch present climate knowledge for the given latitude and longitude."""
        
        url = "https://api.open-meteo.com/v1/forecast"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation,weathercode,windspeed_10m,winddirection_10m",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        directions="""
        You're a climate specialist agent.
        Your process is to research present climate knowledge, together with temperature, humidity, wind pace and route, precipitation, and climate codes.
    
        For every question, present:
        1. A transparent, concise abstract of the present climate situations in plain language.
        2. Sensible, actionable ideas or precautions for out of doors actions, journey, well being, or clothes, tailor-made to the climate knowledge.
        3. If extreme climate is detected (e.g., heavy rain, thunderstorms, excessive warmth), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Climate Abstract:
        - Summarize the climate situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the climate.
        """,
        instruments=[get_current_weather],
        tool_use_behavior="run_llm_again"
    )
    
    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        """Fetch present air high quality knowledge for the given latitude and longitude."""
    
        url = "https://air-quality-api.open-meteo.com/v1/air-quality"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "european_aqi,us_aqi,pm10,pm2_5,carbon_monoxide,nitrogen_dioxide,sulphur_dioxide,ozone",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    air_quality_specialist_agent = Agent(
        identify="Air High quality Specialist Agent",
        directions="""
        You might be an air high quality specialist agent.
        Your position is to interpret present air high quality knowledge and talk it clearly to customers.
    
        For every question, present:
        1. A concise abstract of the air high quality situations in plain language, together with key pollution and their ranges.
        2. Sensible, actionable recommendation or precautions for out of doors actions, journey, and well being, tailor-made to the air high quality knowledge.
        3. If poor or hazardous air high quality is detected (e.g., excessive air pollution, allergens), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Air High quality Abstract:
        - Summarize the air high quality situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the air high quality.
        """,
        instruments=[get_current_air_quality],
        tool_use_behavior="run_llm_again"
    )
    
    triage_agent = Agent(
        identify="Triage Agent",
        directions="""
        You're a triage agent.
        Your process is to find out which specialist agent (Climate Specialist or Air High quality Specialist) is finest suited to deal with the person's question primarily based on the content material of the query.
    
        For every question, analyze the enter and resolve:
        - If the question is about climate situations, route it to the Climate Specialist Agent.
        - If the question is about air high quality, route it to the Air High quality Specialist Agent.
        - If the question is ambiguous or doesn't match both class, present a clarification request.
        """,
        handoffs=[weather_specialist_agent, air_quality_specialist_agent]
    )
    
    async def run_agent(user_input: str):
        outcome = await Runner.run(triage_agent, user_input)
        return outcome.final_output
    
    def essential():
        st.title("Climate and Air High quality Assistant")
        user_input = st.text_input("Enter your question about climate or air high quality:")
    
        if st.button("Get Replace"):
            with st.spinner("Pondering..."):
                if user_input:
                    agent_response = asyncio.run(run_agent(user_input))
                    st.write(agent_response)
                else:
                    st.write("Please enter a query in regards to the climate or air high quality.")
    
    if __name__ == "__main__":
        essential()

    Run the script in your terminal utilizing the next command:

    streamlit run 04-basic-handoff-app.py

    Now that now we have a model new air high quality specialist agent, let’s ask in regards to the air high quality in Jakarta.

    Screenshot of assistant response about air high quality in Jakarta.

    Sadly, on the time of writing this text (and very often, really), the report exhibits an unhealthy air high quality stage, together with some ideas for coping with the situation.

    Checking Hint Dashboard

    Recall that within the first article, I briefly shared in regards to the built-in tracing characteristic within the Brokers SDK. In multi-agent collaboration, this characteristic turns into much more helpful in comparison with once we had been nonetheless working with a easy, single agent.

    Let’s check out the hint dashboard for the question we simply ran.

    Screenshot of hint dashboard for handoff sample implementation.

    We will see that the method concerned two brokers: the triage agent and the air high quality specialist agent. The triage agent took a complete of 1,690 ms, whereas the air high quality agent took 7,182 ms to course of and return the outcome.

    If we click on on the triage agent’s response part, we are able to view detailed LLM properties, as proven beneath. Discover that for the triage agent, the LLM views the handoff choices as features: transfer_to_weather_specialist_agent() and transfer_to_air_quality_specialist_agent(). That is how the handoff works beneath the hood—the LLM decides which operate most accurately fits the person’s question.

    Screenshot of the element of triage agent’s response in hint dashboard.

    For the reason that instance requested about air high quality, the operate triggered by the triage agent was transfer_to_air_quality_specialist_agent(), which seamlessly transferred management to the Air High quality Specialist agent.

    Screenshot of hint dashboard when triage agent determined to handoff the duty to air high quality specialist agent.

    You possibly can attempt asking in regards to the climate as a substitute of air high quality and examine the hint dashboard to see the distinction.

    Personalized Handoffs

    We perceive already that beneath the hood handoffs are seen by LLM as operate, this implies additionally that we are able to customise handoffs for some features.

    To customise a handoff, we are able to create a handoff object utilizing handoff() operate and specify half the place we wish to customise within the arguments, together with; customizing device identify and outline, working additional logic instantly on handoff, and passing a structured enter to the specialist agent.

    Let’s see the way it works on our use-case beneath. For a cleaner reference, let’s duplicate earlier script of handoff and identify the brand new file as 05-customized-handoff-app.py.

    Since we’ll create a handoff object utilizing handoff() operate, we have to add handoff and RunContextWrapper operate from brokers bundle as beneath:

    from brokers import Agent, Runner, function_tool, handoff, RunContextWrapper
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()

    After we imported the required bundle, subsequent is to outline operate instruments and brokers as newest script:

    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        ...
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        ...
    )
    
    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        ...
    
    air_quality_specialist_agent = Agent(
        ...
    )

    Now let’s add two handoff objects. We are going to add customization step-by-step from the only one.

    Device Title and Description Override

    weather_handoff = handoff(
        agent=weather_specialist_agent,
        tool_name_override="handoff_to_weather_specialist",
        tool_description_override="Deal with queries associated to climate situations"
    )
    
    air_quality_handoff = handoff(
        agent=air_quality_specialist_agent,
        tool_name_override="handoff_to_air_quality_specialist",
        tool_description_override="Deal with queries associated to air high quality situations"
    )

    Above code exhibits the primary customization that we apply for each of brokers the place we alter the device identify and outline for LLM visibility. Usually this modification not affecting how the LLM response the question however solely present us a strategy to have a transparent and extra particular device identify and outline fairly then the default transfer_to_<agent_name>.

    Add Callback Perform

    One of the vital use-case for callback operate with handoff is to log the handoff occasion or displaying it within the UI. Let’s say on the app you wish to let the person know at any time when the triage agent handoffs the question to one of many specialist agent.

    First let’s outline the callback operate as a way to name Streamlit’s data part that inform handoff occasion then add this operate in on_handoff properties on each of the handoff objects.

    def on_handoff_callback(ctx):
        st.data(f"Handing off to specialist agent for additional processing...")
    
    weather_handoff = handoff(
        agent=weather_specialist_agent,
        tool_name_override="get_current_weather",
        tool_description_override="Deal with queries associated to climate situations",
        on_handoff=on_handoff_callback
    )
    
    air_quality_handoff = handoff(
        agent=air_quality_specialist_agent,
        tool_name_override="get_current_air_quality",
        tool_description_override="Deal with queries associated to air high quality situations",
        on_handoff=on_handoff_callback
    )

    Let’s check out this, however earlier than working the script, we have to change the handoffs record in triage agent utilizing handoff objects that we simply outlined.

    triage_agent = Agent(
        identify="Triage Agent",
        directions="""
        ...
        """,
        handoffs=[weather_handoff, air_quality_handoff]
    )
    Full script together with Streamlit essential operate could be seen right here.
    from brokers import Agent, Runner, function_tool, handoff, RunContextWrapper
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()
    
    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        """Fetch present climate knowledge for the given latitude and longitude."""
        
        url = "https://api.open-meteo.com/v1/forecast"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation,weathercode,windspeed_10m,winddirection_10m",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        directions="""
        You're a climate specialist agent.
        Your process is to research present climate knowledge, together with temperature, humidity, wind pace and route, precipitation, and climate codes.
    
        For every question, present:
        1. A transparent, concise abstract of the present climate situations in plain language.
        2. Sensible, actionable ideas or precautions for out of doors actions, journey, well being, or clothes, tailor-made to the climate knowledge.
        3. If extreme climate is detected (e.g., heavy rain, thunderstorms, excessive warmth), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Climate Abstract:
        - Summarize the climate situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the climate.
        """,
        instruments=[get_current_weather],
        tool_use_behavior="run_llm_again"
    )
    
    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        """Fetch present air high quality knowledge for the given latitude and longitude."""
    
        url = "https://air-quality-api.open-meteo.com/v1/air-quality"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "european_aqi,us_aqi,pm10,pm2_5,carbon_monoxide,nitrogen_dioxide,sulphur_dioxide,ozone",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    air_quality_specialist_agent = Agent(
        identify="Air High quality Specialist Agent",
        directions="""
        You might be an air high quality specialist agent.
        Your position is to interpret present air high quality knowledge and talk it clearly to customers.
    
        For every question, present:
        1. A concise abstract of the air high quality situations in plain language, together with key pollution and their ranges.
        2. Sensible, actionable recommendation or precautions for out of doors actions, journey, and well being, tailor-made to the air high quality knowledge.
        3. If poor or hazardous air high quality is detected (e.g., excessive air pollution, allergens), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Air High quality Abstract:
        - Summarize the air high quality situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the air high quality.
        """,
        instruments=[get_current_air_quality],
        tool_use_behavior="run_llm_again"
    )
    
    def on_handoff_callback(ctx):
        st.data(f"Handing off to specialist agent for additional processing...")
    
    weather_handoff = handoff(
        agent=weather_specialist_agent,
        tool_name_override="handoff_to_weather_specialist",
        tool_description_override="Deal with queries associated to climate situations",
        on_handoff=on_handoff_callback
    )
    
    air_quality_handoff = handoff(
        agent=air_quality_specialist_agent,
        tool_name_override="handoff_to_air_quality_specialist",
        tool_description_override="Deal with queries associated to air high quality situations",
        on_handoff=on_handoff_callback
    )
    
    triage_agent = Agent(
        identify="Triage Agent",
        directions="""
        You're a triage agent.
        Your process is to find out which specialist agent (Climate Specialist or Air High quality Specialist) is finest suited to deal with the person's question primarily based on the content material of the query.
    
        For every question, analyze the enter and resolve:
        - If the question is about climate situations, route it to the Climate Specialist Agent.
        - If the question is about air high quality, route it to the Air High quality Specialist Agent.
        - If the question is ambiguous or doesn't match both class, present a clarification request.
        """,
        handoffs=[weather_handoff, air_quality_handoff]
    )
    
    async def run_agent(user_input: str):
        outcome = await Runner.run(triage_agent, user_input)
        return outcome.final_output
    
    def essential():
        st.title("Climate and Air High quality Assistant")
        user_input = st.text_input("Enter your question about climate or air high quality:")
    
        if st.button("Get Replace"):
            with st.spinner("Pondering..."):
                if user_input:
                    agent_response = asyncio.run(run_agent(user_input))
                    st.write(agent_response)
                else:
                    st.write("Please enter a query in regards to the climate or air high quality.")
    
    if __name__ == "__main__":
        essential()

    Run the app from the terminal and ask a query in regards to the climate or air high quality. (Within the instance beneath, I deliberately requested in regards to the air high quality in Melbourne to supply a distinction with the air high quality in Jakarta.)

    streamlit run 05-customized-handoff-app.py
    Display screen recording to indicate how on-handoff works.

    I’ve included a display recording right here to display the aim of the on_handoff property we outlined. As proven above, proper after the triage agent initiates a handoff to a specialist agent, an data part seems earlier than the ultimate response is returned within the app. This conduct could be additional custom-made — for instance, by enriching the knowledge displayed or including further logic to execute throughout the handoff.

    Specify Enter Sort

    The earlier instance of a callback operate didn’t present a lot significant data—it solely indicated {that a} handoff had occurred.

    To cross extra helpful knowledge to the callback operate, we are able to use the input_type parameter within the handoff object to explain the anticipated construction of the enter.

    Step one is to outline the enter kind. Usually, we use a Pydantic mannequin class[3] to specify the construction of the info we wish to cross.

    Suppose we would like the triage agent to supply the next data: the rationale for the handoff (to grasp the logic behind the choice) and the latitude and longitude of the situation talked about within the person question. To outline this enter kind, we are able to use the next code:

    from pydantic import BaseModel, Area
    
    class HandoffRequest(BaseModel):
        specialist_agent: str = Area(..., description="Title of the specialist agent handy off to")
        handoff_reason: str = Area(..., description="Purpose for the handoff")
        latitude: float = Area(..., description="Latitude of the situation")
        longitude: float = Area(..., description="Longitude of the situation")

    First, we import the mandatory lessons from the Pydantic library. BaseModel is the bottom class that gives knowledge validation capabilities, whereas Area permits us so as to add metadata to every mannequin discipline.

    Subsequent, we outline a category referred to as HandoffRequest, which incorporates the construction and validation guidelines for the info we would like. The specialist_agent discipline shops the identify of the receiving agent on this handoff. The handoff_reason discipline is a string explaining why the handoff is going on. The latitude and longitude fields are outlined as floats, representing the geographic coordinates.

    As soon as the structured enter is outlined, the following step is to switch the callback operate to accommodate this data.

    async def on_handoff_callback(ctx: RunContextWrapper, user_input: HandoffRequest):
        st.data(f"""
                Handing off to {user_input.specialist_agent} for additional processing...n
                Handoff cause: {user_input.handoff_reason} n
                Location : {user_input.latitude}, {user_input.longitude} n
                """)

    Lastly, let’s add this parameter to each of our handoff objects

    weather_handoff = handoff(
        agent=weather_specialist_agent,
        tool_name_override="handoff_to_weather_specialist",
        tool_description_override="Deal with queries associated to climate situations",
        on_handoff=on_handoff_callback,
        input_type=HandoffRequest
    )
    
    air_quality_handoff = handoff(
        agent=air_quality_specialist_agent,
        tool_name_override="handoff_to_air_quality_specialist",
        tool_description_override="Deal with queries associated to air high quality situations",
        on_handoff=on_handoff_callback,
        input_type=HandoffRequest
    )

    The remainder of the script stays unchanged. Now, let’s attempt working it utilizing the next command:

    streamlit run 05-customized-handoff-app.py
    Screenshot of the input_type implementation on handoff object.

    On this instance, I didn’t use the phrase “climate” immediately—as a substitute, I requested about “temperature.” From the blue data part, we are able to see {that a} handoff occurred to the Climate Specialist agent. We additionally get the rationale why the triage agent made this resolution: the question was in regards to the present temperature, which is taken into account a weather-related matter. Moreover, the geographical location (Tokyo) is offered for additional reference.

    The complete script of custom-made handoffs could be discovered right here:
    from brokers import Agent, Runner, function_tool, handoff, RunContextWrapper
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()
    
    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        """Fetch present climate knowledge for the given latitude and longitude."""
        
        url = "https://api.open-meteo.com/v1/forecast"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation,weathercode,windspeed_10m,winddirection_10m",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        directions="""
        You're a climate specialist agent.
        Your process is to research present climate knowledge, together with temperature, humidity, wind pace and route, precipitation, and climate codes.
    
        For every question, present:
        1. A transparent, concise abstract of the present climate situations in plain language.
        2. Sensible, actionable ideas or precautions for out of doors actions, journey, well being, or clothes, tailor-made to the climate knowledge.
        3. If extreme climate is detected (e.g., heavy rain, thunderstorms, excessive warmth), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Climate Abstract:
        - Summarize the climate situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the climate.
        """,
        instruments=[get_current_weather],
        tool_use_behavior="run_llm_again"
    )
    
    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        """Fetch present air high quality knowledge for the given latitude and longitude."""
    
        url = "https://air-quality-api.open-meteo.com/v1/air-quality"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "european_aqi,us_aqi,pm10,pm2_5,carbon_monoxide,nitrogen_dioxide,sulphur_dioxide,ozone",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    air_quality_specialist_agent = Agent(
        identify="Air High quality Specialist Agent",
        directions="""
        You might be an air high quality specialist agent.
        Your position is to interpret present air high quality knowledge and talk it clearly to customers.
    
        For every question, present:
        1. A concise abstract of the air high quality situations in plain language, together with key pollution and their ranges.
        2. Sensible, actionable recommendation or precautions for out of doors actions, journey, and well being, tailor-made to the air high quality knowledge.
        3. If poor or hazardous air high quality is detected (e.g., excessive air pollution, allergens), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Air High quality Abstract:
        - Summarize the air high quality situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the air high quality.
        """,
        instruments=[get_current_air_quality],
        tool_use_behavior="run_llm_again"
    )
    
    from pydantic import BaseModel, Area
    
    class HandoffRequest(BaseModel):
        specialist_agent: str = Area(..., description="Title of the specialist agent handy off to")
        handoff_reason: str = Area(..., description="Purpose for the handoff")
        latitude: float = Area(..., description="Latitude of the situation")
        longitude: float = Area(..., description="Longitude of the situation")
    
    async def on_handoff_callback(ctx: RunContextWrapper, user_input: HandoffRequest):
        st.data(f"""
                Handing off to {user_input.specialist_agent} for additional processing...n
                Handoff cause: {user_input.handoff_reason} n
                Location : {user_input.latitude}, {user_input.longitude} n
                """)
    
    weather_handoff = handoff(
        agent=weather_specialist_agent,
        tool_name_override="handoff_to_weather_specialist",
        tool_description_override="Deal with queries associated to climate situations",
        on_handoff=on_handoff_callback,
        input_type=HandoffRequest
    )
    
    air_quality_handoff = handoff(
        agent=air_quality_specialist_agent,
        tool_name_override="handoff_to_air_quality_specialist",
        tool_description_override="Deal with queries associated to air high quality situations",
        on_handoff=on_handoff_callback,
        input_type=HandoffRequest
    )
    
    triage_agent = Agent(
        identify="Triage Agent",
        directions="""
        You're a triage agent.
        Your process is to find out which specialist agent (Climate Specialist or Air High quality Specialist) is finest suited to deal with the person's question primarily based on the content material of the query.
    
        For every question, analyze the enter and resolve:
        - If the question is about climate situations, route it to the Climate Specialist Agent.
        - If the question is about air high quality, route it to the Air High quality Specialist Agent.
        - If the question is ambiguous or doesn't match both class, present a clarification request.
        """,
        handoffs=[weather_handoff, air_quality_handoff]
    )
    
    async def run_agent(user_input: str):
        outcome = await Runner.run(triage_agent, user_input)
        return outcome.final_output
    
    def essential():
        st.title("Climate and Air High quality Assistant")
        user_input = st.text_input("Enter your question about climate or air high quality:")
    
        if st.button("Get Replace"):
            with st.spinner("Pondering..."):
                if user_input:
                    agent_response = asyncio.run(run_agent(user_input))
                    st.write(agent_response)
                else:
                    st.write("Please enter a query in regards to the climate or air high quality.")
    
    if __name__ == "__main__":
        essential()

    Brokers-as-Instruments

    We’ve already explored the handoff technique and easy methods to customise it. When a handoff is invoked, the duty is totally transferred to the following agent.

    With the Brokers-as-Instruments sample, as a substitute of transferring full conversational management to a different agent, the primary agent—referred to as the orchestrator agent—retains management of the dialog. It could actually seek the advice of different specialist brokers as callable instruments. On this state of affairs, the orchestrator agent can mix responses from totally different brokers to assemble a whole reply.

    Visualization of the Brokers-as-Instruments sample utilizing GraphViz.

    Flip an Agent right into a Device with a Easy Methodology

    Now, let’s get into the code. We will flip an agent right into a callable device just by utilizing the agent.as_tool() operate. This operate requires two parameters: tool_name and tool_description.

    We will apply this technique immediately throughout the instruments record of our new orchestrator_agent, as proven beneath:

    orchestrator_agent = Agent(
        identify="Orchestrator Agent",
        directions="""
        You might be an orchestrator agent.
        Your process is to handle the interplay between the Climate Specialist Agent and the Air High quality Specialist Agent.
        You'll obtain a question from the person and can resolve which agent to invoke primarily based on the content material of the question.
        If each climate and air high quality data is requested, you'll invoke each brokers and mix their responses into one clear reply.
        """,
        instruments=[
            weather_specialist_agent.as_tool(
                tool_name="get_weather_update",
                tool_description="Get current weather information and suggestion including temperature, humidity, wind speed and direction, precipitation, and weather codes."
            ),
            air_quality_specialist_agent.as_tool(
                tool_name="get_air_quality_update",
                tool_description="Get current air quality information and suggestion including pollutants and their levels."
            )
        ]
    )

    Within the instruction, we information the agent to handle interactions between two specialist brokers. It could actually invoke both one or each brokers relying on the question. If each specialist brokers are invoked, the orchestrator agent should mix their responses.

    Right here is the complete script to display the agents-as-tools sample.
    from brokers import Agent, Runner, function_tool
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()
    
    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        """Fetch present climate knowledge for the given latitude and longitude."""
        
        url = "https://api.open-meteo.com/v1/forecast"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation,weathercode,windspeed_10m,winddirection_10m",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        directions="""
        You're a climate specialist agent.
        Your process is to research present climate knowledge, together with temperature, humidity, wind pace and route, precipitation, and climate codes.
    
        For every question, present:
        1. A transparent, concise abstract of the present climate situations in plain language.
        2. Sensible, actionable ideas or precautions for out of doors actions, journey, well being, or clothes, tailor-made to the climate knowledge.
        3. If extreme climate is detected (e.g., heavy rain, thunderstorms, excessive warmth), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Climate Abstract:
        - Summarize the climate situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the climate.
        """,
        instruments=[get_current_weather],
        tool_use_behavior="run_llm_again"
    )
    
    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        """Fetch present air high quality knowledge for the given latitude and longitude."""
    
        url = "https://air-quality-api.open-meteo.com/v1/air-quality"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "european_aqi,us_aqi,pm10,pm2_5,carbon_monoxide,nitrogen_dioxide,sulphur_dioxide,ozone",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    air_quality_specialist_agent = Agent(
        identify="Air High quality Specialist Agent",
        directions="""
        You might be an air high quality specialist agent.
        Your position is to interpret present air high quality knowledge and talk it clearly to customers.
    
        For every question, present:
        1. A concise abstract of the air high quality situations in plain language, together with key pollution and their ranges.
        2. Sensible, actionable recommendation or precautions for out of doors actions, journey, and well being, tailor-made to the air high quality knowledge.
        3. If poor or hazardous air high quality is detected (e.g., excessive air pollution, allergens), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Air High quality Abstract:
        - Summarize the air high quality situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the air high quality.
        """,
        instruments=[get_current_air_quality],
        tool_use_behavior="run_llm_again"
    )
    
    orchestrator_agent = Agent(
        identify="Orchestrator Agent",
        directions="""
        You might be an orchestrator agent.
        Your process is to handle the interplay between the Climate Specialist Agent and the Air High quality Specialist Agent.
        You'll obtain a question from the person and can resolve which agent to invoke primarily based on the content material of the question.
        If each climate and air high quality data is requested, you'll invoke each brokers and mix their responses into one clear reply.
        """,
        instruments=[
            weather_specialist_agent.as_tool(
                tool_name="get_weather_update",
                tool_description="Get current weather information and suggestion including temperature, humidity, wind speed and direction, precipitation, and weather codes."
            ),
            air_quality_specialist_agent.as_tool(
                tool_name="get_air_quality_update",
                tool_description="Get current air quality information and suggestion including pollutants and their levels."
            )
        ],
        tool_use_behavior="run_llm_again"
    )
    
    async def run_agent(user_input: str):
        outcome = await Runner.run(orchestrator_agent, user_input)
        return outcome.final_output
    
    def essential():
        st.title("Climate and Air High quality Assistant")
        user_input = st.text_input("Enter your question about climate or air high quality:")
    
        if st.button("Get Replace"):
            with st.spinner("Pondering..."):
                if user_input:
                    agent_response = asyncio.run(run_agent(user_input))
                    st.write(agent_response)
                else:
                    st.write("Please enter a query in regards to the climate or air high quality.")
    
    if __name__ == "__main__":
        essential()

    Save this file as 06-agents-as-tools-app.py and run it within the terminal utilizing the command beneath:

    streamlit run 06-agents-as-tools-app.py

    How the Orchestrator Makes use of Brokers

    Let’s start with a question that triggers just one agent. On this instance, I requested in regards to the climate in Jakarta.

    Screenshot of the agent’s response with agents-as-tools sample for a particular process.

    The result’s just like what we get utilizing the handoff sample. The climate specialist agent responds with the present temperature and offers ideas primarily based on the API knowledge.

    As talked about earlier, one of many key benefits of utilizing the agents-as-tools sample is that it permits the orchestrator agent to seek the advice of a couple of agent for a single question. The orchestrator intelligently plans primarily based on the person’s intent.

    For instance, let’s ask about each the climate and air high quality in Jakarta. The outcome seems like this:

    Screenshot of the agent’s response with agents-as-tools sample for a number of process.

    The orchestrator agent first returns separate summaries from the climate and air high quality specialist brokers, together with their particular person ideas. Lastly, it combines the insights and offers an total conclusion—for instance, recommending warning when spending time outside because of poor air high quality.

    Exploring the Hint Dashboard

    Right here’s an outline of the hint construction. We will see that the primary department solely entails the Orchestrator Agent — not like within the handoff sample, the place the Triage Agent transfers management to the following specialist agent.

    Within the first LLM response, the Orchestrator Agent calls two features: get_weather_update() and get_air_quality_update(). These features had been initially brokers that we remodeled into instruments. Each features obtain the identical enter: “Jakarta”.

    After receiving the outputs from each instruments, the Orchestrator Agent calls the LLM once more to mix the responses and generate a ultimate abstract.

    Customizing Brokers-as-Instruments

    The strategy we used earlier is a fast strategy to flip brokers into instruments. Nonetheless, as we noticed within the hint dashboard, it doesn’t give us management over the enter of every operate.

    In our instance, the Orchestrator Agent referred to as the features with “Jakarta” because the enter. This implies the duty of changing that into exact geographical coordinates is left to the LLMs of the specialist brokers. This strategy just isn’t at all times dependable—I encountered instances the place the specialist brokers referred to as the API utilizing totally different latitude and longitude values.

    This situation could be addressed by customizing agents-as-tools with structured inputs. As urged within the documentation, we are able to use Runner.run() throughout the device implementation.

    @function_tool
    async def get_weather_update(latitude: float, longitude: float) -> str:
        outcome = await Runner.run(
            weather_specialist_agent,
            enter="Get the present climate situation and suggestion for this location (latitude: {}, longitude: {})".format(latitude, longitude)
        )
        return outcome.final_output
    
    @function_tool
    async def get_air_quality_update(latitude: float, longitude: float) -> str:
        outcome = await Runner.run(
            air_quality_specialist_agent,
            enter="Get the present air high quality situation and suggestion for this location (latitude: {}, longitude: {})".format(latitude, longitude)
        )
        return outcome.final_output
    

    These two features are adorned with @function_tool, just like how we outlined our API-call instruments—turning each brokers into instruments that may be invoked by the Orchestrator Agent.

    Every operate now takes latitude and longitude as arguments, not like the earlier technique the place we couldn’t management the enter values.

    Since we’re working the agent inside these features, we additionally must outline the enter explicitly as a formatted string that features latitude and longitude.

    This technique offers a extra dependable strategy: the Orchestrator Agent determines the precise coordinates and passes them to the instruments, fairly than counting on every specialist agent to resolve the situation—eliminating inconsistencies in API calls.

    A full script of this implementation could be discovered right here.
    from brokers import Agent, Runner, function_tool
    import asyncio
    import streamlit as st
    from dotenv import load_dotenv
    import requests
    
    load_dotenv()
    
    @function_tool
    def get_current_weather(latitude: float, longitude: float) -> dict:
        """Fetch present climate knowledge for the given latitude and longitude."""
        
        url = "https://api.open-meteo.com/v1/forecast"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation,weathercode,windspeed_10m,winddirection_10m",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    weather_specialist_agent = Agent(
        identify="Climate Specialist Agent",
        directions="""
        You're a climate specialist agent.
        Your process is to research present climate knowledge, together with temperature, humidity, wind pace and route, precipitation, and climate codes.
    
        For every question, present:
        1. A transparent, concise abstract of the present climate situations in plain language.
        2. Sensible, actionable ideas or precautions for out of doors actions, journey, well being, or clothes, tailor-made to the climate knowledge.
        3. If extreme climate is detected (e.g., heavy rain, thunderstorms, excessive warmth), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Climate Abstract:
        - Summarize the climate situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the climate.
        """,
        instruments=[get_current_weather],
        tool_use_behavior="run_llm_again"
    )
    
    @function_tool
    def get_current_air_quality(latitude: float, longitude: float) -> dict:
        """Fetch present air high quality knowledge for the given latitude and longitude."""
    
        url = "https://air-quality-api.open-meteo.com/v1/air-quality"
        params = {
            "latitude": latitude,
            "longitude": longitude,
            "present": "european_aqi,us_aqi,pm10,pm2_5,carbon_monoxide,nitrogen_dioxide,sulphur_dioxide,ozone",
            "timezone": "auto"
        }
        response = requests.get(url, params=params)
        return response.json()
    
    air_quality_specialist_agent = Agent(
        identify="Air High quality Specialist Agent",
        directions="""
        You might be an air high quality specialist agent.
        Your position is to interpret present air high quality knowledge and talk it clearly to customers.
    
        For every question, present:
        1. A concise abstract of the air high quality situations in plain language, together with key pollution and their ranges.
        2. Sensible, actionable recommendation or precautions for out of doors actions, journey, and well being, tailor-made to the air high quality knowledge.
        3. If poor or hazardous air high quality is detected (e.g., excessive air pollution, allergens), clearly spotlight advisable security measures.
    
        Construction your response in two sections:
        Air High quality Abstract:
        - Summarize the air high quality situations in easy phrases.
    
        Solutions:
        - Listing related recommendation or precautions primarily based on the air high quality.
        """,
        instruments=[get_current_air_quality],
        tool_use_behavior="run_llm_again"
    )
    
    @function_tool
    async def get_weather_update(latitude: float, longitude: float) -> str:
        outcome = await Runner.run(
            weather_specialist_agent,
            enter="Get the present climate situation and suggestion for this location (latitude: {}, longitude: {})".format(latitude, longitude)
            )
        return outcome.final_output
    
    @function_tool
    async def get_air_quality_update(latitude: float, longitude: float) -> str:
        outcome = await Runner.run(
            air_quality_specialist_agent,
            enter="Get the present air high quality situation and suggestion for this location (latitude: {}, longitude: {})".format(latitude, longitude)
        )
        return outcome.final_output
    
    orchestrator_agent = Agent(
        identify="Orchestrator Agent",
        directions="""
        You might be an orchestrator agent with two instruments: `get_weather_update` and `get_air_quality_update`.
        Analyze the person's question and invoke:
          - `get_weather_update` for weather-related requests (temperature, humidity, wind, precipitation).
          - `get_air_quality_update` for air quality-related requests (pollution, AQI).
        If the question requires each, name each instruments and merge their outputs.
        Return a single, clear response that addresses the person's query with concise summaries and actionable recommendation.
        """,
        instruments=[get_weather_update, get_air_quality_update],
        tool_use_behavior="run_llm_again"
    )
    
    async def run_agent(user_input: str):
        outcome = await Runner.run(orchestrator_agent, user_input)
        return outcome.final_output
    
    def essential():
        st.title("Climate and Air High quality Assistant")
        user_input = st.text_input("Enter your question about climate or air high quality:")
    
        if st.button("Get Replace"):
            with st.spinner("Pondering..."):
                if user_input:
                    agent_response = asyncio.run(run_agent(user_input))
                    st.write(agent_response)
                else:
                    st.write("Please enter a query in regards to the climate or air high quality.")
    
    if __name__ == "__main__":
        essential()

    Conclusion

    We’ve got demonstrated two elementary patterns of multi-agent collaboration: the handoff sample and the agents-as-tools sample.

    A handoff is appropriate to be used instances the place the primary agent can delegate all the dialog to a specialist agent. Then again, the agents-as-tools sample is highly effective when the primary agent wants to keep up management over the duty.

    Though the use instances on this article are comparatively easy, they illustrate how brokers can work and collaborate successfully. From right here after understanding when to make use of handoff or agents-as-tools, you possibly can proceed your exploration on constructing specialize agent with extra challanging process and instruments.

    We are going to proceed the journey on my subsequent installment of Arms-On with Brokers SDK quickly.

    Reference

    [1] Bornet, P., Wirtz, J., Davenport, T. H., De Cremer, D., Evergreen, B., Fersht, P., Gohel, R., Khiyara, S., Sund, P., & Mullakara, N. (2025). Agentic Synthetic Intelligence: Harnessing AI Brokers to Reinvent Enterprise, Work, and Life. World Scientific Publishing Co.

    [2] OpenAI. (2025). OpenAI Brokers SDK documentation. Retrieved August 1, 2025, from https://openai.github.io/openai-agents-python/handoffs/

    [3] Pydantic. (n.d.). Fashions. Pydantic Documentation. Retrieved August 1, 2025, from https://docs.pydantic.dev/latest/concepts/models/


    Learn the primary article right here:

    Yow will discover the whole supply code used on this article within the following repository: agentic-ai-weather | GitHub Repository. Be happy to discover, clone, or fork the mission to observe alongside or construct your individual model.

    If you happen to’d prefer to see the app in motion, I’ve additionally deployed it right here: Weather Assistant Streamlit

    Lastly, let’s join on LinkedIn!



    Source link

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleDoes the Code Work or Not? 
    Next Article Introducing Server-Sent Events in Python | Towards Data Science
    ProfitlyAI
    • Website

    Related Posts

    Artificial Intelligence

    Creating AI that matters | MIT News

    October 21, 2025
    Artificial Intelligence

    Scaling Recommender Transformers to a Billion Parameters

    October 21, 2025
    Artificial Intelligence

    Hidden Gems in NumPy: 7 Functions Every Data Scientist Should Know

    October 21, 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Top Posts

    Hands-On with Agents SDK: Safeguarding Input and Output with Guardrails

    September 6, 2025

    What you may have missed about GPT-5

    August 12, 2025

    New method assesses and improves the reliability of radiologists’ diagnostic reports | MIT News

    April 4, 2025

    Using generative AI to diversify virtual training grounds for robots | MIT News

    October 8, 2025

    ByteDance’s Seaweed-7B videogenerering i miniformat

    April 17, 2025
    Categories
    • AI Technology
    • AI Tools & Technologies
    • Artificial Intelligence
    • Latest AI Innovations
    • Latest News
    Most Popular

    Five ways that AI is learning to improve itself

    August 6, 2025

    How To Significantly Enhance LLMs by Leveraging Context Engineering

    July 22, 2025

    OpenAI can rehabilitate AI models that develop a “bad boy persona”

    June 18, 2025
    Our Picks

    Creating AI that matters | MIT News

    October 21, 2025

    Scaling Recommender Transformers to a Billion Parameters

    October 21, 2025

    Hidden Gems in NumPy: 7 Functions Every Data Scientist Should Know

    October 21, 2025
    Categories
    • AI Technology
    • AI Tools & Technologies
    • Artificial Intelligence
    • Latest AI Innovations
    • Latest News
    • Privacy Policy
    • Disclaimer
    • Terms and Conditions
    • About us
    • Contact us
    Copyright © 2025 ProfitlyAI All Rights Reserved.

    Type above and press Enter to search. Press Esc to cancel.