将ChatGPT API的调用封装成一个独立的Go模块,这样可以更方便地在项目中重用。以下是封装后的版本:
创建项目结构
首先,创建项目结构:
chatgpt-go/
|-- main.go
|-- chatgpt/
| |-- client.go
编写封装模块
在chatgpt目录下创建一个名为client.go的文件,并编写以下代码:
package chatgpt
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
const apiURL = "https://api.openai.com/v1/chat/completions"
type Client struct {
APIKey string
}
type ChatRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
}
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type ChatResponse struct {
Choices []struct {
Message Message `json:"message"`
} `json:"choices"`
}
func NewClient(apiKey string) *Client {
return &Client{APIKey: apiKey}
}
func (c *Client) SendMessage(model string, messages []Message) (string, error) {
chatRequest := ChatRequest{
Model: model,
Messages: messages,
}
requestBody, err := json.Marshal(chatRequest)
if err != nil {
return "", fmt.Errorf("error marshaling request: %w", err)
}
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(requestBody))
if err != nil {
return "", fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+c.APIKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("error sending request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("received non-200 response: %d", resp.StatusCode)
}
var chatResponse ChatResponse
err = json.Unmarshal(resp.Body, &chatResponse)
if err != nil {
return "", fmt.Errorf("error unmarshaling response: %w", err)
}
if len(chatResponse.Choices) > 0 {
return chatResponse.Choices[0].Message.Content, nil
}
return "", fmt.Errorf("no response from ChatGPT")
}
使用封装模块
在项目根目录下创建main.go文件,并编写以下代码:
package main
import (
"fmt"
"log"
"os"
"chatgpt-go/chatgpt"
)
func main() {
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
log.Fatal("Please set the OPENAI_API_KEY environment variable")
}
client := chatgpt.NewClient(apiKey)
// Replace with your own prompt and user input
userInput := "Hello, how are you?"
messages := []chatgpt.Message{
{Role: "user", Content: userInput},
}
response, err := client.SendMessage("gpt-4", messages)
if err != nil {
log.Fatalf("Error: %v\n", err)
}
fmt.Printf("ChatGPT: %s\n", response)
}
运行代码
确保设置环境变量,并运行代码:
export OPENAI_API_KEY="your_api_key_here"
go run main.go
代码解释
chatgpt/client.go
- Client结构体: 包含API密钥的客户端结构体。
- NewClient函数: 创建并返回一个新的Client实例。
- SendMessage方法:
- 构建请求数据结构并将其序列化为JSON。
- 使用
net/http包发送HTTP POST请求到OpenAI的API端点。 - 处理响应,包括错误处理和解析响应体。
- 返回ChatGPT的回复内容或错误。
main.go
- 主函数:
- 读取API密钥并创建一个ChatGPT客户端实例。
- 构建用户输入的消息并调用
SendMessage方法发送请求。 - 处理并输出ChatGPT的回复。
通过这种方式,你将ChatGPT的API调用逻辑封装在一个独立的模块中,使得代码结构更加清晰,便于维护和扩展。