输入关键词搜索

AI 消息回调

更新时间: 2026/05/28 11:45:15

本文介绍使用网易云信嵌入式 SDK(NERTC SDK)在 AI 对话过程中,如何通过 OnAiData 回调接收和处理 AI 服务端下发的各类消息,包括工具控制、事件通知和内容传递。

消息类型

AI 服务端通过 OnAiData 回调向设备端下发消息,主要分为三大消息类型(type):

消息类型 标识 说明 典型场景
工具控制 tool 执行具体的设备功能调用 调节音量、控制播放、设备开关
事件通知 event AI 内部状态变化通知 AI 开始/结束说话、被打断
内容传递 content 传递结构化内容 情绪识别、表情动画

这三种类型在单次回调中是互斥的,即每次 OnAiData 回调的 type 字段只会是其中一种。

回调数据格式

on_ai_data 回调当前通过两个字段向设备侧传递消息:

  • ai_data->type:消息类型,例如 tooleventcontent
  • ai_data->data:该类型对应的 JSON 字符串负载

典型处理方式如下:先读取 type,再按类型解析 data

C++std::string type(ai_data->type ? ai_data->type : "", ai_data->type_len);
std::string data(ai_data->data ? ai_data->data : "", ai_data->data_len);

其中,data 的典型结构示例如下:

  • type = "tool" 时:
JSON{
    "timestamp": 1754654765,
    "request": "把声音调大一点",
    "toolCalls": [{
        "id": "call_123",
        "type": "function",
        "function": {
            "name": "good_bye_call",
            "arguments": "{}"
        }
    }]
}
  • type = "event" 时:
JSON{
    "event": "audio.agent.speech_stopped"
}
  • type = "content" 时:
JSON{
    "content": {
        "type": "emotion",
        "message": "happy"
    }
}

工具控制(Tool)

工具控制消息用于执行具体的设备功能调用,当 AI 识别到用户意图需要操作设备时,会下发此类消息。

使用流程

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#AFDDFF', 'primaryTextColor': '#5409DA', 'primaryBorderColor': '#4E71FF', 'lineColor': '#4E71FF', 'secondaryColor': '#FF9149', 'tertiaryColor': '#F8FAFC' }}}%%

sequenceDiagram
    participant User as 用户
    participant Device as 设备端
    participant AI as AI 服务
    participant Platform as 智能体平台

    Note over User, Platform: 配置阶段
    Platform->>AI: 配置工具函数(名称、参数)

    Note over User, Platform: 运行阶段
    User->>Device: 语音指令:"把声音调大一点"
    Device->>AI: 发送语音数据
    AI->>AI: 意图识别
    AI->>Device: OnAiData 回调<br/>type="tool"<br/>function="good_bye_call"<br/>arguments={}
    Device->>Device: 解析参数并执行结束通话流程

常见工具类型

实际工具函数名以智能体平台配置和设备侧解析逻辑为准。当前示例工程中,可用 good_bye_call 作为结束通话类工具函数示例。

工具功能 描述 arguments 参数示例
结束通话 执行挂断或结束当前通话流程 {}
播放控制 控制音乐播放 {"action": "play", "song": "歌曲名"}
设备控制 控制智能设备 {"device": "light", "state": "on"}
信息查询 查询设备状态 {"type": "battery"}

配置方式

网易云信智能体管理平台 中配置工具函数:

工具控制配置示例
tool-config.png

解析示例

C++void MyAppClass::HandleToolCall(cJSON* data_item) {
    cJSON* tool_calls_item = cJSON_GetObjectItem(data_item, "toolCalls");
    if (!cJSON_IsArray(tool_calls_item)) return;

    cJSON* tool_call;
    cJSON_ArrayForEach(tool_call, tool_calls_item) {
        cJSON* function_item = cJSON_GetObjectItem(tool_call, "function");
        if (!cJSON_IsObject(function_item)) continue;

        cJSON* name_item = cJSON_GetObjectItem(function_item, "name");
        cJSON* args_item = cJSON_GetObjectItem(function_item, "arguments");

        if (cJSON_IsString(name_item) && cJSON_IsString(args_item)) {
            std::string func_name = name_item->valuestring;
            std::string func_args = args_item->valuestring;
            
            // 处理结束通话
            if (func_name == "good_bye_call") {
                RTC_LOGI(TAG, "Receive tool call: good_bye_call");
                EndCurrentCall();
            }
            // 处理其他工具调用...
        }
    }
}

事件通知(Event)

