上周我在准备一次内部分享时,遇到一个很典型但又很难彻底解决的问题:PPT内容其实不复杂,但一到现场就容易出现三件事,第一是讲解节奏被打断,第二是同一份材料要反复讲,第三是观众提问很容易把讲解主线拉偏。说白了,问题不在“有没有PPT”,而在“PPT有没有表达能力”。

我这次没有再去优化模板动画,而是直接做了一个“数字人PPT讲解系统”:上传 PDF 后,自动抽取每页文本,调用大模型生成讲解词,再由魔珐数字人播报;讲完当前页后自动翻页续讲,同时支持观众提问并由数字人回答。

最终这个仓库在本地可以直接 npm run build 通过,核心讲解链路代码已经完整打通(前提是你填好魔珐与模型配置)。这篇文章我只写真实跑过、真实看过源码的内容,不写空话。

image-20260424152423296


资源入口

如果你准备用魔珐星云实操这套方案,注册时填写我的专属邀请码 JHSAYDL7TM可以免费获得 1000 积分,官方口径约可体验 2000 分钟数字人能力,足够把 Demo 跑通并做多轮验证。


封面图:AI数字人PPT讲解系统


一、这个项目到底在解决什么问题

1. 演讲准备时间被反复消耗

传统流程是“每页写备注 + 排练 + 修稿”,尤其是页数多的时候,讲稿维护成本非常高。这个项目把“每页讲什么”交给模型实时生成,减少了人工维护讲稿的重复劳动。

2. 讲解链路缺少稳定节奏

大多数演示系统只能翻页展示,不负责讲解节奏控制。这个项目把“讲解结束回调”接到“自动翻页续讲”上,形成了闭环链路:讲完 -> 翻页 -> 继续讲,不需要手动干预。

3. 观众问题无法贴着当前页回答

很多问答系统是全局回答,容易偏题。这里问答是“当前页文本上下文 + 用户问题”拼接后再发给模型,所以回答更贴近当页内容。

4. 数字人常见的“等待卡顿”体验

系统做了下一页讲解词预加载:讲当前页时后台静默生成下一页讲解词,翻页后可以直接播报,体感上更连贯。


二、架构怎么落地的(不是概念图,是真实代码职责)

系统架构图

