從 Semantic Kernel 談 AI 浪潮下的開發人員的挑戰

從 Semantic Kernel 談 AI 浪潮下的開發人員的挑戰



圖片來源:https://blockcast.it/2023/03/22/will-chatgpt-replace-blockhcain-developers/


前言

近年來,從前年 2022年11月30號 ChatGPT 推出以來,可說席捲整個世界,生成式 AI 將取代你的工作一詞不斷的在新聞媒體版面、各行各業、甚至你生活周遭出現,不亞於當年 iPhone 的推出,但我覺得更甚於此,因為 AIGC 的出現,讓我原先不看好的 LLM 大型語言模型原來能夠 Pre-Trained 到這樣的地步,類神經網路居然能將自然語言(NLP)的處裡,表達做到基本邏輯推演甚至通過圖靈測試的地步,這讓許多人、各行各業、開發人員都燃起盞明燈。而取代之說,也如雨後春筍般地湧現,是好是壞大家不僅開始思考各種因應的對策與方法。但趨勢通常都不可檔,只能去理解它、瞭解它、利用它、接受它、擁抱它、未來它會成為我們生活周遭的一部份。


在 AI 浪潮下,開發人員面對的是什麼?

最近我一直在思考一個問題,在生成式 AI 的浪潮下,這對開發人員有什麼影響?我個人的看法是,開發人員未來要生存只會越來越難,我們得先做好充足的準備,但凡事總是有一體兩面,因為生成式 AI 有可能會使的基本的工具與技能不再重要?像是比較細微的工作,也就是粒度比較小的工作,像是翻譯這一段文字、為這個 Method 撰寫測試等等,以及一些需求明確,能夠以自然語言完整表達的(內容/Code)產生的工作可能都可以由生成式 AI 來完成即可。

但前面提到凡事都是一體兩面的,目前的 AI 以上下文來預測下一個字詞,這目前仍然可能有幻覺,也就是開發人員還是得做最後生成的內容的把關的動作,只是善用 AI 是能夠大大增加生產力,而開發人員可以更完全專注在(商業需求/業務需求 or 藥物目標)上。


對軟體產業的影響

當工具與技能不再重要??其實這句話這樣說,其實也不太對,以前我們常說,替客戶開發專案使用的程式語言或是技術不重要,重要的是要能夠完全的達成客戶的期望。

因為,在人工智慧開始蓬勃發展的現代,如果 AI 能夠完成你的軟體架構的基礎樣貌,可能是 Class/Design Patterns 屬於客戶端自然語言生成的部分,也許有 50%-60% 我們可以不用關心,但是反過來說,你對基礎架構的不熟悉衍伸其他的問題這之後再來討論。針對 50% 至 60% 有人認為可以有 70% 但我認為沒有,人類還是得關心其內容的產出的正確性,我個人認為軟體系統發展初期又 AI 來產生部分基礎架構是可以節省許多人力成本,但隨著系統不斷的發展變的龐大,資訊系統產生的『參數(Query/Key/Value)』超過的回饋量時,你還是會回到軟體開發最原始的問題,就是技術債的包袱,也就是當系統越做越大時 AI 就越來越不可控。

其實 AI 本來就不可控,因為它是用預測的方式,然而預測總是會有失誤的時候,最後還是要人類來進行最後的把關行為,只是當 AI 完成的範圍越廣,人們對於系統的掌握度就越低,這時系統就越容易失控。當然了,是當的使用 AI 是有好處的。

再回到生成式 AI 對軟體產業的影響,整體的來說,生成式 AI 目前還在幼幼班的程度,所以目前也不是將工作權交給 AI 後人類就沒事了,反倒是複雜性變得更高。

但也不是完全沒有影響,前面提到一部份,這邊我列個幾點出來,也就是目前生成式 AI 對於:

(1). 程式開發者門檻提高

如上,一些瑣碎性工作(需求精確的/撰寫單一方法/撰寫測試..etc)重複性高的工作由 AI 來做肯定比人還快,初級人員對於需求精確地、粒度小的工作產生的速度仍產出不如 AI 快,對於初級人員再基礎都還不熟悉的情況下,比較難切入這個產業,因為你無法確認 AI 生成的內容是否有務,盲目使用生成式 AI 的產出將產生下面第 (3) 點隱憂。但門檻變高會是真的。

