golang集成OpenAI ChatGPT、DALL·E和Whisper API功能插件库go-openai的使用

Go OpenAI 库使用指南

这个库提供了非官方的Go客户端来访问OpenAI API。支持以下功能:

  • ChatGPT 4o, o1
  • GPT-3, GPT-4
  • DALL·E 2, DALL·E 3, GPT Image 1
  • Whisper

安装

go get github.com/sashabaranov/go-openai

当前go-openai需要Go 1.18或更高版本。

使用示例

ChatGPT基础示例

package main

import (
	"context"
	"fmt"
	openai "github.com/sashabaranov/go-openai"
)

func main() {
	client := openai.NewClient("your token")
	resp, err := client.CreateChatCompletion(
		context.Background(),
		openai.ChatCompletionRequest{
			Model: openai.GPT3Dot5Turbo,
			Messages: []openai.ChatCompletionMessage{
				{
					Role:    openai.ChatMessageRoleUser,
					Content: "Hello!",
				},
			},
		},
	)

	if err != nil {
		fmt.Printf("ChatCompletion error: %v\n", err)
		return
	}

	fmt.Println(resp.Choices[0].Message.Content)
}

获取OpenAI API密钥

  1. 访问OpenAI网站
  2. 如果没有账号,点击"Sign Up"创建。如果有账号,点击"Log In"
  3. 登录后,导航到API密钥管理页面
  4. 点击"Create new secret key"
  5. 输入新密钥的名称,然后点击"Create secret key"
  6. 新API密钥将显示。使用此密钥与OpenAI API交互

注意:您的API密钥是敏感信息。不要与任何人分享。

其他示例

ChatGPT流式响应

package main

import (
	"context"
	"errors"
	"fmt"
	"io"
	openai "github.com/sashabaranov/go-openai"
)

func main() {
	c := openai.NewClient("your token")
	ctx := context.Background()

	req := openai.ChatCompletionRequest{
		Model:     openai.GPT3Dot5Turbo,
		MaxTokens: 20,
		Messages: []openai.ChatCompletionMessage{
			{
				Role:    openai.ChatMessageRoleUser,
				Content: "Lorem ipsum",
			},
		},
		Stream: true,
	}
	stream, err := c.CreateChatCompletionStream(ctx, req)
	if err != nil {
		fmt.Printf("ChatCompletionStream error: %v\n", err)
		return
	}
	defer stream.Close()

	fmt.Printf("Stream response: ")
	for {
		response, err := stream.Recv()
		if errors.Is(err, io.EOF) {
			fmt.Println("\nStream finished")
			return
		}

		if err != nil {
			fmt.Printf("\nStream error: %v\n", err)
			return
		}

		fmt.Printf(response.Choices[0].Delta.Content)
	}
}

GPT-3补全

package main

import (
	"context"
	"fmt"
	openai "github.com/sashabaranov/go-openai"
)

func main() {
	c := openai.NewClient("your token")
	ctx := context.Background()

	req := openai.CompletionRequest{
		Model:     openai.GPT3Babbage002,
		MaxTokens: 5,
		Prompt:    "Lorem ipsum",
	}
	resp, err := c.CreateCompletion(ctx, req)
	if err != nil {
		fmt.Printf("Completion error: %v\n", err)
		return
	}
	fmt.Println(resp.Choices[0].Text)
}

语音转文本(Whisper)

package main

import (
	"context"
	"fmt"
	openai "github.com/sashabaranov/go-openai"
)

func main() {
	c := openai.NewClient("your token")
	ctx := context.Background()

	req := openai.AudioRequest{
		Model:    openai.Whisper1,
		FilePath: "recording.mp3",
	}
	resp, err := c.CreateTranscription(ctx, req)
	if err != nil {
		fmt.Printf("Transcription error: %v\n", err)
		return
	}
	fmt.Println(resp.Text)
}

DALL·E 2图像生成

package main

import (
	"bytes"
	"context"
	"encoding/base64"
	"fmt"
	openai "github.com/sashabaranov/go-openai"
	"image/png"
	"os"
)

