您可以通过客户端或服务端实时接收用户与智能体的对话文本。
通常情况下,通过客户端接收可实现在设备显示屏上实时呈现交互字幕,提升用户交互体验;通过服务端接收则便于将对话数据进行持久化存储,以供后续的业务分析。
在智能体创建或配置页面,选择 高级配置,并开启 字幕显示。更多信息,请参见智能体管理。
在客户端监听回调 on_volc_message_data 接收字幕数据。
回调消息格式如下:
参数名 | 类型 | 描述 |
|---|---|---|
uid | String | 消息发送者 ID。 |
message | Binary | Base64 编码的二进制消息内容。解码后结构请参见字幕消息数据结构。 |
在智能体创建或配置页面,选择 高级配置,并在 字幕显示 区域配置以下参数:
配置项 | 说明 |
|---|---|
ServerMessageUrl | 设置接收字幕结果的公网 URL 地址。
|
ServerMessageSignature | 设置鉴权签名。服务端在接收到字幕结果后,与结果中的 |
更多信息,请参见智能体管理。
您配置的 URL 地址将收到 HTTP(S) POST 请求,内容格式如下:
参数名 | 类型 | 描述 |
|---|---|---|
message | String | Base64 编码的二进制消息内容。解码后结构请参见字幕消息数据结构。 |
signature | String | 鉴权签名。请与您配置的 |
您可以参考以下示例代码对回调信息中的 message 内容进行解析。
const ( subtitleHeader = "subv" exampleSignature = "example_signature" ) type RtsMessage struct { Message string `json:"message"` Signature string `json:"signature"` } type Subv struct { Type string `json:"type"` Data []Data `json:"data"` } type Data struct { Definite bool `json:"definite"` Paragraph bool `json:"paragraph"` Language string `json:"language"` Sequence int `json:"sequence"` Text string `json:"text"` UserID string `json:"userId"` } func HandleSubtitle(c *gin.Context) { msg := &RtsMessage{} if err := c.BindJSON(&msg); err != nil { fmt.Printf("BindJson failed,err:%v\n", err) return } if msg.Signature != exampleSignature { fmt.Printf("Signature not match\n") return } subv, err := Unpack(msg.Message) if err != nil { fmt.Printf("Unpack failed,err:%v\n", err) return } fmt.Println(subv) //业务逻辑 c.String(200, "ok") } func Unpack(msg string) (*Subv, error) { data, err := base64.StdEncoding.DecodeString(msg) if err != nil { return nil, fmt.Errorf("DecodeString failed,err:%v", err) } if len(data) < 8 { return nil, fmt.Errorf("Data invalid") } dataHeader := string(data[:4]) if dataHeader != subtitleHeader { return nil, fmt.Errorf("Header not match") } dataSize := binary.BigEndian.Uint32(data[4:8]) if dataSize+8 != uint32(len(data)) { return nil, fmt.Errorf("Size not match") } subData := data[8:] subv := &Subv{} err = json.Unmarshal(subData, subv) if err != nil { return nil, fmt.Errorf("Unmarshal failed,err:%v\n", err) } return subv, nil } func main() { r := gin.Default() r.POST("/example_domain/vertc/subtitle", HandleSubtitle) r.Run() }
无论是通过客户端还是服务端接收字幕回调,解码后的 message 字段均遵循以下二进制格式标准。
消息头部包含固定的 Magic Number 和消息长度信息。
参数名 | 类型 | 描述 |
|---|---|---|
magic number | Binary | 消息格式标识,固定为 |
length | Binary | 消息负载长度,单位为 Bytes,大端序。 |
协议头后的 subtitle_message 为 JSON 格式字符串的消息负载,包含具体的字幕信息。消息结构如下:
参数名 | 类型 | 描述 |
|---|---|---|
type | String | 消息类型,固定为 |
data | List | 字幕详细信息列表,包含字幕文本、说话人 ID 等具体信息。 |
参数名 | 类型 | 描述 |
|---|---|---|
text | String | 字幕文本内容。 |
language | String | 字幕语言代码(如 |
userId | String | 说话人 ID。
|
sequence | Integer | 字幕序号,用于排序。 |
definite | Boolean | 是否为完整的分句。
|
paragraph | Boolean | 是否为完整的一句话。
|
roundId | Integer | 对话轮次 ID。 |
{ "type": "subtitle", "data": [ { "text": "上海天气炎热。气温为", "language": "zh", "userId": "bot1", "sequence": 1, "definite": false, "paragraph": false, "roundId": 1 } ] }
{ "type": "subtitle", "data": [ { "text": "上海天气炎热。气温为 30 摄氏度。", "language": "zh", "userId": "bot1", "sequence": 2, "definite": true, "paragraph": false, "roundId": 1 } ] }