Megosztás a következőn keresztül:


Az Azure AI kiterjesztése eszközökkel és helyi függvény végrehajtása a .NET-tel

A Szemantic Kernel használatának első lépései egy egyszerű .NET 8 konzolos csevegőalkalmazás létrehozásával. Az alkalmazás helyileg fog futni, és az Azure OpenAI-fiókban üzembe helyezett OpenAI-modellt gpt-35-turbo fogja használni, de az Eszköz használatával kibővítheti a modell képességeit, amelyeket helyi függvénynek fog hívni. Kövesse ezeket a lépéseket az Azure OpenAI kiépítéséhez, és ismerje meg a Szemantic Kernel használatát.

A .NET Azure OpenAI SDK használatának első lépései egy egyszerű .NET 8 konzolos csevegőalkalmazás létrehozásával. Az alkalmazás helyileg fog futni, és az Azure OpenAI-fiókban üzembe helyezett OpenAI-modellt gpt-35-turbo fogja használni, de az Eszköz használatával kibővítheti a modell képességeit, amelyeket helyi függvénynek fog hívni. Kövesse az alábbi lépéseket az Azure OpenAI kiépítéséhez, és ismerje meg a .NET Azure OpenAI SDK használatát.

Előfeltételek

Az Azure-erőforrások üzembe helyezése

Győződjön meg arról, hogy az Azure OpenAI szolgáltatáshoz és az Azure Developer CLI-hez való hozzáférés előfeltételeit követi, majd a mintaalkalmazással való kezdéshez kövesse az alábbi útmutatót.

  1. Az adattár klónozása: dotnet/ai-samples

  2. Egy terminálból vagy parancssorból lépjen a rövid útmutatók könyvtárába .

  3. Ez kiépítja az Azure OpenAI-erőforrásokat. Az Azure OpenAI szolgáltatás létrehozása és a modell üzembe helyezése több percet is igénybe vehet.

    azd up
    

Feljegyzés

Ha már rendelkezik elérhető Azure OpenAI szolgáltatással, kihagyhatja az üzembe helyezést, és ezt az értéket használhatja a Program.cs, lehetőleg egy IConfiguration.

Hibaelhárítás

Windows rendszeren a következő hibaüzenetek jelenhetnek meg a futtatás azd upután:

A postprovision.ps1 nincs digitálisan aláírva. A szkript nem lesz végrehajtva a rendszeren

A postprovision.ps1 szkript végrehajtása az alkalmazásban használt .NET-felhasználói titkos kódok beállításához történik. A hiba elkerülése érdekében futtassa a következő PowerShell-parancsot:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

Ezután futtassa újra a azd up parancsot.

Egy másik lehetséges hiba:

A "pwsh" nem ismerhető fel belső vagy külső parancsként, kezelhető programként vagy kötegelt fájlként. FIGYELMEZTETÉS: A "postprovision" horog a következő kilépési kóddal meghiúsult: '1', Elérési út: '.\infra\post-script\postprovision.ps1'. : kilépési kód: 1 A végrehajtás folytatódik, mivel a ContinueOnError értéke igaz.

A postprovision.ps1 szkript végrehajtása az alkalmazásban használt .NET-felhasználói titkos kódok beállításához történik. A hiba elkerülése érdekében futtassa manuálisan a szkriptet a következő PowerShell-paranccsal:

.\infra\post-script\postprovision.ps1

A .NET AI-alkalmazások most már konfigurálva vannak a felhasználói titkos kulcsokkal, és tesztelhetők.

Próbálja ki a HikerAI Pro-mintát

  1. Nyissa meg a semantic-kernel\04-HikerAIPro könyvtárat egy terminálból vagy parancssorból.
  1. Nyissa meg a azure-openai-sdk\04-HikerAIPro könyvtárat egy terminálból vagy parancssorból.
  1. Itt az ideje kipróbálni a konzolalkalmazást. Az alkalmazás futtatásához írja be a következőt:

    dotnet run
    

    Ha hibaüzenetet kap, előfordulhat, hogy az Azure OpenAI-erőforrások nem fejezték be az üzembe helyezést. Várjon néhány percet, és próbálkozzon újra.

A kód értelmezése

Az alkalmazás a Microsoft.SemanticKernel NuGeten elérhető csomagot használja a kérések Azure-ban üzembe helyezett Azure OpenAI-szolgáltatásba való küldéséhez és fogadásához.

A teljes alkalmazás a Program.cs fájlban található. Az első több sornyi kód betölti azokat a titkos kulcsokat és konfigurációs értékeket, amelyek az dotnet user-secrets alkalmazás kiépítése során lettek beállítva az Ön számára.

var config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
string endpoint = config["AZURE_OPENAI_ENDPOINT"];
string deployment = config["AZURE_OPENAI_GPT_NAME"];
string key = config["AZURE_OPENAI_KEY"];

