Golang接入GPT

634 阅读2分钟

将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调用逻辑封装在一个独立的模块中,使得代码结构更加清晰,便于维护和扩展。