Usiamo i cookie. Cookie e memoria del browser ti mantengono connesso e ricordano le tue preferenze. Con il tuo consenso misuriamo anche come viene usato il sito. Puoi in qualsiasi momento. Consulta la nostra cookie policy.

Go

Guide agli SDK

Go

Usa la libreria ufficiale openai-go con api14 in Go: configurazione, chat, streaming, strumenti, output strutturato, immagini, embeddings, errori e retry.

Usa la libreria ufficiale openai-go con api14. Punta option.WithBaseURL ad api14 e passa come modello qualsiasi id di modello (ad esempio openai/gpt-5-mini).

Installazione

go get github.com/openai/openai-go
export API14_API_KEY="sk-api14-..."

Configurazione

package main

import (
	"context"
	"fmt"
	"os"

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

var client = openai.NewClient(
	option.WithBaseURL("https://api14.com/api/v1/"),
	option.WithAPIKey(os.Getenv("API14_API_KEY")),
)

var ctx = context.Background()

// Gli snippet qui sotto vanno eseguiti dentro func main().

openai.NewClient() senza opzioni legge OPENAI_BASE_URL e OPENAI_API_KEY, quindi puoi configurarlo anche dall'ambiente:

export OPENAI_BASE_URL="https://api14.com/api/v1/"
export OPENAI_API_KEY="sk-api14-..."

Chat

resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
	Model: "openai/gpt-5-mini",
	Messages: []openai.ChatCompletionMessageParamUnion{
		openai.UserMessage("Explain vector databases in two sentences."),
	},
})
if err != nil {
	panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)

Streaming

stream := client.Chat.Completions.NewStreaming(ctx, openai.ChatCompletionNewParams{
	Model:    "anthropic/claude-sonnet-4.5",
	Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("Write a haiku about APIs.")},
})
for stream.Next() {
	chunk := stream.Current()
	if len(chunk.Choices) > 0 {
		fmt.Print(chunk.Choices[0].Delta.Content)
	}
}
if err := stream.Err(); err != nil {
	panic(err)
}

Vedi Streaming.

Tool calling

params := openai.ChatCompletionNewParams{
	Model:    "openai/gpt-5-mini",
	Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("What's the weather in Istanbul?")},
	Tools: []openai.ChatCompletionToolParam{{
		Function: openai.FunctionDefinitionParam{
			Name:        "get_weather",
			Description: openai.String("Current weather for a city"),
			Parameters: openai.FunctionParameters{
				"type":       "object",
				"properties": map[string]any{"city": map[string]string{"type": "string"}},
				"required":   []string{"city"},
			},
		},
	}},
}

for {
	resp, err := client.Chat.Completions.New(ctx, params)
	if err != nil {
		panic(err)
	}
	msg := resp.Choices[0].Message
	if len(msg.ToolCalls) == 0 {
		fmt.Println(msg.Content)
		break
	}
	params.Messages = append(params.Messages, msg.ToParam())
	for _, call := range msg.ToolCalls {
		var args struct{ City string }
		json.Unmarshal([]byte(call.Function.Arguments), &args)
		params.Messages = append(params.Messages, openai.ToolMessage(getWeather(args.City), call.ID))
	}
}

getWeather è la tua funzione che restituisce una stringa. Vedi Tool calling.

Output strutturato

schema := map[string]any{
	"type": "object",
	"properties": map[string]any{
		"name": map[string]string{"type": "string"},
		"born": map[string]string{"type": "integer"},
	},
	"required":             []string{"name", "born"},
	"additionalProperties": false,
}

resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
	Model:    "openai/gpt-5-mini",
	Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("Extract: Ada Lovelace, born 1815.")},
	ResponseFormat: openai.ChatCompletionNewParamsResponseFormatUnion{
		OfJSONSchema: &openai.ResponseFormatJSONSchemaParam{
			JSONSchema: openai.ResponseFormatJSONSchemaJSONSchemaParam{
				Name: "person", Schema: schema, Strict: openai.Bool(true),
			},
		},
	},
})

var person struct {
	Name string `json:"name"`
	Born int    `json:"born"`
}
_ = json.Unmarshal([]byte(resp.Choices[0].Message.Content), &person)

Vedi Output strutturati.

Input di immagini

resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
	Model: "google/gemini-2.5-flash",
	Messages: []openai.ChatCompletionMessageParamUnion{
		openai.UserMessage([]openai.ChatCompletionContentPartUnionParam{
			openai.TextContentPart("What is in this picture?"),
			openai.ImageContentPart(openai.ChatCompletionContentPartImageImageURLParam{
				URL: "https://example.com/photo.jpg", // oppure un URL data:image/png;base64,...
			}),
		}),
	},
})

Vedi Visione e file.

Parametri aggiuntivi

I campi per cui l'SDK non ha un tipo, reasoning, provider, models, si aggiungono con option.WithJSONSet:

resp, err := client.Chat.Completions.New(ctx, params,
	option.WithJSONSet("reasoning", map[string]any{"effort": "high"}),
	option.WithJSONSet("provider", map[string]any{"sort": "throughput"}),
)

Embeddings

emb, err := client.Embeddings.New(ctx, openai.EmbeddingNewParams{
	Model: "openai/text-embedding-3-small",
	Input: openai.EmbeddingNewParamsInputUnion{OfArrayOfStrings: []string{"The quick brown fox", "Lorem ipsum"}},
})
if err == nil {
	fmt.Println(len(emb.Data[0].Embedding))
}

Errori

Gli errori dell'API vengono restituiti come *openai.Error, che contiene lo stato HTTP, il Code leggibile da macchina e la risposta grezza:

import "errors"

var apiErr *openai.Error
if errors.As(err, &apiErr) {
	switch apiErr.StatusCode {
	case 402: // insufficient_balance
		fmt.Println("Balance too low, add funds:", apiErr.Code)
	case 429: // rate_limited o daily_limit_reached
		fmt.Println("Retry after", apiErr.Response.Header.Get("Retry-After"), "s:", apiErr.Code)
	}
}

Vedi Errori.

Timeout e retry

Per impostazione predefinita il client ripete due volte 408, 409, 429 e 5xx con backoff esponenziale. Imposta il numero di retry e un timeout per tentativo come opzioni del client o della richiesta, e limita l'intera chiamata con un context:

client := openai.NewClient(
	option.WithBaseURL("https://api14.com/api/v1/"),
	option.WithAPIKey(os.Getenv("API14_API_KEY")),
	option.WithMaxRetries(4),
	option.WithRequestTimeout(60*time.Second), // per tentativo
)

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) // tutti i tentativi
defer cancel()

Riprovare non serve con daily_limit_reached o insufficient_balance. Vedi Limiti di frequenza.

Tutte le funzionalità

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api14.com/api/v1",
  apiKey: process.env.API14_API_KEY,
});

const result = await client.chat.completions.create({
  "model": "openai/gpt-5-mini",
  "messages": [
    {
      "role": "user",
      "content": "Explain vector databases in two sentences."
    }
  ]
});
console.log(result.choices[0].message.content);