func main() {
	c := openai.NewClient("your token")
	ctx := context.Background()

	// 通过链接获取示例图像
	reqUrl := openai.ImageRequest{
		Prompt:         "Parrot on a skateboard performs a trick, cartoon style, natural light, high detail",
		Size:           openai.CreateImageSize256x256,
		ResponseFormat: openai.CreateImageResponseFormatURL,
		N:              1,
	}

	respUrl, err := c.CreateImage(ctx, reqUrl)
	if err != nil {
		fmt.Printf("Image creation error: %v\n", err)
		return
	}
	fmt.Println(respUrl.Data[0].URL)

	// 示例图像作为base64
	reqBase64 := openai.ImageRequest{
		Prompt:         "Portrait of a humanoid parrot in a classic costume, high detail, realistic light, unreal engine",
		Size:           openai.CreateImageSize256x256,
		ResponseFormat: openai.CreateImageResponseFormatB64JSON,
		N:              1,
	}

	respBase64, err := c.CreateImage(ctx, reqBase64)
	if err != nil {
		fmt.Printf("Image creation error: %v\n", err)
		return
	}

	imgBytes, err := base64.StdEncoding.DecodeString(respBase64.Data[0].B64JSON)
	if err != nil {
		fmt.Printf("Base64 decode error: %v\n", err)
		return
	}

	r := bytes.NewReader(imgBytes)
	imgData, err := png.Decode(r)
	if err != nil {
		fmt.Printf("PNG decode error: %v\n", err)
		return
	}

	file, err := os.Create("example.png")
	if err != nil {
		fmt.Printf("File creation error: %v\n", err)
		return
	}
	defer file.Close()

	if err := png.Encode(file, imgData); err != nil {
		fmt.Printf("PNG encode error: %v\n", err)
		return
	}

	fmt.Println("The image was saved as example.png")
}

配置代理

config := openai.DefaultConfig("token")
proxyUrl, err := url.Parse("http://localhost:{port}")
if err != nil {
	panic(err)
}
transport := &http.Transport{
	Proxy: http.ProxyURL(proxyUrl),
}
config.HTTPClient = &http.Client{
	Transport: transport,
}

c := openai.NewClientWithConfig(config)

结构化输出

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/sashabaranov/go-openai"
	"github.com/sashabaranov/go-openai/jsonschema"
)

func main() {
	client := openai.NewClient("your token")
	ctx := context.Background()

	type Result struct {
		Steps []struct {
			Explanation string `json:"explanation"`
			Output      string `json:"output"`
		} `json:"steps"`
		FinalAnswer string `json:"final_answer"`
	}
	var result Result
	schema, err := jsonschema.GenerateSchemaForType(result)
	if err != nil {
		log.Fatalf("GenerateSchemaForType error: %v", err)
	}
	resp, err := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{
		Model: openai.GPT4oMini,
		Messages: []openai.ChatCompletionMessage{
			{
				Role:    openai.ChatMessageRoleSystem,
				Content: "You are a helpful math tutor. Guide the user through the solution step by step.",
			},
			{
				Role:    openai.ChatMessageRoleUser,
				Content: "how can I solve 8x + 7 = -23",
			},
		},
		ResponseFormat: &openai.ChatCompletionResponseFormat{
			Type: openai.ChatCompletionResponseFormatTypeJSONSchema,
			JSONSchema: &openai.ChatCompletionResponseFormatJSONSchema{
				Name:   "math_reasoning",
				Schema: schema,
				Strict: true,
			},
		},
	})
	if err != nil {
		log.Fatalf("CreateChatCompletion error: %v", err)
	}
	err = schema.Unmarshal(resp.Choices[0].Message.Content, &result)
	if err != nil {
		log.Fatalf("Unmarshal schema error: %v", err)
	}
	fmt.Println(result)
}

常见问题

为什么在温度设为0时,相同问题会得到不同答案?

即使在温度字段设为0时,也不能保证总是得到相同的响应。有几个因素会影响结果:

  1. Go OpenAI行为:当在Go OpenAI中将温度字段设为0时,omitempty标签会导致该字段从请求中移除。因此,OpenAI API会应用默认值1。
  2. 输入/输出的令牌数量:如果输入和输出中有大量令牌,即使温度设为0,仍可能出现非确定性行为。特别是当使用约32k令牌时,即使温度为0,非确定性行为的可能性也最高。

解决方法

  1. 使用新的seed参数与system_fingerprint响应字段,结合温度管理。
  2. 尝试使用math.SmallestNonzeroFloat32:在温度字段中指定math.SmallestNonzeroFloat32而不是0,可以模拟设为0的行为。
  3. 限制令牌数量:通过限制输入和输出中的令牌数量,特别是避免接近32k令牌的大型请求,可以降低非确定性行为的风险。

Go OpenAI是否提供令牌计数方法?

不,Go OpenAI不提供令牌计数功能,并且未来也没有计划提供此功能。但是,如果有一种零依赖的方式实现令牌计数功能,可能会将其合并到Go OpenAI中。否则,更适合在专用库或存储库中实现它。

贡献

遵循贡献指南,我们希望确保您的贡献能够顺利高效地进行。

致谢

我们要向该项目的贡献者和赞助商表示最深切的感谢。


更多关于golang集成OpenAI ChatGPT、DALL·E和Whisper API功能插件库go-openai的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang集成OpenAI ChatGPT、DALL·E和Whisper API功能插件库go-openai的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-openai库集成OpenAI API功能

go-openai是一个优秀的Golang库,可以方便地集成OpenAI的各种API功能,包括ChatGPT、DALL·E和Whisper。下面我将详细介绍如何使用这个库。

安装

首先安装go-openai库:

