基于DeepSeek+魔珐星云具身交互智能的垃圾分类助手落地实战
基于DeepSeek+3D具身交互智能的垃圾分类助手落地实战
如何将我们的产品拟人化?先给大家抛出一个问题,大家可以思考一下。
这两年真的太明显了,不管是深圳还是全国,人形机器人、具身智能这个赛道直接彻底爆火,绝对是 AI 接下来的核心风口。
我最近闲下来总刷各类博主的实测测评,发现近两年人形硬件机器人赛道热度高涨,但实体设备成本高、线上大屏、社区科普等轻量化场景难以复用;而纯文本国产大模型又缺少可视化交互载体。很多企业、社区都有疑问:官网接待、科普大屏、24 小时宣教这类轻量化线上场景,该低成本搭建专属具身交互智能体?
常规我们的AI对话仅依托 DeepSeek 这类国产大模型搭建纯文本问答,交互模式极度单一冰冷,没有具象载体支撑自然沟通。是不是看起来蛮死板的?

接入补齐完整具身交互智能后,3D 具身交互智能体搭配同步表情、手势,科普交互体验实现质的升级,是不是看起来生动形象了很多。
早年间我们做线上服务、智能科普,方式真的特别简陋。要么靠人工客服24小时值守,人力成本巨高还容易出错;要么搭个简单的RAG知识库问答,交互死板、功能单一,毫无体验感,用来做垃圾分类科普基本没人愿意看。
如今国产大模型能力日趋成熟,搭配AI具身智能数字人标准化具身交互智能底座,即可实现真人般的细腻表情、自然流畅的肢体动作、贴合场景的语音播报,再加上大模型的智能问答能力,接入难度极低,不用组建专业研发团队,就能直接落地到网站、大屏、线上科普场景中。
魔珐星云官网:点击查看链接
二、落地实拍:彻底换掉老旧死板的垃圾分类科普

大家平时小区里的垃圾分类大屏,基本都是摆设:几张静态海报、固定文字介绍,没人愿意看。社区、学校想做科普,要么靠人工值守讲解,费人费力;要么就是无人问津的展板,根本起不到效果。
但换成DeepSeek打造的的3D具身垃圾分类助手**之后,整个体验直接升级。一块普通大屏,直接变成24小时在岗的专属环保讲解员,不用人工看管,随时有人问就随时答。
给大家描述下真实使用场景:居民扔垃圾拿不准,直接对着大屏提问,“奶茶杯是什么垃圾”“废电池怎么扔”“破损陶瓷碗属于哪一类”。屏幕里的3DAI助手会带着自然的表情、抬手、点头,一边做动作一边口语化讲解,不仅说清分类类别,还会提醒投放注意事项。遇到复杂的混合垃圾,会一步步拆解说明,而且你随时可以打断它、问新问题,互动感拉满,完全不像机器。

对比传统方案,是不是看起来很拟人化。
三、硬核实战:单文件搭建DeepSeek+AI数字人垃圾分类智能助手


本次实战无需复杂后端架构,抛弃Node.js、FastAPI中转,仅通过单HTML文件+原生SSE流式解析+XmovAvatar****具身交互 SDK,快速搭建可直接运行、可实时交互的3D具身垃圾分类智能助手。全程前端轻量化部署,开发者零门槛复刻,快速落地垃圾分类具身AI场景。
3.1 前期准备工作
咱们先把准备工作说清楚,超级简单,没有任何复杂操作,小白照着弄就行。
首先需要两个核心凭证,一个是 DeepSeek 大模型的 API Key,另一个是AI数字人的应用密钥。
Ai-DeepSeek官网:https://deepseek.com/

DeepSeek 的 Key 大家自己去官网注册、开通额度就能拿到,现在国产大模型开户都很方便,免费额度完全够咱们测试 Demo 使用,我这里就不啰嗦细讲流程了。
重点说下数字人这边:大家直接点击链接打开官网,注册登录之后,新建一个自己的具身交互智能应用。里面可以随便选喜欢的数字人形象、适配科普场景的音色、默认待机动作,全部可视化操作,点点鼠标就能配置好。

配置完成之后,后台会自动生成两个关键信息:App ID、App Secret,这两个东西一定要保存好,后面代码里必须用到。

