跳到主要内容

系统架构设计文档

「吃什么」决策助手 — 技术架构总览 v1.0 文档版本:v1.0 关联 PRD:PRD-v1.0.md 编写日期:2026-05-18


一、系统架构概览

1.1 整体架构图

┌──────────────────────────────────────────────────────────────┐
│ 用户层(WeChat Mini Program) │
│ 首页 │ 搜索页 │ 盲盒页 │ 人群页 │ 详情页 │ 个人中心 │
└──────────────────────────────────────────────────────────────┘

│ HTTPS / JSON API

┌──────────────────────────────────────────────────────────────┐
│ API 网关层 │
│ 统一入口 · 鉴权 · 限流 · 路由 │
└──────────────────────────────────────────────────────────────┘

┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ 推荐服务 │ │ 菜谱服务 │ │ 用户服务 │
│ (Recommend) │ │ (Dish) │ │ (User) │
│ │ │ │ │ │
│ · F1 食材搜索 │ │ · F4 菜谱详情 │ │ · 收藏管理 │
│ · F2 盲盒推荐 │ │ · F5 营养查询 │ │ · 偏好设置 │
│ · F3 人群推荐 │ │ · F6 季节节日 │ │ · 搜索历史 │
│ · F7 场景推荐 │ │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│ │ │
└───────────────────┼───────────────────┘

┌──────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 菜品库 │ │ 用户库 │ │ 节日历 │ │ 推荐日志│ │
│ │ MongoDB │ │ MySQL │ │ Redis │ │ ClickHouse│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└──────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────┐
│ AI / 数据处理层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 菜谱爬虫系统 │ │ 菜谱清洗/结构化│ │ 营养数据计算 │ │
│ │ (Python爬虫) │ │ (AI+LLM) │ │ (营养API) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 推荐算法引擎 │ │ 意图识别引擎 │ │
│ │ (规则+CF) │ │ (NLP) │ │
│ └──────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘

二、技术栈选型

2.1 前端(小程序)

技术选型说明
框架原生小程序 / TaroMVP 阶段用原生,跨平台时切换 Taro
状态管理MobX / Redux管理用户状态和推荐上下文
UI 组件Vant Weapp有赞出品的轻量组件库
动画Lottie / wx.createAnimation盲盒动画
网络请求Fly.js统一请求拦截和错误处理

2.2 后端

技术选型说明
框架Node.js (Express/Koa) 或 Python (FastAPI)推荐 FastAPI,Python 方便 AI 集成
API 风格RESTful + GraphQL(部分场景)REST 作为主协议
网关Kong / Nginx限流、鉴权、路由
ORMPrisma(Node)/ SQLAlchemy(Python)类型安全

2.3 数据存储

存储选型用途
菜品数据库MongoDB菜品非结构化数据,灵活扩展
用户数据MySQL用户信息、收藏、偏好
缓存Redis热门菜品缓存、Session、节日数据
日志/分析ClickHouse用户行为日志、推荐效果分析
对象存储阿里云 OSS / 腾讯云 COS菜品图片 CDN

2.4 AI 层

能力技术选型说明
菜谱清洗/结构化LLM API(GPT-4 / 通义千问)将爬取的原始数据转为结构化字段
意图识别轻量 NLP 模型 / 关键词匹配识别用户模糊输入的意图
营养数据计算本地营养数据库 + AI 辅助参考 USDA 食物营养数据库
相似菜品推荐向量数据库(Milvus)语义相似菜品匹配

三、数据模型设计

3.1 核心实体关系

┌─────────────┐ ┌─────────────┐
│ User │ │ Dish │
├─────────────┤ ├─────────────┤
│ id │──┐ │ id │
│ nickname │ │ │ name │
│ avatar │ │ │ coverImage │
│ crowdType │ │ │ ingredients │
│ preferences │ │ │ nutrition │
│ createdAt │ │ │ steps │
└─────────────┘ │ │ crowdType │
│ │ │ scenes │
│ │ │ seasons │
│ │ │ festivals │
▼ │ │ createdAt │
┌─────────────┐ │ └─────────────┘
│ Collection │ │ │
├─────────────┤ │ │
│ id │ │ │
│ userId │──┘ │
│ dishId │─────────────┘
│ createdAt │
└─────────────┘

3.2 菜品索引设计

MongoDB 菜品集合需建立复合索引:

// 食材搜索索引
db.dishes.createIndex({ "ingredients.name": 1 })

// 人群推荐索引
db.dishes.createIndex({ crowdType: 1, "nutrition.calories": 1 })

// 季节节日索引
db.dishes.createIndex({ seasons: 1, festivals: 1 })

// 场景索引
db.dishes.createIndex({ "sceneTags.suitableScenes": 1, "sceneTags.maxDuration": 1 })

// 全文搜索索引(菜品名、描述)
db.dishes.createIndex({ name: "text", description: "text" })

四、核心服务设计

4.1 推荐服务(Recommendation Service)

核心职责:聚合所有推荐场景(F1/F2/F3/F6/F7),输出统一推荐结果

interface RecommendService {
// F1: 食材搜索推荐
searchByIngredients(ingredients: string[], filters?: Filter): Promise<Dish[]>;

// F2: 盲盒推荐
mysteryBox(mode: 'global' | 'category' | 'crowd', context?: any): Promise<Dish>;

// F3: 人群定向推荐
recommendForCrowd(crowdType: string, formData: any): Promise<Dish[]>;

// F6: 季节节日推荐(叠加层)
applySeasonalBoost(dishes: Dish[]): Dish[];

// F7: 场景推荐
recommendByScene(sceneContext: SceneContext): Promise<Dish[]>;
}

