メインコンテンツまでスキップ

後端 SDK 使用指南

後端 SDK 是讓你的伺服器以可信端的角色與 Asgard Bot Provider 溝通的工具, 是 Backend Relay 模式的核心。本指南介紹後端語言 SDK 用法、以及後端中繼層的整體實作範式。

完成模式選型再閱讀

本頁專為採用 Backend Relay 模式的讀者撰寫 — 也就是「你的後端作為前端與 Asgard Edge Server 之間中繼層」的情境。其他 Pattern(Direct Connect / Workflow Auth / Hosted Embed)不需要後端 SDK。

如果你對 Pattern 還不熟悉, 請先閱讀 總覽與選型, 確認確實需要 Backend Relay 再回到本頁。

後端 SDK 是什麼

當你採用 Backend Relay 模式時,你的後端會成為前端與 Asgard Edge Server 之間的中繼層, 流程簡化如下:

後端 SDK 就是上方藍色節點 ③④ 用來與 Edge Server 溝通的工具(其餘步驟由你的後端自行實作)。完整流程的時序圖見 Pattern: Backend Relay — 架構圖


語言支援現況

語言套件狀態
Gogo.asgard-ai.com/asgard-sdk-go✅ 可用
Node.js@asgard-js/nodejs✅ 可用
Java後端 Java SDK🔜 規劃中
.NET後端 .NET SDK🔜 規劃中
Python後端 Python SDK🔜 規劃中

若你使用的語言尚未有原生 SDK, 可以直接呼叫 Bot Provider 的 HTTP API(本質是 SSE / REST / Multipart 等標準協定)。請參考 Send Message API 介紹 取得完整的 endpoint、事件型別與 payload schema。

後端 Node.js SDK ≠ 前端 Javascript SDK

Asgard 的「後端 Node.js SDK」(@asgard-js/nodejs)是跑在你的伺服器(例如 Express / Fastify / Next.js Route Handler 的伺服器側), 用途是中繼前端到 Asgard。

這跟「前端 Javascript SDK」(@asgard-js/core / @asgard-js/react)完全不同。前端 SDK 跑在使用者瀏覽器中, 用途是渲染聊天 UI 與直連 Asgard 或你的後端。

兩者套件名稱、執行位置、用途都不同, 使用時請確認上下文。詳見 前端 SDK 使用指南


SDK 完整指南

安裝

go get go.asgard-ai.com/asgard-sdk-go

建立 Bot Provider Client

Bot Provider client 是與單一 Bot Provider 互動的入口, 提供 streaming、訊息發送、檔案上傳、自訂工具觸發等能力。

整個後端服務共用同一份 client 即可(client 設計為執行緒/併發安全), 無需每次請求都重建。Bot Provider API Key 從環境變數 / secrets manager 讀取, 絕對不要 hardcode 進程式碼

import (
"os"

"go.asgard-ai.com/asgard-sdk-go/pkg/client"
)

// 從環境變數讀取設定,請勿 hardcode 機敏資訊到程式碼
var (
edgeServerHost = getEnvOrDefault("EDGE_SERVER_HOST", "https://api.asgard-ai.com")
namespace = os.Getenv("NAMESPACE")
botProviderName = os.Getenv("BOT_PROVIDER_NAME")
botProviderApiKey = os.Getenv("BOT_PROVIDER_API_KEY") // 從 secrets manager 注入
)

func getEnvOrDefault(key, defaultVal string) string {
if v := os.Getenv(key); v != "" {
return v
}
return defaultVal
}

// 建立 Bot Provider Client(整個後端共用一份即可)
bpClient := client.NewBotProviderClientWithConfig(&client.BotProviderConfig{
EdgeServerHost: edgeServerHost,
Namespace: namespace,
BotProviderName: botProviderName,
BotProviderApiKey: botProviderApiKey,
})

SSE 串流

NewStreamer 對單則訊息建立 SSE 串流, 逐一接收事件, 使用結束務必 Close。事件型別與 payload schema 見 Send Message API 介紹

import "go.asgard-ai.com/asgard-sdk-go/pkg/models"

// 組裝送往 Edge Server 的訊息
msg := &models.GenericBotMessage{
CustomChannelId: "channel-abc-123", // 對話識別,後續同 channel 訊息會串成一個 Conversation
CustomMessageId: "msg-001", // 訊息識別,用於去重 / idempotency
Text: "Hello",
Action: models.PostBackActionNone,
Payload: map[string]interface{}{ // 任意 JSON-serializable 資料,Workflow 內可透過 prevPayload.* 讀取
"user_id": "user-456",
},
}

