该库为OpenAI API提供了非正式的GO客户。我们支持:
go get github.com/sashabaranov/go-openai
当前,Go-Openai需要GO版本1.18或更高版本。
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 )
}注意:您的API密钥是敏感信息。不要与任何人分享。
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 ( " n Stream finished" )
return
}
if err != nil {
fmt . Printf ( " n Stream error: %v n " , err )
return
}
fmt . Printf ( response . Choices [ 0 ]. Delta . Content )
}
} 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 )
} package main
import (
"errors"
"context"
"fmt"
"io"
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" ,
Stream : true ,
}
stream , err := c . CreateCompletionStream ( ctx , req )
if err != nil {
fmt . Printf ( "CompletionStream error: %v n " , err )
return
}
defer stream . Close ()
for {
response , err := stream . Recv ()
if errors . Is ( err , io . EOF ) {
fmt . Println ( "Stream finished" )
return
}
if err != nil {
fmt . Printf ( "Stream error: %v n " , err )
return
}
fmt . Printf ( "Stream response: %v n " , response )
}
} 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 )
} package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main () {
c := openai . NewClient ( os . Getenv ( "OPENAI_KEY" ))
req := openai. AudioRequest {
Model : openai . Whisper1 ,
FilePath : os . Args [ 1 ],
Format : openai . AudioResponseFormatSRT ,
}
resp , err := c . CreateTranscription ( context . Background (), req )
if err != nil {
fmt . Printf ( "Transcription error: %v n " , err )
return
}
f , err := os . Create ( os . Args [ 1 ] + ".srt" )
if err != nil {
fmt . Printf ( "Could not open file: %v n " , err )
return
}
defer f . Close ()
if _ , err := f . WriteString ( resp . Text ); err != nil {
fmt . Printf ( "Error writing to file: %v n " , err )
return
}
} 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 ()
// Sample image by link
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 )
// Example image as 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 )另请参阅:https://pkg.go.dev/github.com/sashabaranov/go-openai#clientconfig
package main
import (
"bufio"
"context"
"fmt"
"os"
"strings"
"github.com/sashabaranov/go-openai"
)
func main () {
client := openai . NewClient ( "your token" )
messages := make ([]openai. ChatCompletionMessage , 0 )
reader := bufio . NewReader ( os . Stdin )
fmt . Println ( "Conversation" )
fmt . Println ( "---------------------" )
for {
fmt . Print ( "-> " )
text , _ := reader . ReadString ( 'n' )
// convert CRLF to LF
text = strings . Replace ( text , " n " , "" , - 1 )
messages = append ( messages , openai. ChatCompletionMessage {
Role : openai . ChatMessageRoleUser ,
Content : text ,
})
resp , err := client . CreateChatCompletion (
context . Background (),
openai. ChatCompletionRequest {
Model : openai . GPT3Dot5Turbo ,
Messages : messages ,
},
)
if err != nil {
fmt . Printf ( "ChatCompletion error: %v n " , err )
continue
}
content := resp . Choices [ 0 ]. Message . Content
messages = append ( messages , openai. ChatCompletionMessage {
Role : openai . ChatMessageRoleAssistant ,
Content : content ,
})
fmt . Println ( content )
}
} package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai"
)
func main () {
config := openai . DefaultAzureConfig ( "your Azure OpenAI Key" , "https://your Azure OpenAI Endpoint" )
// If you use a deployment name different from the model name, you can customize the AzureModelMapperFunc function
// config.AzureModelMapperFunc = func(model string) string {
// azureModelMapping := map[string]string{
// "gpt-3.5-turbo": "your gpt-3.5-turbo deployment name",
// }
// return azureModelMapping[model]
// }
client := openai . NewClientWithConfig ( config )
resp , err := client . CreateChatCompletion (
context . Background (),
openai. ChatCompletionRequest {
Model : openai . GPT3Dot5Turbo ,
Messages : []openai. ChatCompletionMessage {
{
Role : openai . ChatMessageRoleUser ,
Content : "Hello Azure OpenAI!" ,
},
},
},
)
if err != nil {
fmt . Printf ( "ChatCompletion error: %v n " , err )
return
}
fmt . Println ( resp . Choices [ 0 ]. Message . Content )
} package main
import (
"context"
"log"
openai "github.com/sashabaranov/go-openai"
)
func main () {
client := openai . NewClient ( "your-token" )
// Create an EmbeddingRequest for the user query
queryReq := openai. EmbeddingRequest {
Input : [] string { "How many chucks would a woodchuck chuck" },
Model : openai . AdaEmbeddingV2 ,
}
// Create an embedding for the user query
queryResponse , err := client . CreateEmbeddings ( context . Background (), queryReq )
if err != nil {
log . Fatal ( "Error creating query embedding:" , err )
}
// Create an EmbeddingRequest for the target text
targetReq := openai. EmbeddingRequest {
Input : [] string { "How many chucks would a woodchuck chuck if the woodchuck could chuck wood" },
Model : openai . AdaEmbeddingV2 ,
}
// Create an embedding for the target text
targetResponse , err := client . CreateEmbeddings ( context . Background (), targetReq )
if err != nil {
log . Fatal ( "Error creating target embedding:" , err )
}
// Now that we have the embeddings for the user query and the target text, we
// can calculate their similarity.
queryEmbedding := queryResponse . Data [ 0 ]
targetEmbedding := targetResponse . Data [ 0 ]
similarity , err := queryEmbedding . DotProduct ( & targetEmbedding )
if err != nil {
log . Fatal ( "Error calculating dot product:" , err )
}
log . Printf ( "The similarity score between the query and the target is %f" , similarity )
} package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai"
)
func main () {
config := openai . DefaultAzureConfig ( "your Azure OpenAI Key" , "https://your Azure OpenAI Endpoint" )
config . APIVersion = "2023-05-15" // optional update to latest API version
//If you use a deployment name different from the model name, you can customize the AzureModelMapperFunc function
//config.AzureModelMapperFunc = func(model string) string {
// azureModelMapping := map[string]string{
// "gpt-3.5-turbo":"your gpt-3.5-turbo deployment name",
// }
// return azureModelMapping[model]
//}
input := "Text to vectorize"
client := openai . NewClientWithConfig ( config )
resp , err := client . CreateEmbeddings (
context . Background (),
openai. EmbeddingRequest {
Input : [] string { input },
Model : openai . AdaEmbeddingV2 ,
})
if err != nil {
fmt . Printf ( "CreateEmbeddings error: %v n " , err )
return
}
vectors := resp . Data [ 0 ]. Embedding // []float32 with 1536 dimensions
fmt . Println ( vectors [: 10 ], "..." , vectors [ len ( vectors ) - 10 :])
}现在,聊天完成可以选择拨打函数以获取更多信息(请参阅此处的开发人员文档)。
为了描述可以调用的函数的类型,必须提供JSON模式。许多JSON模式库存在,并且比我们在此库中提供的更先进,但是我们为那些想使用此功能而无需格式化自己的JSON模式有效负载的人提供了一个简单的jsonschema软件包。
开发人员文档将此JSON模式定义为一个例子:
{
"name" : " get_current_weather " ,
"description" : " Get the current weather in a given location " ,
"parameters" :{
"type" : " object " ,
"properties" :{
"location" :{
"type" : " string " ,
"description" : " The city and state, e.g. San Francisco, CA "
},
"unit" :{
"type" : " string " ,
"enum" :[
" celsius " ,
" fahrenheit "
]
}
},
"required" :[
" location "
]
}
}使用jsonschema软件包,可以使用结构这样创建此架构:
FunctionDefinition {
Name : "get_current_weather" ,
Parameters : jsonschema. Definition {
Type : jsonschema . Object ,
Properties : map [ string ]jsonschema. Definition {
"location" : {
Type : jsonschema . String ,
Description : "The city and state, e.g. San Francisco, CA" ,
},
"unit" : {
Type : jsonschema . String ,
Enum : [] string { "celsius" , "fahrenheit" },
},
},
Required : [] string { "location" },
},
} FunctionDefinition的Parameters字段可以接受上述样式,甚至可以从另一个库中嵌套结构(只要可以将其编码为JSON)即可。
Open-AI保留有关如何处理API错误的清晰文档
例子:
e := &openai.APIError{}
if errors.As(err, &e) {
switch e.HTTPStatusCode {
case 401:
// invalid auth or key (do not retry)
case 429:
// rate limiting or engine overload (wait and retry)
case 500:
// openai server error (retry)
default:
// unhandled
}
}
package main
import (
"context"
"fmt"
"github.com/sashabaranov/go-openai"
)
func main () {
client := openai . NewClient ( "your token" )
ctx := context . Background ()
// create a .jsonl file with your training data for conversational model
// {"prompt": "<prompt text>", "completion": "<ideal generated text>"}
// {"prompt": "<prompt text>", "completion": "<ideal generated text>"}
// {"prompt": "<prompt text>", "completion": "<ideal generated text>"}
// chat models are trained using the following file format:
// {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
// {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
// {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}
// you can use openai cli tool to validate the data
// For more info - https://platform.openai.com/docs/guides/fine-tuning
file , err := client . CreateFile ( ctx , openai. FileRequest {
FilePath : "training_prepared.jsonl" ,
Purpose : "fine-tune" ,
})
if err != nil {
fmt . Printf ( "Upload JSONL file error: %v n " , err )
return
}
// create a fine tuning job
// Streams events until the job is done (this often takes minutes, but can take hours if there are many jobs in the queue or your dataset is large)
// use below get method to know the status of your model
fineTuningJob , err := client . CreateFineTuningJob ( ctx , openai. FineTuningJobRequest {
TrainingFile : file . ID ,
Model : "davinci-002" , // gpt-3.5-turbo-0613, babbage-002.
})
if err != nil {
fmt . Printf ( "Creating new fine tune model error: %v n " , err )
return
}
fineTuningJob , err = client . RetrieveFineTuningJob ( ctx , fineTuningJob . ID )
if err != nil {
fmt . Printf ( "Getting fine tune model error: %v n " , err )
return
}
fmt . Println ( fineTuningJob . FineTunedModel )
// once the status of fineTuningJob is `succeeded`, you can use your fine tune model in Completion Request or Chat Completion Request
// resp, err := client.CreateCompletion(ctx, openai.CompletionRequest{
// Model: fineTuningJob.FineTunedModel,
// Prompt: "your prompt",
// })
// if err != nil {
// fmt.Printf("Create completion error %vn", err)
// return
// }
//
// fmt.Println(resp.Choices[0].Text)
} 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的温度字段,也不能保证您始终得到相同的响应。有几个因素发挥了作用。
由于上述因素,即使对于同一问题,也可以返回不同的答案。
解决方法:
seed参数与system_fingerprint响应字段以及温度管理一起使用。math.SmallestNonzeroFloat32 :通过在温度字段中指定math.SmallestNonzeroFloat32而不是0,您可以模仿将其设置为0的行为。通过采用这些策略,您可以期望获得更多一致的结果。
相关问题:
请求结构的OmitEmpty选项将在参数为0时生成不正确的请求。
不,Go Openai不提供计算令牌的功能,并且没有计划在将来提供此类功能。但是,如果有一种方法可以实现具有零依赖性的令牌计数功能,则可能可以将该功能合并到OpenAi中。否则,在专用的库或存储库中实施它将更合适。
对于计数令牌,您可能会发现以下链接有帮助:
相关问题:
是否可以加入GPT3 Tokenizer的实现
通过遵循贡献指南,我们希望确保您的贡献顺利,有效地做出效率。
我们想花点时间对该项目的贡献者和赞助商表示最深切的感谢:
向大家:谢谢。您帮助我们取得了比以往任何时候都更能实现的。迫不及待想看看我们下一个去哪里!