> ## Documentation Index
> Fetch the complete documentation index at: https://docs.acedata.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Guida all'integrazione del SDK Go

> Platform API guide - Ace Data Cloud

[`github.com/AceDataCloud/SDK/go`](https://pkg.go.dev/github.com/AceDataCloud/SDK/go) è l'SDK Go ufficiale di Ace Data Cloud, che incapsula le chat completions / immagini / video / musica / ricerca su `api.acedata.cloud` in una catena di metodi in stile `client.OpenAI().Chat().Completions().Create(...)`, con flusso SSE (basato su channel), ripetizione automatica con backoff e errori tipizzati.

Stile allineato a `context.Context` + opzioni funzionali, adatto per qualsiasi servizio backend Go o CLI.

Codice sorgente e documentazione:

* Repository SDK: [https://github.com/AceDataCloud/SDK](https://github.com/AceDataCloud/SDK)
* Modulo Go: [https://pkg.go.dev/github.com/AceDataCloud/SDK/go](https://pkg.go.dev/github.com/AceDataCloud/SDK/go)

## Installazione

```bash theme={null}
go get github.com/AceDataCloud/SDK/go
```

Output della verifica della versione del modulo Go pulito:

```text theme={null}
$ go list -m github.com/AceDataCloud/SDK/go
github.com/AceDataCloud/SDK/go v0.0.0-20260505072132-4a3d921f9bb4
```

Spiegazione dei risultati:

* Attualmente non è stato etichettato alcun semver, `go get` recupera la versione fittizia del commit `v0.0.0-<timestamp>-<sha>`; questa versione sarà bloccata in `go.sum`, i membri del team che recuperano lo stesso codice possono ottenere dipendenze completamente coerenti.
* L'SDK Go attualmente si concentra su `chat.completions` (sincrono + in streaming) come percorso principale stabile, le risorse multimediali (`images` / `video` / `audio`) e il polling di `TaskHandle` sono in fase alpha. Per scenari che richiedono queste capacità, si prega di scegliere prima [TypeScript SDK](https://platform.acedata.cloud/documents/sdk-typescript) o [Python SDK](https://platform.acedata.cloud/documents/sdk-python).

## Preparare il Token API

Fare riferimento a [Panoramica SDK - Richiesta Token API](https://platform.acedata.cloud/documents/acedatacloud-sdk#申请-api-token) per ottenere il token, quindi in shell `export`:

```bash theme={null}
export ACEDATACLOUD_API_TOKEN={token}
```

Durante la costruzione del client, iniettare esplicitamente tramite l'opzione `WithAPIToken(...)`; l'SDK Go non leggerà automaticamente le variabili d'ambiente, è necessario che il codice aziendale utilizzi `os.Getenv`, in modo che in scenari con più account o di auto-test sia più controllabile.

## Esempio 1: chat.completions (non in streaming)

```go theme={null}
package main

import (
    "context"
    "fmt"
    "os"
    "time"

    adc "github.com/AceDataCloud/SDK/go"
)

func main() {
    client, err := adc.NewClient(adc.WithAPIToken(os.Getenv("ACEDATACLOUD_API_TOKEN")))
    if err != nil {
        panic(err)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    defer cancel()

    t0 := time.Now()
    res, err := client.OpenAI().Chat().Completions().Create(ctx, adc.ChatCompletionRequest{
        Model:     "gpt-4o-mini",
        Messages:  []map[string]any{{"role": "user", "content": "Rispondi esattamente: ADC_GO_SDK_OK"}},
        MaxTokens: 20,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("elapsed_ms", time.Since(t0).Milliseconds())
    fmt.Println("id", res["id"])
    fmt.Println("model", res["model"])
    choices := res["choices"].([]any)
    msg := choices[0].(map[string]any)["message"].(map[string]any)
    fmt.Println("content", msg["content"])
    usage := res["usage"].(map[string]any)
    fmt.Printf("usage prompt=%v completion=%v total=%v\n",
        usage["prompt_tokens"], usage["completion_tokens"], usage["total_tokens"])
}
```

Risultato dell'esecuzione del programma:

```text theme={null}
elapsed_ms 6436
id chatcmpl-89DHExvFvBc4ciIPfolZYUOy7ivxv
model gpt-4o-mini
content ADC_GO_SDK_OK
usage prompt=16 completion=5 total=21
```

Spiegazione dei risultati:

* `id` è l'ID di risposta compatibile con OpenAI, che può essere trovato nella console [storico utilizzi](https://platform.acedata.cloud/console/usages).
* `content ADC_GO_SDK_OK` è l'output reale del modello, che dimostra che l'SDK non ha alterato la risposta.
* La maggior parte dei 6,4 secondi è stata impiegata per il primo handshake TLS + generazione del modello, dopo il riutilizzo dell'istanza client, la latenza è coerente con TS / Python (circa 2\~3 secondi).
* La risposta è uniformemente un `map[string]any`, è necessario effettuare l'asserzione di tipo; questa è la scelta di design attuale dell'SDK Go: non introdurre struct generici per evitare una forte dipendenza da uno schema di risposta unico per il routing di più modelli.

## Esempio 2: chat.completions (streaming SSE)

`CreateStream` restituisce due channel: `&lt;-chan map[string]any` è il chunk SSE analizzato frame per frame, `&lt;-chan error` avrà elementi leggibili solo dopo la fine del flusso (normalmente o per errore).

```go theme={null}
package main

import (
    "context"
    "fmt"
    "os"
    "time"

    adc "github.com/AceDataCloud/SDK/go"
)

func main() {
    client, err := adc.NewClient(adc.WithAPIToken(os.Getenv("ACEDATACLOUD_API_TOKEN")))
    if err != nil {
        panic(err)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    defer cancel()

    t0 := time.Now()
    chunks, errs := client.OpenAI().Chat().Completions().CreateStream(ctx, adc.ChatCompletionRequest{
        Model:     "gpt-4o-mini",
        Messages:  []map[string]any{{"role": "user", "content": "Conta da 1 a 5 separati da spazi. Solo i numeri."}},
        MaxTokens: 30,
    })

    first := int64(-1)
    cnt := 0
    collected := ""
    for chunk := range chunks {
        if first < 0 {
            first = time.Since(t0).Milliseconds()
        }
        cnt++
        if ch, ok := chunk["choices"].([]any); ok && len(ch) > 0 {
            if c0, ok := ch[0].(map[string]any); ok {
                if d, ok := c0["delta"].(map[string]any); ok {
                    if s, ok := d["content"].(string); ok {
                        collected += s
                    }
                }
            }
        }
    }
    if e, ok := <-errs; ok && e != nil {
        fmt.Println("stream_err", e)
    }
    fmt.Println("total_elapsed_ms", time.Since(t0).Milliseconds())
    fmt.Println("first_chunk_ms", first)
    fmt.Println("chunks", cnt)
    fmt.Println("collected", collected)
}
```

Risultato dell'esecuzione del programma:

```text theme={null}
total_elapsed_ms 1816
first_chunk_ms 1633
chunks 13
collected 1 2 3 4 5
```

Spiegazione dei risultati:

* Il primo frame ha impiegato 1633 ms, tutti i 13 chunk sono stati ricevuti in 1816 ms—gli ultimi 12 frame hanno impiegato solo 183 ms.
* `range chunks` uscirà naturalmente dal ciclo alla fine del flusso; il channel `errs` restituirà al massimo un elemento, è sufficiente utilizzare `ok` per ottenere l'errore.
* Il vantaggio di questo stile basato su channel è che può essere direttamente utilizzato con `select` insieme a `context.Context` per timeout/cancellazione, senza necessità di ulteriori incapsulamenti.

## Esempio 3: gestione degli errori tipizzati

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"

    adc "github.com/AceDataCloud/SDK/go"
)

func main() {
    bad, _ := adc.NewClient(adc.WithAPIToken("definitely-not-a-real-token"))
    _, err := bad.OpenAI().Chat().Completions().Create(context.Background(), adc.ChatCompletionRequest{
        Model:    "gpt-4o-mini",
        Messages: []map[string]any{{"role": "user", "content": "ciao"}},
        MaxTokens: 5,
    })
    if err != nil {
        var apiErr *adc.APIError
        if errors.As(err, &apiErr) {
            fmt.Println("status:", apiErr.StatusCode)
            fmt.Println("code:", apiErr.Code)
            fmt.Println("message:", apiErr.Message)
        } else {
            fmt.Println("altro erro:", err)
        }
    }
}
```

`adc.APIError` copre 401 / 403 / 404 / 422 / 429 / 5xx, il codice aziendale utilizza `errors.As` per ottenere i campi strutturati. I codici di stato HTTP, il `code` e il `message` del server rimangono invariati. Gli errori di rete (fallimento DNS, connessione rifiutata, ecc.) seguono errori standard di Go come `context.DeadlineExceeded`, `net.OpError`, ecc., e non vengono ignorati.

## Opzioni di configurazione (opzioni funzionali)

```go theme={null}
client, err := adc.NewClient(
    // Obbligatorio: token API; si consiglia di leggerlo dalle variabili d'ambiente
    adc.WithAPIToken(os.Getenv("ACEDATACLOUD_API_TOKEN")),

    // Indirizzo base dell'API della piattaforma, predefinito https://api.acedata.cloud
    adc.WithBaseURL("https://api.acedata.cloud"),

    // Timeout per richiesta singola, predefinito 5 minuti
    adc.WithTimeout(60*time.Second),

    // Numero massimo di tentativi automatici, predefinito 2
    adc.WithMaxRetries(2),

    // Intestazioni di richiesta personalizzate
    adc.WithHeader("x-app", "my-service/1.0"),
)
```

`NewClient` restituisce `(*Client, error)`: quando il token è vuoto **e** non è stato passato `WithPaymentHandler` (X402), genera immediatamente un errore, utile per scoprire la mancanza di configurazione durante l'avvio del servizio.

## Avanzato: riutilizzo del Client

Il Go SDK utilizza internamente un `*http.Client` + `http.Transport`, con pool di connessione e riutilizzo HTTP/2. **Si consiglia di creare solo un `*adc.Client` durante il ciclo di vita del processo** e poi condividerlo tra le goroutine: tutti i metodi sono thread-safe.

```go theme={null}
// pkg/acelearn/client.go
var sharedClient *adc.Client

func init() {
    var err error
    sharedClient, err = adc.NewClient(adc.WithAPIToken(os.Getenv("ACEDATACLOUD_API_TOKEN")))
    if err != nil {
        log.Fatal(err)
    }
}

func Chat(ctx context.Context, model, prompt string) (string, error) {
    res, err := sharedClient.OpenAI().Chat().Completions().Create(ctx, adc.ChatCompletionRequest{
        Model:    model,
        Messages: []map[string]any{{"role": "user", "content": prompt}},
    })
    if err != nil {
        return "", err
    }
    return res["choices"].([]any)[0].(map[string]any)["message"].(map[string]any)["content"].(string), nil
}
```

## Limitazioni e roadmap

Attualmente stabile / raccomandato per uso in produzione:

* ✅ `client.OpenAI().Chat().Completions().Create` sincrono non streaming
* ✅ `client.OpenAI().Chat().Completions().CreateStream` streaming SSE
* ✅ `errors.As` + gestione degli errori `APIError`
* ✅ tentativi automatici + backoff esponenziale

Ancora in alpha:

* 🚧 `client.Images()` / `client.Video()` / `client.Audio()` — le interfacce sono in evoluzione, si consiglia di utilizzare direttamente HTTP
* 🚧 `TaskHandle` polling asincrono — non è ancora esposto nella superficie del Go SDK
* 🚧 `WithPaymentHandler` (X402 pagamento on-chain) — in programma, attualmente X402 supporta solo [TypeScript](https://platform.acedata.cloud/documents/x402-typescript-sdk) e [Python](https://platform.acedata.cloud/documents/x402-python-sdk)

## Come controllare il saldo rimanente

Attraverso [Ace Data Cloud Console - Elenco applicazioni](https://platform.acedata.cloud/console/applications), è possibile visualizzare il saldo rimanente attuale dell'account.

Attraverso [Ace Data Cloud Console - Storico utilizzo](https://platform.acedata.cloud/console/usages) è possibile visualizzare tutta la cronologia degli utilizzi e i dettagli delle spese.

## Scopri di più

* 🟦 [`github.com/AceDataCloud/SDK/go` su pkg.go.dev](https://pkg.go.dev/github.com/AceDataCloud/SDK/go)
* 🗂 [Codice sorgente SDK](https://github.com/AceDataCloud/SDK/tree/main/go)
* 📘 [Guida all'integrazione del SDK TypeScript](https://platform.acedata.cloud/documents/sdk-typescript)
* 🐍 [Guida all'integrazione del SDK Python](https://platform.acedata.cloud/documents/sdk-python)
* 🔌 [SDK + hook di pagamento X402](https://platform.acedata.cloud/documents/sdk-x402-payment)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.