所有准备工作就这三步,搞定之后,咱们直接上手写代码、跑项目。
先准备好大模型和数字人3D应用的配置:
这里我是用的deepseek作为大模型底座,这个自己去deepseek的平台创建API获取key就OK了 这里就不赘述了
3.2 完整可直接运行源码
我把所有代码都精简好了,整站就一个 HTML 文件,不用搭后端、不用装依赖、不用配置环境。大家直接复制下面全部代码,新建一个 index.html 文件粘贴进去,只需要替换里面三处自己的密钥,直接就能跑通完整的垃圾分类数字人交互效果,提示:此处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>垃圾分类小助手 - 3D 智能导览</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatar@latest.js"></script>
<style>
body {
background: linear-gradient(180deg, #022c22 0%, #064e3b 50%, #0f766e 100%);
background-attachment: fixed;
}
#avatar-container {
background: linear-gradient(135deg, #047857, #022c22);
box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.5);
}
.glass-panel {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.category-card {
transition: all 0.3s ease;
}
.category-card:hover {
transform: translateY(-4px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
}
.glow-text {
text-shadow: 0 0 20px rgba(74, 222, 128, 0.5);
}
</style>
</head>
<body class="text-green-50 min-h-screen">
<div class="w-full max-w-6xl mx-auto p-4 md:p-6">
<header class="mb-6 text-center">
<div class="inline-flex items-center gap-3 mb-2">
<span class="text-4xl animate-bounce">🌍</span>
<h1 class="text-3xl md:text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-green-300 via-emerald-400 to-teal-300 glow-text">
♻️ 垃圾分类智能助手
</h1>
<span class="text-4xl animate-bounce" style="animation-delay: 0.5s">🌱</span>
</div>
<p class="text-green-300/80 text-sm md:text-base">智能识别 · 精准分类 · 共建绿色家园</p>
</header>
<div class="grid grid-cols-4 gap-3 mb-6">
<div class="category-card glass-panel rounded-xl p-4 text-center cursor-pointer hover:bg-blue-600/20">
<div class="w-12 h-12 mx-auto mb-2 rounded-full bg-blue-600 flex items-center justify-center text-2xl shadow-lg shadow-blue-600/30">♻️</div>
<span class="text-xs md:text-sm font-medium text-green-100">可回收物</span>
</div>
<div class="category-card glass-panel rounded-xl p-4 text-center cursor-pointer hover:bg-red-600/20">
<div class="w-12 h-12 mx-auto mb-2 rounded-full bg-red-600 flex items-center justify-center text-2xl shadow-lg shadow-red-600/30">☠️</div>
<span class="text-xs md:text-sm font-medium text-green-100">有害垃圾</span>
</div>
<div class="category-card glass-panel rounded-xl p-4 text-center cursor-pointer hover:bg-yellow-500/20">
<div class="w-12 h-12 mx-auto mb-2 rounded-full bg-yellow-500 flex items-center justify-center text-2xl shadow-lg shadow-yellow-500/30">🥬</div>
<span class="text-xs md:text-sm font-medium text-green-100">厨余垃圾</span>
</div>
<div class="category-card glass-panel rounded-xl p-4 text-center cursor-pointer hover:bg-gray-500/20">
<div class="w-12 h-12 mx-auto mb-2 rounded-full bg-gray-500 flex items-center justify-center text-2xl shadow-lg shadow-gray-500/30">🗑️</div>
<span class="text-xs md:text-sm font-medium text-green-100">其他垃圾</span>
</div>
</div>
<div class="glass-panel rounded-2xl shadow-2xl overflow-hidden">
<div class="relative h-[450px] md:h-[500px]" id="avatar-container">
<div id="sdk_canvas" class="w-full h-full"></div>
<div id="loading-tips" class="absolute inset-0 flex flex-col items-center justify-center bg-black/60 p-4 text-center">
<div class="animate-spin rounded-full h-16 w-16 border-4 border-green-400 border-t-transparent mb-4"></div>
<p class="text-lg text-green-100">环保小助手正在准备中...</p>
<p class="text-sm text-green-400/70 mt-2">首次加载需下载资源,请耐心等待</p>
</div>
<div class="absolute top-4 right-4 bg-black/40 backdrop-blur-md px-4 py-2 rounded-full text-sm flex items-center gap-2 border border-green-500/30">
<span class="h-2 w-2 rounded-full bg-emerald-400 animate-pulse shadow-lg shadow-emerald-400/50"></span>
<span id="status-text" class="text-green-200">环保小助手未就绪</span>
</div>
</div>
<div class="p-6 md:p-8 bg-green-950/30">
<div id="chat-output" class="h-[200px] md:h-[250px] overflow-y-auto bg-black/20 rounded-xl p-4 mb-4 text-sm space-y-3">
<div class="text-center text-green-400/60 text-xs py-4">
💡 有任何垃圾分类的问题,随时问我哦!<br>
<span class="text-green-500/50">表达层首响更快,完整问答耗时仍取决于大模型、网络和文本长度</span>
</div>
</div>
<div class="space-y-3">
<div class="flex gap-3">
<input type="text" id="user-input" placeholder="输入你想问的垃圾分类问题,比如:苹果核属于什么垃圾?"
class="flex-1 bg-black/30 border border-green-700/50 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-green-400 focus:ring-2 focus:ring-green-400/20 transition-all">
<button id="send-btn" class="bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-400 hover:to-emerald-400 px-6 py-3 rounded-xl text-sm font-semibold transition-all shadow-lg shadow-green-500/25 active:scale-95">
发送
</button>
</div>
<button id="stop-btn" class="w-full bg-red-900/30 hover:bg-red-800/50 text-red-200 hover:text-white py-2.5 rounded-xl text-sm font-medium transition-all border border-red-700/30 hover:border-red-500/50">
🛑 停止发言
</button>
</div>
</div>
</div>
<footer class="mt-6 text-center text-green-400/50 text-xs">
<p>让垃圾分类成为一种生活习惯 🌿</p>
</footer>
</div>
<script>
// ⚠️ 安全警告:此文件仅用于演示目的
// 生产环境中,API密钥不应硬编码在前端代码中
// 建议将DeepSeek请求放到后端代理,通过/api/chat中转
// 浏览器直连第三方API存在CORS限制和密钥泄露风险
const CONFIG = {
mofa: {
appId: "xxx",
appSecret: "xxx",
gatewayServer: "https://nebula-agent.xingyun3d.com/user/v1/ttsa/session"
},
deepseek: {
apiKey: "sk-xxx",
apiUrl: "https://api.deepseek.com/v1/chat/completions",
systemPrompt: "你是一个名叫‘小绿’的活泼可爱的垃圾分类小助手。你的语言风格亲切、热情,就像邻家妹妹一样。专门解答各类垃圾分类问题,帮助用户正确识别垃圾种类。回答控制在80字以内,适合口语表达,不要使用分点列表或代码块。"
}
};
let mofaSdk = null;
let isFirstSentence = true;
let textBuffer = "";
const punctReg = /[。!?;;!?]/;
let abortController = null;
let requestVersion = 0;
function toInteractiveIdle() {
if (!mofaSdk) return;
mofaSdk.interactiveidle?.() ?? mofaSdk.interactiveIdle?.();
}
function initMofaAvatar() {
if (typeof XmovAvatar === 'undefined') {
console.error("SDK 脚本未成功加载,请检查网络链接。");
return;
}
mofaSdk = new XmovAvatar({
containerId: '#sdk_canvas',
appId: CONFIG.mofa.appId,
appSecret: CONFIG.mofa.appSecret,
gatewayServer: CONFIG.mofa.gatewayServer,
onMessage: function(msg) {
console.log("SDK 收到通知:", msg);
}
});
mofaSdk.init({
onDownloadProgress: (progress) => {
console.log("资源下载进度:", progress + "%");
document.getElementById('status-text').innerText = `正在加载资源: ${progress}%`;
}
}).then(() => {
console.log("3D 渲染就绪!");
document.getElementById('loading-tips').style.display = 'none';
const statusEl = document.getElementById('status-text');
statusEl.innerText = "环保小助手已就绪";
statusEl.classList.add('text-emerald-300');
}).catch((err) => {
console.error("3D 初始化失败:", err);
document.getElementById('status-text').innerText = "初始化异常";
});
}
window.addEventListener('load', initMofaAvatar);
function processStreamText(textChunk, isFinal = false) {
textBuffer += textChunk;
let match;
while ((match = punctReg.exec(textBuffer)) !== null) {
const breakIndex = match.index + 1;
const sentence = textBuffer.substring(0, breakIndex).trim();
textBuffer = textBuffer.substring(breakIndex);
if (sentence.length > 0) {
driveAvatarSpeak(sentence, false);
}
}
if (isFinal && textBuffer.trim().length > 0) {
driveAvatarSpeak(textBuffer.trim(), true);
textBuffer = "";
}
}
function driveAvatarSpeak(text, isEnd) {
if (!mofaSdk) return;
console.log(`[驱动声音] isStart=${isFirstSentence}, isEnd=${isEnd}, 文本: ${text}`);
mofaSdk.speak(text, isFirstSentence, isEnd);
if (isFirstSentence) {
isFirstSentence = false;
}
}
async function handleSendMessage() {
const inputEl = document.getElementById('user-input');
const outputEl = document.getElementById('chat-output');
const query = inputEl.value.trim();
if (!query) return;
inputEl.value = "";
textBuffer = "";
isFirstSentence = true;
requestVersion++;
const currentVersion = requestVersion;
if (abortController) {
abortController.abort();
}
abortController = new AbortController();
outputEl.innerHTML += `<div class="text-right"><span class="bg-green-500 text-white inline-block px-4 py-2 rounded-xl rounded-tr-none max-w-[85%] text-left shadow-lg"><b>你:</b>${query}</span></div>`;
const aiBubbleContainer = document.createElement('div');
aiBubbleContainer.className = "text-left";
const aiBubble = document.createElement('span');
aiBubble.className = "bg-green-800/80 border border-green-600/50 text-green-100 inline-block px-4 py-2 rounded-xl rounded-tl-none max-w-[85%] shadow-lg";
aiBubble.innerHTML = `<b>小绿:</b>`;
aiBubbleContainer.appendChild(aiBubble);
outputEl.appendChild(aiBubbleContainer);
outputEl.scrollTop = outputEl.scrollHeight;
try {
const response = await fetch(CONFIG.deepseek.apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CONFIG.deepseek.apiKey}`
},
body: JSON.stringify({
model: "deepseek-chat",
messages: [
{ role: "system", content: CONFIG.deepseek.systemPrompt },
{ role: "user", content: query }
],
stream: true
}),
signal: abortController.signal
});
if (!response.ok) throw new Error(`HTTP 异常: ${response.status}`);
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
streamLoop: while (true) {
const { done, value } = await reader.read();
if (done) {
if (currentVersion !== requestVersion) break;
processStreamText("", true);
break;
}
const chunkStr = decoder.decode(value, { stream: true });
const lines = chunkStr.split('\n');
for (let line of lines) {
line = line.trim();
if (!line || line === 'data: [DONE]') continue;
if (line.startsWith('data:')) {
try {
if (currentVersion !== requestVersion) break streamLoop;
const jsonStr = line.replace('data:', '').trim();
const parsed = JSON.parse(jsonStr);
const token = parsed.choices[0]?.delta?.content || "";
if (token) {
aiBubble.innerHTML += token;
outputEl.scrollTop = outputEl.scrollHeight;
processStreamText(token, false);
}
} catch (err) {}
}
}
}
} catch (error) {
if (error.name === 'AbortError') return;
console.error(error);
aiBubble.innerHTML += `<span class="text-red-400"><br>[连接异常]</span>`;
}
}
document.getElementById('send-btn').addEventListener('click', handleSendMessage);
document.getElementById('user-input').addEventListener('keydown', (e) => {
if (e.key === 'Enter') handleSendMessage();
});
document.getElementById('stop-btn').addEventListener('click', () => {
requestVersion++;
if (abortController) {
abortController.abort();
abortController = null;
}
toInteractiveIdle();
textBuffer = "";
isFirstSentence = true;
document.getElementById('chat-output').innerHTML += `<div class="text-center italic text-amber-400 text-xs py-2">⚠️ 已停止</div>`;
});
</script>
</body>
</html>
温馨提示:
Tips:本html示例仅作为学习参考,ApiKey,appSecret不能硬编码展示在项目中,易受CORS和密钥泄露影响,千万不能将我们的密钥给泄露哦~

更多项目以及生产环境项目Vue版本参考请移步Gitee:仓库地址:https://gitee.com/xiaotietou/wangl-xingyun
3.3 核心功能简单讲解

这几十行代码就能引入我们的数字人功能。
第一:彻底解决延迟问题
传统预制视频数字人属于单向播报,无完整具身交互链路,必须等待全文生成再渲染;参数流架构分段流式驱动,是实现流畅具身交互智能的基础,大模型分段文本即可同步驱动表情、语音,大幅降低等待延迟。

数字人的运行流程我们可以在工作台里面去看到,我们可以进行一个测试,500ms就能进行从SDK的调用到成功渲染具身智能形象。

重点就是这句 interactiveIdle(),它可以直接清空当前所有播放内容,让数字人瞬间回到待机状态。不管它讲到哪,你随时提问、随时打断,不会出现声音重叠、画面卡死的情况,这也是商用级具身智能的核心能力。
document.getElementById('stop-btn').addEventListener('click', () => {
if (mofaSdk) {
mofaSdk.interactiveIdle();
textBuffer = "";
isFirstSentence = true;
document.getElementById('chat-output').innerHTML += `<div class="text-center italic text-amber-400 text-xs py-2">⚠️ 已停止</div>`;
}
});
第三:AI大模型的引入和运行

配置文件
const CONFIG = {
mofa: {
appId: "xxx",
appSecret: "xxx",
gatewayServer: "https://nebula-agent.xingyun3d.com/user/v1/ttsa/session"
},
deepseek: {
apiKey: "sk-xxx",
apiUrl: "https://api.deepseek.com/v1/chat/completions",
systemPrompt: "你是一个名叫‘小绿’的活泼可爱的垃圾分类小助手。你的语言风格亲切、热情,就像邻家妹妹一样。专门解答各类垃圾分类问题,帮助用户正确识别垃圾种类。回答控制在80字以内,适合口语表达,不要使用分点列表或代码块。"
}
};
配置文件
AI数字人提示词
你是一个名叫‘小绿’的活泼可爱的垃圾分类小助手。你的语言风格亲切、热情,就像邻家妹妹一样。
专门解答各类垃圾分类问题,帮助用户正确识别垃圾种类。回答控制在80字以内,适合口语表达,不要使用分点列表或代码块。
LLM引入大模型
const response = await fetch(CONFIG.deepseek.apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CONFIG.deepseek.apiKey}`
},
body: JSON.stringify({
model: "deepseek-chat",
messages: [
{ role: "system", content: CONFIG.deepseek.systemPrompt },
{ role: "user", content: query }
],
stream: true
})
});
五、运行避坑指南
很多人第一次跑会翻车,基本都是两个小问题,我提前给大家避坑,百分百能跑通。
1. 绝对不能直接双击打开HTML文件
cnpm install serve
serve -p 3000
然后打开浏览器

2. 正式业务一定要后端中转
咱们这个Demo为了简单,直接把API密钥写在前端了,适合测试学习。但如果是社区、学校、企业正式落地,一定要把大模型请求、密钥验签放到后端,防止密钥泄露,这是商用项目的基本规范。
六、最后总结
现在大家应该彻底看懂了:为什么说大模型负责动脑,3D具身数字人负责落地。
DeepSeek、千问这些国产大模型,已经把知识问答、逻辑判断做到极致了,垃圾分类这种知识性问题,对大模型来说根本没难度。但空有知识,只能困在对话框里,冷冰冰的没人看、没人用,根本落不了地。
而的具身交互智能,就是给 AI 装上身体、表情和动作,通过 AI 端渲、端侧解算与参数流,把枯燥的文字问答,变成可视化、可交互、有温度、全天候在线的真人级服务。
从硬件人形机器人的火爆,到软件端具身数字人的普及,AI的下半场早就不是“比谁更聪明”,而是比谁更贴近场景、更会服务人、更自然好用。
大家可以复制html运行,也可以在html之上通过AI编辑器进行延申。
魔珐星云官网:点击跳转官网
更多推荐


所有评论(0)