[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-5033":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":37,"readmeContent":38,"aiSummary":39,"trendingCount":16,"starSnapshotCount":16,"syncStatus":40,"lastSyncTime":41,"discoverSource":42},5033,"go-openai","sashabaranov\u002Fgo-openai","sashabaranov","OpenAI ChatGPT, GPT-5, GPT-Image-1, Whisper API clients for Go","",null,"Go",10690,1699,68,158,0,5,41,1,76.29,"Apache License 2.0",false,"master",true,[26,27,28,29,30,31,32,33,34,35,36],"chatgpt","chatgpt-api","dall-e","go","golang","gpt-4","gpt-5","gpt-5-api","openai","openai-whisper","streaming-api","2026-06-12 04:00:24","# Go OpenAI\n[![Go Reference](https:\u002F\u002Fpkg.go.dev\u002Fbadge\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai.svg)](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai)\n[![Go Report Card](https:\u002F\u002Fgoreportcard.com\u002Fbadge\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai)](https:\u002F\u002Fgoreportcard.com\u002Freport\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai)\n[![codecov](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fsashabaranov\u002Fgo-openai\u002Fbranch\u002Fmaster\u002Fgraph\u002Fbadge.svg?token=bCbIfHLIsW)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fsashabaranov\u002Fgo-openai)\n\nThis library provides unofficial Go clients for [OpenAI API](https:\u002F\u002Fplatform.openai.com\u002F). We support: \n\n* ChatGPT 4o, o1\n* GPT-3, GPT-4\n* DALL·E 2, DALL·E 3, GPT Image 1\n* Whisper\n\n## Installation\n\n```\ngo get github.com\u002Fsashabaranov\u002Fgo-openai\n```\nCurrently, go-openai requires Go version 1.18 or greater.\n\n\n## Usage\n\n### ChatGPT example usage:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\"your token\")\n\tresp, err := client.CreateChatCompletion(\n\t\tcontext.Background(),\n\t\topenai.ChatCompletionRequest{\n\t\t\tModel: openai.GPT3Dot5Turbo,\n\t\t\tMessages: []openai.ChatCompletionMessage{\n\t\t\t\t{\n\t\t\t\t\tRole:    openai.ChatMessageRoleUser,\n\t\t\t\t\tContent: \"Hello!\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n\n\tif err != nil {\n\t\tfmt.Printf(\"ChatCompletion error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(resp.Choices[0].Message.Content)\n}\n\n```\n\n### Getting an OpenAI API Key:\n\n1. Visit the OpenAI website at [https:\u002F\u002Fplatform.openai.com\u002Faccount\u002Fapi-keys](https:\u002F\u002Fplatform.openai.com\u002Faccount\u002Fapi-keys).\n2. If you don't have an account, click on \"Sign Up\" to create one. If you do, click \"Log In\".\n3. Once logged in, navigate to your API key management page.\n4. Click on \"Create new secret key\".\n5. Enter a name for your new key, then click \"Create secret key\".\n6. Your new API key will be displayed. Use this key to interact with the OpenAI API.\n\n**Note:** Your API key is sensitive information. Do not share it with anyone.\n\n### Other examples:\n\n\u003Cdetails>\n\u003Csummary>ChatGPT streaming completion\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tc := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\treq := openai.ChatCompletionRequest{\n\t\tModel:     openai.GPT3Dot5Turbo,\n\t\tMaxTokens: 20,\n\t\tMessages: []openai.ChatCompletionMessage{\n\t\t\t{\n\t\t\t\tRole:    openai.ChatMessageRoleUser,\n\t\t\t\tContent: \"Lorem ipsum\",\n\t\t\t},\n\t\t},\n\t\tStream: true,\n\t}\n\tstream, err := c.CreateChatCompletionStream(ctx, req)\n\tif err != nil {\n\t\tfmt.Printf(\"ChatCompletionStream error: %v\\n\", err)\n\t\treturn\n\t}\n\tdefer stream.Close()\n\n\tfmt.Printf(\"Stream response: \")\n\tfor {\n\t\tresponse, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tfmt.Println(\"\\nStream finished\")\n\t\t\treturn\n\t\t}\n\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"\\nStream error: %v\\n\", err)\n\t\t\treturn\n\t\t}\n\n\t\tfmt.Printf(response.Choices[0].Delta.Content)\n\t}\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>GPT-3 completion\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tc := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\treq := openai.CompletionRequest{\n\t\tModel:     openai.GPT3Babbage002,\n\t\tMaxTokens: 5,\n\t\tPrompt:    \"Lorem ipsum\",\n\t}\n\tresp, err := c.CreateCompletion(ctx, req)\n\tif err != nil {\n\t\tfmt.Printf(\"Completion error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(resp.Choices[0].Text)\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>GPT-3 streaming completion\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tc := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\treq := openai.CompletionRequest{\n\t\tModel:     openai.GPT3Babbage002,\n\t\tMaxTokens: 5,\n\t\tPrompt:    \"Lorem ipsum\",\n\t\tStream:    true,\n\t}\n\tstream, err := c.CreateCompletionStream(ctx, req)\n\tif err != nil {\n\t\tfmt.Printf(\"CompletionStream error: %v\\n\", err)\n\t\treturn\n\t}\n\tdefer stream.Close()\n\n\tfor {\n\t\tresponse, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tfmt.Println(\"Stream finished\")\n\t\t\treturn\n\t\t}\n\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Stream error: %v\\n\", err)\n\t\t\treturn\n\t\t}\n\n\n\t\tfmt.Printf(\"Stream response: %v\\n\", response)\n\t}\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Audio Speech-To-Text\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tc := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\treq := openai.AudioRequest{\n\t\tModel:    openai.Whisper1,\n\t\tFilePath: \"recording.mp3\",\n\t}\n\tresp, err := c.CreateTranscription(ctx, req)\n\tif err != nil {\n\t\tfmt.Printf(\"Transcription error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(resp.Text)\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Audio Captions\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tc := openai.NewClient(os.Getenv(\"OPENAI_KEY\"))\n\n\treq := openai.AudioRequest{\n\t\tModel:    openai.Whisper1,\n\t\tFilePath: os.Args[1],\n\t\tFormat:   openai.AudioResponseFormatSRT,\n\t}\n\tresp, err := c.CreateTranscription(context.Background(), req)\n\tif err != nil {\n\t\tfmt.Printf(\"Transcription error: %v\\n\", err)\n\t\treturn\n\t}\n\tf, err := os.Create(os.Args[1] + \".srt\")\n\tif err != nil {\n\t\tfmt.Printf(\"Could not open file: %v\\n\", err)\n\t\treturn\n\t}\n\tdefer f.Close()\n\tif _, err := f.WriteString(resp.Text); err != nil {\n\t\tfmt.Printf(\"Error writing to file: %v\\n\", err)\n\t\treturn\n\t}\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>DALL-E 2 image generation\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding\u002Fbase64\"\n\t\"fmt\"\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n\t\"image\u002Fpng\"\n\t\"os\"\n)\n\nfunc main() {\n\tc := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\t\u002F\u002F Sample image by link\n\treqUrl := openai.ImageRequest{\n\t\tPrompt:         \"Parrot on a skateboard performs a trick, cartoon style, natural light, high detail\",\n\t\tSize:           openai.CreateImageSize256x256,\n\t\tResponseFormat: openai.CreateImageResponseFormatURL,\n\t\tN:              1,\n\t}\n\n\trespUrl, err := c.CreateImage(ctx, reqUrl)\n\tif err != nil {\n\t\tfmt.Printf(\"Image creation error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(respUrl.Data[0].URL)\n\n\t\u002F\u002F Example image as base64\n\treqBase64 := openai.ImageRequest{\n\t\tPrompt:         \"Portrait of a humanoid parrot in a classic costume, high detail, realistic light, unreal engine\",\n\t\tSize:           openai.CreateImageSize256x256,\n\t\tResponseFormat: openai.CreateImageResponseFormatB64JSON,\n\t\tN:              1,\n\t}\n\n\trespBase64, err := c.CreateImage(ctx, reqBase64)\n\tif err != nil {\n\t\tfmt.Printf(\"Image creation error: %v\\n\", err)\n\t\treturn\n\t}\n\n\timgBytes, err := base64.StdEncoding.DecodeString(respBase64.Data[0].B64JSON)\n\tif err != nil {\n\t\tfmt.Printf(\"Base64 decode error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tr := bytes.NewReader(imgBytes)\n\timgData, err := png.Decode(r)\n\tif err != nil {\n\t\tfmt.Printf(\"PNG decode error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfile, err := os.Create(\"example.png\")\n\tif err != nil {\n\t\tfmt.Printf(\"File creation error: %v\\n\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tif err := png.Encode(file, imgData); err != nil {\n\t\tfmt.Printf(\"PNG encode error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"The image was saved as example.png\")\n}\n\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>GPT Image 1 image generation\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding\u002Fbase64\"\n\t\"fmt\"\n\t\"os\"\n\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tc := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\treq := openai.ImageRequest{\n\t\tPrompt:            \"Parrot on a skateboard performing a trick. Large bold text \\\"SKATE MASTER\\\" banner at the bottom of the image. Cartoon style, natural light, high detail, 1:1 aspect ratio.\",\n\t\tBackground:        openai.CreateImageBackgroundOpaque,\n\t\tModel:             openai.CreateImageModelGptImage1,\n\t\tSize:              openai.CreateImageSize1024x1024,\n\t\tN:                 1,\n\t\tQuality:           openai.CreateImageQualityLow,\n\t\tOutputCompression: 100,\n\t\tOutputFormat:      openai.CreateImageOutputFormatJPEG,\n\t\t\u002F\u002F Moderation: \t\t openai.CreateImageModerationLow,\n\t\t\u002F\u002F User: \t\t\t\t\t \"\",\n\t}\n\n\tresp, err := c.CreateImage(ctx, req)\n\tif err != nil {\n\t\tfmt.Printf(\"Image creation Image generation with GPT Image 1error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Image Base64:\", resp.Data[0].B64JSON)\n\n\t\u002F\u002F Decode the base64 data\n\timgBytes, err := base64.StdEncoding.DecodeString(resp.Data[0].B64JSON)\n\tif err != nil {\n\t\tfmt.Printf(\"Base64 decode error: %v\\n\", err)\n\t\treturn\n\t}\n\n\t\u002F\u002F Write image to file\n\toutputPath := \"generated_image.jpg\"\n\terr = os.WriteFile(outputPath, imgBytes, 0644)\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to write image file: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Printf(\"The image was saved as %s\\n\", outputPath)\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Configuring proxy\u003C\u002Fsummary>\n\n```go\nconfig := openai.DefaultConfig(\"token\")\nproxyUrl, err := url.Parse(\"http:\u002F\u002Flocalhost:{port}\")\nif err != nil {\n\tpanic(err)\n}\ntransport := &http.Transport{\n\tProxy: http.ProxyURL(proxyUrl),\n}\nconfig.HTTPClient = &http.Client{\n\tTransport: transport,\n}\n\nc := openai.NewClientWithConfig(config)\n```\n\nSee also: https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai#ClientConfig\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>ChatGPT support context\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\"your token\")\n\tmessages := make([]openai.ChatCompletionMessage, 0)\n\treader := bufio.NewReader(os.Stdin)\n\tfmt.Println(\"Conversation\")\n\tfmt.Println(\"---------------------\")\n\n\tfor {\n\t\tfmt.Print(\"-> \")\n\t\ttext, _ := reader.ReadString('\\n')\n\t\t\u002F\u002F convert CRLF to LF\n\t\ttext = strings.Replace(text, \"\\n\", \"\", -1)\n\t\tmessages = append(messages, openai.ChatCompletionMessage{\n\t\t\tRole:    openai.ChatMessageRoleUser,\n\t\t\tContent: text,\n\t\t})\n\n\t\tresp, err := client.CreateChatCompletion(\n\t\t\tcontext.Background(),\n\t\t\topenai.ChatCompletionRequest{\n\t\t\t\tModel:    openai.GPT3Dot5Turbo,\n\t\t\t\tMessages: messages,\n\t\t\t},\n\t\t)\n\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"ChatCompletion error: %v\\n\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tcontent := resp.Choices[0].Message.Content\n\t\tmessages = append(messages, openai.ChatCompletionMessage{\n\t\t\tRole:    openai.ChatMessageRoleAssistant,\n\t\t\tContent: content,\n\t\t})\n\t\tfmt.Println(content)\n\t}\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Azure OpenAI ChatGPT\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tconfig := openai.DefaultAzureConfig(\"your Azure OpenAI Key\", \"https:\u002F\u002Fyour Azure OpenAI Endpoint\")\n\t\u002F\u002F If you use a deployment name different from the model name, you can customize the AzureModelMapperFunc function\n\t\u002F\u002F config.AzureModelMapperFunc = func(model string) string {\n\t\u002F\u002F \tazureModelMapping := map[string]string{\n\t\u002F\u002F \t\t\"gpt-3.5-turbo\": \"your gpt-3.5-turbo deployment name\",\n\t\u002F\u002F \t}\n\t\u002F\u002F \treturn azureModelMapping[model]\n\t\u002F\u002F }\n\n\tclient := openai.NewClientWithConfig(config)\n\tresp, err := client.CreateChatCompletion(\n\t\tcontext.Background(),\n\t\topenai.ChatCompletionRequest{\n\t\t\tModel: openai.GPT3Dot5Turbo,\n\t\t\tMessages: []openai.ChatCompletionMessage{\n\t\t\t\t{\n\t\t\t\t\tRole:    openai.ChatMessageRoleUser,\n\t\t\t\t\tContent: \"Hello Azure OpenAI!\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n\tif err != nil {\n\t\tfmt.Printf(\"ChatCompletion error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(resp.Choices[0].Message.Content)\n}\n\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Embedding Semantic Similarity\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n\n)\n\nfunc main() {\n\tclient := openai.NewClient(\"your-token\")\n\n\t\u002F\u002F Create an EmbeddingRequest for the user query\n\tqueryReq := openai.EmbeddingRequest{\n\t\tInput: []string{\"How many chucks would a woodchuck chuck\"},\n\t\tModel: openai.AdaEmbeddingV2,\n\t}\n\n\t\u002F\u002F Create an embedding for the user query\n\tqueryResponse, err := client.CreateEmbeddings(context.Background(), queryReq)\n\tif err != nil {\n\t\tlog.Fatal(\"Error creating query embedding:\", err)\n\t}\n\n\t\u002F\u002F Create an EmbeddingRequest for the target text\n\ttargetReq := openai.EmbeddingRequest{\n\t\tInput: []string{\"How many chucks would a woodchuck chuck if the woodchuck could chuck wood\"},\n\t\tModel: openai.AdaEmbeddingV2,\n\t}\n\n\t\u002F\u002F Create an embedding for the target text\n\ttargetResponse, err := client.CreateEmbeddings(context.Background(), targetReq)\n\tif err != nil {\n\t\tlog.Fatal(\"Error creating target embedding:\", err)\n\t}\n\n\t\u002F\u002F Now that we have the embeddings for the user query and the target text, we\n\t\u002F\u002F can calculate their similarity.\n\tqueryEmbedding := queryResponse.Data[0]\n\ttargetEmbedding := targetResponse.Data[0]\n\n\tsimilarity, err := queryEmbedding.DotProduct(&targetEmbedding)\n\tif err != nil {\n\t\tlog.Fatal(\"Error calculating dot product:\", err)\n\t}\n\n\tlog.Printf(\"The similarity score between the query and the target is %f\", similarity)\n}\n\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Azure OpenAI Embeddings\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\topenai \"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\n\tconfig := openai.DefaultAzureConfig(\"your Azure OpenAI Key\", \"https:\u002F\u002Fyour Azure OpenAI Endpoint\")\n\tconfig.APIVersion = \"2023-05-15\" \u002F\u002F optional update to latest API version\n\n\t\u002F\u002FIf you use a deployment name different from the model name, you can customize the AzureModelMapperFunc function\n\t\u002F\u002Fconfig.AzureModelMapperFunc = func(model string) string {\n\t\u002F\u002F    azureModelMapping := map[string]string{\n\t\u002F\u002F        \"gpt-3.5-turbo\":\"your gpt-3.5-turbo deployment name\",\n\t\u002F\u002F    }\n\t\u002F\u002F    return azureModelMapping[model]\n\t\u002F\u002F}\n\n\tinput := \"Text to vectorize\"\n\n\tclient := openai.NewClientWithConfig(config)\n\tresp, err := client.CreateEmbeddings(\n\t\tcontext.Background(),\n\t\topenai.EmbeddingRequest{\n\t\t\tInput: []string{input},\n\t\t\tModel: openai.AdaEmbeddingV2,\n\t\t})\n\n\tif err != nil {\n\t\tfmt.Printf(\"CreateEmbeddings error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tvectors := resp.Data[0].Embedding \u002F\u002F []float32 with 1536 dimensions\n\n\tfmt.Println(vectors[:10], \"...\", vectors[len(vectors)-10:])\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>JSON Schema for function calling\u003C\u002Fsummary>\n\nIt is now possible for chat completion to choose to call a function for more information ([see developer docs here](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Fgpt\u002Ffunction-calling)).\n\nIn order to describe the type of functions that can be called, a JSON schema must be provided. Many JSON schema libraries exist and are more advanced than what we can offer in this library, however we have included a simple `jsonschema` package for those who want to use this feature without formatting their own JSON schema payload.\n\nThe developer documents give this JSON schema definition as an example:\n\n```json\n{\n  \"name\":\"get_current_weather\",\n  \"description\":\"Get the current weather in a given location\",\n  \"parameters\":{\n    \"type\":\"object\",\n    \"properties\":{\n        \"location\":{\n          \"type\":\"string\",\n          \"description\":\"The city and state, e.g. San Francisco, CA\"\n        },\n        \"unit\":{\n          \"type\":\"string\",\n          \"enum\":[\n              \"celsius\",\n              \"fahrenheit\"\n          ]\n        }\n    },\n    \"required\":[\n        \"location\"\n    ]\n  }\n}\n```\n\nUsing the `jsonschema` package, this schema could be created using structs as such:\n\n```go\nFunctionDefinition{\n  Name: \"get_current_weather\",\n  Parameters: jsonschema.Definition{\n    Type: jsonschema.Object,\n    Properties: map[string]jsonschema.Definition{\n      \"location\": {\n        Type: jsonschema.String,\n        Description: \"The city and state, e.g. San Francisco, CA\",\n      },\n      \"unit\": {\n        Type: jsonschema.String,\n        Enum: []string{\"celsius\", \"fahrenheit\"},\n      },\n    },\n    Required: []string{\"location\"},\n  },\n}\n```\n\nThe `Parameters` field of a `FunctionDefinition` can accept either of the above styles, or even a nested struct from another library (as long as it can be marshalled into JSON).\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Error handling\u003C\u002Fsummary>\n\nOpen-AI maintains clear documentation on how to [handle API errors](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Ferror-codes\u002Fapi-errors)\n\nexample:\n```\ne := &openai.APIError{}\nif errors.As(err, &e) {\n  switch e.HTTPStatusCode {\n    case 401:\n      \u002F\u002F invalid auth or key (do not retry)\n    case 429:\n      \u002F\u002F rate limiting or engine overload (wait and retry) \n    case 500:\n      \u002F\u002F openai server error (retry)\n    default:\n      \u002F\u002F unhandled\n  }\n}\n\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Fine Tune Model\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com\u002Fsashabaranov\u002Fgo-openai\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\t\u002F\u002F create a .jsonl file with your training data for conversational model\n\t\u002F\u002F {\"prompt\": \"\u003Cprompt text>\", \"completion\": \"\u003Cideal generated text>\"}\n\t\u002F\u002F {\"prompt\": \"\u003Cprompt text>\", \"completion\": \"\u003Cideal generated text>\"}\n\t\u002F\u002F {\"prompt\": \"\u003Cprompt text>\", \"completion\": \"\u003Cideal generated text>\"}\n\n\t\u002F\u002F chat models are trained using the following file format:\n\t\u002F\u002F {\"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.\"}]}\n\t\u002F\u002F {\"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?\"}]}\n\t\u002F\u002F {\"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.\"}]}\n\n\t\u002F\u002F you can use openai cli tool to validate the data\n\t\u002F\u002F For more info - https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Ffine-tuning\n\n\tfile, err := client.CreateFile(ctx, openai.FileRequest{\n\t\tFilePath: \"training_prepared.jsonl\",\n\t\tPurpose:  \"fine-tune\",\n\t})\n\tif err != nil {\n\t\tfmt.Printf(\"Upload JSONL file error: %v\\n\", err)\n\t\treturn\n\t}\n\n\t\u002F\u002F create a fine tuning job\n\t\u002F\u002F 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)\n\t\u002F\u002F use below get method to know the status of your model\n\tfineTuningJob, err := client.CreateFineTuningJob(ctx, openai.FineTuningJobRequest{\n\t\tTrainingFile: file.ID,\n\t\tModel:        \"davinci-002\", \u002F\u002F gpt-3.5-turbo-0613, babbage-002.\n\t})\n\tif err != nil {\n\t\tfmt.Printf(\"Creating new fine tune model error: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfineTuningJob, err = client.RetrieveFineTuningJob(ctx, fineTuningJob.ID)\n\tif err != nil {\n\t\tfmt.Printf(\"Getting fine tune model error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(fineTuningJob.FineTunedModel)\n\n\t\u002F\u002F once the status of fineTuningJob is `succeeded`, you can use your fine tune model in Completion Request or Chat Completion Request\n\n\t\u002F\u002F resp, err := client.CreateCompletion(ctx, openai.CompletionRequest{\n\t\u002F\u002F\t Model:  fineTuningJob.FineTunedModel,\n\t\u002F\u002F\t Prompt: \"your prompt\",\n\t\u002F\u002F })\n\t\u002F\u002F if err != nil {\n\t\u002F\u002F\t fmt.Printf(\"Create completion error %v\\n\", err)\n\t\u002F\u002F\t return\n\t\u002F\u002F }\n\t\u002F\u002F\n\t\u002F\u002F fmt.Println(resp.Choices[0].Text)\n}\n```\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Structured Outputs\u003C\u002Fsummary>\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com\u002Fsashabaranov\u002Fgo-openai\"\n\t\"github.com\u002Fsashabaranov\u002Fgo-openai\u002Fjsonschema\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\"your token\")\n\tctx := context.Background()\n\n\ttype Result struct {\n\t\tSteps []struct {\n\t\t\tExplanation string `json:\"explanation\"`\n\t\t\tOutput      string `json:\"output\"`\n\t\t} `json:\"steps\"`\n\t\tFinalAnswer string `json:\"final_answer\"`\n\t}\n\tvar result Result\n\tschema, err := jsonschema.GenerateSchemaForType(result)\n\tif err != nil {\n\t\tlog.Fatalf(\"GenerateSchemaForType error: %v\", err)\n\t}\n\tresp, err := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{\n\t\tModel: openai.GPT4oMini,\n\t\tMessages: []openai.ChatCompletionMessage{\n\t\t\t{\n\t\t\t\tRole:    openai.ChatMessageRoleSystem,\n\t\t\t\tContent: \"You are a helpful math tutor. Guide the user through the solution step by step.\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tRole:    openai.ChatMessageRoleUser,\n\t\t\t\tContent: \"how can I solve 8x + 7 = -23\",\n\t\t\t},\n\t\t},\n\t\tResponseFormat: &openai.ChatCompletionResponseFormat{\n\t\t\tType: openai.ChatCompletionResponseFormatTypeJSONSchema,\n\t\t\tJSONSchema: &openai.ChatCompletionResponseFormatJSONSchema{\n\t\t\t\tName:   \"math_reasoning\",\n\t\t\t\tSchema: schema,\n\t\t\t\tStrict: true,\n\t\t\t},\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"CreateChatCompletion error: %v\", err)\n\t}\n\terr = schema.Unmarshal(resp.Choices[0].Message.Content, &result)\n\tif err != nil {\n\t\tlog.Fatalf(\"Unmarshal schema error: %v\", err)\n\t}\n\tfmt.Println(result)\n}\n```\n\u003C\u002Fdetails>\nSee the `examples\u002F` folder for more.\n\n## Frequently Asked Questions\n\n### Why don't we get the same answer when specifying a temperature field of 0 and asking the same question?\n\nEven when specifying a temperature field of 0, it doesn't guarantee that you'll always get the same response. Several factors come into play.\n\n1. Go OpenAI Behavior: When you specify a temperature field of 0 in Go OpenAI, the omitempty tag causes that field to be removed from the request. Consequently, the OpenAI API applies the default value of 1.\n2. Token Count for Input\u002FOutput: If there's a large number of tokens in the input and output, setting the temperature to 0 can still result in non-deterministic behavior. In particular, when using around 32k tokens, the likelihood of non-deterministic behavior becomes highest even with a temperature of 0.\n\nDue to the factors mentioned above, different answers may be returned even for the same question.\n\n**Workarounds:**\n1. As of November 2023, use [the new `seed` parameter](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Ftext-generation\u002Freproducible-outputs) in conjunction with the `system_fingerprint` response field, alongside Temperature management.\n2. Try using `math.SmallestNonzeroFloat32`: By specifying `math.SmallestNonzeroFloat32` in the temperature field instead of 0, you can mimic the behavior of setting it to 0.\n3. Limiting Token Count: By limiting the number of tokens in the input and output and especially avoiding large requests close to 32k tokens, you can reduce the risk of non-deterministic behavior.\n\nBy adopting these strategies, you can expect more consistent results.\n\n**Related Issues:**  \n[omitempty option of request struct will generate incorrect request when parameter is 0.](https:\u002F\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai\u002Fissues\u002F9)\n\n### Does Go OpenAI provide a method to count tokens?\n\nNo, Go OpenAI does not offer a feature to count tokens, and there are no plans to provide such a feature in the future. However, if there's a way to implement a token counting feature with zero dependencies, it might be possible to merge that feature into Go OpenAI. Otherwise, it would be more appropriate to implement it in a dedicated library or repository.\n\nFor counting tokens, you might find the following links helpful:  \n- [Counting Tokens For Chat API Calls](https:\u002F\u002Fgithub.com\u002Fpkoukk\u002Ftiktoken-go#counting-tokens-for-chat-api-calls)\n- [How to count tokens with tiktoken](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fopenai-cookbook\u002Fblob\u002Fmain\u002Fexamples\u002FHow_to_count_tokens_with_tiktoken.ipynb)\n\n**Related Issues:**  \n[Is it possible to join the implementation of GPT3 Tokenizer](https:\u002F\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai\u002Fissues\u002F62)\n\n## Contributing\n\nBy following [Contributing Guidelines](https:\u002F\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai\u002Fblob\u002Fmaster\u002FCONTRIBUTING.md), we hope to ensure that your contributions are made smoothly and efficiently.\n\n## Thank you\n\nWe want to take a moment to express our deepest gratitude to the [contributors](https:\u002F\u002Fgithub.com\u002Fsashabaranov\u002Fgo-openai\u002Fgraphs\u002Fcontributors) and sponsors of this project:\n- [Carson Kahn](https:\u002F\u002Fcarsonkahn.com) of [Spindle AI](https:\u002F\u002Fspindleai.com)\n\nTo all of you: thank you. You've helped us achieve more than we ever imagined possible. Can't wait to see where we go next, together!\n","sashabaranov\u002Fgo-openai 是一个为 Go 语言开发者提供的非官方 OpenAI API 客户端库，支持包括 ChatGPT、GPT-3、GPT-4、DALL·E 2、DALL·E 3 和 Whisper 在内的多种模型。其核心功能涵盖了文本生成、图像生成及语音转文字等，并且支持流式响应以实现更自然的对话体验。该项目采用了 Apache License 2.0 开源许可协议，适合需要在 Go 项目中集成先进人工智能能力的应用场景，如智能客服系统、内容自动生成工具或多媒体处理平台等。",2,"2026-06-11 03:02:11","top_language"]