1. 展示交互层(App.vue

负责上传 PDF、页面渲染、翻页控制、状态提示、问答输入,以及“自动续讲/预加载”开关。

2. PDF能力层(usePDF.js

pdfjs-dist 加载文档,并在加载阶段把所有页面文本提取出来缓存到 pageTexts。后续讲解、问答都基于这份文本。

3. 模型能力层(useGPT.js

提供两套调用方式:

  • generateNarration():前台生成讲解词(会占用生成状态)
  • generateNarrationSilent():后台静默生成(用于预加载,不打断主流程)

4. 数字人能力层(useXingyunAvatar.js

封装魔珐 SDK 初始化、播报、待机、销毁、讲完回调;并支持男女双形象切换(两套 appId/appSecret)。


三、我认为最有价值的 5 个实现细节

“讲解词缓存”不是锦上添花,是稳定性的基础

项目里有 narrationCache,键是页码,值是讲解词。首次生成后缓存,后续回到同页不再重复请求模型。这个设计直接减少了重复消耗,也避免了同一页每次讲解口径漂移。

“预加载下一页”用的是静默链路,不会抢占前台状态

预加载逻辑里调用的是 generateNarrationSilent(),而不是前台 streamChat。这意味着当前页讲解期间不会出现“UI状态被切到思考中”的错觉,交互上更稳。

自动续讲的触发点选在“说完回调”而不是定时器

很多项目会用固定延迟翻页,这在语速变化时会出问题。这里是 onSpeakEnd -> handleSpeakEnd -> nextPage,并且根据下一页是否命中缓存选择不同延迟(500ms 或 1500ms),这比纯定时器更可靠。

问答提示词只绑定当前页,降低跑题率

提问时会拼接“当前第N页文本 + 用户问题”,模型回答被限定在当页语境中。对会议讲解场景来说,这比全局泛答更实用。

形象切换做的是“销毁并重建”,避免跨配置污染

当从女讲解员切到男讲解员时,会先销毁旧实例再初始化新实例。虽然切换有一点等待,但状态更干净,不容易出现残留连接问题。


四、配置实操:魔珐 + 模型怎么接

配置步骤图

第一步:配置数字人参数(src/composables/useXingyunAvatar.js

仓库默认是空值,需要你填:

const avatarConfigs = {
  female: { appId: '你的female_app_id', appSecret: '你的female_app_secret' },
  male: { appId: '你的male_app_id', appSecret: '你的male_app_secret' }
}

第二步:配置模型参数(src/composables/useGPT.js

同样默认空值,需要你填:

const config = {
  apiUrl: 'https://你的模型网关/v1/chat/completions',
  apiKey: '你的api_key',
  model: '你的model_id'
}

第三步:启动并验证

npm install
npm run dev

默认端口是 3004。进入页面后:上传 PDF -> 唤醒数字人 -> 观察是否自动讲第一页。

第四步:验证问答链路

在底部输入一个与当前页相关的问题,观察是否完成:

  1. 输入受理
  2. 模型返回
  3. 数字人播报答案

如果前两步成功但不播报,优先检查数字人初始化状态与 isBusy 条件。


五、我做的客观验证结果(本地)

验证结果与上线清单

依赖安装

npm install 成功。安装后提示存在 3 个漏洞(2 moderate,1 high),属于依赖层告警,不影响本次构建通过。

构建验证

npm run build 成功,关键产物如下:

  • dist/assets/index-*.js440.44 kB(gzip 138.12 kB
  • CSS 约 7.98 kB
  • 构建耗时约 2.60s

边界说明(这点很重要)

我没有在这次复盘里伪造“全链路线上实测”结论。仓库里 appId/appSecret/apiKey 默认为空,因此你必须先填配置,才能验证数字人播报和模型回答的真实效果。


六、上线前别跳过这 4 件事(每件都对应真实风险)

密钥隔离:前端配置只适合 Demo,不适合生产

当前仓库是前端直连模型和数字人配置,Demo 跑通很快,但风险也直接:浏览器请求可见密钥,一旦被抓包滥用,账单和调用安全都会出问题。生产建议是新增后端代理(例如 /api/chat/proxy),前端只传业务参数,密钥放服务端并做审计。

错误兜底:不要让“思考中”停在屏幕上

模型超时、SDK初始化失败、PDF文本为空,这三类是最常见故障。建议每类都给明确兜底播报与UI状态恢复路径,比如:请求超时后提示“请稍后重试”,并自动回到待命状态,而不是停留在“思考中”。

可观测性:至少记录 3 个指标

上线后最怕“感觉卡,但不知道哪里卡”。建议最少采集:

  • 讲解词生成耗时(p50/p95)
  • 数字人播报成功率
  • 自动续讲成功率(是否按页连续完成)

有了这三个指标,后续优化才有抓手。

数据策略:问答目前只看当前页,适合讲解但不适合全局检索

当前实现是“当前页上下文问答”,在演示现场很好用,但如果你要做“整份PPT知识库问答”,就需要额外做全局向量索引或多页召回。这个边界要在产品层先讲清楚。

七、总结

这个项目最值得肯定的不是“用了数字人”,而是把讲解链路做成了一个可运行闭环:PDF提取、讲解词生成、数字人播报、自动续讲、当前页问答、下一页预加载,这些能力是连起来的,而不是散点功能。

如果你正好在做企业培训、路演讲解、内部汇报自动化,这个仓库是一个不错的起点:前端结构清晰、可快速跑通、核心逻辑可二次扩展。你真正要投入精力的,是生产化三件事:后端密钥代理、错误兜底、观测体系。另一个实用建议是先用邀请码 JHSAYDL7TM 拿到免费 1000 积分(约 2000 分钟体验时长),先把核心讲解链路完整压一遍,再决定后续投入规模。

Logo

电影级数字人,免显卡端渲染SDK,十行代码即可调用,工业级demo免费开源下载!

更多推荐