@@ -37,6 +37,7 @@ To report an issue with the client library, or request additional features, plea
3737 - [ Azure Function Call] ( #create-agent-with-azure-function-call )
3838 - [ OpenAPI] ( #create-agent-with-openapi )
3939 - [ Fabric data] ( #create-an-agent-with-fabric )
40+ - [ Connected agents] ( #create-an-agent-using-another-agents )
4041 - [ Deep Research] ( #create-agent-with-deep-research )
4142 - [ Create thread] ( #create-thread ) with
4243 - [ Tool resource] ( #create-thread-with-tool-resource )
@@ -801,6 +802,178 @@ with project_client:
801802
802803<!-- END SNIPPET -->
803804
805+ ### Create an Agent using another agents
806+
807+ We can use ` ConnectedAgentTool ` to call specialized agents. In the example below we will create two agents, one is returning the Microsoft stock price and another returns weather. Note that the ` ConnectedAgentTool ` does not support local functions, we will use Azure function to return weather. The code of that function is given below; please see [ Azure Function Call] ( #create-agent-with-azure-function-call ) section for the instructions on how to deploy Azure Function.
808+
809+ ``` python
810+ import azure.functions as func
811+ import datetime
812+ import json
813+ import logging
814+
815+ app = func.FunctionApp()
816+
817+ @app.function_name (name = " GetWeather" )
818+ @app.queue_trigger (
819+ arg_name = " arguments" ,
820+ queue_name = " weather-input" ,
821+ connection = " AzureWebJobsStorage" )
822+ @app.queue_output (
823+ arg_name = " outputQueue" ,
824+ queue_name = " weather-output" ,
825+ connection = " AzureWebJobsStorage" )
826+ def foo (arguments : func.QueueMessage, outputQueue : func.Out[str ]) -> None :
827+ """
828+ The function, answering question about weather.
829+
830+ :param arguments: The arguments, containing json serialized request.
831+ :param outputQueue: The output queue to write messages to.
832+ """
833+
834+ parsed_args = json.loads(arguments.get_body().decode(' utf-8' ))
835+ location = parsed_args.get(" Location" )
836+ try :
837+ response = {
838+ " Value" : " 60 degrees and cloudy" if location == " Seattle" else " 10 degrees and sunny" ,
839+ " CorrelationId" : parsed_args[' CorrelationId' ]
840+ }
841+ outputQueue.set(json.dumps(response))
842+ logging.info(f ' The function returns the following message: { json.dumps(response)} ' )
843+ except Exception as e:
844+ logging.error(f " Error processing message: { e} " )
845+ raise
846+ ```
847+ We will define two agents that has descriptions, explaining when they need to be called.
848+
849+ <!-- SNIPPET:sample_agents_multiple_connected_agents.create_two_toy_agents -->
850+
851+ ``` python
852+ connected_agent_name = " stock_price_bot"
853+ weather_agent_name = " weather_bot"
854+
855+ stock_price_agent = agents_client.create_agent(
856+ model = os.environ[" MODEL_DEPLOYMENT_NAME" ],
857+ name = connected_agent_name,
858+ instructions = (
859+ " Your job is to get the stock price of a company. If asked for the Microsoft stock price, always return $350."
860+ ),
861+ )
862+
863+ azure_function_tool = AzureFunctionTool(
864+ name = " GetWeather" ,
865+ description = " Get answers from the weather bot." ,
866+ parameters = {
867+ " type" : " object" ,
868+ " properties" : {
869+ " Location" : {" type" : " string" , " description" : " The location to get the weather for." },
870+ },
871+ },
872+ input_queue = AzureFunctionStorageQueue(
873+ queue_name = " weather-input" ,
874+ storage_service_endpoint = storage_service_endpoint,
875+ ),
876+ output_queue = AzureFunctionStorageQueue(
877+ queue_name = " weather-output" ,
878+ storage_service_endpoint = storage_service_endpoint,
879+ ),
880+ )
881+
882+ weather_agent = agents_client.create_agent(
883+ model = os.environ[" MODEL_DEPLOYMENT_NAME" ],
884+ name = weather_agent_name,
885+ instructions = (
886+ " Your job is to get the weather for a given location. "
887+ " Use the provided function to get the weather in the given location."
888+ ),
889+ tools = azure_function_tool.definitions,
890+ )
891+
892+ # Initialize Connected Agent tools with the agent id, name, and description
893+ connected_agent = ConnectedAgentTool(
894+ id = stock_price_agent.id, name = connected_agent_name, description = " Gets the stock price of a company"
895+ )
896+ connected_weather_agent = ConnectedAgentTool(
897+ id = weather_agent.id, name = weather_agent_name, description = " Gets the weather for a given location"
898+ )
899+ ```
900+
901+ <!-- END SNIPPET -->
902+
903+ Add the ` ConnectedAgentTool ` -s to main agent.
904+
905+ <!-- SNIPPET:sample_agents_multiple_connected_agents.create_agent_with_connected_agent_tool -->
906+
907+ ``` python
908+ # Create agent with the Connected Agent tool and process assistant run
909+ agent = agents_client.create_agent(
910+ model = os.environ[" MODEL_DEPLOYMENT_NAME" ],
911+ name = " my-assistant" ,
912+ instructions = " You are a helpful assistant, and use the connected agents to get stock prices and weather." ,
913+ tools = [
914+ connected_agent.definitions[0 ],
915+ connected_weather_agent.definitions[0 ],
916+ ],
917+ )
918+ ```
919+
920+ <!-- END SNIPPET -->
921+
922+ Create thread and run.
923+
924+ <!-- SNIPPET:sample_agents_multiple_connected_agents.run_agent_with_connected_agent_tool -->
925+
926+ ``` python
927+ # Create thread for communication
928+ thread = agents_client.threads.create()
929+ print (f " Created thread, ID: { thread.id} " )
930+
931+ # Create message to thread
932+ message = agents_client.messages.create(
933+ thread_id = thread.id,
934+ role = MessageRole.USER ,
935+ content = " What is the stock price of Microsoft and the weather in Seattle?" ,
936+ )
937+ print (f " Created message, ID: { message.id} " )
938+
939+ # Create and process Agent run in thread with tools
940+ run = agents_client.runs.create_and_process(thread_id = thread.id, agent_id = agent.id)
941+ print (f " Run finished with status: { run.status} " )
942+ ```
943+
944+ <!-- END SNIPPET -->
945+
946+ To understand what calls were made by the main agent to the connected ones, we will list run steps.
947+
948+ <!-- SNIPPET:sample_agents_multiple_connected_agents.list_tool_calls -->
949+
950+ ``` python
951+ for run_step in agents_client.run_steps.list(thread_id = thread.id, run_id = run.id, order = ListSortOrder.ASCENDING ):
952+ if isinstance (run_step.step_details, RunStepToolCallDetails):
953+ for tool_call in run_step.step_details.tool_calls:
954+ print (f " \t Agent: { tool_call._data[' connected_agent' ][' name' ]} "
955+ f " query: { tool_call._data[' connected_agent' ][' arguments' ]} " ,
956+ f " output: { tool_call._data[' connected_agent' ][' output' ]} " )
957+ ```
958+
959+ <!-- END SNIPPET -->
960+
961+ The messages contain references, marked by unicode opening and closing brackets, which cannot be printed by python ` print ` command. To fix this issue we will replace them by ASCII brackets.
962+
963+ <!-- SNIPPET:sample_agents_multiple_connected_agents.list_messages -->
964+
965+ ``` python
966+ # Fetch and log all messages
967+ messages = agents_client.messages.list(thread_id = thread.id, order = ListSortOrder.ASCENDING )
968+ for msg in messages:
969+ if msg.text_messages:
970+ last_text = msg.text_messages[- 1 ]
971+ text = last_text.text.value.replace(' \u3010 ' , ' [' ).replace(' \u3011 ' , ' ]' )
972+ print (f " { msg.role} : { text} " )
973+ ```
974+
975+ <!-- END SNIPPET -->
976+
804977
805978### Create Thread
806979
0 commit comments