0%

Go SDK 接入教程

github.com/AceDataCloud/SDK/go 是 Ace Data Cloud 官方 Go SDK,把 api.acedata.cloud 上的 chat completions / images / video / music / search 封装成 client.OpenAI().Chat().Completions().Create(...) 风格的方法链,自带 SSE 流式(基于 channel)、自动重试退避和类型化错误。

风格上对齐 context.Context + functional options,适合放进任何 Go 后端服务或 CLI。

源码与文档:

安装

1
go get github.com/AceDataCloud/SDK/go

干净 Go 模块的版本检查输出:

1
2
$ go list -m github.com/AceDataCloud/SDK/go
github.com/AceDataCloud/SDK/go v0.0.0-20260505072132-4a3d921f9bb4

结果说明:

  • 当前没有打 semver 标签,go get 拉到的是 commit 伪版本 v0.0.0-<timestamp>-<sha>;这个版本会被锁进 go.sum,团队成员拉同一份代码可以拿到完全一致的依赖。
  • Go SDK 目前以 chat.completions(同步 + 流式)为主路径稳定,多媒体资源(images / video / audio)和 TaskHandle 轮询处于 alpha 阶段。需要这些能力的场景请优先选 TypeScript SDKPython SDK

准备 API Token

参考 SDK 总览 - 申请 API Token 取到 token,然后在 shell 里 export

1
export ACEDATACLOUD_API_TOKEN={token}

构造客户端时通过 WithAPIToken(...) option 显式注入;Go SDK 不会自动读取环境变量,需要业务代码 os.Getenv 一下,这样在多账号或自测场景里更可控。

示例 1:chat.completions(非流式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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": "Reply with exactly: 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"])
}

程序运行结果:

1
2
3
4
5
elapsed_ms 6436
id chatcmpl-89DHExvFvBc4ciIPfolZYUOy7ivxv
model gpt-4o-mini
content ADC_GO_SDK_OK
usage prompt=16 completion=5 total=21

结果说明:

  • id 是 OpenAI 兼容响应 ID,可以在控制台 使用历史 里搜到。
  • content ADC_GO_SDK_OK 是模型真实输出,证明 SDK 没有篡改响应。
  • 6.4 秒里大部分是首次 TLS 握手 + 上游模型生成,复用 client 实例之后延迟和 TS / Python 一致(约 2~3 秒)。
  • 响应统一是 map[string]any,需要自己做类型断言;这是 Go SDK 当前的设计取舍——不引入泛型 struct 是为了让多模型路由不强依赖单一上游 schema。

示例 2:chat.completions(SSE 流式)

CreateStream 返回两个 channel:<-chan map[string]any 是逐帧解析好的 SSE chunk,<-chan error 在流结束(正常或出错)后才会有可读元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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": "Count from 1 to 5 separated by spaces. Just the numbers."}},
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)
}

程序运行结果:

1
2
3
4
total_elapsed_ms 1816
first_chunk_ms 1633
chunks 13
collected 1 2 3 4 5

结果说明:

  • 首帧 1633 ms,13 个 chunk 全部到齐用了 1816 ms——后 12 帧只用了 183 ms。
  • range chunks 自然会在流结束时退出循环;errs channel 始终最多 yield 一个元素,配 ok 判断即可拿到错误。
  • 这套 channel 风格的好处是可以直接 select 配合 context.Context 超时/取消,不需要额外封装。

示例 3:类型化错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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": "hi"}},
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("other err:", err)
}
}
}

adc.APIError 同时覆盖 401 / 403 / 404 / 422 / 429 / 5xx,业务代码用 errors.As 取到结构化字段即可。HTTP 状态码、上游 codemessage 都保留原样。网络层错误(DNS 失败、连接被拒等)走 context.DeadlineExceedednet.OpError 等标准 Go 错误,不会被吞掉。

配置选项(functional options)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
client, err := adc.NewClient(
// 必填:API token;建议从环境变量读
adc.WithAPIToken(os.Getenv("ACEDATACLOUD_API_TOKEN")),

// 平台 API 根地址,默认 https://api.acedata.cloud
adc.WithBaseURL("https://api.acedata.cloud"),

// 单次请求超时,默认 5 分钟
adc.WithTimeout(60*time.Second),

// 自动重试次数,默认 2
adc.WithMaxRetries(2),

// 自定义请求头
adc.WithHeader("x-app", "my-service/1.0"),
)

NewClient 返回 (*Client, error):当 token 为空 没有传 WithPaymentHandler(X402)时会立即报错,便于在服务启动期就发现配置缺失。

进阶:复用 Client

Go SDK 内部用一个 *http.Client + http.Transport,自带连接池和 HTTP/2 复用。推荐在进程生命周期内只建一个 *adc.Client,然后跨 goroutine 共享——所有方法都是并发安全的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 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
}

局限和路线图

当前稳定 / 推荐生产使用:

  • client.OpenAI().Chat().Completions().Create 同步非流式
  • client.OpenAI().Chat().Completions().CreateStream SSE 流式
  • errors.As + APIError 错误处理
  • ✅ 自动重试 + 指数退避

仍处于 alpha:

  • 🚧 client.Images() / client.Video() / client.Audio() — 接口在演进中,建议先用 HTTP 直接调
  • 🚧 TaskHandle 异步轮询 — 还没暴露到 Go SDK 表层
  • 🚧 WithPaymentHandler(X402 链上付费)— 计划中,目前 X402 只支持 TypeScriptPython

如何查看剩余额度

通过 Ace Data Cloud 控制台 - 应用列表,即可查看当前账户的剩余额度。

通过 Ace Data Cloud 控制台 - 使用历史 即可查看所有使用历史和扣费详情。

了解更多