移动端 H5 应用:用户三角度自拍后由火山方舟多模态大模型分析肤质,输出结构化报告。
面向美容护肤场景的移动端 H5 应用:用户从正面、左侧、右侧三个角度自拍后,由火山方舟多模态大模型进行肤质分析,输出包含肤色、纹理、斑点、毛孔、皱纹等维度的结构化报告。支持微信小程序和 H5 双端,报告通过 SSE 流式渲染逐步呈现,4 人核心团队 8 周完成生产环境上线。
皮肤分析是一个对延迟敏感的场景——用户拍完照等超过 3 秒就会开始怀疑"是不是卡住了"。但火山方舟的多模态模型单次推理耗时在 1.5–2.5 秒之间,三张图片串行发送的话总延迟接近 6–8 秒,远超可接受范围。
我们做了两个关键优化:第一,三张图片在服务端并行发送给火山方舟——FastAPI 用 asyncio.gather 同时发起三个请求,总等待时间压到约 2.5 秒(取决于最慢的那路);第二,分析开始后立即通过 SSE 推送"正在分析肤色…""正在分析纹理…"等进度提示,让用户感知到系统在工作而不是卡死。最终用户端的感知延迟约 2 秒左右看到第一条结果、3.5 秒看到完整报告。
上线第一周的统计数据让我们意外:约 22% 的用户上传的照片因为光线过暗或过曝,导致模型分析结果明显偏差——比如把正常肤色判为"暗沉"、或者漏检了弱光下的细纹。
解决方案分两层:前端在拍照时做实时亮度检测,低于阈值的提示用户"光线较暗,建议面向自然光拍摄";后端在图片送入火山方舟前加了一层自动白平衡校正和对比度增强——用了 OpenCV 的 CLAHE(自适应直方图均衡化),在保留皮肤纹理细节的前提下拉均匀光照。这道预处理让弱光环境下的分析准确率提升了约 30 个百分点。
一个教训:很多人以为多模态大模型"啥都能处理",实际上模型对输入质量极其敏感——进去的是黑乎乎的自拍,出来的分析报告用户不会信。图像预处理不是"锦上添花",而是"及格线"。
微信小程序和 H5 在图片上传的处理上差异很大:小程序的 wx.chooseMedia 返回临时文件路径,H5 用的是 File API。最初我们试图在前端统一抽象——结果在小程序的低版本基础库上遇到了 canvas 截图和文件路径兼容问题,白折腾了一周。
最终方案是:前端不做格式统一,各端按原生能力采集图片 → 统一转 base64 后通过同一套 FastAPI 接口上传 → 后端做统一处理(格式校验、压缩、预处理)。这个"把复杂性后移"的策略反而省了时间——后端做格式兼容比前端跨端适配可控得多。
初版为了"保证分析精度",前端上传的是原始分辨率的自拍照片——单张约 3–5MB。在内网 Wi-Fi 环境下没问题,但上线后大量用户在地铁、商场等弱网环境下使用,上传三张照片耗时 20–40 秒,超时率一度飙到 40%+。
后来我们意识到:多模态大模型对皮肤分析的精度瓶颈不在像素数量——模型输入分辨率一般不超过 1024×1024,传 4000×3000 的原图完全是浪费带宽。加上前端压缩(限制最大边 1920px、JPEG quality 80%)后,单张照片降到约 300–500KB,上传超时率降到了 3% 以内,分析准确率没有可测量的下降。
这个教训适用于所有移动端 AI 应用:先搞清楚模型的输入分辨率上限,再反推前端该传多大的图——而不是"越大越好"。
前端:Next.js 16 · React 19 · Tailwind CSS · Lucide / Heroicons · Zustand · TanStack Query · react-markdown · qrcode.react
后端:FastAPI · SQLAlchemy · asyncpg · Alembic · PostgreSQL · Redis · sse-starlette · 火山方舟(多模态 LLM)
移动端:微信小程序客户端(WXclient)
图片处理:OpenCV(CLAHE 自适应直方图均衡化)· Pillow(前端压缩 + 格式转换)