每一句话都可能是线索,每一个人都可能在撒谎 - 迷局如何用端到端具身交互智能重构沉浸式剧本杀推理

剧本杀正在成为年轻人最喜爱的社交娱乐方式之一,但线上化体验始终差一口气——核心瓶颈在于,传统线上剧本杀要么靠文字聊天模拟,要么播放预录音频,缺少一个能实时扮演多个角色、根据玩家追问即兴演绎的主持人。
迷局 MíJú 尝试用魔珐星云端到端具身交互智能解决这个问题:一位名叫「暗线」的 AI 主持人,同时扮演四位性格迥异的嫌疑人,用声音和表情实时演绎每一句对白。玩家自由审讯、搜查线索、发现矛盾、指控凶手——整个过程不是播放脚本,而是智能体根据调查进度动态生成回应。
本文将完整拆解这个项目的架构设计、游戏引擎实现与 SDK 集成链路。
一、星云控制台配置:六步完成具身应用全链路
在动手写代码之前,需要先在魔珐星云控制台完成具身应用的全链路配置。以下六步决定了智能体的形象、声音、大脑与交互能力。
1、创建具身应用

2、形象配置

3、场景配置

4、音色配置

5、表演配置

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

配置完成后,记录应用 ID 与密钥,后续代码中通过环境变量注入即可。
二、技术选型:四个依赖撑起整个项目
迷局的项目依赖极简到只有四个包:
{
"dependencies": {
"vue": "^3.5.18"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.1",
"typescript": "~5.8.3",
"vite": "^7.1.2",
"vue-tsc": "^3.0.5"
}
}
没有 OpenAI SDK,没有腾讯 ASR SDK,没有 CryptoJS 签名库——因为端到端 SDK 内部已经集成了语音识别、大模型推理与语音合成,业务侧只需要关注「游戏规则」本身。
SDK 以单条 CDN 脚本引入,写在 index.html 的普通 script 标签中,必须位于模块脚本之前:
<!-- index.html -->
<script src="https://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatar_e2e@latest.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
这个顺序不是随意的——type=module 脚本天然具备 defer 特性,会比普通 script 更早执行。如果 SDK 标签写在模块脚本之后,Vue 组件挂载时 window.XingyunAvatarAgent 尚不存在,连接将永久挂起。这是端到端系列项目反复踩过的时序陷阱。
三、项目架构:三层结构一览
src/
├── types/index.ts # 类型定义:GamePhase / NPC / Clue / GameState / Script
├── constants/index.ts # 常量:GM 人设提示词 / 雨夜迷踪剧本(4 NPC + 8 线索)
├── utils/gameEngine.ts # 游戏引擎:状态持久化 / 线索发现 / 审讯记录 / 上下文构建
├── services/avatar.ts # SDK 服务层:连接 / 提问 / 语音 / 打断 / 断开
├── stores/app.ts # 状态管理:游戏全链路流程控制
├── components/
│ ├── LandingPage.vue # 介绍首页(暗色主题 + 剧本预览 + 凭证弹窗)
│ ├── AvatarDisplay.vue # 智能体渲染区(加载 / 语音波形 / 说话指示 / 字幕)
│ ├── GamePanel.vue # 对话面板(消息列表 / 操作栏 / 输入区 / 指控选择)
│ ├── ClueBoard.vue # 线索板浮层(已发现 / 未发现的线索卡片)
│ └── SuspectPanel.vue # 嫌疑人面板(NPC 卡片 + 审讯状态 + 受害者信息)
├── App.vue # 三栏布局:嫌疑人 | 对话 + 线索板 | 智能体
└── style.css # 全局暗色主题重置
整个项目围绕三个核心层展开:数据建模层(剧本、角色、线索的类型与常量)、游戏引擎层(状态流转与上下文构建)、具身表达层(SDK 集成与交互控制)。
四、数据建模:一个完整的剧本杀世界

