从预订问到退房:一间山野民宿的数字人「旅程地图」——Theme07_Homestay.vue 端到端拆解

从预订问到退房:一间山野民宿的数字人「旅程地图」------Theme07_Homestay.vue 端到端拆解

住民宿和住酒店最大的差别,是这中间站着一个「人」------他记得你订的是山景还是阁楼,知道今晚院子里的星空好不好看,也清楚退房那天中午 12 点前要把房卡放在哪儿。

所以这篇不按「背景 → 接入 → CSS → 知识 → 小结」那套通用骨架写。我们跟着一位旅客,把界面从头到位走一遍:预订、到店、入住、在店、退房 。每一站停一下,聊一个技术话题,顺手把 Theme07_Homestay.vue 里对应的那一段样式拆开看。走完这趟,你会发现这个组件的样式不是装饰,而是「旅途进度」的可视化。

先把这次旅程要带的四件行李摆出来,它们会在不同站点反复出现:

  • 专属智脑:让智能体知道「我是谁、知道什么、应该做什么」。这一篇的主概念,会花最多笔墨。

  • 多模态感知 :持续知道这间民宿正在发生什么------听觉、视觉、业务数据多通道并行输入,是「在店」那一站的核心。持续感知,而不是一次输入。

  • 多模态表达 :实时生成统一、连续、同步的具身表达------语言、口型、表情、眼神、头部、手势统一实时生成,会在「入住」的 ask() 里登场。

  • AI 端渲 :让实时交互真正变成终端基础能力,把渲染下沉到终端侧,是「在店」弱网场景里的兜底。省带宽、省机器、弱网也不掉链子。

而贯穿全程的那条链路,也早已不是早年的写法。项目已经从「前端自建 DeepSeek 流式 + 前端按标点拆句 + 前端手写 SSML」的三段拼装,迁移到了魔珐星云 Xingyun 端到端(端对端)SDK:全局对象 window.XingyunAvatarAgent 负责把 LLM 回复、TTS、口型、表情、动作一次编排到底。组件做的,只剩下「把话说出去」和「把界面点亮」。

