从一个真实场景说起

上周陪朋友去美容店看皮肤,进门看到一块大屏,上面跑着一个聊天框式的美容科普助手。朋友试着问了一句"可以看看我的皮肤问题吗",屏幕上弹出一大段文字。朋友皱了皱眉,没看完就走了。

这个场景让我意识到一个问题:Agent 的"大脑"已经很聪明了,但"身体"还停留在聊天框里。

大模型让 AI 具备了理解、推理和生成能力,Qwen、DeepSeek 这些模型在知识问答上已经非常能打。但如果 AI 要真正进入门店、展厅、教育、文旅这些终端场景,仅靠聊天框是远远不够的。用户在门店里不会耐心读一大段文字——他们期望的是走过去、开口问、看到一个"人"在回应自己。

这就是我最近在探索的方向:具身交互智能——让 AI 拥有身体、感知世界、理解环境,并通过语音、表情、动作和实时响应,自然地与人交互。

说白了,大模型解决 AI 的"大脑",魔珐星云补齐 AI 的"身体、表达和交互"。

魔珐星云是什么?

在开始实操之前,先简单说下我用的工具,(魔珐星云)不是单纯的数字人工具,也不是 Agent 套壳工具,而是具身交互智能开放平台。它补齐的是大模型和 Agent 在真实终端落地时缺少的"交互层":

  • 大模型负责理解和生成

  • Agent 负责任务执行和流程调度

  • 星云负责让 AI 拥有身体、表达能力和实时交互体验

  • 最终让 AI 从聊天框进入屏幕、网页、APP、机器人、大屏、AR/VR 等终端

技术层面,它实现了端到端全链路,封装为 SDK 一站式接入:多模态感知层(听见·看见·理解)× 大模型智能体层(理解·决策·调度)× 表达引擎层(3D 大模型·端侧渲染·百元芯片可跑·千路并发)。

下面是我用魔珐星云 SDK + 豆包大模型,搭建一个医美顾问具身 Agent 的完整过程。

技术架构与工具选型

整体链路:

用户语音 → 文本 → doubao LLM → 流式文本 → 魔珐星云SDK(参数流驱动) → 3D数字人实时表达
模块 选型 理由
AI Coding 工具 Cursor 代码补全 + 对话式编程,前端 Demo 效率高
大模型 豆包(豆包) 零售领域知识面广,OpenAI 兼容 API 接入简单,流式输出稳定
ASR 腾讯云实时语音识别 流式识别,文档全
数字人驱动 魔珐星云具身驱动 SDK(JS 版) 参数流技术,端到端约 500ms 响应
前端框架 原生 HTML + JS 最小依赖,方便读者复制体验

为什么选 豆包?因为门店导购场景需要中文语境理解 + 商品知识,Qwen 在中文零售场景的表现不错,而且阿里云 DashScope 提供了 OpenAI 兼容接口,对接成本极低。

实操:从零搭建门店导购具身 Agent

Step 1:在魔珐星云平台创建驱动应用

登录魔珐星云官网,进入控制台 → 应用管理 → 创建驱动应用。

在这里插入图片描述

按流程选择数字人形象、场景、音色和表演风格。门店导购场景我选了一个职业女性形象,音色选了亲切自然的风格。

创建完成后点击「App 密钥」,拿到 App IDApp Secret

Step 2:最小可用——让数字人出现在页面上

打开 Cursor,新建一个 HTML 文件。这一步目标很简单:让数字人渲染出来。

核心就四步:定义容器 → 引入 SDK → 创建实例 → 初始化连接。

index.html 中引入数字人渲染SDK,这是整个系统的核心依赖:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>医美科普顾问 - 专业护肤指导t</title>
  <style>
    /* 容器比例需与控制台选择的应用类型一致(横屏16:9) */
    #avatar-container {
      width: 800px;
      height: 450px;
      position: relative;
      background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
      border-radius: 12px;
      overflow: hidden;
    }
    #sdk {
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
  <div id="avatar-container">
    <div id="sdk"></div>
  </div>

  <!-- 引入魔珐星云具身驱动SDK -->
  <script src="https://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatar@latest.js"></script>

  <script>
    const sdk = new XmovAvatar({
      containerId: '#sdk',
      appId: 'your_appid',          // 替换为你的 App ID
      appSecret: 'your_appsecret',   // 替换为你的 App Secret
      gatewayServer: 'https://nebula-agent.xingyun3d.com/user/v1/ttsa/session',
      hardwareAcceleration: 'prefer-hardware', // 开启硬件加速提升渲染
      onMessage: (message) => {
        console.log('SDK message:', message);
      },
    });

    sdk.init({
      onDownloadProgress: (progress) => {
        console.log('资源加载:', progress + '%');
      },
    });

    // 页面关闭前主动销毁,避免房间并发限制
    window.addEventListener('beforeunload', () => {
      if (sdk) sdk.destroy();
    });
  </script>
</body>
</html>

注意:SDK 仅支持 localhosthttps 访问,直接用 IP 打开会报 VideoDecoder is not defined。本地调试用 localhost 就行。