Az Kernel osztály a szolgáltatás segítségével AddAzureOpenAIChatCompletion megkönnyíti a kéréseket és a válaszokat.

// Create a Kernel containing the Azure OpenAI Chat Completion Service
IKernelBuilder b = Kernel.CreateBuilder();

Kernel kernel = b
    .AddAzureOpenAIChatCompletion(deployment, endpoint, key)
    .Build();

A függvények ImportPluginFromFunctionsCreateFromMethod a modell által meghívandó helyi függvény meghatározására szolgálnak.

// Add a new plugin with a local .NET function that should be available to the AI model
// For convenience and clarity of into the code, this standalone local method handles tool call responses. It will fake a call to a weather API and return the current weather for the specified location.
kernel.ImportPluginFromFunctions("WeatherPlugin",
[
    KernelFunctionFactory.CreateFromMethod(([Description("The city, e.g. Montreal, Sidney")] string location, string unit = null) =>
    {
        // Here you would call a weather API to get the weather for the location
        return "Periods of rain or drizzle, 15 C";
    }, "get_current_weather", "Get the current weather in a given location")
]);

kernel Az ügyfél létrehozása után egy rendszerkérés hozzáadásával több kontextust biztosítunk a modellnek. Ez arra utasítja a modellt, hogy hogyan működjön a beszélgetés során. Figyelje meg, hogyan emeli ki az időjárást a rendszer parancssora.

ChatHistory chatHistory = new("""
    You are a hiking enthusiast who helps people discover fun hikes in their area. You are upbeat and friendly.
    A good weather is important for a good hike. Only make recommendations if the weather is good or if people insist.
    You introduce yourself when first saying hello. When helping people out, you always ask them 
    for this information to inform the hiking recommendation you provide:

    1. Where they are located
    2. What hiking intensity they are looking for

    You will then provide three suggestions for nearby hikes that vary in length after you get that information. 
    You will also share an interesting fact about the local nature on the hikes when making a recommendation.
    """);

Ezután hozzáadhat egy felhasználói üzenetet a modellhez a AddUserMessage functon használatával.

Ha azt szeretné, hogy a modell a rendszerkérés és a felhasználói kérés alapján hozzon létre választ, használja a függvényt GetChatMessageContentAsync .

chatHistory.AddUserMessage("""
    Is the weather is good today for a hike?
    If yes, I live in the greater Montreal area and would like an easy hike. I don't mind driving a bit to get there.
    I don't want the hike to be over 10 miles round trip. I'd consider a point-to-point hike.
    I want the hike to be as isolated as possible. I don't want to see many people.
    I would like it to be as bug free as possible.
    """);

Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}");

chatHistory.Add(await service.GetChatMessageContentAsync(chatHistory, new OpenAIPromptExecutionSettings() { MaxTokens = 400 }));
Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}");

Testre szabhatja a rendszerüzenetet és a felhasználói üzenetet, hogy lássa, hogyan reagál a modell, hogy segítsen megtalálni a kívánt túrát.

A kód értelmezése

Az alkalmazás a Azure.AI.OpenAI NuGeten elérhető ügyféloldali SDK használatával küld és fogad kéréseket egy Azure-ban üzembe helyezett Azure OpenAI-szolgáltatásnak.

A teljes alkalmazás a Program.cs fájlban található. Az első több sornyi kód betölti azokat a titkos kulcsokat és konfigurációs értékeket, amelyek az dotnet user-secrets alkalmazás kiépítése során lettek beállítva az Ön számára.

// == Retrieve the local secrets saved during the Azure deployment ==========
var config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
string openAIEndpoint = config["AZURE_OPENAI_ENDPOINT"];
string openAIDeploymentName = config["AZURE_OPENAI_GPT_NAME"];
string openAiKey = config["AZURE_OPENAI_KEY"];

// == Creating the AIClient ==========
var endpoint = new Uri(openAIEndpoint);
var credentials = new AzureKeyCredential(openAiKey);

Az OpenAIClient osztály megkönnyíti a kéréseket és a válaszokat. ChatCompletionOptions a modell válaszának paramétereit adja meg. Figyelje meg, hogyan adja hozzá a definíciót az Eszközök tulajdonság.

var openAIClient = new OpenAIClient(endpoint, credentials);

var completionOptions = new ChatCompletionsOptions
{
    MaxTokens = 400,
    Temperature = 1f,
    FrequencyPenalty = 0.0f,
    PresencePenalty = 0.0f,
    NucleusSamplingFactor = 0.95f, // Top P
    DeploymentName = openAIDeploymentName,
    Tools = { getWeather }
};

Az osztály ChatCompletionsFunctionToolDefinition a modell által meghívandó helyi függvény meghatározására szolgál.

