OpenAI 这两天发布了 ChatGPT API,基于 gpt-3.5-turbo 模型,这是一个 GPT-3.5 的优化版本,用于支持开发者把 ChatGPT 集成到自己的产品中,同时把 API 调用价格降到 $0.002 每千 token,意味着处理 100 万字符的文本只需要 2 美元,也就是差不多十几块钱人民币,效果更好、价格更低,这让 ChatGPT API 更具性价比,因此这两天基于 ChatGPT API 的各种套壳应用如雨后春笋般大量冒出。
今天就来实现一个命令行版 ChatGPT 应用。
代码如下:
package main
import (
"context"
"fmt"
"github.com/charmbracelet/glamour"
"github.com/common-nighthawk/go-figure"
gpt3 "github.com/sashabaranov/go-gpt3"
"strings"
)
func main() {
// 获取 OpenAI API Key
//apiKey := os.Getenv("OPENAI_API_KEY")
apiKey := "你自己的 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("ChatGPT 启动成功,输入您的问题回车即可,输入 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 string
fmt.Println("--问题---------------------\n")
for {
fmt.Scanln(&userInput)
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.Content
mdOutput, err := mdRenderer.Render(output)
if err != nil {
fmt.Printf("Markdown 渲染失败: %s\n", err.Error())
continue
}
fmt.Println("")
fmt.Println("--回答---------------------")
fmt.Println(mdOutput)
messages = append(
messages, gpt3.ChatCompletionMessage{
Role: "assistant",
Content: output,
},
)
fmt.Println("--问题---------------------\n")
}
}
}