Server-side Go SDK

更新时间:
复制 MD 格式

This document describes how to use the server-side Go SDK for the multimodal real-time interaction service from Alibaba Cloud Model Studio (Bailian). It covers SDK installation, key APIs, and code examples.

Multimodal real-time interaction architecture

多模态实时交互服务接入架构-通用-流程图

Prerequisites

Activate the service and obtain the required parameters.

Enable an Alibaba Cloud Model Studio real-time multimodal interaction application to get your workspace ID, app ID, and API key.

Dependencies

Runtime environment: Go 1.18 or later.

Installation: This SDK is integrated from source code. Download the multimodal-go-sdk and follow the instructions to integrate it. For a complete example, see the examples directory in the package.

Audio formats

The Go SDK uses the WebSocket protocol for data transmission.

  • Audio formats for WebSocket connections:

    • Upstream: Supports PCM (16 kHz sample rate, 16-bit, single-channel) and Opus audio streams.

    • Downstream: Supports PCM and MP3 audio streams.

Client call modes

Item

push2talk

tap2talk

duplex

Type

Client-controlled mode

Tap mode

duplex mode

Audio Upload Method

On-demand

Continuous

An error occurs if no audio is uploaded for over 20 seconds in the Listening state.

Continuous

An error occurs if no audio is uploaded for over 20 seconds in any state.

VAD Detector

Client

Server

Server

Interruption Method

Interrupted by a RequestToSpeak message

Interrupted by a RequestToSpeak message

Voice interruption

Use Cases

The user controls when the client starts and stops sending audio for recognition. This mode is suitable for push-to-talk scenarios where the user presses a button to speak and releases it to stop.

The client continuously uploads audio, and the server automatically detects speech activity. User voice cannot interrupt the model's output. An interruption requires sending a RequestToSpeak message.

The client continuously uploads audio, and the server automatically detects speech activity. The user can interrupt the model's output by speaking at any time.

API reference

dashscope.MultiModalDialog

Client requests (Client → Server)

The main class for managing dialogs. It provides all methods for server interaction.

1. NewMultiModalDialog

Creates an interactive session and sets up callbacks.

// Creates a voice dialog session.
//
// This method initializes a new session and sets the necessary parameters
// to prepare for interaction with the model.
//
// Parameters:
//   - requestParams: The collection of request parameters.
//   - multimodalCallback: The callback object for handling messages from the server.
//   - appID: The application ID created in the console.
//   - workspaceID: The customer's Workspace ID (optional).
//   - url: The API URL (optional, defaults to wss://dashscope.aliyuncs.com/api-ws/v1/inference).
//   - apiKey: The unique key for application access.
//   - dialogID: The dialog ID. If provided, the conversation continues from the specified context (optional).
//   - model: The model to use (optional).
func NewMultiModalDialog(
    requestParams *RequestParameters,
    multimodalCallback MultiModalCallback,
    appID string,
    workspaceID string,
    url string,
    apiKey string,
    dialogID string,
    model string,
) (*MultiModalDialog, error)

2. Start

Starts the dialog service and triggers the OnStarted callback. Note that the OnStarted callback returns a dialogID.

// Initializes the WebSocket connection and sends a start request.
//
// Parameters:
//   - dialogID: Identifies a specific dialog session. Pass an empty string for a new dialog.
func (d *MultiModalDialog) Start(dialogID string) error

3. StartSpeech

Notifies the server to start audio upload. This method can only be called when the state is LISTENING.

// Starts uploading speech data.
func (d *MultiModalDialog) StartSpeech() error

4. SendAudioData

Sends speech data.

// Sends speech data.
//
// Parameters:
//   - speechData: The binary speech data.
func (d *MultiModalDialog) SendAudioData(speechData []byte) error

5. StopSpeech

Notifies the server to stop audio upload.

// Stops uploading speech data.
func (d *MultiModalDialog) StopSpeech() error

6. Interrupt

Notifies the server to interrupt the current interaction and let the client speak.

// Requests the server to let the client start speaking (interrupt).
func (d *MultiModalDialog) Interrupt() error

7. LocalRespondingStarted

Notifies the server that the client has started playing TTS audio.

// Notifies that local TTS playback has started.
func (d *MultiModalDialog) LocalRespondingStarted() error

8. LocalRespondingEnded

Notifies the server that the client has finished playing TTS audio.

// Notifies that local TTS playback has ended.
func (d *MultiModalDialog) LocalRespondingEnded() error

9. Stop

Ends the current conversation turn.

