<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          基于最新 ChatGPT API 實(shí)現(xiàn)命令行版 ChatGPT

          共 5467字,需瀏覽 11分鐘

           ·

          2023-03-04 01:43

          引子


          OpenAI 這兩天發(fā)布了 ChatGPT API,基于 gpt-3.5-turbo 模型,這是一個(gè) GPT-3.5 的優(yōu)化版本,用于支持開(kāi)發(fā)者把 ChatGPT 集成到自己的產(chǎn)品中,同時(shí)把 API 調(diào)用價(jià)格降到 $0.002 每千 token,意味著處理 100萬(wàn)字符的文本只需要 2 美元,也就是差不多十幾塊錢人民幣,效果更好、價(jià)格更低,這讓 ChatGPT API 更具性價(jià)比,因此這兩天基于 ChatGPT API 的各種套殼應(yīng)用如雨后春筍般大量冒出。


          我也來(lái)湊個(gè)熱鬧,試一試水,正好在我今天新建的 ChatGPT 互助討論群里有人問(wèn)有沒(méi)有命令行版 ChatGPT,那就拿它來(lái)開(kāi)刀吧:



          老規(guī)矩,還是面向 ChatGPT 編程來(lái)實(shí)現(xiàn)這個(gè)命令行版 ChatGPT 應(yīng)用。

          在《面向 ChatGPT 編程實(shí)現(xiàn)全棧開(kāi)發(fā)的 18 種方法》這篇教程中,我在最后說(shuō)到在面向 ChatGPT 編程的時(shí)候,需要牢記兩個(gè)原則:第一,知道你在做什么,第二,不要相信 ChatGPT 的代碼。

          落地到實(shí)踐的時(shí)候,就是在與 ChatGPT 合作形成的結(jié)對(duì)編程聯(lián)盟中,作為開(kāi)發(fā)者我們需要承擔(dān)代碼設(shè)計(jì)、架構(gòu)、編排與審核(CodeReview)的職責(zé),對(duì)方案和結(jié)果負(fù)責(zé),而具體的代碼片段編寫(xiě)這種純體力活則交由 ChatGPT 完成。

          接下來(lái),我們將遵循這個(gè)思路實(shí)現(xiàn)命令行版 ChatGPT 應(yīng)用。

          代碼設(shè)計(jì)

          我在微信群里所說(shuō),這個(gè)需求確實(shí)很簡(jiǎn)單 —— 通過(guò)編程在控制臺(tái)應(yīng)用代碼中調(diào)用 ChatGPT API 接口,實(shí)現(xiàn)一個(gè)命令行版的 ChatGPT,幾十行代碼就能搞定。不過(guò)這里仍然需要做一些簡(jiǎn)單的設(shè)計(jì):

          1. 調(diào)用 API 需要傳遞 API KEY,我們不希望這個(gè) KEY 硬編碼在代碼中,而是從系統(tǒng)環(huán)境變量讀取,從而讓代碼更安全可維護(hù);

          2. 調(diào)用封裝好的 Go OpenAI 庫(kù)與 API 接口進(jìn)行交互,避免通過(guò) HTTP 協(xié)議與原生 API 交互編寫(xiě)大量重復(fù)代碼,讓代碼更簡(jiǎn)潔優(yōu)雅;

          3. 做一個(gè)給客戶使用的產(chǎn)品,美觀會(huì)帶來(lái)更好的用戶體驗(yàn),所以我希望即便是命令行應(yīng)用,也盡可能讓交互和輸出更美觀一些。


          對(duì)于第 2 點(diǎn),可以使用 go-gpt3 庫(kù),這是一個(gè)通過(guò) Go 封裝的 OpenAI API 調(diào)用庫(kù)。

          對(duì)于第3點(diǎn),可以使用 glamour 庫(kù),這是一個(gè) Go 語(yǔ)言實(shí)現(xiàn)的、能夠在兼容 ANSI 終端基于樣式渲染 Markdown 文本的第三方庫(kù),它是讓命令行更美觀的開(kāi)源項(xiàng)目 Charm 的一部分。

          因?yàn)轫?xiàng)目很簡(jiǎn)單,又是在客戶端本地使用,所以不需要做什么復(fù)雜的架構(gòu),下面直接進(jìn)入編碼部分。

          代碼編寫(xiě)

          面向 ChatGPT 編程的核心就是把需求盡可能準(zhǔn)確全面地轉(zhuǎn)化為 Prompt 傳遞給 ChatGPT,這里有產(chǎn)品需求(來(lái)自業(yè)務(wù)和產(chǎn)品),也有代碼設(shè)計(jì)和架構(gòu)上的需求(來(lái)自開(kāi)發(fā)者),然后讓它生成代碼,這是作為一個(gè)合格的 Prompt 工程師自我修養(yǎng)的必要組成部分。


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


          代碼優(yōu)化


          看起來(lái)不錯(cuò),基本流程沒(méi)問(wèn)題,但是代碼審核會(huì)發(fā)現(xiàn),它現(xiàn)在把輸入的 Prompt 寫(xiě)死了,并不能動(dòng)態(tài)接收用輸入,而且運(yùn)行一次后就退出了,這不是 ChatGPT 的問(wèn)題,而是我們的需求并沒(méi)有明確這一點(diǎn),作為一個(gè)完整的需求和程序,需要說(shuō)明是什么,怎么樣,什么時(shí)候開(kāi)始,什么時(shí)候退出。


          不過(guò)細(xì)心的同學(xué)可能還留意到 go-gpt3 包引入的時(shí)候沒(méi)有設(shè)置別名,會(huì)導(dǎo)致運(yùn)行時(shí)出錯(cuò),同時(shí)調(diào)用的 OpenAI API 接口也不對(duì),最新的 ChatGPT API 接口方法應(yīng)該是 CreateChatCompletion,可能是太新的緣故,ChatGPT 還沒(méi)有學(xué)習(xí)到這里,不過(guò)這都屬于 ChatGPT 要優(yōu)化的點(diǎn)了。以及使用了另一個(gè)同名的包,這個(gè)也需要明確告知它。


          細(xì)節(jié)上還是需要優(yōu)化,現(xiàn)在我們基于這些要點(diǎn)先來(lái)完善我們的 Prompt:


          這一次,我們更加細(xì)化了程序的行為,用戶輸入 start 啟動(dòng),輸入 quit 退出,在此期間則不斷讀取用戶輸入,返回 ChatGPT 處理結(jié)果并渲染到控制臺(tái)輸出,另外,我還在讀取系統(tǒng)環(huán)境變量時(shí)囑咐通過(guò) os.Getenv 獲取,因?yàn)橛袝r(shí)候發(fā)現(xiàn) ChatGPT 輸出不穩(wěn)定,會(huì)嘗試從 .env 文件讀取 OPENAI_API_KEY,當(dāng)然這不是 ChatGPT 的問(wèn)題,是我們沒(méi)有給出明確清晰的 Prompt。

          現(xiàn)在再來(lái)看 ChatGPT 輸出的代碼,就更完善了:

          package main
          import ( "context" "fmt" "os" "strings"
          "github.com/charmbracelet/glamour" "github.com/common-nighthawk/go-figure" gpt3 "github.com/sashabaranov/go-gpt3")
          func main() { // 獲取 OpenAI API Key apiKey := os.Getenv("OPENAI_API_KEY") if apiKey == "" { fmt.Println("請(qǐng)?jiān)O(shè)置 OPENAI_API_KEY 環(huán)境變量") return }
          // 初始化 Glamour 渲染器 renderStyle := glamour.WithEnvironmentConfig() mdRenderer, err := glamour.NewTermRenderer( renderStyle, ) if err != nil { fmt.Println("初始化 Markdown 渲染器失敗") return }
          // 輸出歡迎語(yǔ)(命令行應(yīng)用啟動(dòng)界面) myFigure := figure.NewFigure("ChatGPT", "", true) myFigure.Print() fmt.Println("輸入 start 啟動(dòng)應(yīng)用,輸入 quit 退出應(yīng)用")
          // 創(chuàng)建 ChatGPT 客戶端 client := gpt3.NewClient(apiKey) if err != nil { fmt.Printf("創(chuàng)建客戶端失敗: %s\n", err.Error()) return }
          messages := []gpt3.ChatCompletionMessage{ { Role: "system", Content: "你是ChatGPT, OpenAI訓(xùn)練的大型語(yǔ)言模型, 請(qǐng)盡可能簡(jiǎn)潔地回答我的問(wèn)題", }, }
          // 讀取用戶輸入并交互 var userInput string for { fmt.Scanln(&userInput)
          if strings.ToLower(userInput) == "start" { fmt.Println("ChatGPT 啟動(dòng)成功,請(qǐng)輸入您的問(wèn)題:") } else if strings.ToLower(userInput) == "quit" { fmt.Println("ChatGPT 已退出") return } else if userInput != "" { messages = append( messages, gpt3.ChatCompletionMessage{ Role: "user", Content: userInput, }, ) // 調(diào)用 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 接口調(diào)用失敗: %s\n", err.Error()) continue }
          // 格式化輸出結(jié)果 output := resp.Choices[0].Message.Content mdOutput, 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 方法調(diào)用相關(guān)的代碼還是需要手動(dòng)調(diào)整,不過(guò)這也是我前面說(shuō)的面向 ChatGPT 編程的原則之一,最后一定要審核 ChatGPT 的代碼,它目前對(duì)于最新的知識(shí)還是有一定的遲滯性。

          代碼細(xì)節(jié)我就不展開(kāi)解釋了,有不明白的地方可以參考我在《面向 ChatGPT 編程實(shí)現(xiàn)全棧開(kāi)發(fā)的 18 種方法》這篇教程中代碼解釋部分提供的方法自行去基于 ChatGPT 查看。

          效果展示


          最后我們?cè)诮K端體驗(yàn)一下這個(gè)命令行版 ChatGPT,我這里使用的是 Windows WSL 終端,Windows 終端本身體驗(yàn)其實(shí)不太好,尤其是中文輸入的時(shí)候,刪除字符特別費(fèi)勁,且很容易造成消息變形,如果是 Mac 或者 Ubuntu 終端可能效果會(huì)更好一些。


          首先我們啟動(dòng)這個(gè)應(yīng)用,如果沒(méi)有設(shè)置 OPENAI_API_KEY 這個(gè)系統(tǒng)環(huán)境變量(運(yùn)行 export OPENAI_API_KEY={你的 OpenAI SECRET KEY} 命令設(shè)置即可),會(huì)提示你設(shè)置:



          如果已經(jīng)設(shè)置,會(huì)進(jìn)入下面這樣的啟動(dòng)歡迎界面:


          輸入 start 即可啟動(dòng)應(yīng)用,然后我們?cè)诿钚休斎雴?wèn)題,回車,就會(huì)將問(wèn)題提交給 ChatGPT,ChatGPT 處理的結(jié)果會(huì)返回并輸出到控制臺(tái),這里的格式經(jīng)過(guò)了 Glamour 庫(kù)的美化:


          因?yàn)槭?for 循環(huán),所以你可以持續(xù)提問(wèn)、得到答案,直到輸入 quit 退出應(yīng)用。

          終端需要能夠訪問(wèn) OpenAI API 才能調(diào)用成功,這意味著命令行也要支持科學(xué)上網(wǎng)。

          好了,這就是我們基于最新 ChatGPT API 實(shí)現(xiàn)的命令行版 ChatGPT 應(yīng)用,因?yàn)?ChatGPT API 是前兩天才發(fā)布的,所以看起來(lái) ChatGPT 并沒(méi)有學(xué)習(xí)到這個(gè)最新的 API 如何調(diào)用,存在遲滯性,進(jìn)而導(dǎo)致編寫(xiě)的代碼并不能直接滿足需求,需要人為介入去修改,希望未來(lái) ChatGPT 能夠在這一塊上有所進(jìn)化。

          歡迎點(diǎn)贊、關(guān)注、分享,更多關(guān)于 ChatGPT 的學(xué)習(xí)實(shí)踐探討,請(qǐng)關(guān)注這個(gè)訂閱號(hào)或者點(diǎn)擊閱讀原文了解極客書(shū)房最新動(dòng)態(tài)。

          瀏覽 116
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一卡二卡在线 | 特黄特色大片勉费看 | 无码免费在线观看高清 | 操逼免费观看网站 | 日皮网站在线观看 |