类型系统
剧本杀的核心实体只有五个:游戏阶段、NPC 角色、线索、对话消息、剧本。类型定义清晰勾勒出游戏的完整骨架:
// src/types/index.ts
export type GamePhase = 'briefing' | 'investigation' | 'accusation' | 'reveal'
export interface NPC {
id: string
name: string
title: string
emoji: string
motive: string
alibi: string
isKiller: boolean
personality: string
secret: string
dialogueHints: string[]
}
export interface Clue {
id: string
name: string
description: string
category: 'physical' | 'testimony' | 'document'
relatedNpcId?: string
discovered: boolean
}
export interface GameMessage {
id: string
role: 'gm' | 'npc' | 'user' | 'system'
text: string
timestamp: number
speakerName?: string
speakerEmoji?: string
}
export interface GameState {
phase: GamePhase
currentNpcId: string | null
discoveredClues: string[]
interrogatedNpcs: string[]
accusationTarget: string | null
turnCount: number
startedAt: number
}
export interface Script {
id: string
title: string
subtitle: string
difficulty: string
playerCount: string
duration: string
background: string
victim: string
victimEmoji: string
summary: string
npcs: NPC[]
clues: Clue[]
killerId: string
}
每个 NPC 都有动机(motive)、不在场证明(alibi)、性格(personality)、隐藏秘密(secret)和多条对白提示(dialogueHints)。线索分为物证、证词、文书三类,可选关联某位 NPC。消息角色区分主持人(gm)、NPC、玩家(user)和系统提示(system),渲染时用不同颜色气泡区分。
内置剧本「雨夜迷踪」
项目内置了一个完整的推理剧本——1947 年上海法租界,富商赵伯年在反锁书房中被杀,四位嫌疑人各怀心事:
| 嫌疑人 | 身份 | 动机 | 不在场证明 |
|---|---|---|---|
| 老陈 🎩 | 管家 | 赵伯年要卖祖宅,他将失去住所 | 在厨房准备早餐,无人证实 |
| 苏婉清 👩 | 妻子 | 赵伯年秘密起草离婚协议 | 在房间听音乐,女佣听到争吵 |
| 钱世昌 🤵 | 合伙人 | 赵伯年发现他私吞公款要报警 | 在客厅看报纸,管家听到走廊踱步 |
| 林致远 🩺 | 私人医生 | 赵伯年掌握他非法行医证据 | 在房间写病历,病历少了三页 |
凶手是钱世昌,关键证据是烛台底部的纺织纤维与其西装面料一致。八条线索从青铜烛台、纺织纤维到反锁门窗,分布在物证、文书、证词三个维度,玩家需要交叉比对才能锁定真凶。
剧本数据直接以 TypeScript 常量写在 src/constants/index.ts 中,包含每位 NPC 的完整对白提示和每条线索的详细描述,总计近 150 行结构化数据。
五、游戏引擎:四阶段状态流转