// Stops the dialog.
func (d *MultiModalDialog) Stop() error

10. GetDialogState

Gets the current dialog service state. Returns a DialogState enum.

// Gets the dialog state.
//
// Returns:
//   - DialogState: The current dialog state (Idle / Listening / Thinking / Responding).
func (d *MultiModalDialog) GetDialogState() DialogState

11. RequestToRespond

Requests the server to directly synthesize speech from text or sends a command to the server.

// Requests the server to synthesize speech from text or execute a command.
//
// Parameters:
//   - requestType: The request type ("prompt" or "transcript").
//   - text: The request text.
//   - parameters: Additional parameters, such as images (optional).
//   - interruptible: Specifies whether the response can be interrupted.
func (d *MultiModalDialog) RequestToRespond(
    requestType string,
    text string,
    parameters *RequestToRespondParameters,
    interruptible bool,
) error

Request parameters

RequestParameters

Parameter

Type

Description

Upstream

*Upstream

Upstream parameters

Downstream

*Downstream

Downstream parameters

ClientInfo

*ClientInfo

Client information

BizParams

*BizParams

Business parameters (optional)

Upstream

Parameter

Type

Required

Description

AudioFormat

string

No

The audio format. Supported values are pcm and raw-opus. The default is pcm.

Type

string

Yes

Upstream type:

AudioOnly: Audio-only call

AudioAndVideo: Audio and video call

Mode

string

No

The mode used by the client. The default is tap2talk.

Options:

  • push2talk: Client-controlled mode.

  • tap2talk: Tap mode.

  • duplex: duplex mode.

PassThroughParams

map

No

For passing through additional parameters.

Downstream

Parameter

Type

Required

Description

Voice

string

No

The timbre of the synthesized speech. The available range depends on the TTS model selected in the console.

SampleRate

int

No

The sample rate of the synthesized voice. Supported values:

  • 8000

  • 16000

  • 24000

  • 48000

The default is 24000.

The Qianwen-TTS and Qianwen3-TTS models support only 24000.

IntermediateText

string

No

Controls which intermediate text results are returned:

  • transcript: Returns user speech recognition results.

  • dialog: Returns intermediate dialog system results.

You can set multiple types, separated by commas. The default is transcript.

AudioFormat

string

No

The audio format. Supported values are pcm, opus, mp3, and raw-opus. The default is pcm.

Qianwen-TTS models support only pcm.

Note: The difference between opus and raw-opus is that each packet in the opus format has an additional Ogg encapsulation (RFC 7845).

Volume

int

No

The volume of the synthesized audio. Range: 0–100. Default: 50.

PitchRate

int

No

The pitch of the synthesized audio. Range: 50–200. Default: 100.

SpeechRate

int

No

The speech rate of the synthesized audio. Range: 50–200, representing 50% to 200% of the default rate. Default: 100.

PassThroughParams

map

No

For passing through additional parameters.

ClientInfo

Parameter

Sub-parameter

Type

Required

Description

UserID

string

Yes

The end-user ID, generated according to your business rules. It is used to implement customized features for different end users. Max length: 36 characters.

Device

uuid

string

No

A globally unique client ID that you must generate and pass to the SDK. Max length: 40 characters. A single end user can have multiple devices, each with a different UUID but the same UserID.

network

ip

string

No

The caller's public IP address.

Location

CityName

string

No

The city where the caller is located. Specifies the approximate location of the client.

Latitude

string

No

The caller's latitude. Submit this for services that require the client's precise location.

Longitude

string

No

The caller's longitude. Submit this for services that require the client's precise location.

BizParams

Parameter

Type

Required

Description

UserDefinedParams

map

No

Specifies parameters to pass through to the agent. For parameters specific to each agent, see the Call Official Agents documentation. You can set dialog extension parameters in the extra_config sub-node. Currently, enable_web_search is supported, which indicates whether to enable web search. Settings here have a higher priority and override the console configuration.

UserPromptParams

map

No

Specifies custom prompt variables. You can define your own keys and values in the JSON object. For information on how to configure custom prompt variables in the console, see Application Configuration - Prompt.

UserQueryParams

map

No

Specifies custom dialog variables. You can define your own keys and values in the JSON object. For information on how to configure custom dialog variables in the console, see Application Configuration - Dialog Variables.

PassThroughParams

map

No

For passing through additional parameters.

Building parameters

// Configure upstream parameters.
upstream := &dashscope.Upstream{
    Type:        "AudioOnly",
    Mode:        "push2talk",
    AudioFormat: "pcm",
}