浏览器打开页面,资源加载完成后数字人就出现了。
在这里插入图片描述

踩坑提醒:开发时频繁刷新页面容易触发 10005 房间限流 错误。原因是页面刷新后服务端旧连接还没释放,新连接被拒。解决办法就是上面代码里的 beforeunload 监听——页面卸载前调用 sdk.destroy() 主动释放连接。如果已经触发了,等 1-2 分钟自动恢复。

Step 3:接入 豆包 大模型,让导购"有脑子"

在 Cursor 里新建 llm.js,用 doubao 的 OpenAI 兼容接口做流式对话:

import OpenAI from 'openai'

// 初始化客户端(兼容豆包等国产大模型)
const client = new OpenAI({
  apiKey: process.env.LLM_API_KEY,
  baseURL: process.env.LLM_BASE_URL  // 如:https://ark.cn-beijing.volces.com/api/v3
})

// 医美科普场景的System Prompt
const SYSTEM_PROMPT = `你是一位专业的医美科普顾问,名叫小颜。你的职责是:
1. 用通俗易懂的语言讲解护肤项目的原理和流程
2. 提供术后注意事项的专业建议
3. 话术温和专业,避免夸大效果和医疗承诺
4. 遇到超出科普范围的问题,建议顾客咨询专业医生
5. 绝对不使用"保证治愈"、"100%有效"等绝对化用语`

// 非流式对话
async function sendMessage(messages) {
  const response = await client.chat.completions.create({
    model: process.env.LLM_MODEL_ID,
    messages: [
      { role: 'system', content: SYSTEM_PROMPT },
      ...messages
    ],
    temperature: 0.7,
    max_tokens: 1024
  })
  return response.choices[0].message.content
}

// 流式对话(推荐,体验更好)
async function* sendMessageStream(messages) {
  const stream = await client.chat.completions.create({
    model: process.env.LLM_MODEL_ID,
    messages: [
      { role: 'system', content: SYSTEM_PROMPT },
      ...messages
    ],
    temperature: 0.7,
    max_tokens: 1024,
    stream: true
  })
  for await (const chunk of stream) {
    const content = chunk.choices[0]?.delta?.content || ''
    if (content) yield content
  }
}

要点:

  • 使用 OpenAI SDK 的兼容接口对接豆包等国产大模型,只需修改 baseURLapiKey

  • System Prompt 是规避风险的核心:明确规定禁止使用绝对化用语,超出范围引导咨询医生

  • 流式输出配合数字人的逐句播报,体验更自然

Step 4:流式驱动数字人说话——客服主组件(CustomerService.vue)

核心交互逻辑组件,连接数字人渲染与AI对话:

// speech-manager.js - 语音状态管理 + 流式对话
const avatarManager = {
  _pendingText: null,

  // 打断当前播报,排队新内容
  interruptAndSpeak(text) {
    this._pendingText = text;
    sdk.interactiveidle(); // 打断当前状态
  },

  // 监听数字人语音状态,上一句结束后再播下一句
  handleVoiceState(res) {
    const state = (typeof res === 'string') ? res : (res.state || res.data);
    if ((state === 'end' || state === 'idle') && this._pendingText) {
      const nextText = this._pendingText;
      this._pendingText = null;
      sdk.speak(nextText, true, true);
    }
  }
};

// 流式对话主流程:Qwen 输出 → 星云驱动
async function chatAndSpeak(userMessage) {
  let accumulated = '';
  let chunkCount = 0;
  const CHUNK_THRESHOLD = 8; // 积攒一定字数再驱动,保证播报流畅

  await streamChat(userMessage, (chunk) => {
    accumulated += chunk;
    chunkCount++;

    if (chunkCount >= CHUNK_THRESHOLD) {
      const isStart = (accumulated === chunk);
      sdk.speak(accumulated, isStart, false);
      accumulated = '';
      chunkCount = 0;
    }
  });

  // 最后一段
  if (accumulated) {
    sdk.speak(accumulated, false, true);
  }
}

Step 5:后端代理服务,让导购更专业

出于安全考虑,大模型API密钥不应暴露在前端。使用 Express 搭建轻量代理:

import express from 'express'
import cors from 'cors'
import dotenv from 'dotenv'
import OpenAI from 'openai'

dotenv.config()

const app = express()
app.use(cors())
app.use(express.json())

const client = new OpenAI({
  apiKey: process.env.LLM_API_KEY,
  baseURL: process.env.LLM_BASE_URL
})

// 流式对话代理
app.post('/api/chat', async (req, res) => {
  try {
    const { messages } = req.body
    const stream = await client.chat.completions.create({
      model: process.env.LLM_MODEL_ID,
      messages,
      stream: true,
      temperature: 0.7,
      max_tokens: 1024
    })

    res.setHeader('Content-Type', 'text/event-stream')
    res.setHeader('Cache-Control', 'no-cache')
    res.setHeader('Connection', 'keep-alive')

    for await (const chunk of stream) {
      const content = chunk.choices[0]?.delta?.content || ''
      if (content) {
        res.write(`data: ${JSON.stringify({ content })}\n\n`)
      }
    }
    res.write('data: [DONE]\n\n')
    res.end()
  } catch (error) {
    console.error('API代理异常:', error)
    res.status(500).json({ error: '服务暂时不可用' })
  }
})

