首页 > 产品服务 > API服务 > 文档中心

文档中心
融合模态模型
实时交互融合模态模型
文生图模型
拟人对话模型
实时交互融合模态模型
本文自2024年10月29日起生效

通过SenseNova V6 Omni 实时交互融合模态模型的赋能,我们推出了“日日新”融合大模型交互产品【SenseNova V6 Omni】

一、整体接入流程简介


SenseNova V6 Omni接口当前主要提供全双工方案接入(通过RTC频道进行实时交互);半双工方案目前正在升级整合,后续将会支持在websocket连接内的半双工交互能力。

目前接口Beta版本为申请制,在接入测试前,需要先申请对应密钥,以方便您进行鉴权,才能使用API或Webdemo,进行流式交互的体验。


客户端与服务端的交互整体流程如下图所示:

整体的流程说明如下:

  1. 1.准备密钥和连接token

  2. a.请联系我们的客户支持人员获取用户访问服务的密钥。

  3. b. 使用用户名和密钥,通过Python脚本(https://sensenova5o_doc.sensetime.com/_downloads/8bdf6e5649fd3fc4d75c971bcfac0b19/generate_token.py)生成JWT Token。

  4. 2.通过WebSocket实时API连接服务

  5. a. 1. 拼接url参数(包含JWT Token、视频分辨率、VAD相关参数等),并连接WebSocket实时API(地址:wss://api-gai.sensetime.com/agent-5o/duplex/ws2)

  6. b.从WebSocket连接中,获取连接WebRTC所用的App ID、Token 和Channel ID。

  7. 3.通过WebRTC SDK开始推拉音视频流

  8. a.创建WebRTC客户端实例

  9. b.加入WebRTC频道。

  10. c.发送音视频,并订阅模型返回的音频流。

  11. d.此时,服务端会从WebSocket同步返回模型输出所对应的文本。

接入Demo

如需简易上手体验SenseNova V6 Omni,可使用我们的Web Demo:https://nova-platform-prod.oss-cn-hangzhou.aliyuncs.com/250529%E6%9B%B4%E6%96%B0/AgoraStreamingClient-0526-prod.html

    • 下载完成后双击打开,在“服务器地址”栏填入您获取访问密钥后生成的JWT Token,再点击“Connect”,随后点击“Start Stream”,即可开始体验SenseNova V6 Omni。
    • 该html文件同时也是JavaScript版本的接入示例代码,您可参考其中的实现理解如何通过WebSocket和声网RTC接入SenseNova V6 Omni。

安卓版本接入Demo: https://nova-platform-prod.oss-cn-hangzhou.aliyuncs.com/0515%E6%9B%B4%E6%96%B0/Omni%E6%BA%90%E7%A0%81%EF%BC%88v2%E5%8D%8F%E8%AE%AE%EF%BC%89.zip

Python Linux接入Demo(此处以Ubuntu为例):https://nova-platform-prod.oss-cn-hangzhou.aliyuncs.com/250610%E6%9B%B4%E6%96%B0/demo-python-v1.5.zip

二、WebSocket接入步骤


为方便说明,以下步骤中的示例代码均以Web端通过JavaScript接入举例,如有疑问欢迎联系我们的客服人员。

1. 构造请求URL,并连接WebSocket

为了与API的WebSocket建立连接,需要您将初始化阶段所必要的参数,拼接到URL中的Get参数,从而能够进行WebSocket通信的建立。

  • · SenseNova V6 Omni WebSocket接口地址:wss://api-gai.sensetime.com/agent-5o/duplex/ws2

建立通信时,支持的参数有


我们推荐的system prompt如下

    • 通用女生&阳光少女&邻家学姐: 你是一个年轻女生,你的性格友善,充满阳光与正能量。你说话清新自然,言语间透着细腻和体贴,总能以舒缓而愉悦的方式与人交流,让人感到放松和愉快。
    • 通用男生&成熟男音&暖男学长: 你的名字叫商量,你是一个阳光帅气的男孩,你的性格开朗大方,充满阳光与正能量。你说话温柔真诚,总能鼓励和感染别人,让人感到安心和振奋。

  • voice_type: 选填,用于设置SenseNova V6 Omni的回复音色。目前可以设置以下音色:

    • 邻家学姐:nvguo59(默认)
    • 成熟男音:M20
    • 暖男学长:zhili
    • 阳光少女:F12
    • 通用女生: woman
    • 通用男生: man
    • 甜美小源: zh_female_tianmeixiaoyuan_moon_bigtts
    • 邻家女孩: zh_female_linjianvhai_moon_bigtts
    • 温暖阿虎: zh_male_wennuanahu_moon_bigtt
    • 渊博小叔: zh_male_yuanboxiaoshu_moon_bigtts

  • · VAD(语音活跃检测)参数:必填,这些参数用于调整模型如何判断用户已经结束讲话,如果您遇到模型容易被打断、模型太快给出回应等问题,可以尝试调整这些参数。
    • vad_pos_threshold [float]: 开始会话的音量阈值,音量高于这一数值则视为语音开始。(默认值:0.98,取值范围0~1)
    • vad_min_speech_duration_ms [uint32]: 语音的最短时长,单位为毫秒,低于此长度的语音将不获处理。(默认值:400)
    • vad_min_silence_duration_ms [uint32]: 语音结束后,在截断语音前保留这一时长的静默片段,单位为毫秒。(默认值:800)

拼接完成后,您的请求URL应该类似::wss://api-gai.sensetime.com/agent-5o/duplex/ws2?vad_pos_threshold=0.98&vad_min_speech_duration_ms=400&vad_min_silence_duration_ms=800&jwt=[您的jwt]


随后,您便可以通过您的开发环境所对应的WebSocket库,与SenseNova V6 Omni的API建立连接。

javascript
socket = new WebSocket(url);

2. 初始化Session

这一步,需要向服务端请求创建Session,以表示开启一轮会话。

首先,您需要通过WebSocket发送 CreateSession 消息。

  • request_id主要是为了方便客户端内部识别这一条请求消息,在后续针对这一消息的回复中我们会返回这一ID供您辨认,您可以自定义该ID。
java
socket.send(JSON.stringify({    
    type: "CreateSession",    
    request_id: "user defined rid",
}));

随后,您会通过WebSocket接收到 CreateSessionResult 消息,这一消息包含会话是否创建成功的结果,以及会话ID(session_id),并返回该回复响应的是哪一个创建请求(对应创建会话时的request_id)。

  • 注意:此处会话ID(session_id)将作为会话日志查询的依据,请您在接口调试过程中妥善储存,便于在反馈问题的过程中进行沟通排查。

返回体结构如下:

java
{    
    type: "CreateSessionResult",    
    success: boolean,    
    session_id: string | undefined,    
    respond_to: string
}

3. 配置RTC连接参数

目前SenseNova V6 Omni服务支持两种方式连接到声网RTC服务:

  • 方式一:由服务端提供声网频道和token,供客户端连接。此方式适合大部分客户。

  • 方式二:由客户端提供声网频道和token,供服务器连接。如果您自行管理声网服务,请使用这一方式。


方式一:服务端提供声网频道

首先,服务端需要发送 RequestAgoraChannelInfo 消息,申请一个目前可以加入的声网频道ID。

  • 其中,request_id与上一步骤含义相同,主要是为了方便客户端内部识别这一条请求消息,在后续针对这一消息的回复中我们会返回这一ID供您辨认,您可以自定义该ID。
java
socket.send(JSON.stringify({    
    type: "RequestAgoraChannelInfo",    
    request_id: "user defined rid",
}));

其次,服务端需要发送 RequestAgoraToken 消息 ,申请上述声网频道的连接token。

  • 其中,request_id与上一步骤含义相同,主要是为了方便客户端内部识别这一条请求消息,在后续针对这一消息的回复中我们会返回这一ID供您辨认,您可以自定义该ID。
  • duration为您希望连接的时长,单位为秒。单次的设置不建议太长,您可以根据实际使用的连接时长进行设置。
java
socket.send(JSON.stringify({    
    type: "RequestAgoraToken",    
    duration: AGORA_TOKEN_DURATION,    
    request_id: "user defined rid2",
}));

作为上述两条消息的回复,服务端将会返回 AgoraChannelInfo 以及 AgoraToken 两条消息,告知客户端连接声网SDK所需的频道ID和token等参数。

java
{    
    type: "AgoraChannelInfo",    
    appid: string,    
    channel_id: string,    
    server_uid: number,    
    respond_to: string
}
{    
    type: "AgoraToken",    
    client_uid: number,    
    duration: number,    
    token: string,    
    respond_to: string
}

这两条消息中包含的字段含义如下

  • appid: 声网AppID。

  • channel_id: 声网频道ID。

  • server_uid: 服务端用于推流的uid,客户端可以订阅此uid的流,从而获取模型返回的音频结果。

  • client_uid: 指定客户端用于推流的uid,客户端请用这一uid推流,服务端将从这一uid接收用户输入。

  • token: 客户端用于加入声网频道的有效 token。

  • duration: 上文返回的声网token的有效期。如果需要延长服务,客户端可以在有效期结束前,通过重新发送 RequestAgoraToken 消息来刷新token,从而延长服务时间。


方式二:客户端提供声网频道

如果客户端本身已经接入了声网,需要自行指定让SenseNova V6 Omni服务加入哪一个声网频道,则可以选择不使用服务端返回的声网频道ID和token,而是通过主动将声网频道相关参数传递给服务端,让服务端自行加入客户端所指定的声网频道。

为了实现这一效果,需要向服务端发送 PostAgoraChannelInfo PostAgoraToken 这两条消息,格式如下:

java
socket.send(JSON.stringify({    
    type: "PostAgoraChannelInfo",    
    appid: agoraAppid,    
    channel_id: agoraChannelId,    
    client_uid: agoraClientUid,    
    request_id: "user defined rid",
}));
socket.send(JSON.stringify({    
    type: "PostAgoraToken",    
    duration: AGORA_TOKEN_DURATION,    
    server_uid: agoraServerUid,    
    token: agoraServerToken,    
    request_id: "2",
}));

两条消息中包含的字段含义如下

  • appid: 声网AppID。

  • channel_id: 声网频道ID。

  • server_uid: 指定服务端用于推流的uid,客户端可以订阅此 uid 的流,从而获取模型返回的音频结果。

  • client_uid: 指定客户端用于推流的uid,服务端将从这一 uid 接收用户输入。

  • token: 指定服务端用于加入声网频道的有效 token。

  • duration: 用于告知服务端上文传入的声网token的有效期。在有效期内,客户端可以通过重新发送 PostAgoraToken 来刷新服务端所持有的token,从而延长服务时间。


4. 启动服务端服务

客户端在一切就绪后,通过WebSocket发送 StartServing 消息,提示服务器开始启动模型服务。

java
socket.send(JSON.stringify({    
    type: "StartServing",
}));

此时,如果您已经通过上述步骤的参数接入声网频道,您就可以开始与SenseNova V6 Omni模型进行实时对话了。

如何通过声网SDK接入频道,请您参考下文。

附:接口支持的其他功能消息

接口还支持更多的功能消息,让客户端能够更灵活组合出所需的功能服务。

以下是整理后的表格展示:

发送方名称功能消息定义字段说明
服务端ResponseStartTextStream表示服务端开始返回结果文本。{ type: "ResponseStartTextStream", index: number }- index:该段返回文本的编号(递增但不一定连续)。
服务端ResponseTextSegment流式返回模型回复的文本片段。{ type: "ResponseTextSegment", text: string }- text:流式返回的文本片段。
服务端ResponseFullText完整返回模型回复的全文内容。{ type: "ResponseEndTextStream", index: number, text: string, complete: boolean }- index:与开始消息的编号一致。
- text:完整文本。
- complete:是否为完整输出(false表示被中断)。
客户端PostMultimodalGenerate向服务端发送文本/图片/音频的 user prompt。{ type: "PostMultimodalGenerate", text: string | undefined, images: [{ type: "jpg", url | base64 }] | undefined, audio: { type: "mp3" | "wav", url | base64 } | undefined }- text:文本 prompt。
- images:≤3 张 JPG(≤720p)。
- audio:MP3/WAV(≤20MB)。
注意:格式错误可能导致服务卡死。
服务端ResourceDownloadError提示未能获取客户端发送的图片/音频 URL 文件。{ type: "ResourceDownloadError", url: string, respond_to: string | undefined }检查 URL 是否正确或可公网访问。
服务端InvalidMultimodRequest提示客户端数据结构无法解析。{ type: "InvalidMultimodRequest", err_msg: string, respond_to: string | undefined }检查 JSON 结构体格式。
服务端ResourceEncodeError提示图片/音频数据格式错误。{ type: "ResourceEncodeError", resource: string, respond_to: string | undefined }检查图片/音频格式。
客户端SetVoiceType重设服务输出音色(下一轮生效)。{ type: "SetVoiceType", voice_type: string }- voice_type:新音色类型。
服务端VoiceTypeSet提示音色设置成功。{ type: "VoiceTypeSet", respond_to: string | undefined }-
服务端InvalidVoiceType提示音色类型不存在。{ type: "InvalidVoiceType", respond_to: string | undefined }-
客户端SetSystemPrompt重设 System prompt(下一轮生效)。{ type: "SetSystemPrompt", system_prompt: string, request_id: string }- system_prompt:仅支持文本。
服务端SystemPromptSet提示 System prompt 设置成功。{ type: "SystemPromptSet", request_id: string }-
客户端EnableRag启用 RAG 知识库查询。{ type: "EnableRag", dataset_id: string, top_k: 1, confidence: 0.7, weight: 0.5, structure_weight: 0.5 }默认参数需联系技术支持调整。
服务端RagEnabled提示 RAG 已开启。{ type: "RagEnabled", request_id: string }-
服务端RagDisabled提示 RAG 已关闭。{ type: "RagDisabled", request_id: string }-
客户端ConfigASR启用 ASR 回显用户输入(需在 StartServing 前发送)。{ type: "ConfigASR", enable: boolean }- enabletrue 为启用。
注意:回显内容可能与模型理解不一致。
服务端AsrTraceStart标记用户 ASR 回显开始。{ type: "AsrTraceStart", trace_id: string }- trace_id:所属音频 ID。
服务端AsrTraceUpdate逐步返回用户回显内容。{ type: "AsrTraceUpdate", trace_id: string, result: string }- result:当前所有回显文本。
服务端AsrTraceEnd标记用户 ASR 回显结束。{ type: "AsrTraceEnd", trace_id: string, result: string }- result:完整回显文本。
客户端ResetHistory清除对话历史(保留当前设置)。{ type: "ResetHistory", request_id: string }适用于重置会话或解决人设偏移。
服务端HistoryReset提示对话历史已清除。{ type: "HistoryReset", request_id: string }-
服务端AudioAccepting反馈已收到音频流。{ type: "AudioAccepting" }-
服务端VideoAccepting反馈已收到视频流。{ type: "VideoAccepting" }-
服务端StartSpeaking反馈监测到人声开始。{ type: "StartSpeaking" }-
服务端StopSpeaking反馈监测到人声结束。{ type: "StopSpeaking", duration: number }- duration:音频长度(秒)。
注:表格中省略了部分重复的字段说明(如 respond_to 多表示响应关联的请求 ID)。

附:如何以半双工模式(无RTC)接入

SenseNova V6 Omni之所以接入RTC服务,是为了保障您在与模型交互时的低时延、高可用性,也为您节省在降噪、音视频处理等问题上的处理精力,在条件允许的情况下,推荐您使用RTC方式进行接入。

但有以下两类情况,您也许需要绕开RTC与模型进行交互:

  1. 1.在机器性能难以支撑音视频实时推拉流的情况下,例如编解码性能弱、无法长时间开启摄像头的设备等。

  2. 2.您需要对SenseNova V6 Omni输出的文本或音频做进一步处理再进行输出,例如具身智能、合成数字人等场景。

此时,您可以按照以下步骤,不通过RTC方式与模型同步交互,而是采用类似半双工形式的问答交互,完全通过WebSocket与模型进行互动:

  1. 1.参照上述接入步骤的(1)~(4),获取所有参数并发送启动服务消息,但不需要引入声网SDK连接服务。
  2. 2.使用"PostMultimodalGenerate"消息,向模型发送音频、图片、文本指令。
  3. 3.通过"ResponseTextSegment"、"ResponseFullText"消息,获取模型返回的文本结果。

请注意,通过这种方式暂时无法获取模型的音频生成结果。如果您需要音频生成,可以自行接入第三方流式TTS服务进行低时延的语音合成。

三、声网SDK接入


在通过WebSocket与SenseNova V6 Omni模型建立连接,并确定了需要接入的频道ID、token等参数后,就可以通过接入声网SDK,与SenseNova V6 Omni模型开始进行实时互动。

SDK传入参数

为保障正常接入SDK,您需要为声网SDK设置下列参数:

  • mode:rtc
  • codec(视频编码):vp8 或 h264(安卓SDK请使用h264)
  • 分辨率:小于720p,亦即长×宽小于1280x720
  • uid:该参数含义为客户端拨入到声网频道后,在频道中的用户ID,填写方式如下:
    1. 当由服务端提供声网频道的时候,请按照WebSocket接口AgoraToken 消息返回的client_uid 填写。
    2. 当由客户端提供声网频道的时候,请按照PostAgoraChannelInfo接口提供给服务端的client_uid进行填写。
  • · 其他连接参数(上一轮通过websocket从服务器收取获得):
    • · 声网AppID
    • · 频道ID
    • · 连接token

Web接入指引

首先,为了在网页端接入声网SDK,请引入网页端的JavaScript SDK:

https://download.agora.io/sdk/release/AgoraRTC_N.js

通过这一SDK,建立连接的步骤如下:

    1. 调用AgoraRTC.createClient方法,创建连接对象。此时需要传入模式(mode: rtc)和编码(codec: vp8/h264)。
    1. 调用上述client连接对象的join方法,传入AppID、频道ID、连接token、uid,加入声网频道。
    1. 可通过AgoraRTC.createMicrophoneAudioTrackAgoraRTC.createCameraVideoTrack方法,获取本地音视频流,并调用上述client连接对象的publish方法,将本地音视频流推到频道中。
    1. 可监听上述client连接对象的"user-published"事件,在本地音视频推流完成后,通过clientsubscribe方法,获取服务器端(模型)返回的音频流并进行播放。

Python接入指引

您可联系我们获取Python(Ubuntu)接入demo脚本。 为了在python端接入声网SDK,请引入python端的声网SDK:


bash
pip install agora_python_server_sdk

通过这一SDK,建立连接的步骤如下:

    1. 调用 AgoraService() 来创建 AgoraService 实例。
    1. 调用AgoraServiceConfig()创建一个配置项的实例,将SenseNova V6 Omni WebSocket获取到的AppID传入它的.appid字段。
    1. 调用AgoraService 实例的initialize() 方法进行初始化,将上述配置项实例传入。
    1. 调用RTCConnConfig() 构造函数,创建一个连接配置项的实例;并用它传入调用 create_rtc_connection 方法,创建 RTCConnection 对象,用于与声网服务器建立连接。
    1. 调用 register_observer 方法注册连接事件观测器,可以监听RTC连接的状态,并在连接、断开等场合触发对应操作。请按照您的需要进行使用。
    1. 调用上述步骤(4)创建的 RTCConnection 对象的connect()方法,传入SenseNova V6 Omni WebSocket获取到的连接Token(token)、频道ID(channel_id)、客户端uid(client_uid),即可建立连接。
    1. 发送流媒体,请参考MediaNodeFactory对象的使用文档;接收流媒体,请参考使用register_audio_frame_observerregister_video_frame_observer 方法注册音视频数据观测器的使用文档。

更详细、完善的接入代码指引,请参考声网官方SDK文档:

https://doc.shengwang.cn/doc/rtc-server-sdk/python/get-started/send-receive

安卓端接入指引

使用声网安卓SDK,需要使用以下开发环境:

  • Android Studio 4.1 以上版本。
  • Android API 级别 16 或以上。

通过SDK建立连接的简要步骤如下:

    1. 将SDK添加到您的工程依赖中。
    1. 初始化SDK的RTC连接实例RtcEngine,并在创建实例、调用RtcEngine.create(config)时,将SenseNova V6 Omni WebSocket获取到的AppID传入config.mAppId字段。
    1. 创建VideoEncoderConfiguration配置实例(假设名为videoConfig),将视频编码(videoConfig.codecType)设置为h264(VIDEO_CODEC_H264),将分辨率(videoConfig.dimensions)调节到720p以下,并将设置应用到RtcEngine中。
  1. a. 详细配置方式可参考:https://doc.shengwang.cn/doc/rtc/windows/basic-features/video-profile#%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95
    1. 在完成其他配置后,调用RtcEngine.joinChannel加入频道,传入SenseNova V6 Omni WebSocket获取到的连接Token(token)、频道ID(channel_id)、客户端uid(client_uid),即可建立连接。

更详细、完善的接入指引,请参考声网官方SDK文档:https://doc.shengwang.cn/doc/rtc/android/get-started/quick-start

四、常见问题解答


  • WebSocket连接时,接口返回401:目前401仅对应jwt token无效一种情况,请您参考上述WebSocket接入步骤中生成jwt token的步骤,重新生成jwt token;同时,可以在生成时适当调高jwt token的过期时间(但不可超过1天),避免在使用前token就过期了的情况发生。

  • 声网安卓SDK对设备系统版本号的要求:至少需要安卓4.1,API级别16以上。

  • 环境杂音大,或者使用时容易被旁边的声音打断输入,应该如何改善:您可以采用调整设备采集音量、调整VAD参数的方式进行改善。我们推荐您首先尝试调整采集音量的方式,一般能取得较好的成效。

    1. a. 可以调整设备的采集音量为最低采集音量:

    2. i. 您可以按照您使用设备的收音距离(例如随身设备可能30cm,机器人类设备可能1m,等等),测试并调整人在这一距离上正常说话时恰好可正常收音、没有遗漏的最低采集音量,以后在同类设备上都使用相同的采集音量配置。

    3. ii. 最低采集音量的调整方式:在完全安静的情况下,从一个较小的值(例如5)开始逐渐增大采集音量,直到刚好能够正常触发用户语音输入,且没有遗漏用户语音的情况为止。按照声网文档中的经验,调整完成后的值一般不会超过85。

    4. iii. 参考声网文档:https://doc.shengwang.cn/api-ref/rtc/android/API/toc_audio_capture

    5. b. 可以调整VAD参数,推荐在调整过程中持续测试,直到找到在设备上表现能令人满意的值:

    6. i. vad_pos_threshold可调整到大于0.98的值。

    7. ii.vad_min_speech_duration_ms可调整到大于400的值。

    8. c. 可以调整声网SDK自带的降噪功能:

  • 加入房间后,音视频模式模型都不回复:进入房间的uid,需要设置为接口传回的channel_id。

  • 安卓API接入时,视频模式下模型无法识别图像输入:安卓声网SDK中的视频编码格式需要设置为h264。

  • 多台设备如何进行同时接入:请使用我们支持团队提供的ak、sk获取不同的jwt token,即可在多个设备同时调用,不会产生相互影响。