Mesh 201 Tutorial Chapter 6: Get answers to questions using Azure OpenAI

In this chapter, we move on to the fifth and final station where you'll learn how to implement an Azure OpenAI-based virtual assistant or "chatbot". Note that you could use any AI service you want here (for example, Copilot Studio). Keeping with the theme of searching for a location for a wind farm, the AI assistant will be customized to answer wind farm-related questions.

Important notes:

Setting up for this station

In order to complete this station, you'll need to visit the Azure Portal and then get a URI (also called "Endpoint") and a key for your tenant. Later, you'll insert the key into some code that'll enable you to call Azure OpenAI. Let's do this step now so that you don't have to interrupt your workflow later on.

Create and deploy an Azure OpenAI resource

  1. In your browser, navigate to the Azure Portal and then log in.

  2. In the Search box at the top of the window, type in "azure openai" and then press the Enter key. This takes you to the Azure AI services | Azure OpenAI page.

    __________________________________

  3. Click the Create button.

    __________________________________

    IMPORTANT: For many of the settings detailed below, we don't make a specific recommendation. You should choose the options that make the most sense for you and your organization.

  4. On the Basics page, create names where requested, and choose the options you want for Subscription, Region, and Pricing tier.

  5. On the Network page, choose the option you want.

    __________________________________

  6. On the Tags page, you can add tags or skip these options.

  7. On the Review and Submit page, review the information and then click the Create button.

The resource deploys and you should see a message saying that the deployment is in progress. Eventually, you'll see a Deployment is complete page.

__________________________________

Deploy the model in Azure OpenAI Studio

  1. Click the Go to Resource button.

  2. On the Resource page, click Go to Azure OpenAI Studio.

    __________________________________

  3. In the left-side menu under Management, select Deployments.

    __________________________________

  4. Select Create new deployment.

  5. Click the Deploy Model drop-down and then select Deploy base Model.

  6. In the Select a model dialog, select "gpt-35-turbo".

  7. If you wish, take a moment to view the description. When you're finished, click the Confirm button.

    __________________________________

Note: You can choose a different model, but this would require some changes to the code.

  1. In the Deployment name field, type in "gpt-35-turbo".

  2. For the other settings, choose the names and options that make the most sense for you and your organization. When you're finished, click the Deploy button.