var getWeather = new ChatCompletionsFunctionToolDefinition()
{
    Name = "get_current_weather",
    Description = "Get the current weather in a given location",
    Parameters = BinaryData.FromObjectAsJson(
    new
    {
        Type = "object",
        Properties = new
        {
            Location = new
            {
                Type = "string",
                Description = "The city, e.g. Montreal, Sidney",
            },
            Unit = new
            {
                Type = "string",
                Enum = new[] { "celsius", "fahrenheit" },
            }
        },
        Required = new[] { "location" },
    },
    new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }),
};

OpenAIClient Az ügyfél létrehozása után egy rendszerkérés hozzáadásával több kontextust biztosítunk a modellnek. Ez arra utasítja a modellt, hogy hogyan működjön a beszélgetés során. Figyelje meg, hogyan emeli ki az időjárást a rendszer parancssora.

var systemPrompt = 
"""
You are a hiking enthusiast who helps people discover fun hikes in their area. You are upbeat and friendly.
A good weather is important for a good hike. Only make recommendations if the weather is good or if people insist.
You introduce yourself when first saying hello. When helping people out, you always ask them 
for this information to inform the hiking recommendation you provide:

1. Where they are located
2. What hiking intensity they are looking for

You will then provide three suggestions for nearby hikes that vary in length after you get that information. 
You will also share an interesting fact about the local nature on the hikes when making a recommendation.
""";

completionOptions.Messages.Add(new ChatRequestSystemMessage(systemPrompt));

Ezután hozzáadhat egy felhasználói üzenetet a modellhez az ChatRequestUserMessage osztály használatával.

A kód egyszerűsége és egyértelműsége érdekében ez az önálló helyi metódus kezeli az eszköz hívási válaszait. Meg fog hamisítani egy időjárási API-t, és visszaadja a megadott hely aktuális időjárását.

ChatRequestToolMessage GetToolCallResponseMessage(ChatCompletionsToolCall toolCall)
{
    var functionToolCall = toolCall as ChatCompletionsFunctionToolCall;
    if (functionToolCall?.Name == getWeather.Name)
    {
        string unvalidatedArguments = functionToolCall.Arguments;
        var functionResultData = (object)null;

        // == Here call a weather API to get the weather for specified the location ==========
        functionResultData = "Periods of rain or drizzle, 15 C";

        return new ChatRequestToolMessage(functionResultData.ToString(), toolCall.Id);
    }
    else
    {
        throw new NotImplementedException();
    }
}

Ha azt szeretné, hogy a modell a rendszerkérés és a felhasználói kérés alapján hozzon létre választ, használja a függvényt GetChatCompletionsAsync .

string hikeRequest = """
Is the weather is good today for a hike?
If yes, I live in the greater Montreal area and would like an easy hike. I don't mind driving a bit to get there.
I don't want the hike to be over 10 miles round trip. I'd consider a point-to-point hike.
I want the hike to be as isolated as possible. I don't want to see many people.
I would like it to be as bug free as possible.
""";

Console.WriteLine($"\n\nUser >>> {hikeRequest}");
completionOptions.Messages.Add(new ChatRequestUserMessage(hikeRequest));

response = await openAIClient.GetChatCompletionsAsync(completionOptions);

Most meg kell vizsgálni a választ. Ha a válasz tartalmazza ToolCalls, a metódus korábban deklarálta, hogy kezeli, és folytatja a beszélgetést. Fontos megjegyezni, hogy minden üzenet ChatRequestAssistantMessage hozzá lesz adva a beszélgetési előzményekhez. Ez fontos a beszélgetés kontextusának fenntartása érdekében.

ChatChoice responseChoice = response.Choices[0];
if (responseChoice.FinishReason == CompletionsFinishReason.ToolCalls)
{
    // == Include the FunctionCall message in the conversation history ==========
    completionOptions.Messages.Add(new ChatRequestAssistantMessage(responseChoice.Message));

    // == Add a new tool message for each tool call that is resolved ==========
    foreach (ChatCompletionsToolCall toolCall in responseChoice.Message.ToolCalls)
    {
        var ToolCallMsg = GetToolCallResponseMessage(toolCall);
        completionOptions.Messages.Add(ToolCallMsg);
    }

    // == Retrieve the answer from HikeAI Pro ==========
    response = await openAIClient.GetChatCompletionsAsync(completionOptions);
}

assistantResponse = response.Choices[0].Message;
Console.WriteLine($"\n\nAssistant >>> {assistantResponse.Content}");

Testre szabhatja a rendszerüzenetet és a felhasználói üzenetet, hogy lássa, hogyan reagál a modell, hogy segítsen megtalálni a kívánt túrát.

Az erőforrások eltávolítása

Ha már nincs szüksége a mintaalkalmazásra vagy erőforrásokra, távolítsa el a megfelelő üzembe helyezést és az összes erőforrást.

azd down

Következő lépések