Skip to content

Handoff Agent and Tool Call Not Triggering Reliably in Multi-Agent Setup #617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
adhishthite opened this issue Apr 28, 2025 · 1 comment
Labels
question Question about using the SDK

Comments

@adhishthite
Copy link

adhishthite commented Apr 28, 2025

Please read this first

  • Have you read the docs?Agents SDK docs : YES
  • Have you searched for related issues? Others may have had similar requests : YES

Question

I am trying to do hand-offs in my production code, but I am facing a peculiar issue. I am simplifying the code here to show what I am getting.

Here's my code:

import asyncio
import random
from agents import Agent, Runner, function_tool
from agents.extensions.handoff_prompt import RECOMMENDED_PROMPT_PREFIX
from openai.types.responses import ResponseTextDeltaEvent
from pydantic import BaseModel

@function_tool
def how_many_jokes() -> int:
    return random.randint(1, 5)

class JokeFormat(BaseModel):
    joke: list[str]
    language: str

async def main():
    format_agent = Agent(
        name="Format Agent",
        instructions=f"""{RECOMMENDED_PROMPT_PREFIX}
        You will format the received joke as a Markdown. You will only return the formatted jokes.""",
        model="gpt-4.1",
        handoff_description="You are a joke formatter. You will format the jokes in Markdown.",
    )

    english_agent = Agent(
        name="English Joker",
        instructions=f"""{RECOMMENDED_PROMPT_PREFIX}
        First call the `how_many_jokes` tool. Then, tell those many jokes in English. The jokes should be very short!
        Once you have the jokes, you will pass them to the Format Agent
        """,
        tools=[how_many_jokes],
        model="gpt-4.1",
        handoff_description="You are a joke teller. You will tell jokes ONLY in English.",
        output_type=JokeFormat,
        handoffs=[format_agent]
    )

    marathi_agent = Agent(
        name="Marathi Joker",
        instructions=f"""{RECOMMENDED_PROMPT_PREFIX}
        First call the `how_many_jokes` tool. Then, tell those many jokes in Marathi. The jokes should be very short!
        Once you have the jokes, you will pass them to the Format Agent
        """,
        tools=[how_many_jokes],
        model="gpt-4.1",
        handoff_description="You are a joke teller. You will tell jokes ONLY in Marathi.",
        output_type=JokeFormat,
        handoffs=[format_agent]
    )

    agent = Agent(
        name="Triage Agent",
        instructions="You determine which agent to use based on the user joke language preference.",
        handoffs=[english_agent, marathi_agent],
        model="gpt-4.1",
    )


    result = Runner.run_streamed(
        agent,
        input="Hello, tell me a joke in English.",
    )
    print("=== Run starting ===")

    async for event in result.stream_events():
        # We'll ignore the raw responses event deltas
        
        if event.type == "raw_response_event":
            # print(f"** -- Type of event data: {type(event.data)}")
            if isinstance(event.data, ResponseTextDeltaEvent):
                print(event.data.delta, end="", flush=True)
            continue
        
        # When the agent updates, print that
        elif event.type == "agent_updated_stream_event":
            print(f"\nAgent updated: {event.new_agent.name}")
            continue
        
        # When items are generated, print them
        elif event.type == "run_item_stream_event":
            if event.item.type == "tool_call_item":
                print("-- Tool was called")
            elif event.item.type == "tool_call_output_item":
                print(f"-- Tool output: {event.item.output}")
            elif event.item.type == "message_output_item":
                pass
            
        else:
            print(f"** -- Skipped Event Item type: {event.item.type}")


if __name__ == "__main__":
    asyncio.run(main())

For this, consistently, I am getting the following output:

=== Run starting ===

Agent updated: Triage Agent

Agent updated: English Joker
{"joke":["Why did the scarecrow win an award? Because he was outstanding in his field!"],"language":"English"}%          

Problem

As you see, neither the tool is called, nor the format_agent is called. How do I ensure (not enforce, but ensure) that tools and the handoffs will work as expected? I have tried changing the prompts a little bit, the max I have gotten is that the how_many_jokes is called - but the format_agent is never called.

Example:

=== Run starting ===

Agent updated: Triage Agent

Agent updated: English Joker
-- Tool was called
-- Tool output: 2

{"joke":["Why did the scarecrow win an award? Because he was outstanding in his field!","Why don’t skeletons fight each other? They don’t have the guts."],"language":"English"}% 

@rm-openai Could you help me with please? I am running the latest version of the SDK.

@adhishthite adhishthite added the question Question about using the SDK label Apr 28, 2025
@PedroStival
Copy link

you should use this formater as tool

tools=[
spanish_agent.as_tool(
tool_name="translate_to_spanish",
tool_description="Translate the user's message to Spanish",
),
french_agent.as_tool(
tool_name="translate_to_french",
tool_description="Translate the user's message to French",
),
],

like this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question about using the SDK
Projects
None yet
Development

No branches or pull requests

2 participants