数据建模完成后,游戏的核心挑战转向状态管理——玩家的调查进度、已发现的线索、正在审讯的嫌疑人,这些状态需要在内存与持久化之间同步,并在每次与智能体对话时组装成完整上下文。迷局的游戏逻辑由 src/utils/gameEngine.ts 驱动,核心是四阶段流转模型:
briefing(案情通报)→ investigation(自由调查)→ accusation(指控凶手)→ reveal(真相揭晓)
状态持久化与纯函数更新
游戏引擎采用纯函数 + localStorage 的模式——每次状态变更都返回新对象,不修改原状态:
// src/utils/gameEngine.ts
export function createInitialState(): GameState {
return {
phase: 'briefing',
currentNpcId: null,
discoveredClues: [],
interrogatedNpcs: [],
accusationTarget: null,
turnCount: 0,
startedAt: Date.now(),
}
}
export function saveGameState(state: GameState) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
}
export function loadGameState(): GameState | null {
try {
const raw = localStorage.getItem(STORAGE_KEY)
if (raw) return JSON.parse(raw) as GameState
} catch { /* 损坏则忽略 */ }
return null
}
线索发现和审讯记录也是纯函数——先检查是否已存在,不存在才返回新状态:
// src/utils/gameEngine.ts
export function discoverClue(state: GameState, clueId: string): GameState {
if (state.discoveredClues.includes(clueId)) return state
return {
...state,
discoveredClues: [...state.discoveredClues, clueId],
}
}
export function recordInterrogation(state: GameState, npcId: string): GameState {
if (state.interrogatedNpcs.includes(npcId)) return state
return {
...state,
interrogatedNpcs: [...state.interrogatedNpcs, npcId],
}
}
这意味着刷新页面后游戏进度不会丢失——应用启动时会尝试从 localStorage 恢复状态。
上下文构建:让智能体知道「现在发生了什么」
游戏引擎最关键的能力是构建上下文——告诉智能体当前调查进度、正在审讯谁、已发现哪些线索。这段上下文直接注入 GM 提示词,决定了智能体回应的质量:
// src/utils/gameEngine.ts
export function buildScriptContext(): string {
const script = getCurrentScript()
const npcList = script.npcs.map(n =>
`- ${n.name}(${n.title}):动机=${n.motive},不在场证明=${n.alibi},性格=${n.personality},秘密=${n.secret}`
).join('\n')
const clueList = script.clues.map(c =>
`- ${c.name}:${c.description}`
).join('\n')
return `剧本名:${script.title}
背景:${script.background}
受害者:${script.victim}
凶手:${script.npcs.find(n => n.id === script.killerId)?.name}(绝对不能直接告诉玩家)
嫌疑人:
${npcList}
线索列表(仅在玩家搜查时逐步揭示,不要一次性全部给出):
${clueList}`
}
export function buildInvestigationContext(state: GameState): string {
const script = getCurrentScript()
const parts: string[] = []
parts.push(`当前游戏阶段:自由调查。玩家已调查 ${state.turnCount} 轮。`)
parts.push(`已发现线索:${state.discoveredClues.length}/${script.clues.length} 条。`)
parts.push(`已审讯嫌疑人:${state.interrogatedNpcs.length}/${script.npcs.length} 人。`)
if (state.currentNpcId) {
const npc = script.npcs.find(n => n.id === state.currentNpcId)
if (npc) parts.push(`玩家正在审讯:${npc.name}(${npc.title})。请以${npc.personality}的语气回应。`)
}
if (state.discoveredClues.length >= 5 && state.interrogatedNpcs.length >= 3) {
parts.push('提示:玩家已掌握较多信息,可以引导进入指控环节。')
}
return parts.join('\n')
}
注意两个设计细节:
第一,buildScriptContext 在列出凶手名字后紧跟一句「绝对不能直接告诉玩家」——这是 prompt 工程中的负向约束,防止智能体在扮演 NPC 时不小心剧透。
第二,buildInvestigationContext 会在玩家调查轮次和线索数达到阈值时,主动提示智能体「可以引导进入指控环节」——这让游戏节奏不致于无限拖延。
六、GM 人设提示词:让智能体成为剧本杀主持人

游戏引擎构建好上下文后,下一步是定义智能体的身份。迷局的智能体不是通用聊天机器人,而是一位有明确身份和行为准则的剧本杀主持人「暗线」。提示词定义了它的核心行为:
// src/constants/index.ts
export const GM_PROMPT = `你是「迷局」的 AI 剧本杀主持人,代号"暗线"。
## 你的身份
- 你是一位经验丰富的剧本杀主持人,擅长营造悬疑氛围
- 你同时扮演剧本中的所有 NPC 角色,用不同的语气和性格演绎每个人
- 你掌控游戏节奏,引导玩家逐步接近真相
## 你的行为准则
1. 用低沉、神秘的语气叙述案情,营造悬疑感
2. 扮演 NPC 时切换对应性格——管家恭敬但闪烁其词、妻子悲伤但暗藏愤怒、合伙人精明且防备、医生冷静却回避细节
3. 玩家询问线索时,根据已发现的线索给出对应信息,不剧透未发现的线索
4. 如果玩家问到了凶手相关的核心问题,NPC 会撒谎或转移话题
5. 每次回复控制在 3-5 句话,保持节奏紧凑
6. 当玩家准备指控时,引导进入指控环节
## 当前剧本信息
{SCRIPT_CONTEXT}`
提示词末尾的 {SCRIPT_CONTEXT} 占位符在每次提问时由 buildScriptContext 替换为完整剧本信息。第 3 条和第 4 条是核心约束——智能体不能剧透未发现的线索,面对凶手相关问题时 NPC 要撒谎或回避。这两条规则让推理过程有了真正的挑战性。
有了身份定义和上下文构建,接下来看 SDK 服务层如何将它们组合并发送给智能体。
七、具身表达层:SDK 服务封装