(2). 程式語言&開發技術不再是重點,該著重在商業需求&要解決的問題上,透過AI的補助與結合

目前許多市場需求也還在生長中,市場為了生存尋求合適 & 快速的解決方案本來就是無法底擋的,我們只能去面對它、正視它、使用它、利用它、用它來賺錢。

(3). 基礎知識反而更加重要

因為 AI 隨處產生的程式碼,開發人員得有(更多/更深)的專業來判別其正確性,這這些年資尚淺的員工恐怕無法勝任,雖然 AI 節省不少時間,但是產生的程式碼在不了解情況下,貿然的上線將衍伸出更嚴重的技術債等問題(水可載舟;亦可覆舟)


企業如何因應 AI 所造成的市場改變?

其實,在現在這個時間點,AI 已經不只變成一門顯學,不光是影響各行各業,如果你不去了解它,那麼它未來也會來追著你跑,甚至來吞食你,即便它目前還處於萌芽階段。但連 Apple 都放棄研發汽車 Apple Car 的情況下,這證明了 AI 已經是目前整個市場.. 或者應該說,我不敢說是整個市場發展趨勢,但是可以確定的是,AI 外來會是各行各業關注的焦點。

在 AI 元年之後,企業也將面臨更大的【競爭】、【挑戰】,由於在很多同行都開始使用或透過 AI 與企業整合增加了效率與產能,這時,許多企業會開始問:的是 AI 與現有企業系統的整合的可能性?AI 協助企業開發加速的可能性?而這一開始,你要先知道:

  1. 為什麼企業需要 AI?
  2. AI 在開發什麼?為什麼需要開發?
  3. AI 到底要怎麼開發?
  4. 或者是,到底 AI 能幫助我們企業什麼?
  5. AI 與我們企業現有系統的整合的可能性?

我們現在所提及的都是基於 LLM, Large Language Model 大語言模型,比較知名的像是 OpenAI 所堆出的 ChatGPT 以及後來微軟與 OpenAI 合作後在 Azure 加入的 Azure OpenAI,他們的合作方式就是微軟 Azure 提供其海量的運算資源,而 OpenAI 提供其 LLM 模型的相關技術給微軟。且在 OpenAI 的人工智能領域上,微軟還向 OpenAI 投資了大約 130 億美元,並且微軟作為 OpenAI 的主要財務支持者和商業夥伴。

至於 AI 帶底在開發什麼?以及為什麼 AI 需要開發?中間這幾項問題我就留在最嘔一個 Topic 【為什麼需要 Semantic Kernel?它可以為我們做什麼?】來為大家報告!當然了,目前市場還有 LangChain 等 SDK 工具只不過它是使用 Python 的程式語言,我這裡偏向使用 C# 的,由微軟所發展的 Semantic Kernel 的 SDK 來做介紹。


在 AI 的時代軟體架構師應該著重在哪一個方向上?

這裡,我來談談在 AI 正要開始蓬勃發展的現代,如果已經身為軟體架構師如何應對?如果你是身處企業內部的軟體架構師那麼你該思考的是,在企業本身的商業流程上 AI 能夠提供什麼幫助?好比電信公司發展的 AI 客服智能機器人等、或者是線上購物改變為線上購物個人助理,利用 AI 的深度學習實現的分析與預測功能來協助分析你的購物需求、甚至在自動化上面可以改進原本生產線上需要大量人力才能時做感應器和視覺系統,大大提升產量與精確度。甚至據說 2023 年德國賓士(Mercedes-Benz)車廠宣布與微軟(Microsoft)合作,將 ChatGPT 導入 MBUX 多媒體系統,實現人車交談的應用,利用近期相當熱門的 ChatGPT 之生成式 AI,整合到旗下車款的 MBUX 車 載系統中,這項合作是全球首度將 ChatGPT 導入車輛市場中,並透過 Azure OpenAI 服務與 MBUX 系統相互整合。

圖(二)、將 ChatGPT 導入 MBUX 多媒體系統 將 ChatGPT 導入 MBUX 多媒體系統

