
走进一家 4S 店,三款车型一字排开——轿车、SUV、MPV。你坐进星澜 S7 Ultra 旗舰的座舱,好奇问了一句:"Ultra 和 Max 差在哪?"展厅大屏上的 AI 导购"云览"应声开口:"Ultra 多了空气悬架和四座按摩,适合长途通勤较多的行政座舱需求。"与此同时,屏幕上两版配置的差异行自动高亮,轮毂从 20 英寸放大到 21 英寸锻造,激光雷达从 1 颗升级到 2 颗——你还没走到配置表前,答案已经摆在眼前。
这不是预录好的话术轮播。屏幕上的云览,是由端到端具身交互智能驱动的具身交互智能体——她能听你的提问、能理解你在看哪款车哪个配置、能判断该展开差异对比还是部位讲解、还能配合回答自然地做出表情和手势。问什么答什么,看哪里讲哪里,随时打断,随时追问。
本文以云览 YÙNLǍN 为实战样本,拆解一个 4S 店大屏端 AI 导购应用如何基于魔珐星云端到端具身交互智能平台,用一个 SDK 把语音感知、大脑推理、多模态表达与展厅展示联动全链路打通,让三款虚构演示车系在浏览器里"开口讲车"。
第一节:为什么 4S 店导购是端到端具身交互智能的天然舞台?
传统 4S 店的拼接困境
如果按传统思路搭建一个"AI 汽车导购",至少要对接四套服务:
- 语音识别(ASR)接一家
- 大模型推理(LLM)接一家
- 语音合成 + 形象驱动(TTS + Avatar)再接一家
- 展厅展示系统(3D 看车 / 配置对比)自己写
四套服务各自工作,中间需要自己写胶水层做状态同步。代码量 2000+ 行起步,首字响应 1.5 到 3 秒——顾客问完"Max 有没有激光雷达?",等了三秒才听到回答,看车兴致早就凉了。更要命的是——导购讲到一半顾客想打断追问?做不到,因为 ASR 和 TTS 的状态是割裂的,智能体正在"说话"时听不到顾客提问。
这就是典型的"不是端到端"。
端到端方案:一个 SDK 撑起一次看车
云览基于魔珐星云端到端 SDK XingyunAvatarAgent 构建,核心业务代码不到 500 行。整个前端对接只需三步:提供一个 DOM 容器、注册一组回调、调用 agent.ask() 发送消息。ASR、大模型推理、TTS 与流式分片全部由 SDK 内部完成,业务侧不存在独立的语音识别或大模型调用层。
端到端具身交互智能和模块拼接的本质区别:感知、理解、决策、表达不再是前后两个独立阶段,而是在同一次交互中持续并行运行。导购一边讲,一边听顾客有没有追问,一边判断接下来该展开差异对比还是部位高亮。
第二节:在魔珐星云控制台配置一位 AI 导购
云览的具身交互智能体并不是从零搭建的,它的能力底座来自魔珐星云控制台的完整配置体系。以下用实际截图还原配置过程。
1、创建具身应用
在魔珐星云控制台创建一个新应用,系统会自动分配 App ID 和 App Secret,这就是后续 SDK 连接所需的身份凭证。

2、形象配置
选择智能体的外在形象——云览需要的是一位专业克制、坦诚清晰的 4S 店导购。平台提供多种形象可选,也可以自定义。

3、场景配置
为智能体设定交互场景的背景环境。云览采用的是简洁科技风格的展厅背景,和前端 UI 的碳黑 + 电光青主题保持一致。

4、音色配置
选择智能体的语音风格。4S 店导购需要的是专业沉稳、语速适中的音色,魔珐星云自研 TTS 支持多语言多风格。

5、表演配置
配置智能体的肢体语言和表情系统——这正是多模态表达的核心。不是简单的口型同步,而是语气、表情、手势、头部动作和身体动作的统一生成。导购在介绍 Ultra 旗舰的行政座舱时语气温润、在对比 Pro 和 Max 差异时手势明确,都来自这一层的配置。

6、服务配置:ASR 与大脑
为当前应用配置语音识别和大模型服务。这一步体现了星云的可插拔架构——可插拔并非简单的 API 拼接,平台依靠标准化接口契约与统一状态管理,保障模块替换后会话状态、事件流转、交互闭环不受破坏。ASR 支持 Xmov 自研、豆包、腾讯等多家供应商,大脑支持魔珐自研、豆包、OpenAI 兼容协议等多种接入模式。

