ChatGPT 聊天程式練習
发布时间:2026-09-14 | 浏览:2
半年過去,大家已學會平常心看待 ChatGPT,了解它的長處跟弱點,不再過度神化,什麼都問再靠北它瞎扯。我認為這才是面對 ChatGPT 的正確心態,認知到生成式 AI 的產出從來就不保證正確,需自負查核複檢之責,方能善用新科技提升競爭力,而不是亂用搞到 可能飯碗不保 。
現在才開始學寫 ChatGPT 程式,明顯慢半拍,不過倒也符合我的風格 - 等技術成熟點再開始用,功能成熟穩定,學習資源多好上手,適合已跑不快的老人。舉個明顯的例子:Azure OpenAI Studio 在幾個月前還只有 JSON、Python、curl 範例,不提供 C#,現在已經有了 SDK 也有現成範例。
關於 Azure OpenAPI Service 的概念、申請、費用、Token 計算、開發... 大家若跟我一樣剛要下水,MVP 黯雲 有一系列文章是不錯的入門,建議可從這篇 Azure OpenAI Service - Azure OpenAI Service 概觀 開始,裡面有所有文章的連結。
基本上使用 ChatGPT API,可以接 OpenAI 提供的 API 也可以接 Azure OpenAI API,基本上兩個 API 規格相容,改 URL 跟 Api Key 就可切換來源。Azure 版本的好處是若企業已導入 Azure,Azure OpenAPI Service 在 SLA 保證、多區域備援、AD 整合、虛擬網路整合、合規要求上較符企業需要。至於個人使用者,若你手上有學生方案或 Visual Studio 訂閱,有一些免費額度可以玩( 學生 100 USD/年、VS Enterprise 訂閱 150 USD/月 、或有信用卡註冊前 30 天 200 USD 額度,等於可以免費玩玩 ChatGPT API,這些是值得試試 Azure OpenAI Service 的理由。
不過 Azure OpenAI Service 採取申請審核制(理由是要管控 AI 技術不被誤用濫用或惡意使用),需用組織、公司信箱(不接受 Hotmail、Outlook、Gmail 等免費個人信箱)提出申請,網路上成功分享蠻多的,感覺不難通過申請,學生用學校名義即可,總之試試無妨。(不知是否因為 AI 熱潮已退,現在核准很快,我不到一個工作天便收到回覆)
但有個壞消息,申請核准後只會有 ChatGPT 3.5,想用 ChatGPT 4 需另外再申請,得乖乖排隊。 (David 老師前幾天開心分享他 排超久終於輪到了 ,登楞! 上週才提申請的我應該還有得等...)
ChatGPT 3.5 或 4 只是模型不同,程式寫法一樣,不妨礙學習,那就來個簡單練習:用 C# 呼叫 Azure OpenAI API 寫一個可以跟 ChatGPT 聊天的 .NET Console 程式。
我開了一個 .NET 7 Console 專案,用 dotnet add package Azure.AI.OpenAI --prerelease 加入 Beta 版 OpenAI API 程式庫 。參考 Azure OpenAI Studio 遊樂場給的 C# 範例,先寫好服務類別。
要跟 ChatGPT 聊天時,若要 ChatGPT 記得先前的對話內容繼續延伸,需將先前雙方的對話內容以 ChatMessage 物件形式當參數傳給 ChatGPT。每個 ChatMessage 用 ChatRole 識別為 System (初始化提示,定義 ChatGPT 扮演角色)、User (使用者)、Assistant (ChatGPT 的回應內容)、 Function Calling (完成函式)。
由於呼叫傳入的所有對話內容會拆分成 Token 參考 ,而一次所能傳入的 Token 數量有上限且要算錢,故不能無限累積所有對話內容,一般常見做法是取最近的 N 則。我採用的實作方法是宣告一個自訂類別 ChatRecord 儲存對話內容,使用 Queue<ChatRecord> 保存對話過程,當數量大於 10 筆時,捨棄最早的內容直到筆數等於 10。(更精緻的做法應是請 ChatGPT 摘要先前對話濃縮成簡短大綱)
ChatGPT 生成內容有很多參數可以調,例如:回應字數上限、溫度、頂端 P (類似溫度可控制隨機性)、頻率罰則 及 目前狀態罰則 (用來減少文字重複性)... 等,剛開始學走路就都用預設值吧。
生成結果回傳方式有兩種, GetChatCompletionsAsync() 是全部生成好再一次回傳、 GetChatCompletionsStreamingAsync() 則是產生過程以串流方式傳回。
至於結果,型別為 ChatCompletions,Choices 為多個聊天回覆選項的集合,從中擇一(我用 .First()) 取 .Message.Content 即為回覆文字。
我先從簡單的同步回傳開始,以下是一次取回結果的版本:
Console 輸入流程我簡單搭一下,能動就好。裡面有用上昨天介紹的 環境變數保密儲存技巧 保存 API Key,ChatGPT 回應需要時間,我用了 Task.Run() + CancellationToken 技巧在等待過程印出 ... 減少使用者焦慮(謎:只有你這種急性子才需要吧?),程式範例如下:
實測,由於我們有傳送先前對話內容,如下圖所示,在問完 JavaScript 排序後,加問一句 "那 C# 呢?",ChatGPT 便知道是同一個題目改用 C# 解:
但由以上測試會發現,使用者需要乾等 9 秒及 6 秒才會看到結果,而不像 ChatGPT 網站會分段輸出。而 Azure OpenAI API 程式庫也有提供串流形式的回傳方式。我們修改 ChatGptService 加入一個 版本:
GetChatCompletionsStreamingAsync() 傳回的 StreamingChatCompletions 型別,Choice 是以 IAsyncEnumerable<StreamingChatChoice> 形式傳回,而其下的 Message 則是以 IAsyncEnumerable<ChatMessage> 形式傳回,幸好之前研究過 ASP.NET Core IAsyncEnumerable 與 yield return ,現在派上用場,我用兩層 await foreach 加 yield return 接收,這個串流版函式的回傳型別也要改成 IAsyncEnumerable<String> ,再次驗證了 async 病毒傳染性 。
由於 ChatGPT 的回答是以 IAsyncEnumerable<String> 形式分批傳回,呼叫端這裡也要小小改寫:
改為串流後,回答會分段顯示出來(雖然分批間隔有點久),接近 ChatGPT 網頁的操作體驗,比空等十秒再一次冒出結果順暢一點。
Example of using Azure OpenAI ChatGPT model to implement a simple console chat interface.
# 2023-12-23 10:40 AM by Benson
https://learn.microsoft.com/en-us/answers/questions/1459392/cant-azure-for-students-subscription-use-openai-se 是不是沒得玩了
# 2023-12-23 12:15 PM by Jeffrey
to Benson, 找到另一則討論也是相同回覆,免費訂閱及學生方案現在沒法用 Azure OpenAI 了。 https://learn.microsoft.com/en-us/answers/questions/1460307/student-subscription-no-longer-permits-the-creatio