我用通义千问+星云SDK,给医院候诊区做了个能对话的数字人

上个月,我妈打电话说她去社区医院看病,在候诊区等了四十分钟,想问护士自己的号还有多久,护士头也不抬说"等着"。

我妈今年六十二,不太会用智能手机,也不知道去哪里查排队进度。这件事让我开始想一个问题:大模型这一波浪潮里,大家都在卷参数、卷排行榜,但真正走到线下场景——医院、政务大厅、社区服务中心——AI的存在感几乎是零。

大模型确实让AI学会了思考。但思考完了呢?纯文本的聊天框,放在手机里还行,你总不能指望一个七十岁的老大爷掏出一部手机,打开网页,输入"请问我的报告出来了吗"。
[图片]

问题出在哪:AI有大脑,没有身体

我花了几天时间调研,发现医疗场景对AI的需求其实很明确:它需要一个可视化的载体,一个站在终端屏幕后面的"人",能看、能说、能随时被打断。

这就是具身交互智能的概念——不是让AI在云端回答问题,而是给它一个可视化的形象,同步语音、表情和动作,在真实的物理空间里和人面对面交互。

现有的方案大致分两类。一类是纯文本Agent,接上大模型就能用,但交互全靠打字,对老年人极不友好。另一类是传统数字人方案,我试了几个开源的,延迟基本在2秒以上,而且不支持用户实时打断——想象一下,数字人在那里念了一大段术前须知,患者突然想问"这个检查疼不疼",结果数字人根本不理会,还在继续念。

这种体验,别说患者了,我自己都受不了。

我的方案:通义千问 + 星云SDK + 医院平板

技术选型上我做了比较简单的决定:

大模型选了通义千问,中文医疗问答的效果不错,关键是API稳定、价格合理。Agent层我自己写了一个轻量的任务调度,负责把患者的语音转文字后路由到不同的知识库——挂号引导、科室介绍、检查须知、报告解读,四个模块。

交互层是关键。我需要一套SDK,能把大模型的文字回复变成一个3D数字人的实时播报,包括语音、口型、表情和肢体动作。试了几个方案之后,最终用了魔珐星云的SDK。

选它的原因比较实际:第一,自研的参数流+AI端侧解算,端到端延迟大约在500ms左右,这个数字在实际体验中意味着"说完话几乎就能看到数字人开口";第二,支持随时打断,这在医疗场景里是刚需——患者随时可能插嘴问问题;第三,硬件要求低,医院候诊区那台落灰的安卓平板就能跑。

核心代码其实不长

整个项目的技术含量不算高,核心就是SDK的初始化和交互逻辑。

// 初始化星云SDK
const sdk = new XmovAvatar({
  containerId: "#digital-human",
  appId: "YOUR_APP_ID",
  appSecret: "YOUR_APP_SECRET",
  gatewayServer: "https://nebula-agent.xingyun3d.com/user/v1/ttsa/session",
  onMessage: (msg) => {
    if (msg.type === "voice_state_change") {
      handleVoiceState(msg.state);
    }
  },
  proxyWidget: {
    // 接管字幕事件,用自定义样式展示
    "subtitle_on": (data) => {
      document.getElementById("subtitle").innerText = data.text;
      document.getElementById("subtitle").style.display = "block";
      return false; // 屏蔽默认字幕
    },
    "subtitle_off": () => {
      document.getElementById("subtitle").style.display = "none";
      return false;
    }
  }
});

await sdk.init({
  onDownloadProgress: (p) => {
    if (p < 100) updateLoadingUI(p);
  }
});

播报部分,大模型返回的文字会按句拆分,流式发给SDK:

// 流式播报:大模型回复按句切分
function streamResponse(sentences) {
  sentences.forEach((sentence, index) => {
    const isFirst = index === 0;
    const isLast = index === sentences.length - 1;
    sdk.speak(sentence, isFirst, isLast);
  });
}

打断逻辑是医疗场景的重点。患者随时可能开口问问题,这时候需要先打断数字人当前的播报:

// 患者插话:先打断,等状态恢复再播报新内容

function onPatientInterrupt(newQuestion) {
  sdk.interactiveidle(); // 发送打断信号
  // 在onVoiceStateChange回调中,等状态变为idle后再speak新内容
  pendingQueue.push(newQuestion);
}

实际体验如何

我把这个Demo放在一台普通的安卓平板上,屏幕里站着一个穿白大褂的数字人。患者走到前面,可以直接说话问问题。

测试了两周,有几点观察:

老年患者的使用门槛确实降低了。以前让他们在手机上填问卷,十个有八个不会,现在对着屏幕说话就行。有个大爷做完检查出来,对着数字人问"我这个CT结果严不严重",数字人用通俗的话给他解释了一下影像报告的结论,他听完说了句"比那个挂号窗口的小姐态度好多了"。

打断功能的使用频率比我预想的高。大约30%的交互中,患者会在数字人说话的过程中插嘴。如果支持不了打断,体验会非常糟糕。

延迟方面,500ms左右的端到端延迟在面对面场景中基本感觉不到。之前用另一个方案做测试,延迟1.5秒以上,患者会明显愣住,然后重复自己说过的话。

一些思考

这个项目本身不大,但让我对"具身交互智能"这个方向有了比较具体的理解。大模型解决了AI的思考能力,但思考只是起点。在医疗、政务、零售这些线下场景里,AI需要一个"身体"——一个可视化的、能实时交互的载体,才能真正和人建立连接。

星云SDK在这个项目中扮演的角色,就是给AI补上了这个"身体"。它不是大模型,不是Agent框架,它是交互层——负责把文字变成语音、表情和动作,让用户感觉到对面"站着"一个可以交流的对象。

如果你也在考虑把大模型落地到线下终端,可以去星云官网看看SDK和文档,免费的,先跑个Demo感受一下延迟和交互效果,再决定技术路线。
暂时无法在飞书文档外展示此内容
官方地址:https://xingyun3d.com/?utm_campaign=daily&utm_source=juzhen

Logo

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

更多推荐