游戏引擎负责「想什么」,SDK 服务层负责「怎么说」——它需要将游戏引擎构建的上下文转化为智能体的语音和表情。src/services/avatar.ts 是整个项目与魔珐星云 SDK 交互的唯一通道,封装了连接、提问、语音输入、打断、断开五个操作,业务侧不存在任何直接调用 SDK 的代码。
generation 令牌:防止新旧连接回调交叉污染
端到端 SDK 通过回调函数通知状态变化(语音识别结果、对话状态、错误等)。当用户断开重连时,旧连接的回调可能延迟到达,与新连接的回调交叉污染。迷局用 generation 计数器解决这个问题:
// src/services/avatar.ts
let agent: Agent | undefined
let pendingAgent: Agent | undefined
let generation = 0
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'
const scriptCtx = buildScriptContext()
const prompt = GM_PROMPT.replace('{SCRIPT_CONTEXT}', scriptCtx)
await agent.ask(`${prompt}\n请以主持人的身份,用悬疑的语气向玩家介绍案件背景,不超过5句话。`)
avatarState.subtitle = ''
} 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) }
}
每个回调的第一行都是 token !== generation 守卫——如果当前连接代数已变(说明用户已断开重连),回调直接 return,不修改任何状态。
连接采用 Promise.race 加 30 秒超时兜底。SDK 的 init 方法需要建立感知、大脑、表达三条 WebSocket 连接,任一被服务端拒绝(典型场景为控制台积分额度耗尽)则 Promise 永久 pending,超时机制确保用户不会卡在加载界面。
每次提问都注入完整上下文
迷局不缓存提示词——每次调用 askAvatar 都重新构建完整上下文,确保智能体的回应始终基于最新调查进度:
// src/services/avatar.ts
export async function askAvatar(text: string, context: string) {
if (!agent || avatarState.status !== 'online') return
avatarState.subtitle = text
const scriptCtx = buildScriptContext()
const prompt = GM_PROMPT.replace('{SCRIPT_CONTEXT}', scriptCtx)
await agent.ask(`${prompt}\n${context}\n玩家说:${text}`)
}
最终注入智能体的消息由三层拼接:GM 人设提示词(含完整剧本信息)+ 调查阶段上下文(轮次、线索数、当前 NPC)+ 玩家实际输入。这确保了智能体在回答时同时掌握「我是谁」「现在什么阶段」「玩家问了什么」。
八、状态管理:游戏全链路流程控制

