博通BK7258平台SDK大模型互动服务接入
该文档介绍博通BK7258平台SDK接入大模型互动服务的最佳实践,引导用户快速跑通流程,解答常见的问题。
基础:跑通全流程
第一步:控制台开通云服务,配置互动智能体
1.注册和登陆百度智能云账号:个人用户和企业用户均需先注册百度智能云账号。具体步骤见注册账号, 登录账号
2.开通大模型互动服务:首次使用服务需要先开通,开通步骤见开通服务
3.创建和配置智能体:
第一步:填写基本信息、选择互动类型(创建成功后不可更改)
第二步:选择模型、填写人设、选择function call模版和组件,具体内容详见 创建互动应用、 控制台快速接入
4.云上测试智能体 【互动应用】应用列表处找到要体验的应用,在【操作】点击体验Demo,进行体验
5.领取测试license和购买正式license: 新用户自动下发10个license,如要购买,在【资源列表】-【购买资源】按需配置购买。详情见领取和购买license
6.给已创建的应用绑定资源:应用创建成功后,必须绑定资源才可正常使用。绑定操作见 绑定资源
第二步:运行云对接服务示例
说明:百度智能云服务API接口,均采用AK/SK鉴权,为了增强安全性,要求在服务器上调用(不建议在设备上)。该示例代码实现一个访问中转,接收设备端连接请求,代理访问百度大模型互动API接口创建互动智能体,返回设备端侧访问云服务所需的token、agentid等信息。该代码可作为服务端对接的实现参考。
1.下载云端对接服务示例代码
本示例代码基于JDK17开发,需要先安装JDK17环境,确保可运行java -version命令等。具体安装过程可直接搜索JDK17安装,参考开源链接进行安装。
官网下载云对接服务代码示例,解压缩之后获取到rtc-aiagent-userserver-version.jar包,本JAR包可以直接用于部署启动。
本节后续操作均依赖于前一步骤所获取的参数,请在执行后续操作之前,确保之前步骤均已成功执行。
2.配置云对接服务参数
获取到用于百度智能云接口鉴权的AK/SK,如何获取AK/SK。
获取到用于执行接口调用的互动应用AppId,查看互动应用ID。
3.运行云对接服务示例
将本节步骤2获取到的AK/SK参数替换下面执行命令中的对应部分
1## 访问BCE国内节点启动命令
2BCE_APP_AK=your_ak \
3BCE_APP_SK=your_sk \
4nohup java -Djava.net.preferIPv4Stack=true -jar rtc-aiagent-userserver-version.jar \
5--server.address=0.0.0.0 > app.log 2>&1 &
1## 访问BCE香港节点启动命令
2BCE_APP_AK=your_ak \
3BCE_APP_SK=your_sk \
4BCE_ENDPOINT=http://rtc-aiagent-out.baidubce.com \
5nohup java -Djava.net.preferIPv4Stack=true -jar rtc-aiagent-userserver-version.jar \
6--server.address=0.0.0.0 > app.log 2>&1 &
启动成功之后,console/cmd/ssh界面,会打印进程ID, 日志信息会保存到当前目录的app.log中
服务启动之后,可以通过接口调用工具,或使用curl命令,测试服务是否可以正常创建token、agentId等。命令中your_app_id需要替换为本节步骤2获取到的互动应用appId。
1curl --location 'http://localhost:8936/api/v1/aiagent/generateAIAgentCall' \
2--header 'Content-Type: application/json' \
3--data '{
4 "config": "",
5 "app_id": "your_app_id"
6}'
1curl --location 'http://localhost:8936/api/v1/aiagent/stopAIAgentInstance' \
2--header 'Content-Type: application/json' \
3--data '{
4 "app_id": "your_app_id",
5 "ai_agent_instance_id": 2568137789341696
6}'
服务启动成功之后,会占据8936端口,如需停止/重启服务,可参考以下命令
1# 查看占用端口的进程Id
2lsof -i:8936
3
4kill -9 [进程id]
第三步:下载和运行设备端代码示例
1.下载设备SDK和DEMO代码
官网下载RTOS-BK7258代码示例,解压缩之后可以获取到对应的SDK和Demo代码。
Demo示例运行环境配置如下:
1). bk7258系统版本:支持bk_aidk V2.0.1.8版本,RTOS SDK libbrtc.a默认是v2.0.1.8版本编译的。也可以从bk官方代码仓库 baidu_ai_v2.0.1.8 分支,获取对应的百度ai大模型bk工程及app源码;
2).下载链接中的demo/baidu_aiagent是基于BK7258_V3板卡调试好的Demo工程。
2.修改参数配置项
baidu_aiagent app中需要更换成客户申请的appId/licenskey以及客户搭建的服务端的locahost参数即可运行,具体如下:
1# 修改brtc_wrapper.c中your_appId和localhost参数。
2#define BRTC_APP_ID "your_appId" // your_appId换成客户开通的appId。
3#define GENERATE_AI_AGENT_CALL_URL "http://localhost:8936/api/v1/aiagent/generateAIAgentCall" // localhost换成客户搭建云服务时的localhost。
4#define GENERATE_AI_AGENT_CALL_DATA "{\"app_id\": \"your_appId\", \"config\" : \"{ ... ...}\", \"quick_start\": true}" // your_appId换成客户开通的appId。
1# 修改brtc_wrapper.c中licenskey参数,your_licenskey换成客户申请的licensekey。
2void setUserParameters(AgentEngineParams *params) {
3snprintf(params->license_key, sizeof(params->license_key), "%s", "your_licenskey");
4}
完成上面的参数配置即可,执行以下命令即可编译工程:
1# 编译工程(如app置于project/baidu_aiagent目录)
2make bk7258 PROJECT=baidu_aiagent
3.音频采集及播放代码说明
main/cli_intercom.c代码主要实现PCM音频采集与播放,通过分别定义平台相关音频音频采集、停止采集(app_sdk_audio_record_start、app_sdk_audio_record_stop)与播放函数、停止播放(app_sdk_audio_play_start、app_sdk_audio_play_stop)来实现音频采集与播放,这些函数用户侧只需定义即可, 将由sdk发起调用 。 其中音频采样率是16k,单通道,位宽16bit,每帧PCM长度:640byte。接收到的PCM格式是采样率是16k,单通道,位宽16bit,每帧PCM长度:640byte。
音频采集和播放的具体参数和接口如下:
1# 音频采集和播放的代码说明
2
3// audio record and play
4static app_sdk_record_feed_cb g_reocrd_feed_cb = NULL;
5static app_sdk_record_end_cb g_reocrd_end_cb = NULL;
6static bool s_has_record = false;
7
8static app_sdk_play_feed_cb g_play_feed_cb = NULL;
9static app_sdk_play_end_cb g_play_end_cb = NULL;
10static volatile bool g_has_play = false;
11#define PLAYER_FRAME_SIZE (640) //16K 16bit mono 20ms
12
13static aud_intf_voc_setup_t aud_voc_setup = DEFAULT_AUD_INTF_VOC_SETUP_CONFIG();
14static aud_intf_drv_setup_t aud_intf_drv_setup = DEFAULT_AUD_INTF_DRV_SETUP_CONFIG();
15
16// 通过g_reocrd_feed_cb接口向sdk透传采集的pcm音频数据
17static int direct_play_intercom_encode_data(unsigned char *data, unsigned int size)
18{
19 if(g_reocrd_feed_cb){
20 g_reocrd_feed_cb((char *)data, (int)size);
21 }
22
23 return 0;
24}
25
26// 定义开始音频采集函数,配置音频参数及音频采集回调,该接口将由sdk调用,业务侧不需调用
27int app_sdk_audio_record_start(int max_time_ms,int used_vad,app_sdk_record_feed_cb cb_feed,app_sdk_record_end_cb cb_end,char *format){
28 if (!s_has_record)
29 {
30 s_has_record = true;
31 g_reocrd_feed_cb = cb_feed;
32 g_reocrd_end_cb = cb_end;
33
34 aud_voc_setup.data_type = AUD_INTF_VOC_DATA_TYPE_PCM;
35 aud_intf_drv_setup.aud_intf_tx_mic_data = direct_play_intercom_encode_data;
36 int ret = bk_aud_intf_drv_init(&aud_intf_drv_setup);
37
38 ret = bk_aud_intf_set_mode(AUD_INTF_WORK_MODE_VOICE);
39 if (ret != BK_ERR_AUD_INTF_OK)
40 {
41 bk_printf("bk_aud_intf_set_mode fail, ret:%d\n", ret);
42 return 0;
43 }
44
45 aud_voc_setup.aec_enable = true; //回声消除、消噪使能
46 aud_voc_setup.spk_mode = AUD_DAC_WORK_MODE_SIGNAL_END;
47 aud_voc_setup.mic_type = AUD_INTF_MIC_TYPE_BOARD;
48 aud_voc_setup.spk_type = AUD_INTF_SPK_TYPE_BOARD;
49 aud_voc_setup.samp_rate = 16000;
50
51 aud_voc_setup.spk_gain = 0x15;
52 ret = bk_aud_intf_voc_init(aud_voc_setup);
53 if (ret != BK_ERR_AUD_INTF_OK)
54 {
55 bk_printf("bk_aud_intf_voc_init fail, ret:%d\n", ret);
56 return 1;
57 }
58
59 ret = bk_aud_intf_voc_start();
60 if (ret != BK_ERR_AUD_INTF_OK)
61 {
62 bk_printf("bk_aud_intf_voc_start fail, ret:%d\n", ret);
63 return 1;
64 }
65
66 bk_printf("[%s][%d] init success\r\n", __FUNCTION__, __LINE__);
67 }
68 return 0;
69}
70
71// 定义停止音频采集函数,该接口将由sdk调用
72int app_sdk_audio_record_stop(void) {
73 bk_aud_intf_voc_deinit();
74 bk_aud_intf_set_mode(AUD_INTF_WORK_MODE_NULL);
75 bk_aud_intf_drv_deinit();
76 s_has_record = false;
77 return 0;
78}
79
80// 从sdk g_play_feed_cb回调接收pcm音频数据, 并调用bk 平台bk_aud_intf_write_spk_data接口播出音频
81static void audio_play_task_main(beken_thread_arg_t param_data)
82{
83 while (g_has_play)
84 {
85 unsigned char data[1024] = {0,};
86 //播放音频
87 if(g_play_feed_cb){
88 int len = g_play_feed_cb((char *)data, PLAYER_FRAME_SIZE);
89 if (len > 0) {
90 bk_aud_intf_write_spk_data(data, len);
91 }
92 }
93 rtos_delay_milliseconds(20); //是否需要添加sleep函数
94 }
95}
96
97// 创建音频播放任务
98static bk_err_t audio_play_main_task_init(void)
99{
100 bk_err_t ret = BK_OK;
101
102 ret = rtos_create_thread(audio_play_task_thread,
103 5,
104 "audio_play",
105 (beken_thread_function_t)audio_play_task_main,
106 10*1024,
107 NULL);
108 if (ret != kNoErr)
109 {
110 goto fail;
111 }
112
113 os_printf("init audio_control task complete\n");
114
115 return BK_OK;
116
117fail:
118 return BK_FAIL;
119}
120
121// 定义开始音频播放函数, 设置音频播放回调,该接口将由sdk调用,业务侧不需调用
122int app_sdk_audio_play_start(app_sdk_play_feed_cb cb_feed, app_sdk_play_end_cb cb_end) {
123 if (!g_has_play)
124 {
125 g_has_play = true;
126 g_play_feed_cb = cb_feed;
127 g_play_end_cb = cb_end;
128
129 audio_play_main_task_init();
130 }
131 return 0;
132}
133
134// 定义停止音频播放函数,该接口将由sdk调用,业务侧不需调用
135int app_sdk_audio_play_stop(void) {
136
137 g_has_play = false;
138 return 0;
139}
4.其他主要函数、事件代码说明
1# 下载链接中的各文件说明:
2./main/brtc_wrapper.c 智能体语音互动的demo程序代码, 演示了开启对话及退出对话的全流程。
3./include/baidu_chat_agents_engine.h 是BaiduRTC AGENT SDK的头文件。
4./libs/libbrtc.a 是BaiduRTC AGENT SDK的库文件。
5./README.md 说明文档;
6
7brtc_wrapper.c .c 中主要函数说明如下:
81). baidu_create_chat_agent_engine 创建智能体引擎
92). baidu_chat_agent_engine_init 初始化参数和设置事件回调
103). baidu_chat_agent_engine_call 开启智能体对话
114). baidu_chat_agent_engine_destroy 结束智能体对话和销毁
1# 智能体事件回调说明:
2typedef enum AGentCallState {
3 AGENT_LOGIN_SUCCESS = 1, //创建智能体与信令连接成功事件
4 AGENT_LOGIN_OUT_SUCCESS = 2, //登出RTC房间成功事件
5 AGENT_CALL_SUCCESS = 3, //登入RTC房间成功事件
6
7 AGENT_LOGIN_FAIL = 401, //创建智能体与信令连接失败事件,应用层可先退出,再重新登陆
8 AGENT_LOGIN_OUT_FAIL = 402, //登出RTC房间失败事件,表示baidu_chat_agent_engine_destroy失败
9 AGENT_CALL_FAIL = 403 //登入RTC房间失败事件,表示baidu_chat_agent_engine_call失败。
10} AGentCallState;
11
12typedef enum AGentConnectState {
13 AGENT_CONNECTION_STATE_DISCONNECTED = 1, //网络断开,应用层结合业务可重连操作
14 AGENT_CONNECTION_STATE_CONNECTING, //网络正在连接中
15 AGENT_CONNECTION_STATE_CONNECTED, //网络已连接
16 AGENT_CONNECTION_STATE_RECONNECTING //网络重连中
17} AGentConnectState;
进阶:常见问题及解决办法
语音识别不准确,一般是MIC收音问题:噪音或杂音太大,或者是声音能量值偏小(建议声音能量均值在40~50%),建议在端上优化降噪或增益效果;如端侧无法处理可尝试开启云上3A功能优化。
方法1:设备端上调优降噪ANS、增益AGC
./main/cli_intercom.c 通过配置aud_intf_voc_setup_t:mic_gain属性调整MIC的增益参数。
1# 调整增益接口
2int app_sdk_audio_record_start(int max_time_ms,int used_vad,app_sdk_record_feed_cb cb_feed,app_sdk_record_end_cb cb_end,char *format){
3 ...
4 aud_voc_setup.mic_gain = 0x30; //调整mic增益接口
5 ... ...
6}
方法2:云上调优自动降噪ANS、自动增益AGC
- 开启云上自动降噪与自动增益,请参见云端音频3A功能最佳实践
-
问题:端设备自言自语对话(播放的声音,回采后重新回答)
这种现象一般是回声消除异常导致,建议在端上优化AEC,端侧无法处理可尝试云上优化;或是采用采用单工对话方式。
方法1:设备上调优回声消除AEC
./main/cli_intercom.c 通过配置aud_intf_voc_setup_t:aec_enable属性可以打开AEC功能。
1# 调整AEC、speaker增益接口
2int app_sdk_audio_record_start(int max_time_ms,int used_vad,app_sdk_record_feed_cb cb_feed,app_sdk_record_end_cb cb_end,char *format){
3 ...
4 aud_voc_setup.aec_enable = true; //回声消除、消噪使能
5 aud_voc_setup.spk_mode = AUD_DAC_WORK_MODE_SIGNAL_END;
6 aud_voc_setup.mic_type = AUD_INTF_MIC_TYPE_BOARD;
7 aud_voc_setup.spk_type = AUD_INTF_SPK_TYPE_BOARD;
8 aud_voc_setup.samp_rate = 16000;
9 aud_voc_setup.spk_gain = 0x15; //调整speaker增益接口函数
10 ret = bk_aud_intf_voc_init(aud_voc_setup);
11 ... ...
12}
方法2:云上调优回声消除AEC
- 开启云上回声消除AEC功能,请参见云端音频3A功能最佳实践
方法3:切换到对话模式:按键说话、连续对话(唤醒词打断)
按键说话、连续对话(唤醒词打断),这两种是单工对话,不依赖回声消除功能,可解决这个问题。 可参考:语音对话集成模式介绍
在控制台上配置人设,高质量编写人设提示词
如何使用已定义的人设
创建智能体指定已定义的人设
1 - 在服务器上调用generateAIAgentCall接口,传入config参数`sceneRole:人设名称`。 人设名称就是控制台定义的人设名称。
动态切换已定义的人设及音色
在服务器上调用operation?switchSceneRole接口, 指定对应的人设名称、音色名。
-
设备未授权提示及处理办法
设备连接到服务器后,服务器会下发鉴权请求,如鉴权失败,设备有未授权提示,且服务器主动与设备断开连接。造成这个原因一般有3种情况:
Plain Text1* 设备连接服务未正确传入license、DeviceID、UserID信息,或者license无效。 注意:DeviceID可能是SDK自动获取硬件码,无需填写;Websocket对接则需显示传入。DeviceID、UserID要求appid纬度唯一。 2* 网络原因导致服务端未及时收到鉴权的响应。 建议切换到良好的网络。 3* 多台设备非法共用同一个license。 云端会检测到异常,主动断开设备连接。 -
判断对话响应延时正常与否,及优化建议
-
更多的资料从哪里找
- 集成流程完整介绍
- 声纹使用最佳实践
- 定时器使用最佳实践
- 多语言使用最佳实践
- 产品功能特性表介绍
- 更多的服务端接口
