AI具身交互:实现一个会说话的3D虚拟伴侣
引言传统的 3D 虚拟人更多停留在“形象展示”和“内容播报”阶段交互能力有限。如果给这些3D虚拟人注入大模型的理解与生成能力就可以它们从“呆头呆脑的形象”变成“拥有智慧的AI伴侣”。设想一下如果在网页、手机、大屏等任意终端屏幕上我们可以随时召唤一个具备大模型能力的 3D虚拟交互伙伴它能听懂你的问题实时给出回应并通过语音、表情和动作完成自然表达是不是一件非常有趣的事情本篇文章将结合 Trae 与魔珐星云 SDK带大家快速实现一个会说话、可打断、能交流的 智能AI 伴侣。AI 伴侣效果展示参考下面的图片和视频运行前端服务后只需在页面中输入App ID和App Secret点击“连接”按钮即可加载并创建一个 3D 虚拟人。连接成功后我们就可以在右侧对话面板中输入问题与其交流了。Demo 效果视频地址https://www.bilibili.com/video/BV1rtjo6MEJe从最终视频效果来看Demo 中的 3D 虚拟人已经具备了很强的交互性。借助大模型的理解与生成能力它能够理解用户提问并给出自然、连贯的回答同时通过语音、表情和动作完成具身表达让交互不再停留在单纯的文本层面。更重要的是3D 虚拟人的响应速度也非常快基本可以做到约 500ms 的低延迟响应整体交互体验比较流畅。而实现这样一个能听懂问题、实时回应、并完成自然表达的网页 AI 伴侣实际成本并不高。下文将介绍如何借助 Trae 和魔珐星云具身驱动 SDK快速搭建这个最小可运行 Demo。核心技术魔珐星云具身驱动SDK从零实现一个 3D 虚拟人交互并不容易背后需要打通一整套复杂链路3D 形象加载和端侧渲染文本转语音 TTS口型、表情、肢体动作同步AI 回复流式输出后的播报拼接用户打断、思考、倾听、待机状态切换低延迟和多终端兼容好在这些复杂能力已经有了成熟方案魔珐星云具身驱动SDK。魔珐星云是魔珐科技打造的「AI具身交互智能体开放平台」提供 AI 形象生成、多模态感知、大模型 Agent 认知、实时 3D 具象表达、机器人运控等端到端能力。借助其具身驱动 SDK我们可以把 AI 的表达方式从“文本回复”升级为“3D 多模态交互”基于文本输入实时生成语音、表情与动作驱动 3D 数字人完成自然表达。其核心功能包括实时 3D 数字人渲染与驱动支持在网页中加载并驱动 3D 数字人形象语音合成与口型同步支持文本/SSML 播报并自动完成语音、口型、表情同步多状态行为控制支持待机、互动待机、播报等状态切换Widget 组件展示支持字幕、图片、视频等内容展示事件回调与日志调试支持自定义事件回调方便接入业务逻辑和排查问题。具身驱动SDK对浏览器的要求目前具身驱动 SDK 已提供 JS 版本。也就是说只要终端支持浏览器内核就可以接入具备 AI 交互能力的 3D 虚拟人适用于网页、PC 客户端、车机、大屏等多种场景。其 SDK 支持的浏览器版本要求如下实战教程用Trae快速搭建3D虚拟人项目获取App ID、App Secret要使用具身驱动 SDK 快速创建一个可交互的 AI 虚拟形象首先需要登录魔珐星云控制台在应用中心创建一个驱动应用并完成角色、音色、场景和表演风格配置同时获取后续接入 SDK 所需的App ID和App Secret。参考下面的动图登录控制台后进入「应用管理」中的「驱动应用」Tab点击「开始创建」填写应用名称并确认。随后会进入形象选择页面可以根据业务场景选择合适的 3D 数字人形象。选择形象后还可以继续配置场景、音色和表演风格。确认配置无误后点击「保存」系统就会自动完成驱动应用创建。现在点击「接入SDK」按钮即可查看并复制App ID和App Secret用于后续网页 Demo 接入。核心代码实现具身驱动 SDK 的接入方式非常简单整体流程可以分为三步引入 SDK、初始化实例、调用播报方法。首先在页面中引入 SDKscriptsrchttps://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatarlatest.js/script然后创建 SDK 实例并完成初始化。这里需要将appId和appSecret替换为刚才在魔珐星云控制台中复制的内容constsdknewXmovAvatar({containerId:#sdk,// 必填数字人挂载容器appId:your_appid,// 必填应用 AppIDappSecret:your_appsecret,// 必填应用 AppSecretgatewayServer:https://nebula-agent.xingyun3d.com/user/v1/ttsa/session,// 必填服务接口地址// SDK 事件回调方便调试onMessage(message){console.log(SDK message:,message);},});// 初始化 SDK加载数字人资源awaitsdk.init({onDownloadProgress(progress){console.log(资源加载进度${progress}%);},});初始化完成后调用speak方法即可让数字人开口说话sdk.speak(你好石小石我是你的 AI 伴侣~,true,true);如果只是播报一句完整的话后两个参数通常都传true接下来我们可以把以上接入逻辑粘贴到 Trae 的 AI 对话框中让它帮我们快速生成一个基于 Vue 3 的最小 Demo。下面是Trae 生成的一个最小使用Demotemplate !-- 数字人挂载容器 -- div idsdk/div /template script setup import { onMounted, onBeforeUnmount } from vue; // 保存 SDK 实例 let sdk null; onMounted(async () { // 创建 SDK 实例 sdk new window.XmovAvatar({ containerId: #sdk, // 数字人挂载容器 appId: 你的 AppID, // 替换为控制台中的 AppID appSecret: 你的 AppSecret, // 替换为控制台中的 AppSecret gatewayServer: https://nebula-agent.xingyun3d.com/user/v1/ttsa/session, // SDK 事件回调方便查看运行状态 onMessage(message) { console.log(SDK message:, message); }, }); // 初始化 SDK加载数字人资源 await sdk.init({ onDownloadProgress(progress) { console.log(资源加载进度${progress}%); }, }); // 初始化完成后让数字人播报一句话 sdk.speak(你好我是你的网页 AI 伴侣很高兴见到你。, true, true); }); onBeforeUnmount(() { // 页面卸载时销毁 SDK释放资源 if (sdk) { sdk.destroy(); } }); /script style scoped #sdk { width: 800px; height: 450px; background: #000; border-radius: 12px; overflow: hidden; } /style启动项目后页面会渲染出 3D 数字人并在初始化完成后自动播报一句欢迎语。对接DeepSeek让AI伴侣具备智慧接入 DeepSeek获取 AI 回复前面的 Demo 已经可以让数字人播报固定文本。接下来我们单独接入 DeepSeek让页面具备 AI 回复能力。这里先不考虑复杂的流式输出只用最简单的非流式接口用户输入一句话前端请求 DeepSeek拿到完整回复后再交给数字人播报。首先准备一个 DeepSeek API Key然后在代码中定义// DeepSeek API KeyDemo 为了方便直接写在前端constDEEPSEEK_API_KEY你的 DeepSeek API Key;然后封装一个最简单的请求方法asyncfunctionaskDeepSeek(question){constresponseawaitfetch(https://api.deepseek.com/chat/completions,{method:POST,headers:{Content-Type:application/json,Authorization:Bearer${DEEPSEEK_API_KEY},},body:JSON.stringify({model:deepseek-chat,messages:[{role:system,content:你是一个网页 AI 伴侣请用简洁、自然、口语化的中文回答用户问题。,},{role:user,content:question,},],stream:false,}),});constdataawaitresponse.json();// 取出 DeepSeek 返回的回答内容returndata.choices?.[0]?.message?.content||抱歉我暂时没有想好怎么回答。;}这个方法只做一件事把用户的问题发送给 DeepSeek并返回 AI 的文本回复。可以先用一段简单代码验证接口是否正常asyncfunctiontestDeepSeek(){constanswerawaitaskDeepSeek(请用一句话介绍你自己);console.log(DeepSeek 回复,answer);}如果控制台能正常打印回复说明 DeepSeek 已经接通了。将 DeepSeek 回复交给数字人播报DeepSeek 接通后我们只需要把它返回的answer传给sdk.speak()数字人就可以把 AI 回复说出来。核心逻辑如下asyncfunctionaskAndSpeak(){if(!sdk){alert(请先初始化数字人);return;}constquestioninputText.value.trim();if(!question){alert(请先输入问题);return;}try{// 用户提问后让数字人进入思考状态sdk.think();// 请求 DeepSeek 获取回答constanswerawaitaskDeepSeek(question);// 将 AI 回复交给数字人播报sdk.speak(answer,true,true);}catch(error){console.error(DeepSeek 请求失败,error);// 出错时也可以让数字人播报错误提示sdk.speak(抱歉AI 服务暂时不可用请稍后再试。,true,true);}}这里为了让 Demo 更容易理解直接把 DeepSeek API Key 写在了前端。实际开发中不建议这样做正式项目应通过后端接口转发请求避免密钥泄露。进阶 API状态控制、流式播报与事件监听完成最小 Demo 后如果要把它升级成一个真正可交互的 AI 伴侣就需要用到一些进阶 API。这里重点介绍几个最常用的能力状态切换、流式播报、打断、音量控制和事件监听。数字人状态切换在真实交互中数字人不应该一直处于同一个状态而是要根据用户行为和 AI 响应过程切换状态。例如用户没说话时待机用户提问时进入思考AI 回复时开始播报用户打断时回到互动待机。常用状态 API 如下// 普通待机状态sdk.idle();// 互动待机状态常用于打断当前播报sdk.interactiveidle();// 进入离线模式此状态下不消耗积分sdk.offlineMode();// 从离线模式切回在线模式sdk.onlineMode();在 Demo 中最常用的是idle()和interactiveidle()// 初始化完成后让数字人进入待机状态awaitsdk.init();sdk.idle();// 用户点击“打断”按钮时打断当前播报functioninterrupt(){sdk.interactiveidle();}其中interactiveidle()很适合用来处理“打断”场景。比如数字人正在播报一段长文本用户想重新提问就可以先调用它让数字人回到互动待机状态再开始下一轮对话。对接大模型流式输出如果只是播报一句固定文本可以这样调用sdk.speak(欢迎使用魔珐星云,true,true);但在 AI 伴侣场景里大模型通常是流式返回内容的。此时可以多次调用speak()通过is_start和is_end标识告诉 SDK 当前文本处于哪一段。// 第一段is_start 为 trueis_end 为 falsesdk.speak(你好我是你的 AI 伴侣,true,false);// 中间段is_start 和 is_end 都为 falsesdk.speak(我可以陪你聊天、讲故事,false,false);// 最后一段is_start 为 falseis_end 为 truesdk.speak(也可以帮你解答问题。,false,true);参数说明sdk.speak(ssml,is_start,is_end);ssml播报文本也可以是 SSMLis_start是否为本轮播报的第一段is_end是否为本轮播报的最后一段。需要注意的是流式播报时建议先积攒一小段文本再开始调用speak()避免文本太短导致数字人频繁等待。同时前一轮speak(..., true)结束后不建议马上连续开启下一轮播报最好先通过interactiveidle()做一次状态切换。使用 SSML 触发动作speak()不仅可以传普通文本也可以传 SSML。通过 SSML 可以让数字人在播报时执行指定动作比如欢迎、挥手、跳舞等。例如让数字人说欢迎语时触发一个 Hello 动作constssmlspeak ue4event typeka/type dataaction_semanticHello/action_semantic/data /ue4event 欢迎来到星云具身 3D 数字人平台很高兴见到你。 /speak;sdk.speak(ssml,true,true);如果需要根据语义触发动作也可以使用ka_intentconstssmlspeak 热烈 ue4event typeka_intent/type dataka_intentWelcome/ka_intent/data /ue4event 欢迎各位来到今天的分享。 /speak;sdk.speak(ssml,true,true);这类能力很适合用于虚拟主持人、欢迎页、导览讲解等场景让数字人不只是“说话”而是能配合语义做动作表达。监听播报状态在真实项目中我们经常需要知道数字人什么时候开始说话、什么时候说完。可以通过onVoiceStateChange监听音频播放状态。constsdknewXmovAvatar({containerId:#sdk,appId:your_appid,appSecret:your_appsecret,gatewayServer:https://nebula-agent.xingyun3d.com/user/v1/ttsa/session,// 监听数字人播报状态onVoiceStateChange(status){console.log(数字人语音状态,status);// 开始说话if(statusvoice_start||statusstart){console.log(数字人开始播报);}// 播报结束if(statusvoice_end||statusend){console.log(数字人播报结束);}},});监听 SDK 消息和错误onMessage是调试时非常重要的回调。SDK 的错误信息、运行消息都可以通过它输出。constsdknewXmovAvatar({containerId:#sdk,appId:your_appid,appSecret:your_appsecret,gatewayServer:https://nebula-agent.xingyun3d.com/user/v1/ttsa/session,onMessage(message){console.log(SDK message:,message);// message 中通常包含 code、message、timestamp 等字段if(message.code){console.warn(SDK 错误码,message.code);console.warn(SDK 错误信息,message.message);}},});常见错误可以简单理解为几类10001容器不存在通常是containerId写错或 DOM 还没渲染10002Socket 连接异常可能是网络或服务连接问题10003会话创建失败优先检查appId、appSecret、应用配置30001背景图片加载失败40001音频解码失败50001 / 50002离线/在线状态变化50003 / 50004网络重试或网络断开。在开发阶段建议始终保留onMessage日志这样排查问题会快很多。音量与调试信息最后还有几个开发调试时比较实用的方法。控制音量// 静音sdk.setVolume(0);// 一半音量sdk.setVolume(0.5);// 最大音量sdk.setVolume(1);显示或隐藏调试信息// 显示调试信息sdk.showDebugInfo();// 隐藏调试信息sdk.hideDebugInfo();在联调阶段可以临时打开调试信息上线前再关闭保持页面干净。使用 Trae 完善交互体验到这里我们的 Demo 已经具备了基础能力页面可以加载 3D 虚拟人并通过 DeepSeek 获取 AI 回复再交给数字人进行播报。接下来我继续结合具身驱动 SDK 的常用 API让 Trae 帮我做多轮代码迭代逐步完善页面交互体验。这一步主要补充了几个能力支持在页面中输入App ID和App Secret无需手动修改代码增加连接状态展示方便判断 SDK 是否初始化成功增加对话面板用于和 AI 虚拟伴侣对话在请求 DeepSeek 时让数字人进入“思考”状态AI 回复后调用speak方法驱动数字人播报增加“打断”能力用户可以中断当前播报经过与 Trae 的多轮对话、调试和修复后最终交互效果界面如下实际使用时只需要在页面顶部输入App ID和App Secret点击“连接”完成初始化。连接成功后在输入框中输入问题虚拟助手就会调用 DeepSeek 获取回答并通过 3D 数字人形象进行语音播报。具体交互可以参考下面的视频Demo 效果视频地址https://www.bilibili.com/video/BV1rtjo6MEJe可以看到虚拟人的响应几乎没有延迟神情、动作都比较自然。如果你对当前的形象不满意在魔珐星云控制台创建新的形象更换App ID和App Secret即可。增加语音对话功能在上面的示例中我们已经完成了基本的文本输入、AI 回复和数字人播报能力。但在很多真实场景中比如车载大屏、商场导览屏、智能客服终端等语音对话往往才是更自然的交互方式。要实现语音对话能力其实并不复杂前端可以调用浏览器麦克风权限实时采集用户语音再通过语音识别服务将语音转换为文本随后把识别结果发送给大模型获取回复最后再交给魔珐星云 SDK 驱动 3D 虚拟人播报。这样就可以形成完整的语音交互闭环由于篇幅原因本文不展开语音识别和实时音频采集的具体实现后续我会单独写一篇文章拆解这一部分。如果你对 3D 虚拟人、AI 伴侣、具身智能交互、语音对话等方向感兴趣可以关注我的专栏后续会继续分享更多相关实践。总结借助本文可以看到通过魔珐星云具身驱动 SDK实现一个能说话、可互动的 3D 虚拟人物成本非常低。基于浏览器和安卓 SDK 的支持让它具备很强的终端兼容性让网页、移动端、大屏、车机等多种屏幕和应用都有机会接入 AI 具身交互智能体。这也意味着AI 不再只能停留在文本对话中而是可以通过 3D 形象、语音、表情和动作完成更自然的表达带来更接近真实陪伴的交互体验。当然本文只是一个最小可运行 Demo主要用于验证从 3D 数字人加载、语音播报到大模型回复的完整链路。后续还可以继续扩展流式回复、语音输入、自定义字幕、动作控制等能力让这个 AI 伴侣更加自然、智能和好用。本文中的 Demo 已经开源评论任意内容即可获得。