iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0

Hello, 各位 iT 邦幫忙 的粉絲們大家好~~~

在本系列文會展開使用 Avalonia UI 技術所建立的 TopAOAIConnector App 。由於使用 Avalonia UI 可以很快速的進行各平台的 桌面 應用程式開發,並且透過此 TopAOAIConnector App 來串接 Azure OpenAI Service 時所需的功能研究。

本篇是 就是要來點 A.I. 的 TopAOAIConnector App 系列文的 EP15。


EP 13 成功的可以跟 AOAI Service 的 "聊天" 互動後,要完成 EP 14 的方式其實不難。

來回顧一下 EP 13 跟 AOAI Service 互動所做的事情。

首先在 Utilities 當中設計的 AoaiServiceHelper 類別:

internal class AoaiServiceHelper
{
    static readonly string endpoint = AOAISettings.Instance.Endpoint!;
    static readonly string key = AOAISettings.Instance.SecretKey1!;
    static readonly string deployModelName = AOAISettings.Instance.DeployModelName!;

    public static async Task<string> Go(string userMessage)
    {
        var azureOpenAIclient = new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(key));
        var chatClient = azureOpenAIclient.GetChatClient(deployModelName);

        var completionChat = await chatClient.CompleteChatAsync(
            new List<ChatMessage>()
            {
                new UserChatMessage(userMessage)
            });

        var result = $"{completionChat.Value.Role}:{Environment.NewLine}{completionChat.Value.Content[0].Text}";
        return result;
    }
}

可以注意到:

var completionChat = await chatClient.CompleteChatAsync(
    new List<ChatMessage>()
    {
        new UserChatMessage(userMessage)
    });

所呼叫的 CompleteChatAsync 方法傳遞的參數是個 List<ChatMessage>,這就代表著呼叫 CompleteChatAsync 方法時可以傳遞多個 ChatMessage 進去,而 ChatMessage 又可以是:

  1. SystemChatMessage
  2. UserChatMessage
  3. AssistantChatMessage
  4. ToolChatMessage
  5. FunctionChatMessage

01

在目前來講,上述五種 ChatMessage 的子類別,就會對應到要如何呼叫 CompleteChatAsync 的方式,也就代表著這次的對話將會帶入所建立的 GPT 模型 prompt 進去。

別忘記 LLM 模型通常是沒有記憶能力的,所以每次對話必須把過去交談的資料也再帶回去當作 input。

所以就會變成這樣像 EP 13 結果,而我們如果把有輸入的 input 跟模型所回答的 output 不斷的串接到下一次送出的資料 input,就可以做出一些連續提問並產生有效回答的結果。

按照以上所說的概念,開始來實作吧~~~

首先將原本的 AoaiServiceHelper 類別設計中,設計一個型別為 AzureOpenAIClient 為 static 的 Instance 屬性,並將 Go 方法改變成下列撰寫:

static readonly AzureOpenAIClient _instance = new(new Uri(endpoint), new ApiKeyCredential(key));
static AzureOpenAIClient Instance => _instance;

public static async Task<string> Go(List<ChatMessage> chatMessage)
{
    var chatClient = Instance.GetChatClient(deployModelName);

    var completionChat = await chatClient.CompleteChatAsync(chatMessage);

    var result = $"{completionChat.Value.Role}:{Environment.NewLine}{completionChat.Value.Content[0].Text}";
    return result;
}

改變處可參考下圖紅框:
02

再來回到 Views/ChatPageViewModel.cs 在 ChatPageViewModel 類別當中增加一個 List<ChatMessage> 欄位的設計:

private readonly List<ChatMessage> messages = [];

完成結果如下圖紅框:
03

並對 BuildAoaiResultToChatText 方法進行修正 (點 1):

private async Task BuildAoaiResultToChatText()
{
    var assistantMessage = await Utilities.AoaiServiceHelper.Go(messages).ContinueWith(async task =>
    {
        var result = await task;
        ChatText = $"{ChatText}{Environment.NewLine}{result}{Environment.NewLine}";

        messages.Add(result);
    });
}

在原本的 Send 方法除了改變對 BuildAoaiResultToChatText 方法的呼叫修正外,也增加紀錄到前面所宣告的 message (點 2):

messages.Add(textContent);

await BuildAoaiResultToChatText();

04

在原本的 Attach 方法也一樣,改變對 BuildAoaiResultToChatText 方法的呼叫修正外,也增加紀錄到前面所宣告的 message (點 1):

messages.Add(textContent);

await BuildAoaiResultToChatText();

但考慮到若上傳新的附加檔時,先前對於前一份文字檔的對話紀錄應該就無效,所以在 Attach 方法最一開始執行檢查一下紀錄,並變更 ChatText 的顯示 (點 2):

if (!string.IsNullOrEmpty(fileContent) && messages.Count > 0)
{
    ChatText = $"{Environment.NewLine}{ChatText}{Environment.NewLine}=======Another Attach TextFile======={Environment.NewLine}";
    messages.Clear();
}

05

所以這時候就可以來試試看效果囉~~~

以上完成!

下回見囉!


上一篇
EP 14
下一篇
EP 16
系列文
就是要來點 A.I. 的 TopAOAIConnector App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言