组件主题前缀统一为 stay-,配色是一套奶咖(#fbf7f0 / #efe6da)+ 橄榄绿(#6b7a54)+ 落日橘(#e08a4e)的庭院色调。


第一站 · 预订:智脑先「读懂人」,再谈房

旅客第一次开口,往往不是「我要订房」,而是「我想找个安静点、能看星星的地方,就我们俩」。这句话里没有房型名,也没有日期。能接住它的,不是关键词表,而是专属智脑。

它得先知道「我是谁、我知道什么、我应该做什么」

  • 我是谁:民宿管家「小山」,一个亲切、周到、会说「您打算什么时候来山野间呀」的在地服务者,不是通用客服。

  • 我知道什么:三种房型的可住人数、床型、面积、参考价,以及周边怎么玩、早餐几点、退改怎么算。

  • 我应该做什么:在旅客还没说清需求时,主动往「匹配房型」上收敛,而不是闲聊。

专属智脑要同时回答三层问题:它知道什么(民宿的房型、价格、退改规则、周边玩法这些在地知识),它是谁(民宿管家「小山」这个具体身份),它要做什么(在旅客还没说清需求时主动收敛到匹配房型,而不是闲聊)。三层都答上了,才谈得上从「通用回答」升级为面向具体身份和业务的智能体能力。

这三件事在项目里是被显式约定的。src/constants/index.ts 为每个主题准备了一段 SYSTEM_PROMPT,民宿这一份(主题 7)的定位就是「民宿预订智能管家」,约束它「语言亲切自然、重点区分不同房型适合人群、入住与退房流程、周边玩法搭配」。换句话说,同一套底座,换一段场景提示词,数字人就从侍酒师变成了管家。

不绑死某一家大模型,也不把住客数据交出去

智脑这一层的设计态度很关键:它不绑死某一家大模型 ------豆包、DeepSeek、ChatGPT 等用惯的模型都可以接;没有现成模型时,可以直接用魔珐星云自研的智脑。自研这条路的四个特点是:低延迟、强逻辑、场景化理解、数据安全可控,专为具身交互场景优化。

对民宿这个行业来说,「数据安全可控」不是一句口号。住客的身份证信息、订单金额、门锁密码、行踪时间,全是敏感数据。让智脑跑在可控的环境里、按场景边界使用数据,比模型榜单上的分数重要得多。

而「场景化理解」落到具体动作上,就是组件里的 sendChatMsg 那串关键词分支:旅客话里带「订房 / 预订 / 价格」,走报价;带「房型 / 哪种 / 推荐」,走选型;带「包栋 / 团建 / 派对」,走包场方案。这就是智脑在用业务数据做场景收敛------三种房型的真实价签是它推荐的锚点:

typescript 复制代码
// Theme07_Homestay.vue ------ 房型数据(智脑推荐的锚点)
{ id: "p1", icon: "⛰️", title: "山景大床房", 参考价: "¥680", content: "落地大窗正对山间云雾......" },
{ id: "p2", icon: "🌿", title: "庭院亲子房", 参考价: "¥880", content: "独立小院带秋千......" },
{ id: "p3", icon: "✨", title: "星空阁楼",   参考价: "¥760", content: "斜顶天窗躺看星空......" },

让「房型」以明信片的形式被递出去

预订这一站对应的是左侧的 stay-postcard-grid。三张明信片房型卡,交错旋转、贴邮票、盖邮戳,把「一封信寄到你手里」的意象搬进界面。旋转角度由模板里的 inline style 控制:

vue 复制代码
<!-- 模板中的旋转:三张卡分别 -2° / 1° / -1° -->
<div
  v-for="(product, pIdx) in productList"
  :key="product.id"
  class="stay-postcard"
  :style="{ transform: `rotate(${[-2, 1, -1, 0][pIdx]}deg)` }"
  @click="playProductContent(product)"
>

卡片右上角的 stay-stamp 是 40×40 的落日橘方块 + 虚线描边,模拟邮票锯齿边;stay-postmark 是 52×52 的圆形橄榄绿边框邮戳,opacity: 0.4 加 rotate(-15deg),做出「盖下去的粗糙感」。这两件东西都不是纯装饰------邮票里装着房型图标,邮戳在暗示「这家店有口碑」。

css 复制代码
.stay-postcard:hover {
  transform: rotate(0deg) translateY(-3px) !important;
  box-shadow: 0 10px 24px rgba(107, 122, 84, 0.28);
}
.stay-stamp {
  position: absolute;
  top: 8px; right: 8px;
  width: 40px; height: 40px;
  background: #e08a4e;
  border: 2px dashed #fbf7f0;
  border-radius: 4px;
}
.stay-postmark {
  position: absolute;
  top: 10px; right: 54px;
  width: 52px; height: 52px;
  border: 2px solid #6b7a54;
  border-radius: 50%;
  opacity: 0.4;
  transform: rotate(-15deg);
}

明信片正中间的竖分隔线 stay-divider 用 repeating-linear-gradient 做「橄榄绿 3px + 透明 3px」的循环,比手写 dashed 稳定:

css 复制代码
.stay-divider {
  position: absolute;
  top: 56px; bottom: 34px; left: 50%;
  width: 1px;
  background: repeating-linear-gradient(180deg, #6b7a54 0 3px, transparent 3px 6px);
  transform: translateX(-50%);
}

右侧那四行 stay-metric(可住人数 / 床型 / 面积 / 参考价),是智脑推荐时最常用的四个维度。stay-m-value 用了落日橘加手写体 Caveat,让数字看起来像笔写上去的。


第二站 · 到店:让数字人「出场」,把第一句话说顺

旅客推门进来,管家得先露面、先开口。这一站对应组件的初始化流程。

连接、初始化、再把问候直接播出去

typescript 复制代码
// Theme07_Homestay.vue ------ 到店即出场
const initAvatar = async () => {
  const initContent =
    "你好呀,我是民宿管家小山!订房、入住指引、周边行程,都可以直接问我。您打算什么时候来山野间呀?";
  try {
    await appStore.connectAvatar();
    isAvatarReady.value = true;
    ElMessage.success("民宿管家小山数字人已就绪");
    subtitleText.value = initContent;
    appStore.speakGreeting(initContent);
  } catch (err) {
    console.error("数字人初始化失败:", err);
    ElMessage.error("数字人加载失败,请刷新页面重试");
  } finally {
    isLoading.value = false;
  }
};

这里有个容易忽略的细节:问候语走的是 speakGreeting ,不是 ****ask 。问候是「直接播报」,不需要过一遍大模型。appStore.speakGreeting 内部先 generateSSML(text) 把文本包成 <speak pitch="1" speed="1" volume="1">...</speak>,再调 avatar.speak(ssml, true, true)。省掉一次 LLM 往返,进门第一句就更跟得上人。

底层连接的真正入口是 avatarService.connect()。它负责构造端到端 SDK:

typescript 复制代码
// src/services/avatar.ts ------ 端到端 SDK 构造参数
const agent = new window.XingyunAvatarAgent({
  container: containerEl,          // 组件里的 .stay-avatar-canvas
  appId: APP_ID,
  appSecret: APP_SECRET,
  enableDebugger: false,
  gatewayServer: url.toString(),   // SDK_CONFIG.GATEWAY_URL + data_source/custom_id
  onWidgetEvent, onStateChange, onMessage,
  agentCallbacks: { onError, onConversationChange, onAgentStateChange },
});
await agent.init({ onDownloadProgress, onClose });

网关固定在 SDK_CONFIG.GATEWAY_URL = "https://nebula-agent.xingyun3d.com/user/v1/ttsa_v2/session",并带上 DATA_SOURCE: "2"、CUSTOM_ID: "demo" 两个查询参数。容器 #containerId 由 avatarService.getContainerId() 生成,对应模板里的 <div :id="containerId" class="stay-avatar-canvas">------SDK 会在里面挂 canvas,所以组件还特意等了容器布局非零才初始化。

木牌与光晕:让「出场」有场景感

到店的视觉是顶部那块手绘木牌 stay-wood-plaque:橄榄绿 2px 边框 + 奶咖底 + 12px 圆角,box-shadow 叠了外层橄榄绿投影和内层落日橘 inset 描边,撑出木头的厚度。两侧的圆铆钉由 ::before / ::after 画成 16px 圆点。

css 复制代码
.stay-wood-plaque {
  background: #efe6da;
  border: 2px solid #6b7a54;
  border-radius: 12px;
  padding: 12px 34px 8px;
  box-shadow: 0 6px 16px rgba(107, 122, 84, 0.22),
    inset 0 0 0 1px rgba(224, 138, 78, 0.25);
}
.stay-wood-plaque h1 {
  font-family: "Caveat", "Bradley Hand", cursive, "PingFang SC";
  color: #6b7a54;
  letter-spacing: 4px;
  text-shadow: 1px 1px 0 rgba(224, 138, 78, 0.2);
}

数字人身后那圈暖光来自 .stay-halo:radial-gradient 从中心 rgba(224,138,78,0.3) 向外渐隐到 70%,像傍晚照进庭院的落日;脚下的 stay-grass 直接摆 emoji 🌿🌱🌾🌿,letter-spacing: 6px 撑开。

css 复制代码
.stay-halo {
  position: absolute;
  top: 50%; left: 50%;
  width: 90%; height: 80%;
  transform: translate(-50%, -60%);
  background: radial-gradient(circle at center, rgba(224,138,78,0.3) 0%, transparent 70%);
  pointer-events: none;
}

光晕和木牌不是为了好看而好看:木牌给出「这是一间什么样的店」,光晕给出「管家站在庭院的什么位置」。到店这一站,数字人先被放进了一个有坐标的场景里------顺序很讲究,因为只有先「看见」现场,后面才谈得上感知。


第三站 · 入住:一次 ask(),从「回话」走到「动作」

办入住的时候,旅客开始抛具体问题。这一站是整条链路的心脏。

先说清楚「以前」和「现在」

项目早年的链路是:前端自己拼 DeepSeek 流式请求 → 前端按标点拆句 → 前端手写 SSML 再喂给数字人。拆句和 SSML 全靠前端,口型和语音很容易对不上。

现在换成端到端 SDK,前端的活儿被砍到只剩一层薄薄的转发。核心就是 ask():

typescript 复制代码
// src/stores/app.ts ------ 一条链路直达
async sendMessage(): Promise<string | undefined> {
  const { ui, avatar } = appState;
  if (!ui.text || !avatar.instance) return;
  await avatar.instance.ask(ui.text);   // LLM 回复 → TTS → 口型 → 表情 → 动作
  return ui.text;
}

把「前端自建 LLM 流式 + 前端按标点拆句 + 前端手写 SSML」的三段拼装,收成一次 avatar.instance.ask(text):LLM 回复 → 语音合成 → 口型/表情/动作一次编排完成,前端不再插手中间环节------这就是端到端(端对端) :一条 ask() 打通整条链路。

而它要交付的表达形态,正是多模态表达------实时生成统一、连续、同步的具身表达:

  • 讲到「星空阁楼躺着数流星」时,语气自动放柔、眼神往上一飘,像真的在看那扇斜顶天窗;

  • 报出「880 元、含四份早餐」时,手势比出数字、微微点头,重音落在价格上;

  • 说到「三天内不退」时,表情收敛、语速放缓,把退改规则的严肃感传出去。

语言、口型、表情、眼神、头部动作、手势和身体动作统一实时生成------统一、连续、同步,民宿对话不再是干巴巴的读表。

组件侧的 speakText:只管把界面点亮

组件不直接碰 SDK,它通过 appState.ui.text + appStore.sendMessage() 转发:

typescript 复制代码
// Theme07_Homestay.vue ------ 组件侧转发
const speakText = (text: string) => {
  isAvatarSpeaking.value = true;
  subtitleText.value = text;
  appState.ui.text = text;
  appStore.sendMessage().then(() => {
    setTimeout(() => {
      isAvatarSpeaking.value = false;
    }, text.length * 50);
  });
};

text.length * 50 只是用来估算「管家还在说话」这个动画状态的长度,让界面上的 speaking 态和实际节奏大致同步。真正的语音时长由 SDK 自己管理。

入住这一站的界面:房卡套看板

左侧「今日民宿」是一排房卡套,正好对应「办入住时前台那一眼状态」:外层橄榄绿容器 stay-keycard-slot、顶部 30px 深色卡槽横条 stay-slot-bar(渐变 #4d5a3d → #6b7a54)、底部露出一大半的米白房卡 stay-keycard。

css 复制代码
.stay-keycard-slot {
  position: relative;
  height: 96px;
  background: #6b7a54;
  border-radius: 6px 6px 8px 8px;
  box-shadow: 0 4px 12px rgba(107, 122, 84, 0.25),
    inset 0 -2px 0 rgba(0, 0, 0, 0.22);
}
.stay-slot-bar {
  height: 30px;
  background: linear-gradient(180deg, #4d5a3d, #6b7a54);
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
}
.stay-keycard {
  position: absolute;
  bottom: 0; left: 6px; right: 6px;
  background: #fbf7f0;
  border-radius: 4px 4px 6px 6px;
  padding: 8px 10px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
}

卡面上是四个运营指标:今日可订房数 12 间、近 30 天入住率 92%、好评评分 4.92、回头客占比 38%。趋势值用 stay-kc-trend.up(橄榄绿)/ .down(落日橘)区分升降------这四张房卡,就是「入住率好不好」的一句话体检报告。


第四站 · 在店:自己说话时,也要听得见你插话

住下来之后,交互进入高频状态。这一站的主概念是多模态感知 ,副概念是 AI 端渲。

多通道并行,关键是「插话」

多模态感知要做的,是持续知道这间民宿正在发生什么。它的目标,不是简单把旅客的话转成文字,也不是把门口摄像头里的人脸识别一下就算数。真正要解决的是:旅客一句「想找个安静点、能看星星的地方,就我们俩」,得从中同时读出人数、偏好和大致日期,而不是等他把房型名报全;院子里有人随口问「今晚能不能看到星星」,得结合时间、天气和朝向接得住;而且------即使管家自己正在说话,也能继续听见旅客的插话,让交流继续往下走,而不是被迫听完再重来。

落到组件上,就是聊天面板 stay-chat-input 始终可输入:哪怕小山的问候或播报还在进行,旅客敲一句话回车(@keyup.enter="sendChatMsg"),新问题立刻被接住,不会因为「管家正在讲话」而卡住。业务数据通道则由 sendChatMsg 的分支承担,覆盖订房、房型、早餐、包栋、退改、宠物、周边七类高频诉求------这就是「听觉 + 业务数据」两条通道同时在跑。持续感知,而不是一次输入,这正是多模态感知与「录一句、答一句」的语音助手的分水岭。

字幕事件:把「正在说的话」同步到界面

语音通道的输出,通过 SDK 的 onWidgetEvent 事件回传。构造参数里对字幕事件做了判断:

typescript 复制代码
onWidgetEvent: (event: any) => {
  if (event.type === 'subtitle_on') {
    onSubtitleOn(event.text);   // → appState.ui.subTitleText
  } else if (event.type === 'subtitle_off') {
    onSubtitleOff();            // → 清空
  }
}

组件再用一个 watch 把全局状态同步成局部字幕:

typescript 复制代码
watch(
  () => appState.ui.subTitleText,
  (val) => { subtitleText.value = val || ""; }
);

字幕卡 stay-subtitle-card 在 speaking 时切换成橄榄绿描边并跑 stay-glow 呼吸动画------说话这件事,在界面上是「看得见」的。

css 复制代码
.stay-subtitle-card.speaking {
  border-color: #6b7a54;
  animation: stay-glow 2s ease-in-out infinite;
}
@keyframes stay-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(107, 122, 84, 0.3); }
  50% { box-shadow: 0 0 0 9px rgba(107, 122, 84, 0); }
}

AI 端渲:山里的弱网,得靠终端扛

民宿常在信号不好的山里,弱网甚至断网都是常态。如果渲染全靠云端,一旦网络抖动,画面就会跟着卡。AI 端渲要做的,是让实时交互真正变成终端的基础能力:把渲染下沉到终端侧完成,降低云端 GPU 成本、降低带宽占用、降低延迟、提升稳定性。也就是说,字幕、口型这些高频更新的部分,不必每一次都等云端回包------网络差的时候,现场体验不会直接塌掉。省带宽、省机器、弱网也不掉链子------山里的民宿能用,才是真的能用。

在店的其余两处界面

底部印章快捷按钮 stay-seal 用 border: 3px double #6b7a54 做出双圈印章感,选中态 transform: scale(0.92) + 降低不透明度,模拟盖下去时的形变与墨迹变淡;间隔的 .alt 换成落日橘,做节奏对比。

css 复制代码
.stay-seal {
  width: 66px; height: 66px;
  border-radius: 50%;
  border: 3px double #6b7a54;
  background: #fbf7f0;
}
.stay-seal.active {
  transform: scale(0.92);
  opacity: 0.7;
  box-shadow: inset 0 0 10px rgba(107, 122, 84, 0.3);
}
.stay-seal.alt { border-color: #e08a4e; }

右侧「住客手账」FAQ 每条上面贴着一小片橘色胶带 stay-tape(70×16、rgba(224,138,78,0.55)、rotate(-3deg)),卡片底色叠了一层层手账横线:

css 复制代码
.stay-faq-item {
  background-image: repeating-linear-gradient(
    180deg,
    transparent 0 21px,
    rgba(107, 122, 84, 0.12) 21px 22px
  );
}
.stay-tape {
  position: absolute;
  top: -8px; left: 8px;
  width: 70px; height: 16px;
  background: rgba(224, 138, 78, 0.55);
  transform: rotate(-3deg);
}

展开箭头由 stay-faq-arrow.expanded { transform: rotate(180deg); } 翻转,答案用 stay-fadeIn 淡入。这些细节堆在一起,FAQ 就不再是冷冰冰的折叠面板,而是「管家随手记下的住客常问」。


第五站 · 退房:断得干净,才有下一次入住

旅程的最后一步是退房结账、挂断。技术上也一样------连接得干净地关掉。

typescript 复制代码
// Theme07_Homestay.vue ------ 双重保障断开
onMounted(() => {
  window.addEventListener("beforeunload", () => {
    avatarService.disconnect(appState.avatar.instance);
  });
});

onUnmounted(() => {
  if (appState.avatar.instance) {
    avatarService.disconnect(appState.avatar.instance);
    appState.avatar.instance = null;
  }
});

avatarService.disconnect() 内部只做一件事:agent.destroy('user_disconnect')。onUnmounted 覆盖组件切换(十个主题之间跳转),beforeunload 覆盖关页/刷新,两条路都指向同一个 destroy,避免 WebSocket 泄漏。

断开的同时,SDK 的回调也会给出状态:

typescript 复制代码
agentCallbacks: {
  onError(error) { console.error('[AgentError]', error?.code, error?.message || error); },
  onConversationChange(event) {
    if (event?.state === 'completed') { /* 一轮对话结束 */ }
  },
  onAgentStateChange(state) { /* 状态流转 */ },
}

onConversationChange 里的 state === 'completed' 可以理解为「这一轮话说完、结完账了」;配合 init({ onClose }) 里把状态清空,整个退出过程是有序收尾,而不是直接拔电源。


尾声 · 民宿这门生意的六组数字

界面上的数据来自四个数组,它们本身就很「民宿」:quickServices 六项快捷服务(房型预订 / 入住指引 / 周边行程 / 设施咨询 / 包栋团建 / 退改政策);productList 三种房型(山景大床 2 人 · 1.8m 大床 · 28㎡ · ¥680;庭院亲子 3-4 人 · 1.8m+1.2m · 36㎡ · ¥880;星空阁楼 2 人 · 1.8m 榻榻米 · 22㎡ · ¥760);statsData 四个运营指标;faqList 五条住客高频问题。UI 不是静态画布,而是这些数据的视觉投影。

下面六条是民宿这门生意真正在运转的规则,也解释了「为什么界面要长成订房 + 状态看板 + 手账 FAQ 的样子」:

1. 房型定价逻辑

民宿价格波动比酒店更剧烈。旺季(五一 / 十一 / 暑假)上浮 50-100%,周末上浮 20-30%,工作日是基础价。提前 30 天预订通常有 15% 左右的早鸟折扣。情侣房型、景观房型价格溢价明显,能比基础房型高出 30-50%。

2. 入住退房流程与保洁周转

标准退房时间中午 12:00,入住 14:00 之后,中间 2 小时是保洁窗口。实际运营中保洁需要 4 小时完成全流程------布草换洗送洗、开窗通风 30 分钟、深度清洁、备品补充。如果前一晚客人延迟退房,保洁时间被压缩,最容易出问题的就是卫生间和床品死角。

3. 超售风险应对

民宿房量小(通常 5-15 间),超售的容错率远低于连锁酒店。行业通行做法是保留 10-15% 房数不对外售卖作为缓冲,同时与周边民宿建立紧急房源备份协议。万一真的超售,给客人免费升级房型 + 赠送 50-200 元消费券是最常用的补偿方案。

4. 退改政策设计

三档常见策略:宽松档(入住前 7 天前免费)适合散客、标准档(14 天前免费)适合商旅、严格档(不可退改)适用于旺季和包栋订单。实际运营中会灵活处理------比如遇到台风封路、客人突发疾病,可以破例放行,口碑比规则重要。

5. 周边体验组合思路

把在地手作活动(陶艺、制茶、竹编)、本地私房菜、景区联票打包成「住宿套餐」,可以提升客单价 30-50%。关键是要和本地供应商提前谈好佣金比例(通常 15-25%),并且在入住前一天给客人发推荐短信,转化率最高。

6. 消防与卫生合规

每间房必须有独立烟感报警器 + 走廊灭火器。布草一客一换是底线------床单被套枕套必换,毛巾浴巾通常备两套让客人自己决定是否更换。有浴缸的房型每周要做一次高温消毒并记录。开业前必须过消防验收,每年做一次卫生检测。


这趟旅程走完,把组件重新看一遍就通了:预订是智脑的场景化理解与模型可替换,到店是初始化与问候让数字人带着坐标出场,入住 是 ask() 一条链路统一生成语言与动作,在店是多模态感知接住插话、并用 AI 端渲守住弱网,退房 是 destroy 的干净收尾。明信片、房卡套、木牌、印章、胶带------这些 CSS 物件不是氛围填充,而是这五个时刻各自的信息载体。理解了「旅程」,也就理解了为什么这个界面不多不少,刚好需要这几样东西。

相关推荐
DealFlow AI7 小时前
普法视频同步展示合同和法条的省力方法
数字人
未来之窗软件服务1 天前
web网络请求竞态问题与取消方案-东方仙盟
前端·状态模式·仙盟创梦ide·东方仙盟·网络取消
一级新生2 天前
多智能体协作:常用协作模式详解
人工智能·状态模式·agent·多智能体·智能体
DealFlow AI4 天前
新闻口播语速怎么按内容调整
数字人
喜欢打篮球的普通人4 天前
LLVM 前端与优化层:Clang 如何把 C 代码变成 IR
c语言·前端·状态模式
骑着蜗牛撵大象3274 天前
用 Codex 批量做数字人商品口播视频:从分镜 JSON 到成片校验的流水线
java·ffmpeg·json·音视频·数字人·视频·codex
m0_敲代码的彭于晏1685 天前
Vercel 前端部署与全栈开发实战指南
前端·状态模式
星恒随风5 天前
Linux线程同步与互斥(二):从日志系统与线程池设计,到线程安全单例、可重入函数和死锁原理
linux·运维·状态模式
学Linux的语莫6 天前
python中类的常见写法
开发语言·python·状态模式