go get github.com/sashabaranov/go-openai

初始化客户端

package main

import (
	"context"
	"fmt"
	"os"

	openai "github.com/sashabaranov/go-openai"
)

func main() {
	// 从环境变量获取API密钥
	apiKey := os.Getenv("OPENAI_API_KEY")
	if apiKey == "" {
		fmt.Println("请设置OPENAI_API_KEY环境变量")
		return
	}

	// 创建OpenAI客户端
	client := openai.NewClient(apiKey)
	
	// 使用各种API功能...
}

1. ChatGPT API 使用示例

基本聊天功能

func chatWithGPT(client *openai.Client, prompt string) (string, error) {
	resp, err := client.CreateChatCompletion(
		context.Background(),
		openai.ChatCompletionRequest{
			Model: openai.GPT3Dot5Turbo,
			Messages: []openai.ChatCompletionMessage{
				{
					Role:    openai.ChatMessageRoleUser,
					Content: prompt,
				},
			},
		},
	)

	if err != nil {
		return "", err
	}

	return resp.Choices[0].Message.Content, nil
}

流式响应

func streamChatWithGPT(client *openai.Client, prompt string) error {
	req := openai.ChatCompletionRequest{
		Model:     openai.GPT3Dot5Turbo,
		Messages:  []openai.ChatCompletionMessage{{Role: openai.ChatMessageRoleUser, Content: prompt}},
		Stream:    true,
	}

	stream, err := client.CreateChatCompletionStream(context.Background(), req)
	if err != nil {
		return err
	}
	defer stream.Close()

	for {
		response, err := stream.Recv()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}

		fmt.Printf(response.Choices[0].Delta.Content)
	}

	return nil
}

2. DALL·E API 使用示例

生成图像

func generateImage(client *openai.Client, prompt string) (string, error) {
	req := openai.ImageRequest{
		Prompt:         prompt,
		Size:           openai.CreateImageSize1024x1024,
		ResponseFormat: openai.CreateImageResponseFormatURL,
		N:              1,
	}

	resp, err := client.CreateImage(context.Background(), req)
	if err != nil {
		return "", err
	}

	return resp.Data[0].URL, nil
}

图像编辑

func editImage(client *openai.Client, imagePath, maskPath, prompt string) (string, error) {
	image, err := os.Open(imagePath)
	if err != nil {
		return "", err
	}
	defer image.Close()

	mask, err := os.Open(maskPath)
	if err != nil {
		return "", err
	}
	defer mask.Close()

	req := openai.ImageEditRequest{
		Image:  image,
		Mask:   mask,
		Prompt: prompt,
		N:      1,
		Size:   openai.CreateImageSize1024x1024,
	}

	resp, err := client.CreateEditImage(context.Background(), req)
	if err != nil {
		return "", err
	}

	return resp.Data[0].URL, nil
}

3. Whisper API 使用示例

语音转文字

func transcribeAudio(client *openai.Client, audioPath string) (string, error) {
	audio, err := os.Open(audioPath)
	if err != nil {
		return "", err
	}
	defer audio.Close()

	req := openai.AudioRequest{
		Model:    openai.Whisper1,
		FilePath: audioPath,
		Reader:   audio,
	}

	resp, err := client.CreateTranscription(context.Background(), req)
	if err != nil {
		return "", err
	}

	return resp.Text, nil
}

翻译音频

func translateAudio(client *openai.Client, audioPath string) (string, error) {
	audio, err := os.Open(audioPath)
	if err != nil {
		return "", err
	}
	defer audio.Close()

	req := openai.AudioRequest{
		Model:    openai.Whisper1,
		FilePath: audioPath,
		Reader:   audio,
	}

	resp, err := client.CreateTranslation(context.Background(), req)
	if err != nil {
		return "", err
	}

	return resp.Text, nil
}

高级功能

自定义配置

// 创建自定义配置的客户端
config := openai.DefaultConfig("your-api-key")
config.BaseURL = "https://your-proxy.com/v1" // 如果有代理

client := openai.NewClientWithConfig(config)

错误处理

resp, err := client.CreateChatCompletion(ctx, req)
if err != nil {
    var apiErr *openai.APIError
    if errors.As(err, &apiErr) {
        fmt.Printf("OpenAI API错误: %s, 状态码: %d\n", apiErr.Message, apiErr.HTTPStatusCode)
    } else {
        fmt.Printf("请求错误: %v\n", err)
    }
    return
}

总结

go-openai库提供了简单易用的接口来访问OpenAI的各种API功能。通过上述示例,你可以轻松集成ChatGPT的对话能力、DALL·E的图像生成和编辑功能,以及Whisper的语音识别和翻译功能到你的Golang应用中。

记得在实际使用时:

  1. 妥善管理API密钥
  2. 处理可能出现的错误
  3. 根据需求调整各种参数
  4. 注意API的调用频率和配额限制
回到顶部