事件通知消息用于将 AI 的内部状态变化通知给设备端,例如 AI 开始或结束说话。

支持的事件类型

事件标识 说明 典型处理
audio.agent.speech_started AI 开始说话 更新 UI 状态、显示说话动画
audio.agent.speech_stopped AI 结束说话 恢复待机状态
audio.agent.interrupted AI 被用户打断 停止播放、清空缓冲

当前示例工程中,audio.agent.speech_startedaudio.agent.speech_stopped 会被显式处理;audio.agent.interrupted 属于 SDK/服务端可能下发的事件,设备侧可按业务需要单独处理。

解析示例

C++void MyAppClass::HandleEvent(cJSON* data_item) {
    cJSON* event_item = cJSON_GetObjectItem(data_item, "event");
    if (!cJSON_IsString(event_item)) return;

    std::string event_str = event_item->valuestring;
    RTC_LOGI(TAG, "Received AI event: %s", event_str.c_str());

    if (event_str == "audio.agent.speech_started") {
        // AI 开始说话
        UpdateUIState(AI_SPEAKING);
        StartSpeakingAnimation();
    } else if (event_str == "audio.agent.speech_stopped") {
        // AI 结束说话
        UpdateUIState(AI_IDLE);
        StopSpeakingAnimation();
    } else if (event_str == "audio.agent.interrupted") {
        // AI 被打断
        HandleAIInterrupted();
    }
}

audio.agent.speech_stopped 表示 AI 结束说话;如果需要明确区分“自然结束”和“被打断”,建议结合 audio.agent.interrupted 事件一起处理。

内容传递(Content)

内容传递消息用于从服务端向设备端传递结构化的内容,例如情绪识别结果。设备端可以根据这些内容执行相应的表现,如播放动画。

情绪识别

情绪识别是内容传递的典型应用:

  1. 配置:在 网易云信智能体管理平台 配置情绪识别规则(如 happysad)。
  2. 触发:当对话内容命中规则时,服务端下发 content 消息。
  3. 处理:设备端解析情绪值并执行对应动画或表情。

配置方式

情感识别配置示例
emotion-config.png

解析示例

C++void MyAppClass::HandleContent(cJSON* data_item) {
    cJSON* content_item = cJSON_GetObjectItem(data_item, "content");
    if (!cJSON_IsObject(content_item)) return;

    cJSON* content_type_item = cJSON_GetObjectItem(content_item, "type");
    cJSON* message_item = cJSON_GetObjectItem(content_item, "message");

    if (cJSON_IsString(content_type_item) && cJSON_IsString(message_item)) {
        std::string content_type = content_type_item->valuestring;
        std::string message = message_item->valuestring;
        RTC_LOGI(TAG, "Content type: %s, message: %s", content_type.c_str(), message.c_str());

        // 处理情绪内容
        if (content_type == "emotion") {
            PlayEmotionAnimation(message);  // happy, sad, angry, etc.
        }
    }
}

完整解析代码

以下是完整的 OnAiData 回调处理代码,整合了三种消息类型的解析逻辑:

C++#include "cJSON.h"

void MyAppClass::OnAiData(const nertc_sdk_callback_context_t* ctx,
                          nertc_sdk_ai_data_result_t* ai_data) {
    if (!ai_data) {
        return;
    }

    std::string type(ai_data->type ? ai_data->type : "", ai_data->type_len);
    std::string data(ai_data->data ? ai_data->data : "", ai_data->data_len);
    RTC_LOGI(TAG, "NERtc OnAiData type=%s data=%s", type.c_str(), data.c_str());

    if (type.empty() || data.empty()) {
        return;
    }

    cJSON* data_json = cJSON_Parse(data.c_str());
    if (!data_json) {
        RTC_LOGE(TAG, "Failed to parse data JSON.");
        return;
    }

    if (type == "tool") {
        // 处理工具调用
        HandleToolCall(data_json);
    } else if (type == "event") {
        // 处理事件通知
        HandleEvent(data_json);
    } else if (type == "content") {
        // 处理内容传递
        HandleContent(data_json);
    }

    cJSON_Delete(data_json);
}
此文档是否对你有帮助?
有帮助
去反馈
  • 消息类型
  • 回调数据格式
  • 工具控制(Tool)
  • 使用流程
  • 常见工具类型
  • 配置方式
  • 解析示例
  • 事件通知(Event)
  • 支持的事件类型
  • 解析示例
  • 内容传递(Content)
  • 情绪识别
  • 配置方式
  • 解析示例
  • 完整解析代码