如果你是軟體開發團隊的軟體架構師,你該思考的是,除了如何利用 AI 提升軟體開發的效率外,更重要的是如何讓企業長久以來的學習 Keep 下來?或者說讓 AI 來學習企業的商業命脈、或者換個角度來說,長久以來開發團隊其實已經累積了團隊開發經驗 + 資產,而在未來,透過 Prompt Engineer 的自然語言 與 機器溝通的人機介面會取代我們原本透過 OP 人員透過監控畫面查看系統可能出錯的各種情況,這些歷史發生過的事件,都可以被 AI 透過 Prompt 來學習。

可以試想,未來的軟體開發,所有原本的自動化,還可以更自動化。 透過 AI 人工智慧的預測與分析功能來幫助人類做『最正確讀決策』,並不是說 AI 能夠決策,而是透過 LLM 的學習能力 Keep 軟體開發團隊歷年來的經驗資產,這是透過 LLM 擅長的自然語言 => Code 的能力,試想,未來軟體部署時,在 CI 環節失敗時,由 LLM 來接手這個 Bug 時,你可以下 Prompt 問 LLM 說:這個問題我們是不是曾經遇過?並請 LLM 嘗試修改這段程式碼,然後秀給你!軟體開發人員在畫面確認 LLM 完成的 Code 是否正確即可!試想、而這過程可能只需要幾分鐘而已,原先開發人員得下載程式碼並手動修改,但這不是說 AI 不會出錯,現階段還是要把關其產出的內容,只不過 LLM 對於自然語言的學習能力遠比人類來的快速,且 LLM 不會忘記任何一件它學習過的事情,人蕾只需要判別其產出的內容即可。而 AI 無法做的事情,可以經由像是 Semanatic Kernel 或是 LangChain 等,企業可以自行擴充 LLM 不懂的部分,或者是說客製化一個屬於你企業內部商業模型的資產。

最後一個章節,就是來討論企業如何透過 Semantic Kernel 來開發或擴充、或者客製化屬於自己企業的特定商業 LLM 模型。

了解 AI 相關領域如何與開發結合,已經是刻不容緩的事情了。而且已經成為『趨勢』是不可逆的。


為什麼需要 Semantic Kernel?它可以為我們做什麼?

我們來看看 Semantic Kernel 的架構,這是從官方的 GitHub 擷取下來的。

圖(三)、Semantic Kernel 的架構 Semantic Kernel 的架構

如圖這是 Semantic Kernel 的 Context 架構圖,它說明了在 Semantic Kernel 的環境 Context 下面的幾種(學習/客製化)的能力,就像圖上所表示的,它的學習途徑可以標示為 Semantic function 的 API 或甚至是 Native function 也就是原生的 DLL 內的 Methods 都可以作為擴充 LLM 的能力的來源,只要透過 Plug-In 的架構吃進來即可,可謂非常強大?

那麼你會說這跟企業有什麼關係?這關係可大了!上方我提到的 AI 該怎麼開發?要開發什麼?事實上就是補足 LLM 不能夠精確回答的部分,因為 LLM 是一種深度學習的人工智慧的大語言模型,經由上下文、預測下一個字,雖然它無法 100% 精準,但透過 Semantic Kernel 強大的擴充能力,讓企業內部現有已經開發好的應用程式來跟 ChatGPT 或 Azure OpenAI 來做整合這基本上已經不是太困難的事情了。

舉個常見的情境、LLM 模型其實無法計算數學,但透過 Semantic Kernel 來擴充,就可讓 LLM 執行準確的平方根計算,因為呼叫的是你實際的 C# 方法,這是不是讓你們的 LLM 系統產生無限的可能呢?這幾乎是你想做什麼幾乎都可以做到了!也可以跟你企業內部現有的系統完美的整合。網路上也有人設計了語音請假助理,透過自然語言,而背後 ChatGPT 真的去呼叫企業內實際的『現有請假系統 API』實現只動口就完成請假了。試想,這以後有哪一件事情不能做的,完全透過『自然語言』就完成了,而自然語言就是目前基於 OpenAI 發展的 ChatGPT 等 LLM 深度學習的大型語言模型的強項。


開發的方式、步驟:

環境我使用 .NET 8 加上 Visual Studio 2022,你要使用 VSCode 也可以,我這裡也有一個是使用 VSCode 開發的範例。

這裡我們使用 Console 類型的專案來測試,並時做一個計算平方根的 ChatGPT。