这些配置完成后,保存即生效。前端只需要拿着 App ID 和 App Secret,通过 SDK 就能连上整套能力——接下来三节将逐一拆解连接、解析与联动的实现细节。
同一个智能体,可以拥有不同的身体。 今天她是大屏端的 AI 导购,明天可以变成线下展厅的互动终端、甚至人形机器人——身份、知识和导购业务能力持续复用——这是端到端具身交互智能平台赋予的灵活性。
第三节:单 SDK 接入——一个构造器撑起全链路

云览的具身交互智能体封装在 src/services/avatar.ts 中。整个接入过程只依赖一个全局构造器 window.XingyunAvatarAgent,SDK 通过懒加载方式按需注入,不阻塞页面首屏。
SDK 懒加载与可用性等待
// src/services/avatar.ts — SDK 懒加载(真实代码)
function loadSDK() {
if (window.XingyunAvatarAgent) return Promise.resolve()
if (sdkPromise) return sdkPromise
sdkPromise = new Promise<void>((resolve, reject) => {
sdkScript?.remove()
const script = document.createElement('script')
sdkScript = script
script.src = SDK_CONFIG.SDK_URL
script.async = true
const timer = setTimeout(() => { script.remove(); reject(new Error('导购 SDK 加载超时,可继续使用 3D 看车与配置对比')) }, 15000)
script.onload = () => { clearTimeout(timer); window.XingyunAvatarAgent ? resolve() : reject(new Error('导购 SDK 不可用')) }
script.onerror = () => { clearTimeout(timer); reject(new Error('导购 SDK 加载失败,请检查网络')) }
document.head.append(script)
}).catch(error => { sdkPromise = undefined; throw error })
return sdkPromise
}
这段代码做了三件事:检查全局构造器是否已存在、避免重复注入、15 秒超时兜底。SDK 加载成功后,后续所有连接直接复用已缓存的 Promise。
连接智能体:构造 + 回调 + 超时
// src/services/avatar.ts — 连接具身交互智能体(真实代码)
export async function connectAvatar(container: HTMLElement, appId: string, appSecret: string) {
if (avatarState.status === 'connecting' || avatarState.status === 'online') return
if (!appId.trim() || !appSecret.trim()) throw new Error('请填写有效的应用凭证')
const token = ++generation
avatarState.status = 'connecting'
avatarState.error = ''
let candidate: Agent | undefined
let timer: ReturnType<typeof setTimeout> | undefined
try {
await loadSDK()
if (token !== generation) return
candidate = new window.XingyunAvatarAgent!({
container, appId: appId.trim(), appSecret: appSecret.trim(),
gatewayServer: SDK_CONFIG.GATEWAY_URL,
onMessage: (error: { message?: string }) => {
if (token === generation && error?.message) avatarState.error = '导购渲染暂不可用,请重连'
},
agentCallbacks: {
onAgentStateChange: (state: string | { type?: string }) => {
if (token !== generation) return
const value = typeof state === 'string' ? state : state?.type ?? ''
avatarState.speaking = value === 'speak' || value === 'speaking'
},
onASRResult: (result: { text?: string; isFinal?: boolean }) => {
if (token !== generation) return
avatarState.subtitle = result.text ?? ''
if (result.isFinal && result.text?.trim()) asrFinalHandler?.(result.text.trim())
},
onConversationChange: (event: { state?: string; text?: string }) => {
if (token !== generation) return
if (event.text) avatarState.subtitle = event.text
if (event.state === 'idle') avatarState.speaking = false
},
onError: () => {
if (token !== generation) return
avatarState.error = '导购连接异常,请检查网络、应用配置或平台额度后重连'
avatarState.status = 'error'
void disconnectAvatar(true)
},
},
})
pendingAgent = candidate
const active = candidate
await Promise.race([
active.init({}).then(async () => { if (token !== generation) await active.destroy('cancelled') }),
new Promise<never>((_, reject) => { timer = setTimeout(() => reject(new Error('导购连接超时,请检查网络、凭证与平台额度')), 30000) }),
])
if (token !== generation) return
agent = candidate
pendingAgent = undefined
avatarState.status = 'online'
await agent.ask(`${SYSTEM_PROMPT}\n请用不超过两句话向到店顾客问好,并提示可以语音询问车型配置差异。`)
} catch (error) {
if (token !== generation) return
generation += 1
avatarState.status = 'error'
avatarState.error = error instanceof Error ? error.message : '连接失败'
void candidate?.destroy('failed').catch(() => {})
agent = undefined
pendingAgent = undefined
} finally { clearTimeout(timer) }
}
这段代码里已经包含了后面章节会拆解的所有回调:状态感知(onAgentStateChange)、语音识别终稿分发(onASRResult)、对话状态切换(onConversationChange)、错误处理(onError)——它们构成了云览“问配置即对比,看车模即讲解”的闭环基础。
几个值得注意的设计细节:
generation 令牌机制:每次连接分配一个递增令牌,所有回调入口先校验令牌是否过期。当用户断开重连时,旧连接的回调会被自动丢弃,避免新旧实例状态交叉污染。
Promise.race 超时兜底:agent.init() 需要建立感知、大脑、表达三条 WebSocket,任一被服务端拒绝(典型为控制台积分额度耗尽)则 Promise 永久 pending。30 秒超时确保用户不会卡在“连接中”永远等不到反馈。
连接成功即问好:avatarState.status 置为 online 后立即调用 agent.ask(),附带系统人设提示词,让导购主动向到店顾客问好。
第四节:语音解析——问什么,高亮什么

