2024年10月23日 星期三

Azure OpenAI AOAI 2.0 : 1 第一次使用 Azure.AI.OpenAI 2.0.0 開發教學

Azure OpenAI AOAI 2.0 : 1 第一次使用 Azure.AI.OpenAI 2.0.0 開發教學

在2024/10/01 微軟宣布Azure.AI.OpenAI 2.0.0正式發布,這是一個重大的里程碑,因為這是一個全新的版本,並且有許多新功能和改進。在此之前,所使用的Azure OpenAI client library for .NET 套件都是Beta 版本,而在此正式版堆出之後,將會有一些使用方式的改變與增加許多功能,所以,將會針對這些Azure OpenAI client library for .NET 2.0 版本進行一系列的教學。

在這裡先要來了解AOAI 採用的是大語言模型技術,使用者可以傳入文字,透過大語言模型的處理,就會產生出一段回應文字,這樣的技術可以應用在許多場景,例如:對話式應用程式、自動回覆、自動翻譯、自動摘要、自動產生程式碼等等。

這個傳入的文字可以稱之為Prompt 「提示詞」、「提示訊息」或「引導詞」,而產生的回應文字可以稱之為Completion 「完成字」、「完成訊息」或「完成句」。

在這個教學中,將會介紹如何使用Azure.AI.OpenAI 2.0.0 來開發一個提問與回答的應用程序,這個應用程序可以通過Prompt 提問,然後通過Completion 來回答,這個應用程序可以應用在許多場景,例如:自動回复、自動翻譯、自動摘要、自動產生代碼等等。

例如,若使用者輸入了一個Prompt “Say 'this is a test.'”,這個Prompt 將會被傳入到Azure OpenAI 服務中,然後Azure OpenAI 服務將會產生一段Completion 回應文字[ This is a test. ]。下圖將會展示這個應用程式的運作方式。

建立測試專案

