小家菜单
家庭饮食管理与 AI Agent 全栈练习项目。从需求梳理到前后端实现、数据建模、权限设计、AI 接入与部署链路,完整走了一遍全栈开发的流程。目前仍在学习中,持续补充和重构。
项目背景
普通家庭的饮食记录通常分散在聊天记录、备忘录和临时拍的图片里——菜单、库存和点单之间没有统一上下文,导致「今天吃什么」这个高频问题一直靠临场发挥解决。
这个项目想把这些信息串成一条业务链:家庭成员、菜单菜谱、冰箱食材、收藏和点单放在同一个家庭空间里,再用 AI 帮忙查询和解释饮食信息。AI 只负责只读的查询与建议,真正修改业务数据的动作仍然由用户确认后走正常接口。
它同时是我用来补齐全栈能力的练习场——重点不在做成产品,而在于把每一层都真正写一遍。
技术栈
| 层次 | 技术选型 | 承担的角色 |
|---|---|---|
| 用户端 | UniApp · Vue 3 · TypeScript | 家庭、菜单、冰箱、收藏、点单与 AI 交互,用 uni.* 统一跨端调用 |
| 管理端 | Vue · JavaScript | 家庭管理、用户审核、角色、通知与审计 |
| 后端 | Python · FastAPI · Uvicorn | REST API、参数校验、鉴权与业务编排 |
| 数据层 | SQLAlchemy 2 async · Alembic · PostgreSQL | 异步 ORM、结构迁移、事务持久化 |
| 缓存 | Redis | 营养查询缓存与 AI 每日配额计数 |
| AI | OpenAI 兼容接口 · httpx · 手写 ReAct 循环 | 对话、受限工具调用与菜品识图 |
| AI 协议 | MCP 客户端 / MCP Server | 向外查询营养数据;向内暴露只读数据工具 |
后端分层设计
后端采用五层结构,避免把 SQL、权限和业务规则全部堆在路由函数里:
API 路由 → Schema → Service → Repository → Model / Database
- API:接收请求、依赖注入、选择响应,不堆业务规则
- Schema:校验请求与响应字段,挡住无效数据
- Service:承载业务规则、权限校验与事务协作
- Repository:封装数据库读写,不决定业务策略
- Model / Database:映射数据结构并持久化
这样做的直接好处是:普通 API、AI 工具、管理后台三个入口能复用同一套 Service 权限逻辑,不会出现某条路径绕过越权检查。
几个我在意的设计点
权限不能交给模型判断
家庭数据都带家庭标识,Service 层在查询和写入前统一做成员关系校验。客户端传来的家庭标识不被信任——真实家庭归属从已认证用户推导。
AI 工具也遵循同一条约束:不接受模型自行指定的家庭 ID,不直接拼 SQL,统一经 Service 走权限路径。因为模型输出是概率性的,如果它能自己选数据范围,就可能跨家庭读到不该读的内容。
AI 只读,写入由用户确认
Agent 提供有限的只读工具,步数有上限。需要修改数据的场景,由前端出确认卡片,用户确认后再调用正常业务接口——重新经过一遍权限与参数校验。牺牲了一点自动化程度,换来可解释、可回滚的边界。
降级优先于报错
AI 是加分项,不是主业务的单点。菜单、冰箱、家庭管理这些核心流程不依赖 AI 也能用。配置缺失、外部超时、解析失败都有可解释的降级路径,并且结果会明确标注来源,不把估算结果伪装成精确识别。
当前状态
这是一个本地练习项目,仍在学习中。功能在持续补充和重构,还没有面向真实用户运营,也不作为成熟产品对外提供服务。文中的技术选型和设计思路,是我在练习过程中真实采用并验证过的部分。
- 后端接口与数据层已跑通,覆盖家庭、菜单、冰箱、收藏、点单等主要业务链
- UniApp 用户端与管理后台页面已完成主要流程
- AI Agent 与 MCP 工具链已接通,工具边界与权限校验有自动化用例覆盖
- 仍在持续:补充测试、重构模块划分、梳理更清晰的学习路径