發表文章

Semantic Kernel Plugin 的錯誤處理

圖片
先前我們 提到了 透過Semantic Kernel,可以讓AI/LLM在與用戶對談的過程中,自動在需要的時候去呼叫 PlugIn 物件的方法(Method),特別的事情是,這個呼叫並非是我們寫程式去做的,而是 AI 自己做的,我們並沒有寫這部分程式碼的邏輯,我們寫的只是提示(prompt)而已。 那問題來了,如果不是我們寫程式去呼叫這個方法,而是AI自己去呼叫的,那假設,這個被呼叫的方法裡面發生了 Exception ,那會發生什麼事情!? 我們看底下這段程式碼: public class LeaveRequestPlugin { [KernelFunction] [Description("取得請假天數")] public int GetLeaveRecordAmount([Description("要查詢請假天數的員工名稱")] string employeeName) { isRock.LineBot.Bot bot = new LineBot.Bot(ChannelAccessToken); bot.PushMessage(AdminUserId, $"[action : 查詢 {employeeName} 假單]"); if (employeeName.ToLower() == "david") return 3; else if (employeeName.ToLower() == "mary") throw new System.ArgumentOutOfRangeException("無法取得假單資料"); else return 5; } (...略...) } 請注意上面這段查詢員工請假天數的程式碼,你會發現,我們刻意在程式碼裡面,加入了底下這段 code: (...略...) else if (employeeName.ToLower() == "mary") throw new System.Ar

在 LINE Bot 開發中使用Semantic Kernel建立自然語言請假系統

圖片
身為 LAE(LINE API Expert) 與 LINE 的支持者,既然知道透過Semantic Kernel可以快速的開發對談機器人,那當然要嘗試用在 LINE Bot的開發上。 先前我們 介紹過 如何使用 Semantic Kernel 來開發一個支援記憶與對話前後文、可以用自然語言進行請假的對談機器人,但當時的架構是在 console 環境,負責記憶處理的 ChatHistory 是可以被長時間保存的實體物件,但換成了LINE Bot開發的WebAPI架構,一切就變的有所不同了。 首先,由於ChatHistory物件會隨著WebAPI行程消失而遺失,且我們的LINE Bot還得面對多個用戶,因此也無法簡單的用一個 ChatHistory 物件就保存所有用戶的對話紀錄。所以我們要做一些調整,為每一位用戶建立一個自己的ChatHistory物件。 因此,我們在 WebAPI 中撰寫了底下這樣的程式碼: static Dictionary<string, ChatHistory> ChatHistoryByUser = new Dictionary<string, ChatHistory>(); private ChatHistory getHistoryFromStaticRepo(string UserId) { if (ChatHistoryByUser.ContainsKey(UserId)) return ChatHistoryByUser[UserId]; else return new ChatHistory(); } private void saveHistory(string UserId, ChatHistory chatHistory) { if (ChatHistoryByUser.ContainsKey(UserId)) ChatHistoryByUser[UserId] = chatHistory; else ChatHistoryByUser.Add(UserId, chatHistory); } 這段程式碼以靜態方式儲存ChatHistory物件的Dictionary,搭配 getHistoryF

使用Semantic Kernel 建立自然語言請假系統

圖片
既然我們已經知道,可以透過 Semantic Kernel 輕易地建立聊天機器人/智能助理,我們之前(參考 這篇 )也看到了如何用自然語言驅動 AI ,來自動呼叫 IoT 控制開關燈類別中的方法,體驗過了它的威力,接著,我們就來實作一下,如何透過 Semantic Kernel 來建立一個可以透過自然語言請假的對談機器人。 我得說,我過去幾年做過無數次這個範例,試圖用自然語言以對談方式來完成請假。從最初LINE Bot 出現的時候,以手工苦刻的方式,來建立請假機器人,到使用 Azure AI 上的 Language Understanding 解決方案,讓機器人能夠『稍微』看懂用戶以自然語言的方式輸入的請假資訊,但整個過程從來沒有愉快過。 過去,電腦對自然語言的理解實在太差了,直到GPT的出現,直到有了LLM,一切才開始不同。現在,我們可以輕易地透過 Semantic Kernel 使用大語言模型,來建立一個類似底下這樣,表現非常好的自然語言請假系統: 你會發現,我們實作了一個可以幫助用戶請假的對談機器人。他會蒐集用戶的請假資訊,然後在資訊滿足之後,呼叫API來完成請假動作。 上面這段對談紀錄當中,黃色的部分就是AI自動進行的 Action,也就是具體的『請假』或是『查詢』動作,其他的則是自然語言的交談對話。 我們之前說過,透過 Semantic Kernel ,我們可以快速地完成上面這個功能的開發。為了完成這個需求,我們建立了底下這個 LeaveRequestPlugin 類別。這個類別裡面有三個方法,你可以從Description描述看到這些方法的功能(當然,範例裡面的Action暫且用示意的方式來呈現,不真的寫入資料庫): // 請假功能 Plugin public class LeaveRequestPlugin { [KernelFunction] [Description("取得請假天數")] public int GetLeaveRecordAmount([Description("要查詢請假天數的員工名稱")] string employeeName) { //修改顯示顏色 Console.ForegroundColor = Con

