<i id="bcuty"><sub id="bcuty"></sub></i>

<b id="bcuty"></b>

您的位置:首頁 >聚焦 >

基于最新 ChatGPT API 實現命令行版 ChatGPT

2023-03-04 05:42:30    來源:程序員客棧
引子OpenAI 這兩天發布了ChatGPT API,基于gpt-3.5-turbo模型,這是一個 GPT-3.5 的優化版本,用于支持開發者把 ChatGPT 集成到自己的產品中,同時把 API 調用價格降到 $0.002 每千 token,意味著處理 100萬字符的文本只需要 2 美元,也就是差不多十幾塊錢人民幣,效果更好、價格更低,這讓 ChatGPT API 更具性價比,因此這兩天基于 ChatGPT API 的各種套殼應用如雨后春筍般大量冒出。我也來湊個熱鬧,試一試水,正好在我今天新建的 ChatGPT 互助討論群里有人問有沒有命令行版 ChatGPT,那就拿它來開刀吧:
老規矩,還是面向 ChatGPT 編程來實現這個命令行版 ChatGPT 應用。
在《面向 ChatGPT 編程實現全棧開發的 18 種方法》這篇教程中,我在最后說到在面向 ChatGPT 編程的時候,需要牢記兩個原則:第一,知道你在做什么,第二,不要相信 ChatGPT 的代碼。
落地到實踐的時候,就是在與 ChatGPT 合作形成的結對編程聯盟中,作為開發者我們需要承擔代碼設計、架構、編排與審核(CodeReview)的職責,對方案和結果負責,而具體的代碼片段編寫這種純體力活則交由 ChatGPT 完成。
接下來,我們將遵循這個思路實現命令行版 ChatGPT 應用。
代碼設計
如我在微信群里所說,這個需求確實很簡單 —— 通過編程在控制臺應用代碼中調用 ChatGPT API 接口,實現一個命令行版的 ChatGPT,幾十行代碼就能搞定。不過這里仍然需要做一些簡單的設計:

調用 API 需要傳遞 API KEY,我們不希望這個 KEY 硬編碼在代碼中,而是從系統環境變量讀取,從而讓代碼更安全可維護;

調用封裝好的 Go OpenAI 庫與 API 接口進行交互,避免通過 HTTP 協議與原生 API 交互編寫大量重復代碼,讓代碼更簡潔優雅;


(資料圖片僅供參考)

做一個給客戶使用的產品,美觀會帶來更好的用戶體驗,所以我希望即便是命令行應用,也盡可能讓交互和輸出更美觀一些。

對于第 2 點,可以使用 go-gpt3 庫,這是一個通過 Go 封裝的 OpenAI API 調用庫。

對于第3點,可以使用 glamour 庫,這是一個 Go 語言實現的、能夠在兼容 ANSI 終端基于樣式渲染 Markdown 文本的第三方庫,它是讓命令行更美觀的開源項目 Charm 的一部分。

因為項目很簡單,又是在客戶端本地使用,所以不需要做什么復雜的架構,下面直接進入編碼部分。

代碼編寫

面向 ChatGPT 編程的核心就是把需求盡可能準確全面地轉化為 Prompt 傳遞給 ChatGPT,這里有產品需求(來自業務和產品),也有代碼設計和架構上的需求(來自開發者),然后讓它生成代碼,這是作為一個合格的 Prompt 工程師自我修養的必要組成部分。

在《ChatGPT 提示的藝術 —— 編寫清晰有效提示指南(二)》這篇教程中,我已經給大家介紹了編寫清晰有效 Prompt 的原則、做法和技巧,感興趣的可以去看下,這里我先將我的需求轉化為 Prompt 讓 ChatGPT 替我編寫對應的 Go 代碼實現:

代碼優化看起來不錯,基本流程沒問題,但是代碼審核會發現,它現在把輸入的 Prompt 寫死了,并不能動態接收用輸入,而且運行一次后就退出了,這不是 ChatGPT 的問題,而是我們的需求并沒有明確這一點,作為一個完整的需求和程序,需要說明是什么,怎么樣,什么時候開始,什么時候退出。不過細心的同學可能還留意到go-gpt3包引入的時候沒有設置別名,會導致運行時出錯,同時調用的 OpenAI API 接口也不對,最新的 ChatGPT API 接口方法應該是CreateChatCompletion,可能是太新的緣故,ChatGPT 還沒有學習到這里,不過這都屬于 ChatGPT 要優化的點了。以及使用了另一個同名的包,這個也需要明確告知它。細節上還是需要優化,現在我們基于這些要點先來完善我們的 Prompt:
這一次,我們更加細化了程序的行為,用戶輸入start啟動,輸入quit退出,在此期間則不斷讀取用戶輸入,返回 ChatGPT 處理結果并渲染到控制臺輸出,另外,我還在讀取系統環境變量時囑咐通過os.Getenv獲取,因為有時候發現 ChatGPT 輸出不穩定,會嘗試從.env文件讀取OPENAI_API_KEY,當然這不是 ChatGPT 的問題,是我們沒有給出明確清晰的 Prompt。
現在再來看 ChatGPT 輸出的代碼,就更完善了:

package mainimport ("context""fmt""os""strings""github.com/charmbracelet/glamour""github.com/common-nighthawk/go-figure"gpt3 "github.com/sashabaranov/go-gpt3")func main() {// 獲取 OpenAI API KeyapiKey := os.Getenv("OPENAI_API_KEY")if apiKey == "" {fmt.Println("請設置 OPENAI_API_KEY 環境變量")return}// 初始化 Glamour 渲染器renderStyle := glamour.WithEnvironmentConfig()mdRenderer, err := glamour.NewTermRenderer(renderStyle,)if err != nil {fmt.Println("初始化 Markdown 渲染器失敗")return}// 輸出歡迎語(命令行應用啟動界面)myFigure := figure.NewFigure("ChatGPT", "", true)myFigure.Print()fmt.Println("輸入 start 啟動應用,輸入 quit 退出應用")// 創建 ChatGPT 客戶端client := gpt3.NewClient(apiKey)if err != nil {fmt.Printf("創建客戶端失敗: %s\n", err.Error())return}messages := []gpt3.ChatCompletionMessage{{Role:    "system",Content: "你是ChatGPT, OpenAI訓練的大型語言模型, 請盡可能簡潔地回答我的問題",},}// 讀取用戶輸入并交互var userInput stringfor {fmt.Scanln(&userInput)if strings.ToLower(userInput) == "start" {fmt.Println("ChatGPT 啟動成功,請輸入您的問題:")} else if strings.ToLower(userInput) == "quit" {fmt.Println("ChatGPT 已退出")return} else if userInput != "" {messages = append(messages, gpt3.ChatCompletionMessage{Role:    "user",Content: userInput,},)// 調用 ChatGPT API 接口生成回答resp, err := client.CreateChatCompletion(context.Background(),gpt3.ChatCompletionRequest{Model:       gpt3.GPT3Dot5Turbo,Messages:    messages,MaxTokens:   1024,Temperature: 0,N:           1,},)if err != nil {fmt.Printf("ChatGPT 接口調用失敗: %s\n", err.Error())continue}// 格式化輸出結果output := resp.Choices[0].Message.ContentmdOutput, err := mdRenderer.Render(output)if err != nil {fmt.Printf("Markdown 渲染失敗: %s\n", err.Error())continue}fmt.Println(mdOutput)messages = append(messages, gpt3.ChatCompletionMessage{Role:    "assistant",Content: output,},)}}}

gpt3 別名和 CreateChatCompletion 方法調用相關的代碼還是需要手動調整,不過這也是我前面說的面向 ChatGPT 編程的原則之一,最后一定要審核 ChatGPT 的代碼,它目前對于最新的知識還是有一定的遲滯性。

代碼細節我就不展開解釋了,有不明白的地方可以參考我在《面向 ChatGPT 編程實現全棧開發的 18 種方法》這篇教程中代碼解釋部分提供的方法自行去基于 ChatGPT 查看。

效果展示最后我們在終端體驗一下這個命令行版 ChatGPT,我這里使用的是 Windows WSL 終端,Windows 終端本身體驗其實不太好,尤其是中文輸入的時候,刪除字符特別費勁,且很容易造成消息變形,如果是 Mac 或者 Ubuntu 終端可能效果會更好一些。首先我們啟動這個應用,如果沒有設置OPENAI_API_KEY這個系統環境變量(運行export OPENAI_API_KEY={你的 OpenAI SECRET KEY}命令設置即可),會提示你設置:
如果已經設置,會進入下面這樣的啟動歡迎界面:
輸入start即可啟動應用,然后我們在命令行輸入問題,回車,就會將問題提交給 ChatGPT,ChatGPT 處理的結果會返回并輸出到控制臺,這里的格式經過了 Glamour 庫的美化:
因為是 for 循環,所以你可以持續提問、得到答案,直到輸入quit退出應用。

終端需要能夠訪問 OpenAI API 才能調用成功,這意味著命令行也要支持科學上網。

好了,這就是我們基于最新 ChatGPT API 實現的命令行版 ChatGPT 應用,因為 ChatGPT API 是前兩天才發布的,所以看起來 ChatGPT 并沒有學習到這個最新的 API 如何調用,存在遲滯性,進而導致編寫的代碼并不能直接滿足需求,需要人為介入去修改,希望未來 ChatGPT 能夠在這一塊上有所進化。

歡迎點贊、關注、分享,更多關于 ChatGPT 的學習實踐探討,請關注這個訂閱號或者點擊閱讀原文了解極客書房最新動態。

關鍵詞: 系統環境 這是一個 可以使用

相關閱讀

巨胸护士在线播放视频二区

<i id="bcuty"><sub id="bcuty"></sub></i>

<b id="bcuty"></b>