app.listen(3001, () => {
  console.log('代理服务运行在 http://localhost:3001')
})

Step 6:环境变量配置

在项目根目录创建 .env 文件:

# 数字人SDK配置
VITE_XINGYUN_APP_ID=your_app_id
VITE_XINGYUN_APP_SECRET=your_app_secret
VITE_AVATAR_ID=your_avatar_id
VITE_VOICE_ID=your_voice_id

# 大模型配置(后端使用,不以VITE_开头)
LLM_API_KEY=your_api_key
LLM_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
LLM_MODEL_ID=your_model_endpoint_id

安全提示:

  • VITE_ 前缀的变量会暴露到前端,仅放SDK相关配置

  • API密钥等敏感信息放在后端,通过代理接口访问

  • .env 文件必须加入 .gitignore,禁止提交到代码仓库

Step 7:安装与运行

# 安装依赖
npm install

# 启动开发服务器(前端)
npm run dev

# 启动后端代理(另一个终端)
node server.js

# 构建生产版本
npm run build

# 预览生产版本
npm run preview

星云官方也提供了完整的 Vue 3 Demo,GitHub 仓库:https://github.com/publicize0828/XmovLiteAvatarJSDemo,ASR 和 LLM 的封装更完善,可以直接 clone 下来改。

医美场景话术规范要点

在 System Prompt 设计中,以下规则至关重要:

  1. 禁止绝对化用语:不使用”保证治愈”、”100%有效”、”完全无副作用”等表述

  2. 效果描述留余地:用”多数用户反馈”、”一般而言”等限定词

  3. 主动引导线下咨询:涉及具体方案和定价时,建议”到店由专业医生面诊”

  4. 术后护理标准化:按项目类型提供通用护理要点,同时声明”个体差异请遵医嘱”

  5. 敏感问题转人工:涉及不适症状、过敏反应等,立即建议就医

在这里插入图片描述

Step 7:部署建议

  1. 大屏适配:数字人展示区建议使用 16:99:16 比例,CSS通过 vw/vh 适配大屏

  2. 离线兜底:AI服务不可用时,预设常见问题的标准回复脚本,确保数字人仍可播报

  3. 自动循环:闲时自动播放项目介绍、护理知识等预设内容,提高大屏利用率

  4. 并发控制:门店大屏场景通常为单用户交互,无需考虑高并发,但流式接口需做好超时处理

在这里插入图片描述

跑通之后的几点真实感受

1. 参数流方案是真正解决视频流痛点的

之前接触过其他数字人方案走视频流路线,一个屏幕一路推流,门店 10 块屏带宽就吃满了。星云的参数流方案下发的数据量极小,通过 AI 端渲和端侧解算在端侧完成渲染,并发几乎不受限。百元级硬件芯片就能跑,这对门店规模化部署是硬指标。

2. 端到端约 500ms 响应,体感够用

从用户开口到数字人开始回答,整体延迟约 1.2 秒(含 ASR +doubao + SDK 驱动)。纯 SDK 驱动环节端到端约 500ms,日常对话基本无感知。之前试过的一些方案动辄 3-5 秒,用户早就走了。

3. AI Coding 工具让开发效率翻倍

这个项目用 Cursor 写代码、豆包 做 Agent 大脑,从零到跑通大概半天。Cursor 对 SDK 接入这种有固定模式的代码补全效果很好,基本写个注释它就帮你生成。豆包在美容科普顾问场景的回答质量也不错,口语化表达和主动引导都到位。

4. 具身交互是 Agent 落地的关键拼图

这是最重要的一点。纯文本 Agent 解决的是"能不能回答"的问题,但 Agent 落地到真实场景,面对的是"用户愿不愿意问"的问题。一个有形象、能微笑、会点头的 3D 数字人,和一个冷冰冰的聊天框,用户的心理门槛完全不同。魔珐星云数字人作为可实时交互的具身智能体,补齐的正是纯文本交互生硬、无拟人反馈的行业痛点。

小结

Agent 赛道的竞争正在从"谁的模型更聪明"转向"谁能让用户更自然地用起来"。大模型让 AI 学会了思考,下一步是让 AI 进入终端——以具身的方式与人交互。

魔珐星云补齐的正是 Agent 落地最缺的那块:可实时交互的具身智能体形态。参数流 + AI 端渲的技术路线在低延时、高并发、低成本上的优势,让它能在门店导购、展厅大屏、财税咨询这类需要"面对面"交互的场景真正跑起来。一套 SDK 同步适配屏幕、人形机器人、AR/VR 眼镜全品类终端,对开发者来说接入门槛很低。

如果你也在做 Agent 落地,不妨试试给你的 Agent 一个"身体"——也许就是从对话框到大屏的那一步,决定了你的 Agent 是被用起来还是被搁置。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