精彩(且驚人)的Semantic Kernel入門範例

圖片
之前開直播的時候,和線上朋友聊到,因為AI的出現,未來的應用程式,勢必會和現在有所不同。 先不要跳到 黃仁勳 說的,未來『每個開發人員都可以直接用自然語言做程式設計』(這樣也太駭人聽聞了一點),先看看眼下我們可以做到什麼程度。 你會發現透過 Semantic Kernel,這個所謂的 AI 開發框架,已經可以做到, 讓 AI 自己決定何時(以及如何)呼叫一個類別(Class)中的方法(Method) 。而我們只需要讓用戶輸入對話與機器人對談,就可以控制程式運行的流程與邏輯。也就是說,現在不需要滑鼠點選,不用選單操作,只要與機器人透過自然語言對談(底下的範例是打字,但當然可以是語音),就可以操控系統。 我前陣子一直說的,AI 會讓 GUI 有著天翻地覆的改變,意即如此。 看底下這個類別的程式碼: //控制開關燈的類別 public class LightPlugin { //當前燈的狀態 public bool IsOn { get; set; } = false; [KernelFunction] [Description("取得燈的狀態")] public string GetState() { return IsOn ? "on" : "off"; } [KernelFunction] [Description("改變燈的狀態")] public string ChangeState(bool newState) { this.IsOn = newState; var state = GetState(); // Print the state to the console Console.WriteLine($"[Light is now {state}]"); return state; } } 上面這個很簡單的 LightPlugin 類別,具有兩個方法:GetState 和 ChangeState。這兩個方法都被標記為 [KernelFunctio

使用CLI指令快速開啟Windows Terminal

圖片
不知道你會不會和我一樣有種感覺,Terminal 用久了,喜歡打字勝過用滑鼠點GUI。 這導致,我在VS 2022中寫 code 的時候,有時候要安裝套件,我喜歡用 windows terminal 多過用 NuGet 管理員,包含執行類似 dotnet run 指令,我都比較喜歡在 CLI 環境下執行(也許是用慣了VS Code的關係)。 當然,在 VS 2022中,不是沒有 Terminal,其實它有一個 『開發人員 PowerShell』,一般你按 Ctrl + ~ 就會出現: 但我很不喜歡用它,主要是因為『醜』。 沒法很簡單的調整文字大小,也沒什麼色彩,而且有時候還會有奇怪的換行或顯示問題。 我忍耐它好一陣子了,我一直想,是不是有什麼方法,可以從這個 『開發人員 PowerShell』直接開啟 windows terminal? 總該有個指令可以簡單的完成這件事情對吧? 類似像是在一般的終端機下 『start . 』指令,我就可以啟動檔案總管,並且開啟當前資料夾。下『code .』指令,就可以用 VS Code 開啟當前資料夾。 那 windows terminal 呢? 有沒有簡單的指令可以呼叫它? 稍微一找,發現還真簡單,指令是: wt -d . 就這樣,搞定:

Azure OpenAI 的申請與使用

