AI绘本上线后才发现:难点不在模型调参
从一个 AI 儿童绘本 MVP 出发,回看 StoryBloom 的产品开发、上线过程与踩坑经验。真正棘手的并不是“再调一次模型”,而是把文字内容、插画呈现、朗读体验、风控策略、失败兜底机制以及分享链路,完整串成一个能稳定使用的产品。
StoryBloom 已经上线了:https://storybloom.valleylmh.vip/。它的定位很直接:让家长输入孩子的名字,并选择年龄、主题、主角设定和插画风格,随后自动生成一套共 8 页的儿童绘本。用户既能在网页端直接预览,也能获得中文、英文或中英双语朗读,最后还能将内容整合成一张方便转发给家人的 PNG 分享长图。
最开始我以为项目真正的难点在“把故事写好”。但做完才明白,文本生成只是开端。要把 AI 产品做成可上线的形态,难点往往集中在后半段:某一页插图失败如何处理、生成耗时过长怎么办、用户中途刷新页面如何保障体验、免费次数的规则怎么计算、如何正确接入人机验证、微信浏览器里哪些能力会不可用、图片跨域会不会影响 Canvas 合成长图等。
StoryBloom 的第一版没有急着做付费下载,而是先把 MVP 锚定在三个核心动作:生成完整的 8 页内容、在网页上直接阅读与朗读、以及导出可分享的长图。这样的取舍很关键。对家长而言,价值不在于“调用了多少模型”,而在于孩子的名字能被写进故事、页面打开顺畅、声音能正常播放、图片可以直接保存。
开发过程中让我踩得最深的是“插图”这件事。故事文字通常一次就能返回,但 8 张插画本质上不是同一个稳定同步任务。不同服务商的响应速度、失败率、限流方式都不同。如果把所有插图都塞进同一个生成请求里,用户会一直等待;一旦中途失败,也很难快速定位到底是哪一页出问题。后来我把流程拆成两段:先把完整故事和示例图尽快返回,让用户快速进入预览;真正的插图再按页逐次请求、轮询、替换。这样即使某一页失败,也能单独重试而不拖垮整体体验。
第二个坑是角色一致性。儿童绘本常见的问题并不只是“画得不够好看”,更常见的是每一页看起来像换了一个孩子。代码里最后采用了“角色参考 + 身份锁定 + 分镜约束”的组合策略:主角准备了 6 个预设形象,在生成 prompt 时反复强调发型、脸型、服装颜色、年龄气质以及 3D 卡通材质,以保证跨页一致;同时又限制每一页不要机械重复正面头像,而是根据剧情变化来调整动作、构图与场景。
PS:生成出的图片效果仍然会受到所使用的生图模型影响。
第三个坑是免费额度与风控。仅靠前端用 localStorage 记次数不够稳,单靠后端按 IP 限制也不够可靠。StoryBloom 同时做了浏览器指纹、本地免费次数提示、服务端 Redis/内存限流,并接入 Cloudflare Turnstile。还有一个细节:微信浏览器里第三方脚本与浮窗类体验经常不稳定,因此在微信环境中对 Turnstile 以及 Tawk.to 的反馈入口做了专门处理。
第四个坑是“生成长图”。看起来只是点击一下导出 PNG,但实际涉及图片加载、CORS 处理、Canvas 绘制、中文与英文的换行排版、长图高度计算、弹窗预览以及最终下载。当前实现方式是等 8 页插图都完成后,再用浏览器 Canvas 合成 1080 宽的分享长图,最后让用户预览并下载。
这次做 StoryBloom 我最大的体会是:AI 应用不是把模型 API 外面再包一层 UI 就算完成。真正决定体验的,是模型出错或失败之后,产品还能不能继续往前走。能兜底、能重试、能把状态讲清楚、还能让用户少等一点,才是一个 AI 小产品从演示走向上线的关键。