给自己的官网加了个AI分身:把“官网”变成了24小时在线的AI具身智能数字人

0 阅读6分钟

(附代码 + 踩坑记录 + 官网截图,可直接复制使用)

一、痛点:一个人维护官网,消息根本回不过来

我有个个人官网——就是你们现在看到的这个。风格很赛博,有个旋转的线条地球,整体就是技术博客那味儿。

但有个问题一直没解决:

访客来了,留言了,我人不在。

  • 半夜有潜在客户想咨询?等第二天回复,黄花菜都凉了

  • 想了解我的项目经验?得自己翻作品集

  • 想知道我会什么技术?得在技能板块里慢慢找

我问自己:能不能给官网加个“我”的AI分身?7x24小时在线,访客一进来就能对话,还能配合表情和手势,像真人一样。

于是我把目光投向了魔珐星云。

为什么选择魔珐星云这套方案?

传统方案要做个能对话的数字人,需要自己搞定:3D建模、动作绑定、语音合成、口型同步、实时渲染……一套下来至少几个月,成本几十万起。

魔珐星云的端到端方案把这个链条彻底打穿了:

传统方案魔珐星云端到端
3D建模 → 绑定 → 动画 → 语音 → 口型 → 渲染输入文本 → 输出完整数字人表演
需要建模师、动画师、前端、后端一个前端工程师就够了
云端渲染传视频,延迟3-5秒云端只传KB级参数,端侧渲染,端到端响应约 500ms
单路成本高,并发困难百元级芯片就能跑,支持千路并发
动作靠手K,表情僵硬自研文生 3D 多模态大模型自动生成语音 + 表情 + 动作

简单说:魔珐星云把“让数字人动起来”这件事变成了一个API调用。我只需要关心“说什么内容”(交给Kimi),不用管“怎么动起来”(星云搞定)。

这也是我能用几十行代码、一下午时间,就给自己官网加上一个能说会动的AI分身的根本原因。

效果展示:

普通人也能给自己的网站加可随时交互的AI智能具身数字人?

魔珐星云把门槛拉到了最低:

  • 不需要3D建模:几千个现成角色随便选
  • 不需要GPU服务器:AI 端渲与端侧解算,百元级芯片就能跑
  • 不需要写复杂逻辑:几行JS代码搞定

二、环境要求-浏览器要求