圖片
OpenAI 介紹久了,覺得還是需要寫一篇來介紹Azure OpenAI的申請和使用。 和 OpenAI APIs一樣,微軟身為 OpenAI 最大的投資廠商,理當有一組 Azure 上的 OpenAI API 服務。然而其實,兩組API之間,幾乎完全一樣,不管是用法和價格。 那兩者之間的差異如何定位呢? OpenAI 與 Azure OpenAI 之間的差異 目前Azure OpenAI API服務的定位是針對企業用戶,而OpenAI API則有開放給一般個人用戶申請。這使得Azure OpenAI API的嚴謹度與安全性相對比較高。例如,Azure OpenAI API在呼叫時有獨立的Endpoint,針對使用的模型也有獨立的部署,除了不會跟別人共用API呼叫端點因此可以讓安全性和穩定性提升之外,微軟也承諾你上傳的數據不會被用在訓練模型的用途(這也是大家很在意的議題)。 此外,Azure OpenAI API的帳單是跟著Azure訂閱,同時在全球各地有不同的資料中心,這讓開發人員可以選擇距離自己(或自己的客戶)比較近的資料中心進行模型部署,以便於取得最好的運作效能。 由於微軟是透過在地的合作夥伴進行Azure銷售,因此在Azure OpenAI API的使用成本方面,可能因為採購的優惠折扣而有比較低的總體金額,相較之下OpenAI API就是死板板的固定金額,碰到問題的時候大概也只能上討論區尋求解答,比較沒有在地的服務。 OpenAI API有多次因為用戶數量太大,而導致API端點無法呼叫的案例,OpenAI API是全球同一個端點,因此當此問題發生時,很可能大家都會遭遇魚池之殃,全都無法使用。 另外就是,Azure OpenAI API針對具有暴力、自殘、猥褻、情色的文字的過濾相較於OpenAI API更加嚴格,你也可以從後台選擇不同等級的過濾器,來排除可能造成問題的文字,這對服務的安全性也是一種保障。 依照我現在自己測試的結果,最大的差異在於,微軟的API確實有比較嚴謹(有時候甚至過頭)的filter(過濾器),會對偏激或煽情的字眼非常敏感。在呼叫API時,你偶而會收到類似底下這樣的訊息( 註 ): 此外,就是目前(2024/1) OpenAI 有支援 Assistants API,但 Azure OpenAI 我還沒看到(2024/2

周末讀書會 - 姿勢決定你是誰

圖片
某次有位朋友問我:『你現在上台應該都不會緊張了吼,是吧?』 我打從心底笑了出來,回答他:『並不是,我每次上台前都很緊張,不管你看不看得出來,而且沒有一次例外。』 最近,我看完半年前上課時某位老師推薦的『姿勢決定你是誰』一書,內頁第一句話寫著:『有一種勇敢,就是全世界只有你知道自己在害怕。』 其實不管場次大小,是線上或實體,每一次上台前我都還是會緊張、甚至焦慮。 但上台幾分鐘後,我大多能夠慢慢穩定下來,找到自己的節奏。過去我自己也不知道為什麼,但看完這本書之後,我才明白背後的原理。 『姿勢決定你是誰』這本書由 Amy Cuddy 著作,你可能有聽過她在 Ted的演說(我放在底下第一個留言),很多人聽了之後大受激勵。但我得說,其實書的完整內容比起Ted演說要深刻全面的多,從書名或演說15分鐘的內容,你很可能會誤會這本書真正要表達的事情。這本書要說的其實並非很多人誤以為的 fake it till you make it,而是『權力,讓你能夠表現出最佳狀態。』 你看到這邊可能會覺得不可思議。權力,不是那個會讓人腐化的可憎東西嗎? 沒錯,但這邊講的權力並不只是外在的『社會權力』,而是來自內心的『個人權力』。 『個人權力』指的是👉確信對自己的未來能夠掌握的程度。 『個人權力』的反面就是『焦慮』,這個大家就很熟了。但,焦慮的來源是什麼呢? 其實剛剛好就是個人權力的相反,也就是『對自己未來遭遇的不確定性感到無法(或沒有足夠資源可以)控制的程度』。 而『焦慮』,正是讓你無法表現出最佳狀態的關鍵因素。 愈是重要的場合,你愈是會焦慮,愈是焦慮,你愈無法表現出最好的自己。 但,人就是會焦慮啊,上台就是會緊張啊,如何解決這問題? 👉如何讓自己在關鍵時刻能發揮全力,能夠把最好的、真實的那一面呈現出來? 👉如何讓自己隨時能進入『最佳狀態』? 正是這本書真正在講的內容。 順帶一提,從這本書,我也大概搞懂了,為何球類比賽的時候,會有所謂的『主場優勢』? 為何有信仰的人,往往能夠更有力量面對未知的挑戰? 還有那著名的吸引力法則,為何真的有效? 我認為,都是因為恰恰好這些人都掌握到了發揮『最佳狀態』的秘訣。 我覺得,這本書對許多人都會有很大幫助。 有興趣可以找來看看,在這農曆春節假期的周末,推薦給大家。 新的一年,你會成為一個更有力量的自己。 #周末讀書

Azure OpenAI 中的 Assistant API 功能

圖片
過去,如果你有用 Azure OpenAI 開發對談機器人,其中最麻煩的事情之一,大概就是記錄和處理歷史對談訊息。但歷史對談訊息對於AI的正確回覆佔有舉足輕重的角色,不記錄不行。 這是因為本質上API的呼叫是無狀態的(Stateless) 因此,在與API交談的過程中,你每次呼叫API都必須把過去的訊息,當作參數重新傳到後端,這樣API後面的AI Model才會知道先前跟用戶說過了什麼。但如此一來,對談越多,不就得花費愈多Token嗎? 是的,沒錯,這是過去透過OpenAI開發對談機器人時的一個難題。 2023年11/06,OpenAI舉辦了DevDay,在keynote的場次中,Sam Altman介紹了新的API --> Assistants API,把對談機器人的開發,再繼續優化到更簡單的步驟。 搭配Assistants API,你可以輕易建立出一個智能助理(或客服機器人),除了讓開發人員更省事之外,還包含了類似RAG的功能,可以將企業內的資訊先餵給這個AI助理。 如今,Azure OpenAI也提供了這個服務,在 美國東部2 、 澳大利亞東部 和 瑞典中部 率先提供了這個服務(Preview),同樣的,他提供了一個遊樂場後台: 初次進入,畫面上出現『找不到任何佈署』? 那你就給他來個新的佈署: 系統會引導你建立一個獨立的模型: 接著就可以透過該模型來建立助理了: 填寫完智能助理的名稱、提示(system prompt) 之後,就可以儲存和測試了。 乍看之下,和原本的聊天對談沒什麼不同,但背後有一個很大的差異,那就是,過去的聊天對談,前後文(Context)的實踐是透過把先前與機器人的互動(訊息),每次重新回傳給API來實現的,而現在這個助理(Assistant API)則是透過一個新的物件,叫做Thread(執行緒),來保存這些對話記錄。簡單的說就是,你不用再自己保存對話記錄了: Thread(執行緒)聽起來有點抽象,你可以把一個執行緒想成一連串的對話記錄,其中有一則一則的訊息(Messages): 當用戶輸入一則訊息(放上Thread)給機器人(assistant),機器人回覆這則訊息(也放上Thread),這樣就構成了一個Run。 也因此,透過 Assistant api 操作的對談流程,原則上大概是底下這

Azure OpenAI 服務中的DALL-E-3

圖片
先前介紹過 OpenAI API 的 DALL-E-3 ,但如果你要在Azure OpenAI 上使用相同的功能,不管是模型的佈署和API的呼叫,兩者之間都有些不同。 使用在Azure OpenAI上的DALL-E-3,你必須把服務建立在瑞典中部(Sweden Central)的資料中心,才能享用該模型: 目前只有該資料中心有提供 DALL-E-3 的模型選項,當你將AOAI的服務建立在Sweden Central資料中心,就會在模型佈署中,找到底下這個 dall-e-3 的選項: 如果你透過 Azure OpenAI Studio 這個後台測試 DALL-E,你會發現系統會自動幫你佈署 dalle3 模型: (動畫) 有了DALL-E-3模型之後,你就可以透過自然語言產生圖像了: 如果你要採用 API 來生成圖像,可以參考微軟 官網 上的 API 使用方式。 我們也可以透過 Postman 呼叫該 API: 台北 101 的下雪美景,就這樣出現了: 但你需要注意到,Auzre OpenAI DALL-E-3 的 API Endpoint 也明顯與Chat不同: https://{AOAI服務名稱}.openai.azure.com/openai/deployments/{Dalle3佈署名稱}/images/generations?api-version=2023-12-01-preview 不過掌握好了之後,透過程式碼來動態建立圖像,也就只是小菜一碟了。 相關課程: https://www.studyhost.tw/NewCourses/LineBot

LINE Bot 新功能 -- Clipboard Action

圖片
LINE Messaging API 今天 的更新增添了一項新功能:允許開發者在訊息中加入剪貼簿動作(Clipboard Action),這意味著使用者現在能夠透過單一點擊將特定文字直接複製到手機的剪貼簿中。 這個功能的加入為使用者提供了更多便利,特別是在需要複製優惠券代碼、網址連結或是其他重要訊息時,大大提高了互動效率和使用者體驗。 C# Developers 若要要使用這項新功能,可以採用全球最多 C# 開發人員使用的 LineBotSDK 套件😁。該套件是一個非常流行的 LINE Bot 開發工具,完整支援多種 LINE Messaging API 的功能。 以下提供一段 .net core 7.0 範例程式碼(使用最新版 2.12.39 LineBotSDK),展示如何建立一個包含剪貼簿動作的Button Template訊息: using isRock.LineBot; string ChannelAccessToken = "👉ChannelAccessToken"; string AdminUserId = "👉AdminUserId"; var bot = new isRock.LineBot.Bot(ChannelAccessToken); var act = new List<TemplateActionBase>(); // 建立一個剪貼簿動作,當用戶點擊時,指定的文字 "abc" 會被複製到剪貼簿 act.Add(new ClipboardAction() { label = "按這裡", clipboardText = "abc" }); // 建立Button Template訊息,設定文本、標題及動作 var TmpMsg = new ButtonsTemplate() { text = "測試複製到剪貼簿", title = "測試", actions = act }; // 使用 bot 物件推送消息給指定的用戶 bot.PushMessage(AdminUserId, TmpMsg); 透過這段程式碼,開發者可以在 LINE Bot 中建立一個按鈕,當用戶