微信小程序 + AI 大模型实战:从零打造智能美食推荐应用

微信小程序 + AI 大模型实战:从零打造智能美食推荐应用

本文以一个真实项目为例,分享如何将 AI 大模型能力集成到微信小程序中,涵盖云开发、用户激励系统、数据统计等实战经验。

一、项目背景

"每天吃什么"是很多人的日常难题。为了解决这个问题,我开发了一款智能美食推荐小程序,名字叫:喂你推荐-今天吃什么;主要功能包括:

  • 摇一摇推荐:基于用户偏好和时段,随机推荐美食
  • AI 定制饮食计划:接入大模型,根据身体数据生成 7 天饮食计划
  • 饮食打卡:记录每日饮食,培养健康习惯
  • 勋章成就系统:通过打卡、收藏等行为解锁勋章,提升用户粘性

技术栈:微信小程序原生框架 + 云开发 + AI 大模型

二、核心技术实现

2.1 AI 大模型集成

项目中使用了 AI 大模型来生成个性化饮食计划。核心思路是将用户的身体数据(身高、体重、年龄、目标等)构建成结构化 Prompt,然后调用模型 API 获取 JSON 格式的饮食方案。

javascript 复制代码
// 构建 Prompt
function buildPlanPrompt(form) {
  return `你是一位专业营养师。请根据以下用户信息,生成一份 7 天饮食计划...

用户信息:
- 性别:${form.gender}
- 年龄:${form.age} 岁
- 身高:${form.height} cm
- 体重:${form.weight} kg
- 口味偏好:${form.tastes.join('、')}
- 饮食目标:${form.goal}
- 忌口:${form.taboos.join('、')}

请严格按以下 JSON 格式返回...`;
}

关键点

  1. Prompt 工程:明确指定输出格式,要求模型返回纯 JSON,避免 markdown 标记
  2. 容错处理:模型返回可能不规范,需要做 JSON 解析和字段校验
  3. 兜底方案:AI 调用失败时,返回预设的示例数据,保证用户体验
javascript 复制代码
try {
  const text = await ai.callModel(prompt, systemPrompt);
  const parsed = ai.extractJson(text);
  return buildPlanFromParsed(parsed);
} catch (err) {
  // AI 失败时使用兜底数据
  return getMockPlan();
}

2.2 用户激励系统设计

为了提升用户留存,设计了一套完整的激励体系:

打卡系统:记录用户每日饮食,支持早中晚三餐打卡。

勋章系统:定义了 11 种勋章,覆盖不同行为维度:

类型 勋章 解锁条件
打卡 初来乍到 首次打卡
打卡 一周坚持 累计打卡 7 天
连续 三日连续 连续打卡 3 天
收藏 美食猎人 收藏 5 道美食
计划 计划达人 生成 5 个 AI 计划

勋章弹出动画:用户解锁新勋章时,展示炫酷的弹窗动画,包含粒子特效、图标旋转、光晕脉冲等效果,增强成就感。

css 复制代码
/* 粒子飘落动画 */
@keyframes particleFall {
  0% { transform: translateY(0) scale(1); opacity: 1; }
  100% { transform: translateY(600rpx) scale(0); opacity: 0; }
}

/* 勋章弹入动画 */
@keyframes popupBounce {
  0% { transform: scale(0) rotate(-10deg); opacity: 0; }
  50% { transform: scale(1.1) rotate(3deg); }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

2.3 云开发数据架构

使用微信云开发,主要涉及以下集合:

复制代码
├── users          # 用户信息
├── foods          # 美食数据
├── punches        # 打卡记录
├── plans          # AI 饮食计划
├── food_favorites # 美食收藏
└── plan_favorites # 计划收藏

数据查询优化:对于统计数据(打卡天数、收藏数等),采用并行查询减少等待时间:

javascript 复制代码
const [punchRes, foodFavRes, planFavRes] = await Promise.all([
  api.collection('punches').where({ openid }).get(),
  api.collection('food_favorites').where({ openid }).get(),
  api.collection('plan_favorites').where({ openid }).get()
]);

2.4 智能推荐算法

摇一摇推荐不是完全随机,而是基于多维度筛选:

  1. 用户偏好过滤:根据口味偏好筛选辣度
  2. 忌口排除:排除用户设置的忌口食材
  3. 时段匹配:根据当前时间优先推荐对应时段的美食
  4. 饮食类型:区分素食、荤食、荤素皆可
javascript 复制代码
// 根据口味偏好筛选辣度
const allowedSpicy = TASTE_SPICY_MAP[taste] || [0, 1, 2, 3];
const spicyFiltered = allFoods.filter(f => allowedSpicy.includes(f.spicyLevel));

// 根据当前时段优先推荐
const currentMeal = this.getCurrentMealTypes();
const timeMatched = spicyFiltered.filter(f =>
  f.mealTypes && f.mealTypes.some(m => currentMeal.includes(m))
);

三、性能优化实践

3.1 减少不必要的渲染

小程序的 setData 是性能瓶颈之一。优化策略:

  • 合并多次 setData 调用
  • 使用 diff 算法,只更新变化的数据
  • 避免在 setData 中传递大对象

3.2 数据缓存

对于不常变化的数据(如用户偏好),使用本地缓存:

javascript 复制代码
// 写入缓存
wx.setStorageSync('user_preferences', preferences);

// 读取缓存
const prefs = wx.getStorageSync('user_preferences');

3.3 云函数优化

  • 并行查询:使用 Promise.all 同时发起多个请求
  • 分页加载:列表数据分页查询,避免一次性加载过多
  • 索引优化:为常用查询字段添加数据库索引

四、踩坑记录

4.1 云数据库集合不存在

新创建的集合需要在云开发控制台手动创建,否则会报 -502005 错误。

4.2 用户信息获取

微信已废弃 wx.getUserProfile 接口,新版获取用户头像需要使用 open-type="chooseAvatar" 的 button 组件。

4.3 日期对象序列化

云数据库返回的 Date 对象直接渲染会显示 [object Object],需要手动格式化:

javascript 复制代码
formatDate(date) {
  const d = new Date(date);
  return `${d.getMonth() + 1}-${d.getDate()} ${d.getHours()}:${d.getMinutes()}`;
}

五、总结

这个项目涵盖了小程序开发的多个核心场景:AI 集成、云开发、用户激励、动画交互等。通过合理的架构设计和性能优化,可以打造出体验流畅、功能丰富的小程序应用。

完整项目代码已开源,感兴趣的小伙伴可以自行研究学习。


如果觉得本文对你有帮助,欢迎点赞收藏关注!后续会持续分享更多小程序开发实战经验。