請依照底下的操作,建立起這篇文章需要用到的練習項目

  • 打開Visual Studio 2022 IDE 應用程式
  • 從[Visual Studio 2022] 對話窗中,點選右下方的[建立新的項目] 按鈕
  • 在[建立新項目] 對話窗右半部
    • 切換[所有語言(L)] 下拉選單控制項為[C#]
    • 切換[所有項目類型(T)] 下拉選單控制項為[控制台]
  • 在中間的項目模板清單中,找到並且點擊[控制台應用程式] 項目模板選項

    項目,用於建立可在Windows、Linux 及macOS 於.NET 執行的命令列應用程序

  • 點擊右下角的[下一步] 按鈕
  • 在[設定新的項目] 對話窗
  • 找到[項目名稱] 字段,輸入csAzureAIOpenAIQuickStart作為項目名稱
  • 在剛剛輸入的[項目名稱] 欄位下方,確認沒有勾選[將解決方案與項目至於相同目錄中] 這個檢查盒控制項
  • 點擊右下角的[下一步] 按鈕
  • 現在將會看到[其他資訊] 對話窗
  • 在[架構] 欄位中,請選擇最新的開發框架,這裡選擇的[架構] 是 :.NET 8.0 (長期支援)
  • 在這個練習中,需要去勾選[不要使用最上層陳述式(T)] 這個檢查盒控制項

    這裡的這個操作,可以由讀者自行決定是否要勾選這個檢查盒控制項

  • 請點擊右下角的[建立] 按鈕

稍微等候一下,這個背景工作服務項目將會建立完成

安裝要用的NuGet 開發套件

因為開發此專案時會使用這些NuGet 套件,請依照底下說明,將需要用到的NuGet 套件安裝。

安裝Azure.AI.OpenAI 套件

請依照底下說明操作步驟,將這個套件安裝到專案內

  • 鼠標右擊[方案總管] 視窗內的[專案節點] 下方的[依賴] 節點
  • 從彈出功能表清單中,點選[管理NuGet 套件] 這個功能選項清單
  • 此時,將會看到[NuGet: csAzureAIOpenAIQuickStart] 視窗
  • 切換此視窗的標籤頁次到名稱為[瀏覽] 這個標籤頁次
  • 在左上方找到一個搜尋文字輸入盒,在此輸入Azure.AI.OpenAI
  • 在視窗右方,將會看到該套件詳細說明的內容,其中,右上方有的[安裝] 按鈕

    請確認有取消Pre-release 這個選項,與選擇2.0 正式版

  • 點擊這個[安裝] 按鈕,將這個套件安裝到專案內

修改Program.cs 類別內容

在這篇文章中,將會把會使用到的新類別與代碼,都寫入[Program.cs] 這個檔案中,請依照底下的操作,修改[Program.cs] 這個檔案的內容

  • 在專案中找到並開啟[Program.cs] 檔案
  • 將底下的代碼取代掉Program.cs檔案中內容
using Azure.AI.OpenAI;
using Azure;
using OpenAI.Chat;
using System.Net;

namespace csAzureAIOpenAIQuickStart;

internal class Program
{
    static void Main(string[] args)
    {
        // 讀取環境變數 AOAILabKey 的 API Key
        string apiKey = System.Environment.GetEnvironmentVariable("AOAILabKey");
        AzureOpenAIClient azureClient = new(
            new Uri("https://gpt4tw.openai.azure.com/"),
            new System.ClientModel.ApiKeyCredential(apiKey));
        ChatClient chatClient = azureClient.GetChatClient("gpt-4");

        string userPrompt = "Say 'this is a test.'";
        Console.WriteLine($"{DateTime.Now}  [User]: {userPrompt}");
        ChatCompletion completion = chatClient.CompleteChat("Say 'this is a test.'");

        foreach (var message in completion.Content)
        {
            Console.WriteLine($"{DateTime.Now} {message.Text}");
        }
        Console.WriteLine($"Role : {completion.Role}");
        Console.WriteLine($"InputTokenCount : {completion.Usage.InputTokenCount}");
        Console.WriteLine($"OutputTokenCount : {completion.Usage.OutputTokenCount}");
        Console.WriteLine($"ReasoningTokenCount : {completion.Usage.OutputTokenDetails?.ReasoningTokenCount}");
        Console.WriteLine($"TotalTokenCount : {completion.Usage.TotalTokenCount}");
    }
}

當要使用Azure OpenAI library for .NET 來呼叫ChatGPT 相關應用API 的時候,首先需要建立一個[AzureOpenAIClient] 類別的物件,這個物件是用來建立一個Azure OpenAI client library for .NET 的物件,這個物件是用來呼叫Azure OpenAI 的API 服務。

在此需要宣告與傳入兩個參數,第一個參數是Azure OpenAI 的API 服務的網址,第二個參數是Azure OpenAI 的API 服務的密鑰,這個密鑰是用來驗證使用者的身份,這個金鑰是在Azure OpenAI 的網站上申請的。有了這兩個信息,便可以取得與使用Azure 所提供的OpenAI 服務,透過其云大語言模型技術,來進行文字的生成。

因此,在這裡使用了AzureOpenAIClient azureClient = new(new Uri("https://gpt4tw.openai.azure.com/"), new System.ClientModel.ApiKeyCredential(apiKey));敘述來完成上述需求,不過,對於Azure OpenAI 用到的密鑰信息,是具有敏感性的,因為,任何人取得了服務端點與該密鑰,就可以使用你訂閱的服務,所產生的費用,是由你負擔,因此,在這裡不會將該密鑰放在項目原始碼內,而是通過環境變量的方式來取得。這樣的好處是,可以避免密鑰資訊洩露,而且,可以在不同的環境中,使用不同的密鑰資訊。

此時,開啟指令提示字元視窗,輸入[set] 指令,便可以看到所有環境參數的清單

從上面螢幕截圖,可以看到已經有設定一個環境變數AOAILabKey,這個環境變量是用來存放Azure OpenAI 金鑰資訊的。

使用底下指令將建立OpenAI Key 永久性的環境變數,這代表這個環境變量將會一直存在,不會因為該系統重新開機之後,該環境變量就不存在了,直到你刪除它為止

setx AOAILabKey "剪貼簿內的 OpenAI Key 值" /M

如何刪除此環境變數

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V AOAILabKey /f

若金鑰與服務端點都設定完成,且AzureOpenAIClient azureClient 可以正常運作,接下來就要產生ChatClient chatClient 物件,這裡使用了ChatClient chatClient = azureClient.GetChatClient("gpt-4");敘述來取得ChatClient 類別的物件,這個物件是用來呼叫ChatGPT 相關應用API 服務的。

想要知道有那些模型可以使用,可以透過Azure 網頁查詢

進入Azure 網頁,搜尋或找到[Azure OpenAI] 服務

點擊進入後,參考下圖,在網頁中間下方,可以看到[Explore and deploy] 選項

點擊進入後,可以看到[Azure OpenAI Studio] 頁面,在最左方找到[部署] 鏈接,就可以看到所有的模型清單,這裡使用的是gpt-4模型

現在要來建立一個ChatClient chatClient 物件,這個物件是用來呼叫ChatGPT 相關應用API 服務的,這裡使用了ChatClient chatClient = azureClient.GetChatClient("gpt-4");敘述來取得ChatClient 類別的物件,這個物件是用來呼叫ChatGPT 相關應用API 服務的。 azureClient.GetChatClient("gpt-4");

AzureOpenAIClient Class Methods中,有列出所有可用取得特定服務方法

  • GetAudioClient(String)

    取得一個新的OpenAI.Audio.AudioClient實例,該實例配置為與Azure OpenAI 服務一起使用音頻操作。

  • GetChatClient(String)

    取得一個新的OpenAI.Chat.ChatClient實例,該實例配置為與Azure OpenAI 服務一起使用聊天完成操作。

  • GetEmbeddingClient(String)

    取得一個新的OpenAI.Embeddings.EmbeddingClient實例,該實例配置為與Azure OpenAI 服務一起使用嵌入操作。

  • GetImageClient(String) 取得一個新的OpenAI.Images.ImageClient實例,該實例配置為與Azure OpenAI 服務一起使用映像操作。

透過這個方法GetChatClient 所取得的物件,可以進行對指定大語言模型進行對話式應用程式的操作,這個對像是用來呼叫ChatGPT 相關的應用API 服務。

想要對大語言模型提出問題,可以使用類似這樣用法chatClient.CompleteChat("Say 'this is a test.'");其中,使用CompleteChat 方法傳入進去的字符串,就是Prompt,該方法將會回傳[ChatCompletion],透過這個物件,就可以得到大語言模型生成的文字內容。

在[ChatCompletion] 物件內有個類型為[ChatMessageContent] 的屬性[Content] ,這個屬性是用來存放ChatGPT 產生的文字內容,透過這個屬性,就可以取得ChatGPT 產生的文字內容。這裡使用底下方法將生成文字內容印在螢幕上。

foreach (var message in completion.Content)
{
    Console.WriteLine($"{DateTime.Now} {message.Text}");
}

該物件也可以取得ChatGPT 產生的文字內容的其他信息,例如:Role、InputTokenCount、OutputTokenCount、ReasoningTokenCount、TotalTokenCount 等等,這些資訊可以透過ChatCompletion 物件的屬性來取得。有了這些信息,便可以計算出這次呼叫GPT 運算的成本,這樣就可以控制Azure OpenAI 服務的使用成本。

Console.WriteLine($"Role : {completion.Role}");
Console.WriteLine($"InputTokenCount : {completion.Usage.InputTokenCount}");
Console.WriteLine($"OutputTokenCount : {completion.Usage.OutputTokenCount}");
Console.WriteLine($"ReasoningTokenCount : {completion.Usage.OutputTokenDetails?.ReasoningTokenCount}");
Console.WriteLine($"TotalTokenCount : {completion.Usage.TotalTokenCount}");

執行測試專案

  • 按下F5開始執行專案
  • 將會看到輸出結果

2024/10/23 上午 10:14:24  [User]: Say 'this is a test.'
2024/10/23 上午 10:14:26 This is a test.
Role : Assistant
InputTokenCount : 14
OutputTokenCount : 5
ReasoningTokenCount : 

TotalTokenCount : 19 




沒有留言:

張貼留言