// Configure downstream parameters.
downstream := &dashscope.Downstream{
    Voice:            "longanhuan",
    SampleRate:       16000,
    IntermediateText: "transcript,dialog",
    AudioFormat:      "pcm",
}

// Configure client information.
clientInfo := &dashscope.ClientInfo{
    UserID: "user123",
    Device: &dashscope.Device{
        UUID: "1234567890",
    },
}

requestParams := &dashscope.RequestParameters{
    Upstream:   upstream,
    Downstream: downstream,
    ClientInfo: clientInfo,
}

MultiModalCallback interface

Server responses (Server → Client)

A callback interface for handling various events during a voice chat.

type MultiModalCallback interface {
    // OnStarted is called when the dialog has started.
    //   - dialogID: The dialog ID returned by the callback.
    OnStarted(dialogID string)

    // OnStopped is called when the dialog has stopped.
    OnStopped()

    // OnStateChanged is called when the dialog state changes.
    //   - state: The new dialog state.
    //   - inputType: The input source that triggered the state change.
    OnStateChanged(state DialogState, inputType InputType)

    // OnSpeechAudioData is the callback for synthesized audio data.
    //   - data: The binary audio data.
    OnSpeechAudioData(data []byte)

    // OnError is called when an error occurs.
    //   - err: The error information.
    OnError(err error)

    // OnConnected is called after a successful connection to the server.
    OnConnected()

    // OnRespondingStarted is called when the model starts responding.
    OnRespondingStarted()

    // OnRespondingEnded is called when the model finishes responding.
    //   - payload: Additional information at the end of the response.
    OnRespondingEnded(payload map[string]interface{})

    // OnSpeechStarted is called when the start of speech input is detected.
    OnSpeechStarted()

    // OnSpeechEnded is called when the end of speech input is detected.
    OnSpeechEnded()

    // OnSpeechContent provides the recognized speech text.
    //   - payload: Data containing the recognized text.
    OnSpeechContent(payload map[string]interface{})

    // OnRespondingContent provides the model's response text.
    //   - payload: Data containing the response text.
    OnRespondingContent(payload map[string]interface{})

    // OnRequestAccepted is called when an interrupt request is accepted.
    OnRequestAccepted()

    // OnClose is called when the connection is closed.
    //   - closeStatusCode: The closing status code.
    //   - closeMsg: The closing message.
    OnClose(closeStatusCode int, closeMsg string)
}

Dialog states (DialogState)

The states returned by the OnStateChanged interface callback include LISTENING, THINKING, and RESPONDING:

  • Listening: The bot is listening for user input. You can send audio in this state.

  • Thinking: The bot is thinking and processing the request.

  • Responding: The bot is generating or playing a voice response.

Interaction sequence diagram

image

Advanced usage

Image question answering (VQA)

VQA enables multimodal interaction with both images and speech during a conversation.

The core process involves triggering VQA by speaking an intent, such as "take a look at this," or by directly inputting a text request. The service then returns a question-answering result based on the image content.

  • Requesting with voice:

    1. Say something like, "Take a look at what's in front."

    2. The service returns a visual_qa intent through the OnRespondingContent callback.

    3. After receiving this intent, the client calls the RequestToRespond API and submits the image content to trigger a question-answering response.

  • // Handle the visual_qa intent in the callback.
      func (c *MyCallback) OnRespondingContent(payload map[string]interface{}) {
          if output, ok := payload["output"].(map[string]interface{}); ok {
              if extraInfo, ok := output["extra_info"].(map[string]interface{}); ok {
                  if commands, ok := extraInfo["commands"].(string); ok {
                      if strings.Contains(commands, "visual_qa") {
                          // Trigger VQA.
                          sendImageVQA(dialog)
                      }
                  }
              }
          }
      }
    
      // Send a VQA request.
      func sendImageVQA(dialog *dashscope.MultiModalDialog) {
          image := map[string]interface{}{
              "type":  "base64",
              "value": imageBase64Data,
          }
          // Alternatively, use a URL.
          // image := map[string]interface{}{
          //     "type":  "url",
          //     "value": imageURL,
          // }
    
          imagesParams := &dashscope.RequestToRespondParameters{
              Images: []interface{}{image},
          }
    
          // Call VQA with voice; pass an empty string for the text parameter.
          dialog.RequestToRespond("prompt", "", imagesParams, false)
      }
  • Requesting with text:

    1. The client directly calls the RequestToRespond API, submitting both the image content and the text request to trigger a question-answering response.

    image := map[string]interface{}{
          "type":  "base64",
          "value": imageBase64Data,
      }
      // Alternatively, use a URL.
      // image := map[string]interface{}{
      //     "type":  "url",
      //     "value": imageURL,
      // }
    
      imagesParams := &dashscope.RequestToRespondParameters{
          Images: []interface{}{image},
      }
    
      // Request an image response directly with text.
      dialog.RequestToRespond("prompt", "What is in this picture?", imagesParams, false)