Copy the URI and key

  1. Navigate back to the Azure main page, and then under Resources, select the resource you created.

    __________________________________

  2. On the Resource page in the left-side menu, select Keys and Endpoint.

    __________________________________

  3. On the Keys and Endpoint page, click the "Copy to clipboard" button for KEY 1 or KEY 2 (it doesn't matter which one) and then paste it into a text file using Windows Notepad or another text editor.

    __________________________________

  4. Click the "Copy to clipboard" button for Endpoint and paste it into the same text file.

  5. Save the text file. You'll need these two pieces of information later in the tutorial.

Add the prefab for Station 5

  1. In the Project folder, navigate to Assets > MeshCloudScripting and then drag the 5 - AIAssistant prefab to the Hierarchy and place it as a child object to Mesh Cloud Scripting and just under 4 - GlobeWithCloudScripting.

    __________________________________

Insert the URI and API information for Azure OpenAI

  1. In the Hierarchy, select the Mesh Cloud Scripting GameObject.

  2. In the Inspector, navigate to the Mesh Cloud Scripting component and then click Open application folder. This opens the project folder that contains the files for Mesh Cloud Scripting in the Windows File Explorer.

    __________________________________

  3. Open the file named appsettings.UnityLocalDev.json in your code editor. The last two lines of code contain placeholder comments for Azure OpenAI configuration settings.

    __________________________________

  4. Paste the URI and key that you copied earlier from the Azure Portal into these two lines, replacing the placeholder comments.

    __________________________________

  5. Save and close the file.

Update the Directory.packages.props file

  1. In the File Explorer window that displays the Mesh Cloud Scripting files, open the file named Directory.Packages.props in your code editor. Note the comment about adding package references.

    __________________________________

  2. Replace the comment with the line below:

    <PackageVersion Include="Azure.AI.OpenAI" Version="1.0.0-beta.15"/>
    
  3. Save and close the file.

Update the csproj file

  1. In the File Explorer window that displays the Mesh Cloud Scripting files, open the file named StartingPoint.csproj in your code editor.

    __________________________________

  2. Note that at the bottom of the file, just above the ItemGroup element with the WeatherAPI information, there's a comment with a placeholder for a package reference.

    __________________________________

  3. Delete the comment and replace it with the line below:

    <PackageReference Include="Azure.AI.OpenAI" />
    

    __________________________________

  4. Save and close the file.

Add the code that enables OpenAI

  1. In the File Explorer window that displays the Mesh Cloud Scripting files, navigate to the StartingPoint folder and then open the file named App.cs in your code editor.

    __________________________________

  2. In the App.cs file, find the "Paste code here" comment at the top of the list of using directives.

    __________________________________

  3. Copy the code below.

    using Azure;
    using Azure.AI.OpenAI;
    
  4. Replace the "Paste code here" comment you just found with the code you copied.

    __________________________________

  5. Find the "Paste code here" comment located below the _weatherAPIKey_ field.

    __________________________________

  6. Copy the code below.

    private OpenAIClient _openAIClient;
    
  7. Replace the "Paste code here" comment you just found with the code you copied.

    ___

  8. Find the "Paste code here" comment located in the body of the constructor.

    __________________________________

  9. Copy the code below.

    Uri azureOpenAIResourceUri = new(configuration.GetValue<string>("AZURE_OPENAI_API_URI"));
    AzureKeyCredential azureOpenAIApiKey = new(configuration.GetValue<string>("AZURE_OPENAI_API_KEY"));
    _openAIClient = new(azureOpenAIResourceUri, azureOpenAIApiKey);
    
  10. Replace the "Paste code here" comment you just found with the code you copied.

    __________________________________

  11. Find the "Paste code here" comment that follows the refreshButtonNode if statement inside the StartAsync() method.

    __________________________________

  12. Copy the code below.

    var aiParentNode = _app.Scene.FindFirstChild("5 - AIAssistant", true) as TransformNode;
    var infoButton = aiParentNode?.FindFirstChild<InteractableNode>(true);
    
    if (infoButton != null)
    {
        infoButton.Selected += async (sender, args) =>
        {
            // Ensure we have weather data before beginning the conversation
            await GetCurrentWeather(_latlong);
    
            // Display an input dialog for the user to send a message to the large language model (LLM)
            // Paste code here
        };
    }
    
  13. Replace the "Paste code here" comment you just found with the code you copied.

    __________________________________

Add the code that displays the OpenAI input dialog

  1. Find the "Paste code here" comment located shortly after the GetCurrentWeather() method in the infoButton if statement.

    __________________________________

  2. Copy the code below.

    await _app.ShowInputDialogToParticipantAsync("Ask Azure OpenAI", args.Participant).ContinueWith(async (response) =>
    {
        try
        {
            if (response.Exception != null)
            {
                throw response.Exception.InnerException ?? response.Exception;
            }
    
            string participantInput = response.Result;
    
            // Paste code here
    
            // Wait for a response from OpenAI based on the user's message
            // Paste code here
        }
        catch (Exception ex)
        {
            var log = $"Exception during OpenAI request: {ex.Message}";
            _logger.LogCritical(log);
    
            if (!response.IsCanceled)
            {
                _app.ShowMessageToParticipant(log, args.Participant);
            }
        }
    }, TaskScheduler.Default);
    
  3. Replace the "Paste code here" comment you just found with the code you copied.

    __________________________________

    The code does the following:

    • Call Mesh Cloud Scripting through the method named ShowInputDialogToParticipantAsync(). The arguments are the message you want to prompt the user with ("Ask Azure OpenAI") and who you want to display the input dialog to (args.Participant).
    • When the input dialog pops up, check for errors.
    • Save whatever the participant typed in (the result) to participantInput as a String.

Send GPT-3.5 Turbo the result of the input dialog

The code below sends the GPT-3.5 Turbo model the result of the input dialog with instructions on how to respond with the current weather data.

  1. Find the first "Paste code here" comment in the try...catch block you just pasted.

    __________________________________

  2. Copy the code below:

        var chatCompletionsOptions = new ChatCompletionsOptions()
        {
            DeploymentName = "gpt-35-turbo", // Use DeploymentName for "model" with non-Azure clients
            Messages =
            {
                // The system message represents instructions or other guidance about how the assistant should behave
                new ChatRequestSystemMessage(
                    "You are a helpful assistant." +
                    "You're part of a developer sample for the Mesh Toolkit." +
                    "Use brief answers, less than 1 paragraph." +
                    "You can suggest a good location for a wind farm based on current and historical weather data." +
                    "We're looking at globe with the current weather data displayed for each of these locations:  Lagos Nigeria, Redmond WA USA, Dublin Ireland" +
                    "Current weather conditions for these locations:" + _currentWeatherText
                    ),
                new ChatRequestUserMessage(participantInput),
            }
        };
    
  3. Replace the "Paste code here" comment you just found with the code you copied.

    __________________________________

    The code does the following:

    • Create an instance of the ChatCompletionOptions class named chatCompletionOptions.
    • Initialize a variable named DeploymentName with the deployment name you created earlier ("gpt-35-turbo").
    • Initialize a new instance of ChatRequestSystemMessage with guidance on how the assistant should answer questions. This includes the locations with the weather data you're interested in and the current conditions (_currentWeatherText) for those locations. The value of _currentWeatherText was received when we called weatherapi.com in Chapter 5.
    • Initialize a new instance of ChatRequestUserMessage with the question the participant asked.
    • Send the information about the request to the LLM (Large Language Model).

Add the code that displays the response from the LLM

  1. Find the remaining "Paste code here" comment in the try...catch block you just pasted.

    __________________________________

  2. Copy the code below:

            var aiResponse = await _openAIClient.GetChatCompletionsAsync(chatCompletionsOptions);
    
            // Display the first response from the LLM
            var responseMessage = aiResponse.Value.Choices[0].Message;
            _app.ShowMessageToParticipant($"<i>You asked: {participantInput}</i>\n\nResponse: {responseMessage.Content}", args.Participant);
    
  3. Replace the "Paste code here" comment you just found with the code you copied.

    __________________________________

    The code does the following:

    • Wait for the response from the LLM.
    • The LLM sends back several responses in an array (responseMessage). You can choose the one you want to show.
    • Call ShowMessageToParticipant() in the Mesh Cloud Scripting API to display the response.
  4. Save and close the file.

Test your work

  1. In the Unity Editor, save the project and then press the Play button.

  2. Your avatar is spawned on the side of the Sphere Terrace that contains the first three stations. Navigate to the opposite side of the Sphere Terrace and then position yourself in front of Station 5.

    __________________________________

  3. Click the Info button located in the information text box for Station 5.

    __________________________________

  4. When the Ask Azure OpenAI dialog appears, type in a question.

    __________________________________

  5. The response appears in the dialog. When you're finished, click OK.

    __________________________________

Conclusion

Congratulations! In this Mesh 201 tutorial, you learned about the following:

  • Loading local shared and non-shared HTML files into a WebSlate.
  • Using a 3D asset to call a Web API and download data into a WebSlate.
  • Pull data from internal or public sources into your scene and display it in 3D.
  • Set up AI-powered interactions using an Azure OpenAI-based virtual assistant or "chatbot".

Now you can put your new Mesh skills to work and build collaborative experiences that are even more useful and exciting!

Next Steps

Build and Publish

If you want to build and publish this tutorial project, do the following:

  1. Go to our article on preparing a Mesh Cloud Scripting project and then follow the instructions to record your Resource Group and Subscription ID.
  2. Go to our article on building and publishing your environment and then follow the instructions there. At a certain point, you'll have to navigate to a supplementary article with specialized instructions for building a project with Mesh Cloud Scripting and then return to the main build and publish article. This flow is all laid out for you in the articles.
  3. If you want to, you can test your environment in the Mesh app.

Learn more about WebSlates

Visit the WebSlates article on the Mesh Help site.

Read a blog post written by the WebSlates product manager.

Challenge

Try creating your own station with a WebSlate and a button that loads an HTML file. Be sure to share your efforts in our Mesh Developer Forum!