顾客说"Max 和 Ultra 的激光雷达差几个?",云览需要同时完成两件事:把问题发给智能体获取回答,以及在屏幕上自动高亮激光雷达部位、展开 Max 与 Ultra 的差异对比表。
这两件事不能等智能体回答完再做——大模型推理需要几百毫秒,如果等回复再驱动 UI,用户会看到明显的"卡顿-跳变"。云览的做法是:本地解析器先于智能体回答完成意图识别,同步驱动展示层联动,智能体回答到达时只需负责语音播报。
问题解析器
// src/utils/match.ts — 语音/文字问题解析(真实代码)
// 配置版本口语别名
const TRIM_ALIASES: Record<string, string[]> = {
pro: ['pro', '长续航', '入门', '标准', '智享', '商务'],
max: ['max', '四驱', '家庭'],
ultra: ['ultra', '旗舰', '满配'],
}
// 部位关键词 → 3D 高亮
const FOCUS_KEYWORDS: [HotspotKey, string[]][] = [
['roof', ['天幕', '全景', '车顶', '天窗']],
['lidar', ['激光雷达', '雷达', '智驾', '辅助驾驶', '智能驾驶']],
['wheels', ['轮毂', '轮圈', '轮胎', '轮子']],
['suspension', ['悬架', '悬挂', '空气', '底盘', 'cdc']],
['cockpit', ['座舱', '屏幕', '车机', '中控', '芯片', '仪表', '后排屏', '吸顶']],
['lights', ['灯组', '大灯', '尾灯', '灯光']],
]
const COMPARE_WORDS = ['差异', '对比', '区别', '差别', '怎么选', '哪个', '哪款', '不同', '差在哪', '贵在哪', '值不值']
/** 解析用户问题:提到的配置、关注部位、是否对比意图 */
export function parseQuestion(question: string, trims: TrimConfig[]): ParseResult {
const q = question.toLowerCase()
const trimIds = trims
.filter(t => [t.id, t.name.toLowerCase(), ...(TRIM_ALIASES[t.id] ?? [])].some(alias => alias && q.includes(alias)))
.map(t => t.id)
const focus = FOCUS_KEYWORDS.find(([, words]) => words.some(word => q.includes(word)))?.[0] ?? null
const compare = trimIds.length >= 2 || COMPARE_WORDS.some(word => q.includes(word))
return { trimIds, focus, compare }
}
解析器识别三个维度的信息:
- 配置版本:通过口语别名匹配("旗舰"→ Ultra、"四驱"→ Max),支持自然语言中的非标准称呼
- 关注部位:六个可讲解部位(全景天幕、激光雷达、轮毂、悬架系统、智能座舱、智能灯组),每个部位关联一组关键词
- 对比意图:提到两个配置版本,或出现"差在哪""怎么选"等对比关键词,即判定为对比意图
意图分发:解析结果同时驱动展示层与智能体
// src/stores/app.ts — 意图分发与上下文构建(真实代码)
/** 汇总当前展厅上下文,随每次提问附加给智能体 */
function buildContext(): string {
const model = currentModel()
const trim = currentTrim()
const parts = [`车型:${model.name}(${model.tagline})`, `当前配置:${trim.name},指导价 ${trim.price}`]
if (appState.focus) parts.push(`正在关注:${FOCUS_LABELS[appState.focus]}`)
const { trimA, trimB, rows, visible } = appState.compare
if (visible && trimA && trimB) {
parts.push(`屏幕对比:${trimA.name}(${trimA.price}) 对 ${trimB.name}(${trimB.price})`)
parts.push(`差异摘要:${diffSummary(rows)}`)
}
parts.push('价格与参数均为虚构演示数据。')
return parts.join('。')
}
// ...
/** 命中对比意图即展开差异表:提到的两个配置优先,缺省当前 vs 下一档 */
ask(question: string) {
const model = currentModel()
const result = parseQuestion(question, model.trims)
if (result.focus) appState.focus = result.focus
if (result.compare) {
let a: TrimConfig | undefined
let b: TrimConfig | undefined
if (result.trimIds.length >= 2) {
a = model.trims.find(trim => trim.id === result.trimIds[0])
b = model.trims.find(trim => trim.id === result.trimIds[1])
} else if (result.trimIds.length === 1) {
const mentioned = model.trims.find(trim => trim.id === result.trimIds[0])
const index = model.trims.indexOf(mentioned!)
const other = model.trims[index === appState.trimIndex ? (index + 1) % model.trims.length : appState.trimIndex]
a = index < model.trims.indexOf(other) ? mentioned : other
b = index < model.trims.indexOf(other) ? other : mentioned
} else {
a = model.trims[appState.trimIndex]
b = model.trims[(appState.trimIndex + 1) % model.trims.length]
}
if (a && b && a !== b) {
appState.compare = { visible: true, trimA: a, trimB: b, rows: diffTrims(a, b) }
const hotspot = result.focus ?? appState.compare.rows.find(row => row.differs)?.hotspot
if (hotspot) appState.focus = hotspot
}
}
return askAvatar(question, buildContext())
},
这段代码展示了云览的双路分发机制:
- 本地解析先行:parseQuestion() 同步完成意图识别,立即驱动 appState.focus(热点高亮)和 appState.compare(差异对比抽屉),用户看到画面变化的延迟只有几毫秒
- 智能体回答跟进:buildContext() 把当前展厅上下文(所选车系、配置版本、关注部位、差异摘要)打包附加给 askAvatar(),智能体拿到的不是裸问题,而是带完整展厅语境的增强提问
- 缺省对比策略:用户只说"值得升级吗"但没提具体配置时,自动取当前配置与下一档进行对比——不需要顾客精确报名称
动作节奏与画面联动由本地解析保证,不依赖生成式回复的延迟与稳定性。
第五节:导购人设——专业克制,不虚假承诺
云览的导购人设通过系统提示词注入每次 agent.ask() 调用。这段提示词定义了智能体的身份边界和讲解原则:
// src/constants/index.ts — 导购人设提示词(真实代码)
/** 导购人设:客观讲配置差异,不虚假承诺 */
export const SYSTEM_PROMPT = `你是云览,星澜汽车(虚构演示品牌)4S 店的 AI 导购。
## 你的身份
- 名称:云览(YÙNLǍN)
- 身份:展厅大屏 AI 导购,熟悉星澜 S7 / X6 / M8 三个演示车系各配置的差异
- 性格:专业克制、坦诚清晰,不夸大不催单
## 你的讲解原则
1. 只依据屏幕上给出的配置表与差异项回答,不编造参数、价格优惠、交付时间或续航保证
2. 讲差异时先说结论,再补一句使用场景建议,口语化、一次不超过四句
3. 涉及真实购车、金融方案或试驾安排,引导用户咨询店内顾问
4. 用户语音提问可能带口语噪声,先理解意图再回答;听不清时礼貌请用户重复
5. 不贬低任何配置版本,只说明适用人群差异`
五条讲解原则的设计逻辑:
- 不编造:智能体只能基于屏幕上的配置表回答,杜绝大模型常见的"幻觉"风险——这在汽车导购场景中尤其重要,错误的续航或报价信息可能引发客诉
- 先结论后场景:口语化表达,一次不超过四句,适合展厅环境的快速交互
- 引导线下:涉及真实购车和金融,明确引导顾客咨询店内顾问,智能体不越界
- 容错口语:展厅环境嘈杂,语音识别可能带噪声,先理解意图再回答
- 不贬低:每个配置版本都有适用人群,Pro 适合通勤、Max 适合家庭、Ultra 适合行政——导购只说差异,不做高低判断
第六节:三栏展厅布局——碳黑 + 电光青的沉浸式看车
技术底座之上,云览在视觉和交互设计上也形成了自己的气质。
碳黑 + 电光青主题:碳黑底色(#0b1114)搭配电光青强调色(#45d6c0)和晨曦金辅助色(#e8c37a),字体选用 Segoe UI 搭配苹方/微软雅黑,贴合高端 4S 店展厅的科技质感,和市面上千篇一律的蓝色科技风形成区隔。
/* src/style.css — 碳黑 + 电光青主题色(真实代码) */
:root {
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
color: #e8f1f0;
background: #0b1114;
font-synthesis: none;
--cyan: #45d6c0;
--cyan-deep: #2aa392;
--gold: #e8c37a;
--panel: #121b20;
--panel-2: #16222a;
--line: #22333c;
--muted: #8ba3a8;
--red: #e2695a;
-webkit-font-smoothing: antialiased;
}
三栏沉浸式布局:左侧车型选择与配置参数面板(320px)、中央车型展示舞台(自适应)、右侧具身交互智能体面板(380px)。中栏占据最大面积,车型展示图配合六个可讲解热点标记成为视觉焦点;右栏智能体面板让 AI 导购以全屏高度呈现,顾客看车的同时自然感受到智能体的存在。
/* src/style.css — 三栏布局(真实代码) */
.columns {
flex: 1; min-height: 0; display: grid; gap: 14px; padding: 14px 18px 18px;
grid-template-columns: 320px minmax(0, 1fr) 380px;
}
@media (min-width: 1800px) {
.columns { grid-template-columns: 360px minmax(0, 1fr) 420px; }
}
@media (max-width: 1440px) {
.columns { grid-template-columns: 300px minmax(0, 1fr) 360px; gap: 12px; padding: 12px 14px 16px; }
}
三款虚构演示车系:星澜 S7(智电轿跑)、星澜 X6(家庭智享 SUV)、星澜 M8(旗舰智电 MPV),每款提供 Pro / Max / Ultra 三个配置版本,每个版本包含 10 行详细规格(续航、零百加速、驱动形式、智驾硬件、智能座舱、悬架系统、轮毂、天幕、座椅、音响),4 种车身颜色可选。所有参数均为虚构演示数据,不构成任何真实车型报价。
热点标记与差异对比联动:中栏展示图上分布着 6 个可讲解部位热点(全景天幕、激光雷达、轮毂、悬架系统、智能座舱、智能灯组),点击即高亮脉冲 + 浮动标签。当顾客通过语音触发对比意图时,差异对比抽屉从底部滑出,差异行自动高亮,点击差异行还能联动热点标记——展示层与智能体的联动完全由本地解析器驱动,不依赖大模型回复的时序。
第七节:端到端具身交互智能,让每一家 4S 店都有自己的 AI 导购
从传统管线到端到端 SDK,云览的实战经历验证了一个核心认知:
端到端不是 ASR + LLM + TTS 的简单拼接,而是围绕一次完整的人机交互,把感知、理解、决策、表达和行动连接成一套持续运行的系统。
| 对比维度 | 传统管线 | 端到端具身交互智能 |
|---|---|---|
| 核心代码量 | 2000+ 行 | ~500 行 |
| 首字响应 | 1.5 ~ 3 秒 | ~500ms |
| 打断能力 | 需手动管理状态 | 客户端即时生效 |
| 展示联动 | 需自行对接大模型输出 | 本地解析器同步驱动 |
| 状态同步 | 模块间各自独立 | 全链路统一流转 |
| 部署复杂度 | 四套服务分别对接 | 一个 SDK 全搞定 |
云览只是端到端具身交互智能的一种落地形态。在屏幕端,这套能力体现为数字行动——智能体以语音讲解、配置对比、热点高亮的形式与顾客自然互动;当同一个智能体走进线下 4S 店互动大屏或人形机器人时,同样的感知—理解—决策—表达链路延伸为物理行动。身体可以变化,能力持续复用。
魔珐星云是一套端到端具身交互智能平台,让 AI 通过屏幕和机器人进入真实世界,成为能够感知、理解、表达并行动的智能体。
这不只是技术架构的升级,而是 AI 从"文字回复"走向"真实交互"的必经之路——让每一家 4S 店,都能拥有自己的 AI 导购。
如果你想亲自体验端到端具身交互智能的魅力,或者基于魔珐星云平台搭建属于自己的具身交互智能体,欢迎访问魔珐星云官网,开启你的具身交互智能实战之旅:https://xingyun3d.com?utm_campaign=daily&utm_source=CSDNwanfen2&utm_medium=&utm_term=&utm_content=
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/qq_62817113/article/details/166795735




