内容
# MealMate — 每周餐饮规划私人管家
一款个人管家代理,根据家庭的实际情况(如人数、饮食限制、过敏、烹饪偏好、预算和烹饪时间)生成完整的7天餐饮计划和一份合并的、按货架组织好的购物清单。该项目是为Kaggle的**5天AI Agents: Intensive Vibe Coding Course with Google**课程而构建的**Concierge Agents**跟踪。
## 问题
为一个真实的家庭规划一周的晚餐很麻烦,当涉及到过敏或饮食限制时更是如此,因为这关系到安全:一个遗漏的食材可能会导致严重的过敏反应。大多数“食谱创意”工具不能可靠地跟踪限制,不能合并购物清单,也不能让你在计划不合适时进行会话式调整。
## 解决方案
MealMate 根据一个家庭的资料生成:
- **7天餐饮计划**,由谷歌ADK多代理系统(一个协调器 + 规划子代理)生成,背后由Gemini支持。
- **合并的、去重的、按货架组织好的购物清单**,带有预估的总成本,与预算进行比较 — 通过确定性的MCP工具计算,而不是由LLM生成的。
- **会话式优化** — “降低成本”,“更换星期二的晚餐”,“星期五有客人”,“我正在避免洋葱” — 只更新计划中受影响的部分。
- **强化安全门控**,在每个计划和每个优化中运行:任何与声明的过敏或饮食限制(包括同义词、派生词、复数和犹太/清真规则)相匹配的成分都不会被允许到达用户。当请求确实无法满足时,代理会用简单的语言解释原因,而不是猜测。
核心价值:**给定一个家庭的实际限制,MealMate永远不会违反声明的饮食限制。**
## 架构
```
浏览器
│
▼
Web UI (FastAPI + Jinja2) mealmate/web/app.py
│ 资料 → 计划 → 购物清单 → 优化
▼
ADK 协调器 mealmate/agents/orchestrator.py
│ ┌─────────────────────────────┐
│ │ 安全门控 (_find_violation) │◄── 在每次生成和优化中运行
│ │ + 重试反馈循环 │
│ └─────────────────────────────┘
▼
规划子代理 (Gemini) mealmate/agents/planner.py
│ 草拟 7 份晚餐 / 1 份替换晚餐
▼
MCP 服务器(确定性) mealmate/mcp_server.py
│ 营养估计 · 成本估计 · 货架分组 · 食品储藏室检查
▼
Gemini (google-genai / ADK)
```
安全门控(`_find_violation`)位于生成和优化重试循环内部,而不是作为事后过滤器 — 不安全的草稿在到达用户之前会被拒绝并重新生成,并提供纠正反馈。如果每次重试仍然违反限制,则会引发`UnsatisfiableConstraintsError`,并用简单的语言解释原因(而不是静默不安全或空计划)。
## 课程概念演示(6个中的5个)
| 概念 | 位置 |
|---|---|
| 多代理ADK系统 | `mealmate/agents/orchestrator.py` + `mealmate/agents/planner.py` — 协调器委托给规划子代理 |
| 自定义MCP服务器 | `mealmate/mcp_server.py` — 营养、成本、货架分组、食品储藏室工具 |
| 代理技能/记忆和状态 | 会话范围的家庭资料持久性(`mealmate/web/store.py`),会话优化状态 |
| 安全功能 | 强化过敏/饮食安全门控,`UnsatisfiableConstraintsError` 简单语言解释,无PII日志证明,无秘密提交审计 |
| 可部署性 | `Dockerfile` + `.dockerignore` — 容器化,Cloud Run就绪 |
*反重力是故意不在范围内 — 它是一个可选的视频概念,而该项目已经涵盖了6个中的5个评分概念。*
## 评估
一个可重复的对抗性安全评估测试框架证明了防护措施在压力下仍然有效 — 不仅仅是一 handful 个单元测试:
```bash
python -m mealmate.eval.safety_eval
```
这驱动了六个对抗性家庭(多个同时过敏,一个同义词键控过敏,一个派生命名过敏,一个可满足的限制+过敏组合,清真和犹太教)通过实际的`_find_violation`门控,并报告每个家庭的PASS/FAIL,如果有任何不安全,则退出非零。
## 设置
```bash
git clone <此仓库>
cd mealmate # 或您克隆到的位置
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# 编辑 .env 并添加您自己的 GEMINI_API_KEY (来自 Google AI Studio) — 永远不要提交此文件
```
在本地运行:
```bash
uvicorn mealmate.web.app:app --reload
# 打开 http://127.0.0.1:8000
```
运行测试:
```bash
python -m pytest mealmate/
```
运行安全评估:
```bash
python -m mealmate.eval.safety_eval
```
## 部署(Docker / Cloud Run)
```bash
docker build -t mealmate .
docker run -e GEMINI_API_KEY=您的密钥 -p 8080:8080 mealmate
```
相同的镜像部署到Cloud Run,Cloud Run会自动注入 `$PORT`。根据Kaggle评分标准,公开部署是**可选的** — 此仓库以及上面的设置步骤是公开项目链接。
## 安全和隐私
- 没有API密钥或秘密被提交到此仓库 — `.env` 被 gitignore,`GEMINI_API_KEY` 仅从环境中读取。参见 `.env.example`。
- 家庭资料数据(过敏,饮食限制,预算等)和成分字符串在代码库的任何位置都不会传递给 `print()` 或 `logging` — 通过自动化回归测试和静态审计(`mealmate/secrets_audit.py`)证明。
- 过敏/饮食限制安全门控阻止任何与声明的过敏相匹配的成分 — 包括复数,同义词(例如“贝类”→ 虾/虾/蟹)和派生词(例如“乳制品”/“牛奶”→ 黄油/奶酪/奶油) — 跨每个计划生成和每个会话优化。
## 技术栈
谷歌ADK · Gemini(`google-genai`)· 自定义MCP服务器(`mcp`)· FastAPI + Jinja2 · SQLite(会话范围的资料持久性)· pytest。