另外,須注意的是,我這裡的後端 LLM 模型是採用 OpenAI 的 ChatGPT,並不是使用 Azure OpenAI 喔!原因是 Azure OpenAI 目前的申請相當麻煩,而我們來就有 ChatGPT Plus 的訂閱,當然首選的就是使用 ChatGPT 了 XD 因為 Semantic Kernel 本來也就同時支援 OpenAI。

下面我們就來做個範例囉:

(1). 安裝 Semantic Kernel SDK 的 NuGet 套件 

在本文章撰寫之時,Semantic Kernel 的套件版本為 v1.4.0,由於它目前正在發展當中,所以更新的會非常平凡,因此有可能讀者看見此篇文章之時,版本又會再往前推進。


本範例一共需要兩個套件:

1. Microsoft.SemanticKernel

2. Microsoft.SemanticKernel.Connectors.OpenAI


第一個套件是主要核心功能套件,第二個是連結 OpenAI 需要的套件。


(2). 引用與初始化相關 Middleware

下面是建立 Semantic Kernel 的對話模型
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Plugins;

// Create kernel
var builder = Kernel.CreateBuilder();
builder.Services.AddOpenAIChatCompletion(
    "gpt-3.5-turbo",
    "... 你自己 OpenAI 提供的 key...",
    "... 這請代換成你自己訂閱的 OpenAI 的 OrgnizationID ...");

(3). 建立數學的 C# 的 Plug-in

using System;
using System.ComponentModel;
using Microsoft.SemanticKernel;

namespace ConsoleOpenAIPlugins.Plugins
{
    using Math = System.Math;

    public class MathPlugin
    {
        /// <summary>
        /// This is a take thw square root of a number
        /// </summary>
        /// <param name="number1"></param>
        /// <returns></returns>
        [KernelFunction, Description("Take the square root of a number")]
        public static double Sqrt(
            [Description("The number to take a square root of")] double number1
        )
        {
            return Math.Sqrt(number1);
        }
    }
}

上面這段程式碼的重點在於需打上 [KernelFunction] 與 [Description] 這兩個 Attributes,前者是告訴 AI 說,這是一個可以被 OpenAI 的 LLN 模型呼叫的 C# 方法。然後 Description 描述是讓 LLM 學習用的,描述盡可能以問題回主,Semantic Kernel 會告訴 OpenAI 說,只要詢問的這個問題,有關於 square 的,就來執行這個方法。

(4). 記得加入 MathPlugin 這個插件

這是 Semantic Kernel 告訴它擴充的 Plug-in 的位置在哪,在 .NET Core 的環境下當然也變成一個 Middleware 加入到 ServiceCollection 裡。

builder.Plugins.AddFromType<MathPlugin>();

(5). 當然了,別忘了取回 kernelBuilder 務件

var kernel = builder.Build();

(6). 建立 ChatHistory 陣列以存放對話紀錄

ChatHistory history = [];

(7). 透過 IServiceProvider 取得 Chat 的對話服務介面 IChatCompletionService

var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

(8). 建立 Console 的 User> 提示詞 & 讀取指令 & 開啟 auto function calling 功能

Console.Write("User > ");
history.AddUserMessage(Console.ReadLine()!);

當然了,這裡同時得告訴 Semantic Kernel 允許 OpenAI 來呼叫我本機的 Local Function

OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

(9). 撰寫 chatCompletionService 來接收 OpenAI 吐回來的訊息內容

var result = chatCompletionService.GetStreamingChatMessageContentsAsync(
    history,
    executionSettings: openAIPromptExecutionSettings,
    kernel: kernel);

(10). 從 result 取回 StreamingChatContent 的 OpenAI 的回傳內容

string fullMessage = "";
var first = true;
await foreach (var content in result)
{
    if (content.Role.HasValue && first)
    {
        Console.Write("Assistant > ");
        first = false;
    }
    Console.Write(content.Content);
    fullMessage += content.Content;
}
Console.WriteLine();

這一段程式其實非常的簡單,就是跑回圈將 OpenAI 吐回來的 Content 解出來,透過 Console.Write 寫在 Console 畫面上。

執行畫面如下:

圖(四)、在自己 Local 的 Console Prompt 下,與 ChatGPT 進行對話互動 在自己 Local 的 Console Prompt 下,與 ChatGPT 進行對話互動