推荐流程

用户请求


意图识别(判断是哪种推荐场景)

├── F1 食材搜索 → 食材匹配引擎
├── F2 盲盒 → 随机抽取引擎 + 防重复
├── F3 人群推荐 → 人群规则引擎
├── F6 季节节日 → 时令加权层
└── F7 场景推荐 → 场景过滤引擎


综合排序(融合多维度得分)


返回结果 + 记录日志

4.2 菜谱服务(Dish Service)

核心职责:菜品 CRUD、营养数据查询

interface DishService {
getDishDetail(id: string): Promise<DishDetail>;
getNutritionInfo(dishId: string, servingSize?: number): Promise<Nutrition>;
compareNutrition(dishIds: string[]): Promise<NutritionCompare>;
getRelatedDishes(dishId: string, limit?: number): Promise<Dish[]>;
getDishesByTags(tags: string[], page?: number): Promise<Dish[]>;
}

4.3 用户服务(User Service)

核心职责:用户信息、收藏、偏好管理

interface UserService {
getUserProfile(userId: string): Promise<User>;
updateCrowdPreference(userId: string, crowdType: string, formData: any): Promise<void>;
collectDish(userId: string, dishId: string): Promise<void>;
uncollectDish(userId: string, dishId: string): Promise<void>;
getCollections(userId: string, page?: number): Promise<Dish[]>;
recordSearchHistory(userId: string, ingredients: string[]): Promise<void>;
}

五、API 接口设计

5.1 接口目录

方法路径说明
POST/api/v1/search/ingredientsF1 食材搜索
POST/api/v1/mystery-box/openF2 开盲盒
POST/api/v1/recommend/crowdF3 人群推荐
GET/api/v1/dish/:idF4 菜品详情
GET/api/v1/dish/:id/nutritionF5 营养详情
POST/api/v1/dish/compareF5 营养对比
GET/api/v1/seasonal/currentF6 当前季节节日
GET/api/v1/festival/:festivalIdF6 节日专题
POST/api/v1/recommend/sceneF7 场景推荐
GET/api/v1/user/collections用户收藏列表
POST/api/v1/user/collect收藏菜品
DELETE/api/v1/user/collect/:dishId取消收藏

5.2 统一响应格式

interface ApiResponse<T> {
code: number; // 0 = 成功,其他 = 错误码
message: string; // 错误信息
data: T; // 响应数据
timestamp: number; // 时间戳
requestId: string; // 请求追踪 ID
}

// 示例
{
"code": 0,
"message": "success",
"data": { ... },
"timestamp": 1747564800000,
"requestId": "req_abc123"
}

5.3 错误码规范

错误码说明
0成功
1001参数错误
1002鉴权失败
2001菜品不存在
2002菜品库为空
3001推荐服务异常
3002推荐结果为空
5001服务器内部错误

六、AI 数据处理流水线

6.1 菜谱采集流程

1. 确定数据源网站列表(美食天下、下厨房等)


2. AI 生成爬虫脚本(Python + requests + BeautifulSoup)


3. 批量抓取原始菜谱数据(HTML)


4. 数据清洗
├── 去除 HTML 标签
├── 标准化食材格式(如「2个鸡蛋」→「鸡蛋 2个」)
└── 去重(根据菜名+主料指纹)


5. LLM 结构化处理(GPT-4 / 通义千问)
└── 将非结构化文本转为标准 Dish 数据模型


6. 营养数据估算
├── 匹配 USDA 食物营养数据库
└── AI 辅助计算整道菜营养成分


7. 质量抽检
├── 每 50 道随机抽检 1 道
└── 人工审核 + 反馈修正


8. 入库 MongoDB

6.2 数据质量指标

指标目标值
爬取成功率> 95%
字段完整率> 90%(必填字段)
营养数据准确率> 85%(抽检)
每日新增菜品500-1000 道(MVP 期)

七、部署架构(MVP 阶段)

7.1 最小化部署

┌──────────────────────────────────────┐
│ 微信小程序 │
└──────────────────────────────────────┘

│ HTTPS

┌──────────────────────────────────────┐
│ 阿里云 / 腾讯云 │
│ │
│ ┌──────────────────────────────┐ │
│ │ Nginx (反向代理) │ │
│ │ + SSL 证书 │ │
│ └──────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────┐ │
│ │ Docker Compose (单节点) │ │
│ │ │ │
│ │ [API Service] │ │
│ │ [Recommendation Service] │ │
│ │ [MongoDB] │ │
│ │ [Redis] │ │
│ │ [MySQL] │ │
│ └────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ 阿里云 OSS (CDN) │ │
│ │ 菜品图片存储 + 分发 │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────┘

7.2 扩容路径

阶段架构变化
MVP单节点 Docker Compose
增长期服务拆分、K8s 编排、多节点
成熟期微服务架构、数据库读写分离、CDN 加速

八、关键非功能性指标

指标目标值说明
API 响应时间 P99< 500ms99% 请求在 500ms 内返回
推荐接口响应时间 P99< 1s含复杂计算
盲盒开盒响应< 2s含动画加载
服务可用性> 99.9%核心接口
图片加载时间< 2s配合 CDN
系统可支撑 DAU10万MVP 阶段目标

九、复核检查项

检查点状态
前端技术栈选型合理(小程序原生/Taro)
后端技术栈支持 AI 集成
数据存储选型合理(MongoDB/MySQL/Redis)
推荐服务架构覆盖所有 5 个推荐场景
API 接口设计完整
AI 数据流水线完整
错误码规范统一
部署架构可落地
非功能指标可量化
扩容路径清晰