[Dify x EdgeOne] 哄睡童话机——用 Dify + EdgeOne Pages 给娃造一个会现挂的 AI 睡前故事神器

发布时间:2026/6/1 3:45:20

[Dify x EdgeOne] 哄睡童话机——用 Dify + EdgeOne Pages 给娃造一个会现挂的 AI 睡前故事神器 凌晨一点半娃在小床上翻来覆去说再讲一个嘛我已经把《小猪佩奇》《大卫不可以》《猜猜我有多爱你》连讲三遍嗓子哑得像砂纸。这次我用 Dify 编排了一条「主角定制 章节生成 TTS 朗读」三段式工作流再用 EdgeOne Pages 一键部署成 PWA加到主屏幕点一下就能让 AI 用奶爸自己的语气讲一个全新的故事——从此哄睡这件事外包给 AI。一、为什么是这个项目一个新手爸妈的真实崩溃我家娃刚满四岁进入了所谓的「故事高需期」睡前必须讲故事少于三个不睡现成绘本翻来覆去就那么几本他能背下来背到第三句就开始挑你毛病“不对昨天讲的不是这样”想用市面上的故事 App应付一下结果不是广告插得离谱就是只能从固定故事库里点播——讲到一半你想加入「主角是哥哥、配角是家里那只橘猫做不到我自己写故事编不出来。GPT 写一篇可以但每次都要打开网页、复制 Prompt、再朗读给娃听——他等不及。跟几个奶爸聊起来发现这是所有 3-6 岁娃家庭的通病痛点现状故事重复率高一本绘本讲到背个性化几乎为零主角永远是别人家的小熊小兔娃没有代入感嗓子是消耗品一晚连讲三个第二天开会就哑App 体验割裂广告 充值 加载白屏 不能离线收藏我之前折腾过开源的 LLM edge-tts 方案最大的问题有两个第一是部署门槛——要起 Python 服务、配 Coqui/edge-tts、还要搞 HTTPS 才能在手机上听第二是体验断裂——网页打开慢娃等三秒就跑掉去玩积木。直到我把 Dify 0.15 的Workflow LLM ToolTTS三件套和 EdgeOne Pages 的Dify 全场景应用模板凑一块儿我才意识到这件事可以一个晚上做完做完直接发链接给奶爸群谁家娃都能用。最终交付物长这样一个公网可访问的 PWAEdgeOne Pages 全球 CDN加到主屏幕能离线打开外壳进首页有三个大按钮 冒险故事 / 安睡故事 / 脑洞故事选完主题弹出主角定制——填娃的名字、年龄、最喜欢的小动物、今天发生的小事比如今天去了动物园点「开始讲」12 秒内第一段故事文字 语音同步出来一边读一边自动滚到下一段全程无需爸妈说话故事讲完会自动生成一句晚安寄语比如妞妞今天勇敢地把胡萝卜吃完了妈妈很为你骄傲晚安。下面把为什么这样设计 每个节点怎么配 部署怎么走完整拆开来讲。二、整体架构为什么是 Workflow 而不是 Chatflow很多人第一次用 Dify 做故事生成会本能地选 Chatflow——毕竟它能多轮、能改写、能继续。但放到哄睡这个具体场景里Chatflow 反而是错的娃不是来对话的他是来听故事的每次再来一个都应该是一个全新的、独立的、不依赖历史的故事多轮上下文意味着 token 越积越多成本和延迟都会随时间漂移哄睡是一个有明确终点的流程开场 → 三段正文 → 晚安寄语。这是典型的批处理。所以我选了Workflow并且把它拆成清晰的三段[开始] → [角色卡注入] → [LLM: 故事大纲] → [LLM: 三段正文并行生成] → [TTS 工具节点] → [结构化输出]EdgeOne Pages 的 Dify 全场景模板对这种类型有原生支持只要把环境变量NEXT_PUBLIC_APP_TYPE设成workflow前端就会自动渲染成表单 进度条 结果区的形态而不是聊天框。整体架构图如下下面进入实操。三、Dify 工作流把一个故事拆成「能并行的三段」3.1 输入参数把主角定制做成结构化表单开始节点里我加了 6 个输入字段对应前端表单变量名类型示例用途themeSelectadventure / sleep / fantasy决定故事走向与情绪曲线child_nameText“妞妞”主角姓名全文替换child_ageNumber4用来约束词汇难度favorite_animalText“橘猫”配角让娃有代入感today_eventText“今天去了动物园”开场钩子voiceSelectfemale_warm / male_warmTTS 音色为什么把child_age单独抽出来因为 3 岁和 6 岁能听懂的词差异极大。我在 Prompt 里加了一句词汇难度对应 ${child_age} 岁避免使用四字成语和被动句娃听懂率立刻上来。3.2 大纲节点先骨架后血肉第一个 LLM 节点不直接出正文只输出一个 JSON 大纲你是一位儿童睡前故事编剧。请根据以下信息输出一个三段式故事大纲仅 JSON不要解释 主题: {{theme}} 主角姓名: {{child_name}}{{child_age}} 岁 配角动物: {{favorite_animal}} 今日小事: {{today_event}} 要求 1. 三段每段 80-120 字 2. 第二段必须出现一次小冲突第三段必须正向化解 3. 全程无暴力、无恐惧元素 4. 输出格式 {title:,part1:,part2:,part3:,ending:晚安寄语30字内}模型我用的qwen-plus也可以换deepseek-chat开JSON Mode温度 0.8——这是哄睡故事的甜点温度太低会枯燥太高娃听不懂。3.3 三段并行把等的时间砍掉 60%哄睡场景对**首字延迟TTFB**极度敏感——娃的耐心窗口只有 10 秒左右。如果三段故事串行生成加上 TTS 合成整体首句出声往往要 25 秒以上。所以我把工作流改成了**「大纲 → 三个并行 LLM 节点 → 并行 TTS」**┌─→ LLM:正文1 ─→ TTS:1 ─┐ 大纲(JSON) ───┼─→ LLM:正文2 ─→ TTS:2 ─┤─→ 聚合 └─→ LLM:正文3 ─→ TTS:3 ─┘Dify Workflow 的并行分支是天然支持的只要把三个 LLM 节点都从同一个上游连出去再用变量聚合节点合并即可。我实测下来串行版本第一段出声23.4s并行版本第一段出声9.1s娃的耐心阈值是 10 秒这一改动等于把项目从「不可用」变成「可用」。3.4 TTS 节点我用了 EdgeOne 边缘函数做轻量代理Dify 自带的 TTS 工具不一定覆盖国内场景我接的是腾讯云语音合成的TextToVoice接口。但直接在 Dify 里挂 HTTP 节点会暴露 SecretId/SecretKey我把它代理到了 EdgeOne Pages Functions里路径/api/tts// functions/api/tts.jsexportasyncfunctiononRequestPost({request,env}){const{text,voice}awaitrequest.json();constsigawaitsign(env.TC_SECRET_ID,env.TC_SECRET_KEY,text,voice);constupstreamawaitfetch(https://tts.tencentcloudapi.com/,{method:POST,headers:sig.headers,body:sig.body,});// 直接把音频流转回去避免在边缘节点 buffer 整段音频returnnewResponse(upstream.body,{headers:{content-type:audio/mpeg,cache-control:public, max-age86400},});}两个关键点cache-control: max-age86400——同一段文字 同一音色 24 小时内复用结果。哄睡故事的晚安寄语段落复用率极高缓存命中后这一段几乎是 0 延迟、0 成本upstream.body直接 pipe——不要在 Functions 里await response.arrayBuffer()否则音频要在边缘节点缓存完整段才返回娃又要等。3.5 输出结构让前端能边收边播Workflow 的结束节点输出{title:妞妞和橘猫的动物园奇遇,parts:[{text:...,audio:/api/tts?idabc1},{text:...,audio:/api/tts?idabc2},{text:...,audio:/api/tts?idabc3}],ending:妞妞今天勇敢地...}前端拿到结构化结果后第一段音频立刻audio.play()第二段preloadauto第三段preloadmetadata——三段无缝衔接娃完全感知不到分段。四、前端一个让娃和爸妈都开心的 PWAEdgeOne Pages 的 Dify 模板默认是 PC 后台风格我做了三处改动让它变成哄睡专用 PWA。4.1 暗色 大按钮 触觉反馈:root{--bg:#0b0f1a;--fg:#f5f5f5;--accent:#ffb86b;}button.theme{height:96px;font-size:22px;border-radius:24px;box-shadow:0 6px 20pxrgba(255,184,107,0.25);}按钮高度 96px——这是为了防止爸妈夜里半睁眼点错。点击时navigator.vibrate(20)给个轻微震动反馈娃也会觉得这个 App 活的。4.2 PWA 离线外壳manifest.json三件套配齐{name:哄睡童话机,short_name:童话机,display:standalone,background_color:#0b0f1a,theme_color:#0b0f1a,start_url:/,icons:[{src:/icon-512.png,sizes:512x512,type:image/png}]}加上一个最小化 Service Worker把首页 HTML/CSS/JS 全部 precache。这样即使家里 WiFi 抽风App 也能秒开外壳只在请求故事时才需要网络——比白屏 5 秒看转圈的体验好太多。4.3 自动翻页 渐弱每段音频ended事件触发后自动滚到下一段并把上一段透明度降到 0.3。第三段读完后背景音乐一段循环白噪音淡入到 30% 音量这个细节让娃的入睡时间从平均 20 分钟缩短到 11 分钟——亲测有效。五、部署30 分钟从本地到全球可访问5.1 Dify 侧新建 Workflow导入我准备好的 DSLYAML 格式在工具里挂一个 HTTP 工具指向 EdgeOne Pages Functions 的/api/tts发布记下 API Key 和 Endpoint。5.2 EdgeOne Pages 侧Fork 模板仓库dify-frontend-starter-template在控制台项目 → 环境变量里填KeyValueNEXT_PUBLIC_APP_TYPEworkflowNEXT_PUBLIC_API_URLhttps://api.dify.ai/v1DIFY_API_KEYapp-xxxx注意不带NEXT_PUBLIC_只在 Functions 里用TC_SECRET_ID/TC_SECRET_KEY腾讯云 TTS 密钥绑定自定义域名开 HTTPS——PWA 必须 HTTPS 才能装到主屏幕等 90 秒绿灯亮起全球 3200 边缘节点同步完成。我自己测下来国内主要城市的首字节时间测试节点首屏 HTMLTTS 音频 TTFB北京电信87ms142ms上海移动73ms128ms广州联通65ms119ms成都电信102ms168ms对比我之前自建 VPS杭州一台 2c4g首屏 600~900msTTS 首字节 1.2~1.8s。这是数量级的差距对哄睡场景就是娃跑去玩积木和娃乖乖躺下的差距。六、踩过的四个坑6.1 LLM 输出不睡觉最早的 Prompt 里我没写故事结尾必须是主角入睡或闭眼结果娃听完一个故事比之前更亢奋——因为故事讲的是主角打败了怪兽全村庆祝放烟花。后来在大纲节点里加了一行第三段必须以「主角感到困倦、缓缓闭上眼睛」结尾避免任何兴奋情绪上扬。这是哄睡故事和普通儿童故事的关键差别——情绪曲线必须收敛而不是发散。6.2 TTS 把妞妞读成扭扭中文 TTS 对儿化音、叠字、网络流行小名识别率不稳。解决办法是在进入 TTS 前做一次 SSML 包裹speakphonemealphabetpyphniū niu妞妞/phoneme今天去了动物园……/speak我在 Workflow 里加了一个代码节点Python自动把child_name包成 SSML娃终于不会皱眉头了。6.3 Workflow 长任务超时并行优化之后整体仍可能在 25~30s 之间。我把 EdgeOne Pages Functions 的执行时长提到了 60s控制台 → 性能优化 → 函数超时同时让前端在 SSE 的workflow_started事件触发后立即显示AI 正在编故事…的 Loading心理时长就被掩盖了。6.4 PWA 在 iOS 上不能后台播音频iOS Safari 的 PWA 不允许后台播 audio。我的妥协方案是在播放页面保持屏幕常亮navigator.wakeLock.request(screen)并把屏幕亮度通过 CSSfilter: brightness(0.4)压暗——既让娃看不到屏幕、又能持续播音频。这是一个非常具体的端侧工程取舍。七、效果一个让全实验室奶爸都来要链接的项目上线两周我自己家娃用了 11 个晚上平均入睡时间从 19.7 分钟降到 11.3 分钟。我把链接发到奶爸群之后7 天 PV 4200UV 380平均每用户生成故事数 5.4 个高峰时段在每晚 21:00–22:30曲线像一座山EdgeOne Pages 的边缘缓存命中率 73%主要是首屏 HTML/JS/icon以及晚安寄语段的 TTSDify Workflow 平均执行时长 11.8sp95 17.2s。最让我意外的是群里几个妈妈反馈“今天孩子一定要听有自己名字的故事绘本都不要了。”——个性化是娃留存的核心而这件事 Dify 的变量替换 Prompt 工程几乎零成本就做到了。八、总结Dify × EdgeOne 适合「轻业务、重体验」的小场景回头看哄睡童话机这种项目和企业级客服、行业知识库完全不在一个赛道但它恰恰是 Dify × EdgeOne 组合最擅长的形态维度为什么这个组合合适业务复杂度低——一条 Workflow无知识库、无 Agent体验要求高——首字节、PWA、TTS 流式都不能差部署门槛必须低——奶爸没空运维服务器全球可达海外亲戚也用得上朋友把链接发给在加拿大的姐姐娃同步在用成本极低——一晚几百次调用加上 EdgeOne 缓存几乎没花钱如果你也是奶爸/奶妈/姑姑/舅舅或者你身边有 3-6 岁的小朋友真心推荐你花一个晚上 fork 一份——把主角换成你家娃把今日小事换成今天发生的事看着他听到自己名字时眼睛亮起来的那一刻这个比赛对我个人来说就已经赢了。项目栈一句话总结Dify Workflow 编排个性化故事生成 三段并行 TTSEdgeOne Pages 承载 PWA 外壳与边缘 TTS 代理两者把哄娃睡觉这件事从一个嗓子的事变成一个 API 的事。

相关新闻