src/stores/app.ts 是游戏的流程控制器,将游戏引擎、SDK 服务层和 UI 状态串联成完整链路。
消息系统与多角色演绎
游戏面板中的消息分为四种角色:主持人(gm)、NPC、玩家(user)和系统提示(system)。每种角色有专属的消息构建函数:
// src/stores/app.ts
function addMessage(role: GameMessage['role'], text: string, speakerName?: string, speakerEmoji?: string) {
appState.messages.push({
id: nextId(),
role,
text,
timestamp: Date.now(),
speakerName,
speakerEmoji,
})
}
function addGmMessage(text: string) {
addMessage('gm', text, '暗线', '🎭')
}
function addNpcMessage(text: string, npcName: string, npcEmoji: string) {
addMessage('npc', text, npcName, npcEmoji)
}
function addSystemMessage(text: string) {
addMessage('system', text)
}
审讯、搜查与指控
三大核心操作的流程控制:
// src/stores/app.ts
/** 选择审讯 NPC */
selectNpc(npcId: string) {
const script = getCurrentScript()
const npc = script.npcs.find(n => n.id === npcId)
if (!npc) return
appState.gameState.currentNpcId = npcId
appState.gameState = recordInterrogation(appState.gameState, npcId)
saveGameState(appState.gameState)
addSystemMessage(`你选择审讯 ${npc.emoji} ${npc.name}(${npc.title})`)
addNpcMessage(npc.dialogueHints[0], npc.name, npc.emoji)
},
/** 搜查线索 */
searchClues() {
const script = getCurrentScript()
const undiscovered = script.clues.filter(c => !appState.gameState.discoveredClues.includes(c.id))
if (undiscovered.length === 0) {
addSystemMessage('你已经搜查了所有能找到的线索。')
return
}
const count = Math.min(Math.floor(Math.random() * 2) + 1, undiscovered.length)
const found = undiscovered.slice(0, count)
for (const clue of found) {
appState.gameState = discoverClue(appState.gameState, clue.id)
addSystemMessage(`🔍 发现线索:${clue.name}\n${clue.description}`)
}
saveGameState(appState.gameState)
},
/** 提交指控 */
submitAccusation(targetId: string) {
const script = getCurrentScript()
const target = script.npcs.find(n => n.id === targetId)
if (!target) return
appState.gameState.accusationTarget = targetId
appState.gameState.phase = 'reveal'
saveGameState(appState.gameState)
const isCorrect = targetId === script.killerId
const killer = script.npcs.find(n => n.id === script.killerId)!
if (isCorrect) {
addGmMessage(`指控正确!${target.emoji} ${target.name}就是凶手。\n\n真相:${killer.motive}。案发当晚,${killer.name}确实去过书房门口,但声称只是"想敲门谈生意"。然而烛台底部的纺织纤维与他的西装面料完全一致……\n\n你成功破解了这桩雨夜迷案!`)
} else {
addGmMessage(`指控错误。${target.emoji} ${target.name}并不是凶手。\n\n真正的凶手是 ${killer.emoji} ${killer.name}。\n\n动机:${killer.motive}。\n\n关键证据:烛台底部的纺织纤维与${killer.name}当晚所穿西装面料一致,而女佣证实${killer.name}在案发时间出现在书房门外的走廊。\n\n别灰心,好侦探都是从失败中成长的。`)
}
},
搜查线索每次随机发现 1-2 条,模拟真实搜查的渐进感。指控环节直接判定对错并公布完整真相——包括凶手动机和关键证据链。
自然语言指令检测
玩家不需要记忆按钮操作——在输入框中说到「搜查」「搜索」「找线索」时自动触发线索搜查,说到「指控」「指认」「凶手是」时自动进入指控环节:
// src/stores/app.ts
async sendMessage(text: string) {
if (!text.trim() || appState.sending) return
const trimmed = text.trim()
appState.text = ''
addMessage('user', trimmed, '侦探')
appState.gameState.turnCount += 1
const lower = trimmed.toLowerCase()
if (lower.includes('搜查') || lower.includes('搜索') || lower.includes('找线索')) {
appStore.searchClues()
} else if (lower.includes('指控') || lower.includes('指认') || lower.includes('凶手是')) {
appStore.startAccusation()
}
appState.sending = true
try {
const ctx = buildInvestigationContext(appState.gameState)
await askAvatar(trimmed, ctx)
} finally {
appState.sending = false
saveGameState(appState.gameState)
}
},
这意味着玩家可以完全通过自然对话推进游戏——「我想搜查一下书房」「我怀疑凶手是钱世昌」——不需要离开输入框去找按钮。
九、三栏交互界面:嫌疑人、对话、智能体同屏呈现
迷局的游戏界面采用三栏布局,将推理所需的全部信息平铺在同一屏幕:
┌─────────────────────────────────────────────────────┐
│ ← 返回 🔍 迷局 MíJú 📋 线索板 │
├──────────┬──────────────────────┬───────────────────┤
│ 嫌疑人 │ 对话面板 │ 智能体渲染区 │
│ │ [阶段徽章] [统计] │ │
│ 🎩 老陈 │ 🎭 暗线:欢迎来到... │ ┌─────────┐ │
│ 👩 苏婉清 │ 🤵 钱世昌:我和... │ │ 具身 │ │
│ 🤵 钱世昌 │ 🔍 发现线索:... │ │ 智能体 │ │
│ 🩺 林致远 │ │ │ 实时 │ │
│ │ [搜查线索] [发起指控] │ │ 渲染 │ │
│ 💀 受害者 │ [输入框...] [发送] │ └─────────┘ │
└──────────┴──────────────────────┴───────────────────┘
左栏展示四位嫌疑人的动机和不在场证明,点击即可审讯;中栏是对话主区域,消息按角色分色显示(主持人琥珀色、NPC 紫色、玩家蓝色、系统灰色),底部有搜查线索和发起指控的操作按钮;右栏是智能体实时渲染区,具身交互智能体居中展示,底部有字幕和控制栏。
线索板设计为浮层覆盖层——点击顶栏「线索板」按钮后从底部滑入,不占用固定栏位,保持三栏布局的完整性。已发现的线索按物证(红色)、证词(蓝色)、文书(黄色)三色标记,未发现的显示为「???」。
十、架构对比:端到端单链路与传统三线拼接
传统具身交互项目通常采用三线拼接架构:腾讯 ASR 做语音识别 → OpenAI SDK 调豆包大模型 → 手动拼装 SSML 喂给 XmovAvatar.speak,再用 ActionManager 做流式分片。三个模块独立运行,业务侧需要维护状态同步、超时重试、分片拼接大量胶水代码。
迷局采用的端到端 SDK 将感知、大脑、表达打通为单条链路。业务侧的交互只有两个方法——ask 发送文本、startASR 开启语音输入,其余全部由 SDK 内部完成。对比迷局的 avatar.ts(168 行)与传统管线项目动辄 500+ 行的服务层,代码量缩减超过 60%。
更关键的是延迟差异。传统管线中 ASR → LLM → TTS 三段串行,每段都有网络往返;端到端 SDK 内部优化了流水线,语音识别结果可以边出边送大模型推理,TTS 边合成边播放,端到端延迟显著降低。
十一、总结:900 行代码的完整闭环
从类型定义到三栏界面,迷局用不到 900 行业务代码实现了一个完整的 AI 剧本杀游戏:
- 数据建模:类型系统定义了剧本、NPC、线索、消息、游戏状态的完整骨架,内置剧本包含 4 位 NPC、8 条线索、完整的动机与证据链
- 游戏引擎:四阶段状态流转 + localStorage 持久化 + 纯函数更新,上下文构建让智能体始终掌握最新调查进度
- 具身表达:端到端 SDK 单集成,generation 令牌防回调污染,30 秒超时兜底,每次提问注入完整剧本上下文
- 交互设计:三栏同屏布局、自然语言指令检测、线索板浮层、多角色消息分色
从传统管线到端到端 SDK,迷局的实战经历验证了一个核心认知:
端到端不是 ASR + LLM + TTS 的简单拼接,而是围绕一次完整的人机交互,把感知、理解、决策、表达和行动连接成一套持续运行的系统。
| 对比维度 | 传统管线 | 端到端具身交互智能 |
|---|---|---|
| 多角色演绎 | 需要分别调用不同服务 | 单 SDK 实时切换性格与语气 |
| 上下文感知 | 手动拼接 prompt | 游戏引擎自动构建调查进度上下文 |
| 语音交互 | 三段串行,延迟累积 | 边识别边推理边合成,端到端低延迟 |
| 打断能力 | 需手动管理状态 | 客户端即时生效 |
| 首字响应 | 1.5 ~ 3 秒 | ~500ms |
| 部署复杂度 | 三套服务分别对接 | 一个 SDK 全链路打通 |
迷局只是端到端具身交互智能的一种落地形态。同一个智能体,今天可以是 Web 端的剧本杀主持人,明天可以出现在手机、Pad、AI 屏幕甚至人形机器人上——身体可以变化,但角色扮演和推理能力持续复用。
魔珐星云是一套端到端具身交互智能平台,让 AI 通过屏幕和机器人进入真实世界,成为能够感知、理解、表达并行动的智能体。
这不只是技术架构的升级,而是 AI 从"对话框"走向"真实交互"的必经之路——让每一场剧本杀,都拥有一位永远不剧透的主持人。
如果你想亲自体验端到端具身交互智能的魅力,或者基于魔珐星云平台搭建属于自己的具身交互智能体,欢迎访问魔珐星云官网,开启你的具身交互智能实战之旅:https://xingyun3d.com?utm_campaign=daily&utm_source=CSDNwanfen2&utm_medium=&utm_term=&utm_content=
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)