项目要求
协议仅支持 localhosthttps 访问(不支持 file://http IP访问)
浏览器Chrome、Edge、Safari 最新版

三、快速开始

3.1 准备工作

第一步:引入SDK

在页面中引入以下依赖,容器必须有明确的宽高

<!DOCTYPE html>
<html lang="zh-CN">
<body>
  <!-- 容器必须有明确的宽高 -->
  <div style="width: 540px; height: 960px">
    <div id="sdk-container"></div>
  </div>
  <!-- 引入星云SDK -->
  <script src="https://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatar@latest.js"></script>
</body>
</html>

⚠️ 注意:请关注SDK版本号,建议使用 @latest 获取最新特性和效果。

第二步:创建应用,获取凭证

访问星云官网注册 魔珐星云官网

在「应用中心」创建具身驱动应用,选个符合“农民工前端”人设的数字人。

应用名称: 农民工前端AI分身(简短好记,限制20字)

备注: 个人官网AI数字人助手 ( 选填,方便自己辨识)

预览模式: ✅ 竖屏

下一步配置自己喜欢的样貌、声音、场景等信息(感觉有点像在玩游戏)。

创建成功后,获取:

  • App ID:应用唯一标识
  • App Secret:应用密钥(请妥善保管)

3.2 创建SDK实例

const xmovSDK = new XmovAvatar({
  containerId: '#sdk-container',        // 必填:容器元素ID
  appId: 'your_app_id',                  // 必填:应用ID
  appSecret: 'your_app_secret',          // 必填:应用密钥
  gatewayServer: 'https://nebula-agent.xingyun3d.com/user/v1/ttsa/session', // 必填
  hardwareAcceleration: 'prefer-hardware', // 开启硬件加速
  onWidgetEvent: (data) => {             // Widget事件回调
    console.log('Widget事件:', data);
  },
  onNetworkInfo: (networkInfo) => {      // 网络状态监听
    console.log('延迟:', networkInfo.rtt, 'ms');
  },
  onMessage: (message) => {              // SDK消息监听
    console.log('SDK消息:', message);
  },
  onStateChange: (state) => {            // 数字人状态变化
    console.log('数字人状态:', state);
  },
  onStatusChange: (status) => {          // SDK状态变化
    console.log('SDK状态:', status);
  },
  onVoiceStateChange: (status) => {      // 语音播放状态
    console.log('语音状态:', status);     // 'start' / 'end'
  },
  enableLogger: false                    // 是否打印SDK日志
});

(写好放置的位置和样式,这里就不冗余介绍了)

3.3 初始化并连接

await xmovSDK.init({
  onDownloadProgress: (progress) => {
    console.log(`资源加载进度: ${progress}%`);
    if (progress >= 100) {
      console.log('数字人加载完成!');
    }
  },
  initModel: 'normal'  // normal: 正常初始化 / invisible: 隐身初始化
});

3.4 驱动数字人说话

// speak(ssml, is_start, is_end)
// 非流式调用:一句话完整播报
xmovSDK.speak("你好,我是农民工前端的AI分身,有什么可以帮你的吗?", true, true);

3.5 销毁实例

页面卸载前必须调用,释放资源:

window.addEventListener('beforeunload', () => {
  xmovSDK.destroy();
});

3.6 效果展示

现在已经接入成功了,但是想要能够回复问题,还需要接入ai模型。

四、进阶接入

4.1 加上ai大脑

  async function getAIResponse(userMessage) {
  if (!KIMI_API_KEY || KIMI_API_KEY === '你的API_Key') {
    return "⚠️ 主人还没配置 API Key,快去 platform.moonshot.cn 申请一个吧~";
  }
  
  conversationHistory.push({ role: 'user', content: userMessage });
  if (conversationHistory.length > 20) {
    conversationHistory = conversationHistory.slice(-20);
  }
  
  try {
    const response = await fetch(KIMI_API_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${KIMI_API_KEY}`
      },
      body: JSON.stringify({
        model: 'moonshot-v1-8k',  // Kimi 模型,也可以用 'kimi-k2.6'
        messages: [
          { role: 'system', content: SYSTEM_PROMPT },
          ...conversationHistory
        ],
        temperature: 0.7,
        max_tokens: 300
      })
    });
    
    if (!response.ok) {
      const errorData = await response.json();
      console.error('API 错误:', errorData);
      return "😅 哎呀,AI 出了一点小问题,稍后再试吧~";
    }
    
    const data = await response.json();
    const reply = data.choices[0].message.content;
    conversationHistory.push({ role: 'assistant', content: reply });
    return reply;
    
  } catch (error) {
    console.error('调用ai 失败:', error);
    return "📡 网络好像有点问题,请检查网络连接后重试~";
  }
}

效果展示:

4.2 数字人状态切换

状态英文名说明调用方法
待机等待idle长时间无交互xmovSDK.idle()
待机互动interactive_idle可打断当前状态xmovSDK.interactiveidle()
倾听listen用户输入语音中xmovSDK.listen()
思考think用户提问后等待回复xmovSDK.think()
说话speak数字人正在说话xmovSDK.speak()
离线模式offlineMode不消耗积分xmovSDK.offlineMode()
在线模式onlineMode恢复正常模式xmovSDK.onlineMode()

4.3 SSML指令(KA动作)

想让数字人做出特定动作,可以使用SSML格式:

// 语义KA指令(如欢迎动作)
const ssml = `<speak>
  热烈
  <ue4event>
    <type>ka_intent</type>
    <data><ka_intent>Welcome</ka_intent></data>
  </ue4event>
  欢迎来到我的个人官网!
</speak>`;
xmovSDK.speak(ssml, true, true);

// 技能KA指令(如跳舞)
const danceSSML = `<speak>
  <ue4event>
    <type>ka</type>
    <data><action_semantic>dance</action_semantic></data>
  </ue4event>
  让我为你跳个舞吧~
</speak>`;
xmovSDK.speak(danceSSML, true, true);

4.4 其他常用方法

// 设置音量(0-1)
xmovSDK.setVolume(0.8);

// 切换隐身/正常模式
xmovSDK.switchInvisibleMode();

// 显示/隐藏调试信息
xmovSDK.showDebugInfo();
xmovSDK.hideDebugInfo();

// 主动隐藏/显示数字人(UI层面)
xmovSDK.changeAvatarVisible(false);  // 隐藏
xmovSDK.changeAvatarVisible(true);   // 显示

五、错误码与处理建议

类型错误码描述解决方案
初始化错误10001容器不存在检查 containerId 是否正确
10002Socket连接错误检查网络,刷新重试
10003会话错误检查App ID/Secret是否正确
10005超出房间并发限制调用 destroy() 释放旧连接
资源错误30001背景图片加载错误检查网络,刷新重试
30004资源下载错误检查网络,刷新重试
网络问题50001离线模式检查网络连接
50004网络断开自动重连,无需处理

完整错误码请参考官方文档。xingyun3d.com?utm_campaign=daily&utm_source=jixinghuiKoc83

整体总结

从“给官网加个AI分身”这个想法,到最终跑通一个能说会动的AI具身智能数字人,整个项目核心就三件事:用户输入 → 调ai拿回复 → 调星云让AI具身智能数字人说出来。就这么三步。

以前总觉得“做个AI具身智能数字人”是大厂才玩得起的黑科技。现在回头一看,就是一个API调用另一个API的事。

魔珐星云把具身交互做成了基础设施,ai把智能对话做成了基础设施。作为开发者,我们要做的就是把它们拼在一起。

官方链接:xingyun3d.com?utm_campaign=daily&utm_source=jixinghuiKoc83