Note: VQA supports sending image links or Base64-encoded data (for images smaller than 180 KB).

LiveAI video call over WebSocket

LiveAI (video call) is an official agent provided by the Model Studio multimodal interaction service. You can implement video calls by sending a sequence of images through the Go SDK. We recommend that your server and client (web or app) use RTC to transmit video and audio. Then, your server should send the captured video frames to the SDK at a rate of one frame every 500 ms while maintaining real-time audio input.

Note: For LiveAI, images must be Base64-encoded and smaller than 180 KB.

  • LiveAI call sequence

截屏2025-06-20 11

  • Key code example

// 1. Set the request mode to AudioAndVideo.
upstream := &dashscope.Upstream{
    Type:        "AudioAndVideo",
    Mode:        "duplex",
    AudioFormat: "pcm",
}

// 2. Send a request to connect to the video dialog agent.
func sendConnectVideoCommand(dialog *dashscope.MultiModalDialog) {
    videoConnectCommand := []interface{}{
        map[string]interface{}{
            "action": "connect",
            "type":   "voicechat_video_channel",
        },
    }

    params := &dashscope.RequestToRespondParameters{
        BizParams: &dashscope.BizParams{
            Videos: videoConnectCommand,
        },
    }

    dialog.RequestToRespond("prompt", "", params, false)
}

// 3. Send a video frame (under 180 KB) every 500 ms.
func sendVideoFrameLoop(dialog *dashscope.MultiModalDialog, stopChan chan bool) {
    ticker := time.NewTicker(500 * time.Millisecond)
    defer ticker.Stop()

    for {
        select {
        case <-stopChan:
            return
        case <-ticker.C:
            image := map[string]interface{}{
                "type":  "base64",
                "value": getVideoFrameBase64(),
            }
            params := &dashscope.RequestToRespondParameters{
                Images: []interface{}{image},
            }
            dialog.RequestToRespond("prompt", "", params, false)
        }
    }
}

Text-to-speech (TTS)

The SDK lets you request the server to synthesize audio directly from text.

You must send a RequestToRespond request when the client is in the Listening state.

If the current state is not Listening, you must first call the Interrupt API to interrupt the current playback.

dialog.RequestToRespond("transcript", "The weather is nice today.", nil, false)

Custom prompt variables

  • Configure custom variables in the Prompt section of your project in the console.

In the example below, a user_name field is defined to represent a user nickname. The user_name variable is then inserted into the Prompt as the ${user_name} placeholder.

image.png

  • Set the variables in your code.

For example, set "user_name" = "rice".

// Pass BizParams.UserPromptParams in the request parameters.
bizParams := &dashscope.BizParams{
    UserPromptParams: map[string]interface{}{
        "user_name": "Alex",
    },
}

requestParams := &dashscope.RequestParameters{
    Upstream:   upstream,
    Downstream: downstream,
    ClientInfo: clientInfo,
    BizParams:  bizParams,
}
  • Request a response

image.png

Requesting results with text

The SDK supports requesting LLM results and synthesized speech data directly using text.

You must send a RequestToRespond request when the client is in the Listening state.

dialog.RequestToRespond("prompt", "The weather is nice today.", nil, false)

Connection and state management

1. Resource management

Call the Cleanup() method to release all resources when the session is complete:

defer dialog.Cleanup()

2. Heartbeat management

Send heartbeats periodically to keep the connection alive:

ticker := time.NewTicker(45 * time.Second)
go func() {
    for range ticker.C {
        dialog.SendHeartBeat()
    }
}()

3. State monitoring

Monitor dialog state changes by implementing the MultiModalCallback interface:

func (c *MyCallback) OnStateChanged(state dashscope.DialogState, inputType dashscope.InputType) {
    switch state {
    case dashscope.DialogStateListening:
        // The system is listening; you can start sending audio.
    case dashscope.DialogStateThinking:
        // The AI is thinking.
    case dashscope.DialogStateResponding:
        // The AI is responding; prepare to receive audio data.
    }
}