// 建立串流(第三個參數可傳 options,通常 nil 即可)
stream, err := bpClient.NewStreamer(ctx, msg, nil)
if err != nil { /* ... */ }
defer stream.Close() // 必須關閉,避免連線洩漏

// 逐一處理事件。Next() 在串流結束或 ctx 取消時回傳 false
// 注意:asgard.run.error 不會走進 switch,而是讓 Next() 直接回 false;
// 發生錯誤時跳出迴圈後,從 stream.Err() 取得錯誤詳情
for stream.Next() {
event := stream.Current()
switch event.EventType {
case models.SseEventTypeRunInit: // Workflow 開始
case models.SseEventTypeMessageDelta: // AI 逐字回應
case models.SseEventTypeMessageComplete: // AI 一則訊息完成
case models.SseEventTypeToolCallComplete: // 工具呼叫完成
case models.SseEventTypeCompletionModelUsage: // LLM 用量
case models.SseEventTypeRunDone: // Workflow 結束
}
}

// 迴圈結束務必檢查 error,避免上游錯誤被吞掉
if err := stream.Err(); err != nil { /* ... */ }

把 SSE 串流接到 HTTP handler、轉發給前端、攔截事件做 side effects(寫 history、扣點、Human Handoff…)等完整 use case 整合範例, 見 Pattern: Backend Relay — 快速起步

檔案上傳

UploadBlob 把檔案串流上傳到 Edge Server, 回傳含 blobId 的物件; 後續可將 blobId 放入 GenericBotMessage 的 blob 欄位讓 Bot 看到該檔案。

// 參數:ctx、channelId、檔案 reader、filename、MIME type 指標(nil 代表讓 Edge Server 自行偵測)
blob, err := bpClient.UploadBlob(ctx, channelId, fileReader, "filename.png", &mime)
if err != nil { /* ... */ }

// 取得 blob.BlobId 後,可放入後續訊息的 blob 欄位引用

把 HTTP multipart/form-data 解析後接到此 API 的完整 endpoint 範例, 見 Pattern: Backend Relay — 快速起步

單發訊息(非串流)

SendMessage 同步等待 Workflow 跑完最終結果再回傳, 適合非面對使用者的場景(批次任務、server-side 排程):

// 注意:LLM 回應可能耗時數十秒,呼叫端要設好足夠的 timeout
resp, err := bpClient.SendMessage(ctx, msg, nil)
// resp 等同於 SSE 串流跑完後的彙整結果

自訂 HTTP Client

Bot Provider client 可自訂底層 HTTP 連線(用於分散式追蹤、metrics、retry policy 等), 把客製化的 HTTP client 實例傳進建構設定即可:

import (
"net/http"
"time"

"go.asgard-ai.com/asgard-sdk-go/pkg/client"
)

httpClient := &http.Client{
Transport: yourCustomTransport, // 例如 otelhttp.NewTransport(...) 加上 OpenTelemetry tracing
Timeout: 30 * time.Second, // 注意:SSE 是長連線,Timeout 不可設太短
}

bpClient := client.NewBotProviderClientWithConfig(&client.BotProviderConfig{
HTTPClient: httpClient,
EdgeServerHost: edgeServerHost,
Namespace: namespace,
BotProviderName: botProviderName,
BotProviderApiKey: botProviderApiKey,
})

安全與部署注意事項

1. API Key 安全保管

  • Bot Provider API Key 放在 secrets manager(AWS Secrets Manager / Vault / GCP Secret Manager)
  • 絕對不要 寫死在程式碼或 commit 到版本控制
  • 環境變數注入時也要避免在 Docker image / log 暴露

2. SSE 雙向長連線基礎設施

  • 避免緩衝: 某些 API Gateway / CDN 預設會緩衝回應, 要明確關閉(X-Accel-Buffering: no for nginx)
  • 連線數: 預估同時上線使用者數量, 設定足夠的 file descriptor 上限與 Worker 數
  • Idle Timeout: Load Balancer 的 timeout 要長於對話可能的閒置時間, 或實作 keepalive ping

3. 客戶端斷線清理

當使用者關閉頁面、切換頁籤、網路中斷, 你的後端應監聽請求層級的取消訊號(例如 request context / cancellation token / abort signal), 把它傳給 NewStreamer 並在偵測到取消時呼叫 stream.Close(), 避免上游 LLM 還在燒 token 但已無人接收。實作範例見 Pattern: Backend Relay — 快速起步

4. 重試與冪等性

  • 重試建立 SSE 串流時要考慮 customMessageId 是否重複, 避免重複處理同一事件
  • side effects(扣點、寫 history)需設計冪等, 使用 customMessageId 或 SSE event ID 作為去重 key

延伸閱讀