當我問到『Take the square root of 12』的時候,OpenAI 就會回呼我在 Local 註冊的那個計算平方根的 C# Method!我的天!!我覺得這也太強大了,這麼一來,還有什麼做不到的呢?因為企業現有的系統要與 ChatGPT 做整合基本上都不是什麼太困難的事情了,只要將企業內部需要讓 ChatGPT 精確回答、或者是擴充 ChatGPT 只需要在現有功能打上 [SemanticFunction] 即可!而企業也可以自由決定/包裝要讓 ChatGPT回答的部分,所以這可以使 ChatGPT 可執行企業內部工作,這實在太強大了!


圖(五)、OpenAI 回呼我的 Local C# Method 的情況



最後,完整程式如下所示,外面還會放一個 while(ture) 只為了讓 ChatGPT 可接續的對話。

程式碼如下:

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using ConsoleOpenAIPlugins.Plugins;

// Create kernel
var builder = Kernel.CreateBuilder();
builder.Services.AddOpenAIChatCompletion(
        "gpt-3.5-turbo", 
        "... 你自己 OpenAI 提供的 key...", 
        "... 這請代換成你自己訂閱的 OpenAI 的 OrgnizationID ...");

builder.Plugins.AddFromType<MathPlugin>();
var kernel = builder.Build();

// 建立對話紀錄 history 物件
ChatHistory history = [];

var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// 將對話放在迴圈裡、以便反覆地進行對話
while (true)
{
    // 建立一的提示字元 User>
    Console.Write("User > ");
    history.AddUserMessage(Console.ReadLine()!);

    // 開啟 function calling,並允許 AI 可以呼叫本機的 Local 方法
    OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
    {
        ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
    };

    // 從 OpenAI 取回 AI 對話的訊息內容
    var result = chatCompletionService.GetStreamingChatMessageContentsAsync(
        history,
        executionSettings: openAIPromptExecutionSettings,
        kernel: kernel);

    // 處裡 Stream 類型的回傳結果
    string fullMessage = "";
    var first = true;
    await foreach (var content in result)
    {
        if (content.Role.HasValue && first)
        {
            Console.Write("Assistant > ");
            first = false;
        }
        Console.Write(content.Content);
        fullMessage += content.Content;
    }
    Console.WriteLine();
}

Console.ReadLine();

結語: 從 AI 元年開始,或者說是從 ChatGPT 席捲全球之後,對各行各業的影響可說非常劇烈,部分工作取代之說也不斷地湧現,雖然我認為取代工作還不至於,但對於一些客服類型工作、基本商品販賣的問答、結帳銷售幾乎都可以勝任,只不過目前的 AI 其實還有很多不可控的因素,許多 Content 產出其實都還是需要『人類』來把關,所以其實也不用太緊張。膽可以預見的是,在 AI 的幫助下,人們可以更專注在需要『思考』與『創意』類型的工作上,而 AI 是你從旁補助你,節省裡繁瑣細節工作的好夥伴。

References: 

(1).Start learning how to use Semantic Kernel 

https://learn.microsoft.com/en-us/semantic-kernel/get-started/quick-start-guide?tabs=Csharp

(2). Semantic Kernel: empower your LLM apps 

https://medium.com/devrain/semantic-kernel-empower-your-llm-apps-51d8d488cf84

(3). Creating native functions for AI to call 

https://learn.microsoft.com/en-us/semantic-kernel/agents/plugins/using-the-KernelFunction-decorator?tabs=Csharp

(4). Export plugins written for Semantic Kernel as an OpenAI plugin 

https://learn.microsoft.com/en-us/semantic-kernel/agents/plugins/openai-plugins?source=recommendations

(5). Understanding AI plugins in Semantic Kernel 

https://learn.microsoft.com/en-us/semantic-kernel/agents/plugins/?tabs=Csharp

(6). How to run a semantic plugins from file 

https://github.com/microsoft/semantic-kernel/blob/5817c2b92731b7774fcea7b6c820901e46d39b49/dotnet/notebooks/02-running-prompts-from-file.ipynb

(7). What is Semantic Kernel? 

https://learn.microsoft.com/en-us/semantic-kernel/overview/

留言

這個網誌中的熱門文章

什麼是 gRPC ?

什麼是 gRPC(二)- 來撰寫第一個 Hello World 吧!

常見的程式碼壞味道(Code Smell or Bad Smell)