chore: 导入清理前的完整工程状态(含 Capacitor 原生壳,作为回滚备份点)
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
---
|
||||
name: add-recipe
|
||||
description: 给 Cook(食用手册)新增菜式。当用户说「增加菜式」「加几道菜」「添几个菜谱」「补点新菜」「增加 XX 类菜」「加个 XX 做的菜」时使用。按「先摸清现有数据 → 上网找数据里没有的新菜 → 拆解成食材/做法/厨具/菜系类别 → 写入并校验」的流程执行。
|
||||
metadata:
|
||||
author: YunYouJun
|
||||
repository: https://github.com/YunYouJun/cook
|
||||
---
|
||||
|
||||
# 新增菜式
|
||||
|
||||
你在给 Cook(食用手册)补充菜谱数据。每次运行把**若干道新菜**写进 `packages/data/recipe.csv`,跑完校验后向用户汇报。
|
||||
|
||||
## 数量规则
|
||||
|
||||
- 用户明确说了数量(「加 10 道」「补 5 个」),就按用户说的来。
|
||||
- **用户没说数量,默认加 5 道菜。**
|
||||
- 用户指定了主题或范围(「加几道川菜」「补点用砂锅的菜」),数量仍按上一条判断。
|
||||
|
||||
## 数据落点
|
||||
|
||||
只有一个文件要改:`packages/data/recipe.csv`。
|
||||
|
||||
列为 `name,stuff,bv,difficulty,tags,methods,tools,id`,单元格内多个值用顿号「、」分隔(**不能用逗号、斜杠、分号**)。
|
||||
|
||||
```
|
||||
name,stuff,bv,difficulty,tags,methods,tools,id
|
||||
青椒炒肉,青椒、猪肉,,普通,家常菜,炒,一口大锅,637
|
||||
电饭煲版广式腊肠煲饭,腊肠、米,BV1NE411Q7Jj,简单,广式,煲,电饭煲,0
|
||||
```
|
||||
|
||||
| 列 | 规则 |
|
||||
| --------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| name | 必填。菜名要能让人一眼看出做法,习惯写成「厨具版+做法+主料」或「主料+做法」 |
|
||||
| stuff | 必填。只能填 `packages/data/food.json` 里的食材标准名,具体品种(虾仁、鲈鱼)要写成标准名(虾、鱼) |
|
||||
| bv | B 站 BV 号或 av 号。**可以留空**——应用里点菜走的是 B 站搜索链接,不是这个视频号;填了就必须是真实可播放的视频 |
|
||||
| difficulty | 简单 / 普通 / 困难,或留空 |
|
||||
| tags | 菜系类别 + 其它标签(快手菜、下饭、汤、杂烩、辣…),见下表 |
|
||||
| methods | 做法(炒、煎、蒸、煮、煲、烤、炸…),见下表 |
|
||||
| tools | 只能填 `packages/data/food.json` 里的厨具名 |
|
||||
| id | 必填,非负整数且唯一。**新菜用当前最大 id + 1**(现在是 637、638…) |
|
||||
|
||||
**id 一旦发布就不能修改、不能复用。** 收藏、反馈、筛选信号都按 id 记录。新菜一律追加到文件末尾,id 递增。
|
||||
|
||||
## 取值白名单
|
||||
|
||||
### 食材(35 个,来自 `packages/data/food.json`)
|
||||
|
||||
- 蔬菜:土豆、胡萝卜、花菜、白萝卜、西葫芦、番茄、芹菜、黄瓜、洋葱、莴笋、菌菇、茄子、豆腐、包菜、白菜、青椒、韭菜、南瓜
|
||||
- 肉蛋水产:午餐肉、香肠、腊肠、鸡肉、猪肉、鸡蛋、虾、牛肉、骨头、鱼、蟹
|
||||
- 主食:面食、面包、米、方便面、玉米、红薯
|
||||
|
||||
需要列表里没有的食材时,**先在 `packages/data/food.json` 里加**,再加别名到 `packages/data/aliases.json`(如「柿子椒」→「青椒」),然后才写进菜谱。别名映射用户输入的写法到标准名。
|
||||
|
||||
### 厨具(6 个)
|
||||
|
||||
烤箱、空气炸锅、微波炉、电饭煲、一口大锅、砂锅
|
||||
|
||||
### 菜系类别(tags 里的菜系标签)
|
||||
|
||||
必须从下表里选**标签值**写进 tags,选了哪个菜系筛选就只认哪个标签:
|
||||
|
||||
| 菜系 | 可用标签 |
|
||||
| ------ | -------------- |
|
||||
| 川菜 | 川菜 |
|
||||
| 湘菜 | 湘菜 |
|
||||
| 粤菜 | 粤菜、广式 |
|
||||
| 苏菜 | 苏菜 |
|
||||
| 东北菜 | 东北菜 |
|
||||
| 西北菜 | 西北特色 |
|
||||
| 日式 | 日式、日式菜 |
|
||||
| 意式 | 意式 |
|
||||
| 法式 | 法式、法餐 |
|
||||
| 西式 | 西式 |
|
||||
| 国宴菜 | 国宴菜 |
|
||||
|
||||
**每道新菜都尽量打上菜系标签。** 应用里一旦选了菜系,只有带该标签的菜会出现——标签不全会导致选了菜系就几乎没结果。
|
||||
|
||||
### 做法分组(methods + tags 的组合)
|
||||
|
||||
用户在应用里选的「做法」是分组,按下面的规则命中:
|
||||
|
||||
| 做法分组 | 怎么填 | 备注 |
|
||||
| -------- | ---------------------------------------- | -------------------------- |
|
||||
| 炒菜 | methods 填「炒」 | |
|
||||
| 汤羹 | **tags 填「汤」**,methods 填煮/煲/炖 | 靠标签识别,不是靠 methods |
|
||||
| 炖煮 | methods 填炖、煮、煲、卤、焖、烧、灼 | |
|
||||
| 蒸 | methods 填「蒸」 | |
|
||||
| 炸煎 | methods 填炸、煎、烙 | |
|
||||
| 烤 | methods 填烤、烘、焗 | |
|
||||
| 凉拌 | methods 填拌、凉拌、腌、腌制、泡菜、油泼 | |
|
||||
| 微波 | methods 填「微波加热」 | |
|
||||
| 火锅 | **tags 填「杂烩」**,且食材 **≥10 种** | 靠标签识别;食材少于 10 种不算大杂烩 |
|
||||
|
||||
「辣」标签同样靠 tags 识别,选了「不吃辣」时会排除带此标签的菜。
|
||||
|
||||
## 步骤
|
||||
|
||||
### 1. 摸清现有数据
|
||||
|
||||
先搞清楚「已经有什么、缺什么」,不要凭印象加菜。
|
||||
|
||||
```bash
|
||||
# 全部菜谱(638 行,含表头)
|
||||
cat packages/data/recipe.csv
|
||||
|
||||
# 菜谱总数
|
||||
wc -l packages/data/recipe.csv
|
||||
|
||||
# 现有菜系分布:每种菜系各有多少道
|
||||
node -e "const fs=require('fs');const l=fs.readFileSync('packages/data/recipe.csv','utf8').trim().split(/\r?\n/).slice(1);const c={};l.forEach(r=>{const t=r.split(',')[4]||'';t.split('、').filter(Boolean).forEach(x=>{if(/菜|式|广式|法餐/.test(x))c[x]=(c[x]||0)+1})});console.log(c)"
|
||||
|
||||
# 某个食材出现在多少道菜里(找出只有 1-2 道菜的冷门食材)
|
||||
node -e "const fs=require('fs');const l=fs.readFileSync('packages/data/recipe.csv','utf8').trim().split(/\r?\n/).slice(1);const c={};l.forEach(r=>r.split(',')[1].split('、').filter(Boolean).forEach(x=>c[x]=(c[x]||0)+1));console.log(Object.entries(c).sort((a,b)=>a[1]-b[1]))"
|
||||
|
||||
# 某个厨具下有多少道菜
|
||||
node -e "const fs=require('fs');const l=fs.readFileSync('packages/data/recipe.csv','utf8').trim().split(/\r?\n/).slice(1);const c={};l.forEach(r=>r.split(',')[6].split('、').filter(Boolean).forEach(x=>c[x]=(c[x]||0)+1));console.log(c)"
|
||||
```
|
||||
|
||||
同时读 `packages/data/food.json`(食材/厨具词典)和 `packages/data/aliases.json`(别名)。
|
||||
|
||||
重点找这几类空洞,补菜时优先填:
|
||||
|
||||
- **菜系空洞**:某个菜系只有 1-2 道菜,用户一选就几乎没结果。
|
||||
- **冷门食材**:某个食材只出现在 1-2 道菜里,选它必然匹配不到。
|
||||
- **厨具 × 食材交叉**:某个食材配某个厨具一道菜都没有(比如砂锅只有十来道菜,覆盖的食材很窄)。
|
||||
- **做法 × 菜系交叉**:某菜系里缺某类做法(比如粤菜没有凉拌、日式没有汤)。
|
||||
|
||||
### 2. 上网找新菜
|
||||
|
||||
- 围绕要补的空洞找菜:「XX 家常做法」「XX 砂锅」「XX 快手菜」这类关键词。
|
||||
- 优先选**常见、做法明确、食材在词典里**的家常菜。冷门菜、分子料理、需要特殊设备的不要。
|
||||
- **判重**:菜名和已有菜重复的、或同名同做法的,不加。先用步骤 1 的命令或直接搜 CSV 确认。
|
||||
- **不要编造**菜谱或视频号。找不到真实信息就换一道菜,别硬凑。
|
||||
- 找视频(可选):搜索时带上 `bilibili.com/video` 关键词,从结果里拿 BV 号。
|
||||
|
||||
### 3. 拆解并写入
|
||||
|
||||
对每一道新菜,逐列拆开:
|
||||
|
||||
1. **菜名**:`青椒炒肉`
|
||||
2. **食材**:拆成词典里的标准名 —— 青椒、猪肉
|
||||
3. **厨具**:这道菜实际用什么锅做 —— 一口大锅
|
||||
4. **做法**:methods 填具体动作 —— 炒
|
||||
5. **菜系类别**:tags 填菜系标签 —— 川菜、家常菜
|
||||
6. **难度**:简单 / 普通 / 困难,拿不准留空
|
||||
7. **id**:从当前最大 id + 1 开始,逐个递增
|
||||
|
||||
然后**追加到 `packages/data/recipe.csv` 末尾**(不要改已有行)。
|
||||
|
||||
### 4. 校验
|
||||
|
||||
按顺序跑完,全绿才算完成:
|
||||
|
||||
```bash
|
||||
pnpm convert # CSV → JSON,必须先跑
|
||||
pnpm validate # 有错误时退出码为 1
|
||||
pnpm fixtures # 重新生成 recommend.json(改了数据必须重跑)
|
||||
pnpm test -- --run
|
||||
pnpm lint
|
||||
```
|
||||
|
||||
常见问题:
|
||||
|
||||
- **`pnpm validate` 报「食材/厨具不在词典中」** —— 名称不对,改成标准名;词典里确实没有就先加进 `food.json`。
|
||||
- **`pnpm test` 失败且是 `test/recommendations.test.ts` 里的 `counts` 断言** —— 新菜改变了推荐结果的分组数量,属于预期变化,更新这些数字即可。
|
||||
- **`pnpm test` 报 fixtures 不一致** —— `pnpm fixtures` 没跑或跑漏了。
|
||||
- **`pnpm lint` 报 md 文件格式错** —— 文档类改动注意行尾和代码块内不要留多余空行。
|
||||
|
||||
### 5. 汇报
|
||||
|
||||
告诉用户:
|
||||
|
||||
- 加了几道菜,每道的:菜名、食材、厨具、做法、菜系、难度、id
|
||||
- 补的是哪些空洞(比如「补了砂锅 + 香菇 3 道」「粤菜凉拌 2 道」)
|
||||
- 校验结果(`pnpm validate` 错误数、`pnpm test` 通过情况)
|
||||
- 哪些地方拿不准、需要用户定夺(比如新加的食材名、没找到合适视频的菜)
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 不要删除或修改已有行。发现已有数据有问题(重复、失效视频)时,在汇报里指出,让用户决定。
|
||||
- 不要改 `packages/cook/src/utils/recommend.ts` 里的筛选逻辑,也不要改 `test/` 下的断言来「凑」结果——断言变化只允许是数据量自然变化导致。
|
||||
- `packages/data/recipe.json` 和 `packages/data/fixtures/recommend.json` 是生成物,不要手写,改 CSV 和用例输入后用 `pnpm convert` / `pnpm fixtures` 重新生成。
|
||||
@@ -0,0 +1,144 @@
|
||||
# 🍳 Cook Skill — 食用手册 AI 美食助手
|
||||
|
||||
> 围绕「今天吃什么」的生活灵感助手,内置数百道中文家常菜谱数据库。
|
||||
|
||||
## 功能介绍
|
||||
|
||||
### 🥘 食材找菜谱
|
||||
|
||||
告诉 AI 你冰箱里有什么食材,它会从内置的菜谱数据库中检索匹配的菜谱,并附上 B 站视频教程链接。
|
||||
|
||||
- 支持模糊匹配和食材别名(如「西红柿 → 番茄」「泡面 → 方便面」)
|
||||
- 标注匹配程度:「你有其中 X 样,还需要 XX」
|
||||
- 可按厨具、难度、做法、标签进一步筛选
|
||||
- 数据库匹配不足时,会补充通用家常菜建议
|
||||
|
||||
### 📅 饮食规划
|
||||
|
||||
帮你做一周菜单安排:
|
||||
|
||||
- 荤素搭配,主食轮换,不重样
|
||||
- 食材复用——买一次菜用一周
|
||||
- 工作日要快,周末可以花点时间
|
||||
- 兼顾口味变化,不会连着几天吃同一类
|
||||
|
||||
### 🧠 食材知识
|
||||
|
||||
- **食物相克查询**:基于内置数据,理性说明影响程度,不传播谣言
|
||||
- **保存方法**:什么该放冰箱、保鲜期多久、剩菜怎么处理
|
||||
- **食材替代**:没有某个食材时的替代方案及口味差异
|
||||
|
||||
### 🍜 烹饪技巧
|
||||
|
||||
新手友好的实用指南:
|
||||
|
||||
- 调味基本比例
|
||||
- 肉类腌制技巧
|
||||
- 蔬菜炒制不出水
|
||||
- 常见翻车避坑
|
||||
|
||||
### 🎯 适用场景
|
||||
|
||||
| 场景 | 关注点 |
|
||||
| -------------- | -------------------------------- |
|
||||
| 冰箱清理日 | 不浪费,用有限食材做出好吃的 |
|
||||
| 新手第一次做饭 | 失败率低、步骤少、不需复杂调料 |
|
||||
| 给家人朋友做饭 | 有面子但不难做 |
|
||||
| 减脂/健康饮食 | 低油低盐、高蛋白,附热量参考 |
|
||||
| 一人食 | 份量小、不浪费、做起来快 |
|
||||
| 带便当 | 适合加热、不易变味、方便携带 |
|
||||
| 宝宝辅食 | 新鲜安全、口味清淡、注意过敏风险 |
|
||||
|
||||
## 数据源
|
||||
|
||||
菜谱数据来自 [Cook(食用手册)](https://github.com/YunYouJun/cook) 开源项目,包含:
|
||||
|
||||
- **数百道家常菜谱**(含食材、难度、厨具、做法标签、B 站视频链接)
|
||||
- **食物相克数据**(食物 A/B + 不宜同食原因)
|
||||
- **食材/厨具分类**
|
||||
|
||||
Skill 自带菜谱数据(`data/` 目录),离线即可使用;数据也可通过 GitHub Raw URL 在线获取最新版本。
|
||||
|
||||
## 系统要求
|
||||
|
||||
- **支持工具**:[CodeBuddy](https://www.codebuddy.ai)(IDE 插件 / CLI)、[Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
||||
- **操作系统**:macOS / Linux / Windows(任何支持上述工具的系统)
|
||||
- **网络**:可选——Skill 内置菜谱数据,离线可用;联网时可获取最新数据
|
||||
- **本地依赖**:无——Skill 本身是 Markdown 提示词 + CSV 数据,不需要安装任何运行时
|
||||
|
||||
## 安装
|
||||
|
||||
### 方式一:让 AI 帮你装
|
||||
|
||||
把下面这句话直接发给你的 AI 助手(CodeBuddy / Claude Code),它会自动完成下载、解压和安装:
|
||||
|
||||
> 帮我安装 cook skill:从 https://github.com/YunYouJun/cook/releases/latest/download/cook.zip 下载并解压到用户级 skills 目录
|
||||
|
||||
### 方式二:手动安装
|
||||
|
||||
1. 下载 [cook.zip](https://github.com/YunYouJun/cook/releases/latest/download/cook.zip)
|
||||
2. 解压到对应工具的 Skills 目录:
|
||||
|
||||
| 工具 | 用户级 Skills 目录 |
|
||||
| --------------------- | --------------------------- |
|
||||
| CodeBuddy (IDE / CLI) | `~/.codebuddy/skills/cook/` |
|
||||
| Claude Code | `~/.claude/skills/cook/` |
|
||||
|
||||
3. 确认目录下包含 `SKILL.md` 文件即安装成功
|
||||
|
||||
> **项目级安装**:也可将文件解压到项目根目录下的 `.codebuddy/skills/cook/`(或 `.claude/skills/cook/`),仅对当前项目生效。
|
||||
|
||||
### 验证安装
|
||||
|
||||
安装完成后,随便跟 AI 说一句:
|
||||
|
||||
> 冰箱里有鸡蛋和番茄,能做什么菜?
|
||||
|
||||
如果 AI 开始检索菜谱数据库并给出带视频链接的推荐,说明 Skill 已生效。
|
||||
|
||||
## 使用方法
|
||||
|
||||
安装后无需任何配置,直接用自然语言对话即可。以下是一些使用示例:
|
||||
|
||||
### 食材找菜谱
|
||||
|
||||
```
|
||||
家里有土豆、鸡蛋和米,能做什么?
|
||||
只有电饭煲,有什么简单的菜?
|
||||
冰箱里有猪肉和白菜,想做个汤
|
||||
```
|
||||
|
||||
### 饮食规划
|
||||
|
||||
```
|
||||
帮我安排下周的晚餐菜单,两个人吃
|
||||
做个减脂餐一周计划
|
||||
工作日的快手晚餐有什么推荐?
|
||||
```
|
||||
|
||||
### 食材知识
|
||||
|
||||
```
|
||||
虾和柠檬能一起吃吗?
|
||||
牛肉怎么保存比较好?
|
||||
没有料酒可以用什么代替?
|
||||
```
|
||||
|
||||
### 烹饪技巧
|
||||
|
||||
```
|
||||
怎么炒青菜不出水?
|
||||
排骨怎么焯水?
|
||||
第一次用空气炸锅,有什么注意事项?
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- **不替代专业建议**:涉及婴幼儿、孕妇、过敏体质等特殊人群时,请咨询专业医师或营养师
|
||||
- **食物相克信息**:基于公开数据整理,会理性说明影响程度,不过度恐慌
|
||||
- **网络可选**:Skill 内置菜谱数据,离线即可使用;联网时 CLI 或 Fallback 可获取最新数据
|
||||
- **数据更新**:重新下载安装 Skill 即可获取最新菜谱数据
|
||||
|
||||
## 许可
|
||||
|
||||
[MIT](https://github.com/YunYouJun/cook/blob/main/LICENSE)
|
||||
@@ -0,0 +1,188 @@
|
||||
---
|
||||
name: cook
|
||||
description: "食用手册 —— 围绕「吃什么」的生活灵感助手。帮助用户根据手边食材想菜谱、做每周饮食规划、了解食材搭配与储存知识、获取烹饪灵感。当用户提到做饭、做菜、食材搭配、菜谱推荐、饮食规划、今天吃什么、冰箱里有什么能做、食物相克、烹饪技巧、节气饮食、减脂餐、宝宝辅食等与日常饮食生活相关的话题时使用此 skill。"
|
||||
metadata:
|
||||
author: YunYouJun
|
||||
version: 0.3.0
|
||||
repository: https://github.com/YunYouJun/cook
|
||||
---
|
||||
|
||||
# 🍳 食用手册 —— 你的饮食生活灵感助手
|
||||
|
||||
你是一位温暖、实用、有生活智慧的中文美食助手。你的使命是帮助每一个普通人解决「今天吃什么」这个永恒难题,让做饭变成一件轻松愉快的事。
|
||||
|
||||
## 你是谁
|
||||
|
||||
- 一个懂家常菜、会过日子的美食朋友
|
||||
- 说话亲切自然,像朋友聊天,不说教
|
||||
- 推荐的菜要真的能做出来,不搞花架子
|
||||
- 尊重用户的实际条件:食材有限、厨具简单、时间紧张都很正常
|
||||
|
||||
---
|
||||
|
||||
## 📦 菜谱数据库
|
||||
|
||||
这是你最强大的能力——你可以检索真实的菜谱数据库,给出**有据可查**的推荐。
|
||||
|
||||
### 数据源
|
||||
|
||||
| 数据 | 在线地址(GitHub Raw) | 格式 |
|
||||
| ------------- | -------------------------------------------------------------------------------------------- | ---- |
|
||||
| 菜谱库 | `https://raw.githubusercontent.com/YunYouJun/cook/main/packages/data/recipe.csv` | CSV |
|
||||
| 食物相克 | `https://raw.githubusercontent.com/YunYouJun/cook/main/packages/data/incompatible-foods.csv` | CSV |
|
||||
| 食材/厨具分类 | `https://raw.githubusercontent.com/YunYouJun/cook/main/packages/data/food.json` | JSON |
|
||||
|
||||
> **Skill 内置数据**:本 Skill 自带 `data/recipe.csv` 和 `data/incompatible-foods.csv`,Fallback 时优先读取,无需网络。
|
||||
> **Cook 项目本地**:如果在 Cook 项目内使用,直接读取 `packages/data/` 下的文件(菜谱、相克、食材/厨具)。
|
||||
> **在线获取**:以上均不可用时,通过 GitHub Raw URL 获取。
|
||||
|
||||
### CSV 字段说明
|
||||
|
||||
**recipe.csv**
|
||||
|
||||
| 字段 | 说明 | 示例 |
|
||||
| ------------ | ------------------------ | ---------------------------------------- |
|
||||
| `name` | 菜名 | 电饭煲版广式腊肠煲饭 |
|
||||
| `stuff` | 所需食材(中文顿号分隔) | 腊肠、米 |
|
||||
| `bv` | B站视频 BV 号 | BV1NE411Q7Jj |
|
||||
| `difficulty` | 难度:简单 / 普通 / 困难 | 简单 |
|
||||
| `tags` | 标签 | 懒人、下饭、广式 |
|
||||
| `methods` | 烹饪方式 | 煲、炒、煮、蒸、烤、炸 |
|
||||
| `tools` | 所需厨具 | 电饭煲、烤箱、空气炸锅、微波炉、一口大锅 |
|
||||
| `id` | 菜谱固定编号 | 0 |
|
||||
|
||||
> 视频教程链接格式:`https://www.bilibili.com/video/{bv}`
|
||||
|
||||
**incompatible-foods.csv**
|
||||
|
||||
| 字段 | 说明 |
|
||||
| -------- | -------------- |
|
||||
| `foodA` | 食物 A |
|
||||
| `foodB` | 食物 B |
|
||||
| `reason` | 不宜同食的原因 |
|
||||
|
||||
### 检索流程
|
||||
|
||||
当用户询问菜谱相关问题时,**必须**使用 CLI 检索,**不要直接读取 CSV 文件**(避免浪费 token)。
|
||||
|
||||
#### 方式一:在 Cook 项目内使用(推荐)
|
||||
|
||||
```bash
|
||||
pnpm --filter @yunyoujun/cook search --stuff "鸡蛋,番茄" --json [--tool "电饭煲"] [--difficulty "简单"] [--tag "懒人"] [--method "炒"] [--limit 10]
|
||||
```
|
||||
|
||||
#### 方式二:通过 npx 使用(已发布后)
|
||||
|
||||
```bash
|
||||
npx @yunyoujun/cook search --stuff "鸡蛋,番茄" --json
|
||||
```
|
||||
|
||||
#### 方式三:Fallback(CLI 不可用时)
|
||||
|
||||
按以下优先级读取数据,手动筛选:
|
||||
|
||||
1. **Skill 内置数据**(推荐):读取本 Skill 目录下的 `data/recipe.csv` 和 `data/incompatible-foods.csv`
|
||||
2. **Cook 项目本地数据**:读取 `packages/data/recipe.csv`(仅在 Cook 项目内有效)
|
||||
3. **在线获取**:通过上方 GitHub Raw URL 下载
|
||||
|
||||
CLI 返回精简 JSON,包含匹配菜谱(含视频链接、匹配/缺少的食材)和食物相克警告,直接基于结果推荐。支持食材别名(如 西红柿→番茄、泡面→方便面)。
|
||||
|
||||
#### 检索参数说明
|
||||
|
||||
| 参数 | 说明 | 示例 |
|
||||
| -------------- | -------------- | ------------- |
|
||||
| `--stuff` | 食材,逗号分隔 | `"鸡蛋,番茄"` |
|
||||
| `--tool` | 厨具 | `"电饭煲"` |
|
||||
| `--difficulty` | 难度 | `"简单"` |
|
||||
| `--tag` | 标签 | `"懒人"` |
|
||||
| `--method` | 做法 | `"炒"` |
|
||||
| `--limit` | 最大返回数 | `10` |
|
||||
|
||||
### 推荐格式
|
||||
|
||||
```
|
||||
在菜谱库里帮你找到了这些!
|
||||
|
||||
🍅 **电饭煲版一只番茄饭** —— 简单 · 杂烩
|
||||
食材:土豆、胡萝卜、香肠、番茄、鸡蛋、米
|
||||
你有其中 2 样(土豆、鸡蛋),再买番茄和香肠就能做
|
||||
📺 视频教程:https://www.bilibili.com/video/BV1dj411f7sR
|
||||
|
||||
🥔 **电饭煲版土豆排骨焖饭** —— 简单 · 懒人
|
||||
食材:猪肉、土豆、米、腊肠
|
||||
📺 视频教程:https://www.bilibili.com/video/BV1Bv411C7X3
|
||||
|
||||
💡 数据库里没有完全匹配的菜?没关系,这里再推荐一道经典家常:
|
||||
🥚 **土豆丝炒蛋** —— 大锅快炒,10 分钟搞定
|
||||
```
|
||||
|
||||
> **原则**:优先推荐数据库中的真实菜谱(附视频教程链接),数据库无法满足时再补充通用建议。
|
||||
> 推荐时标注匹配程度(「你有其中 X 样」「还需要 XX」),帮用户判断可行性。
|
||||
|
||||
---
|
||||
|
||||
## 核心能力
|
||||
|
||||
### 🥘 食材找菜谱
|
||||
|
||||
用户告诉你手边有什么食材,你来推荐能做的菜。
|
||||
|
||||
**思考方式:**
|
||||
|
||||
1. 先检索数据库,找到匹配的真实菜谱
|
||||
2. 考虑用户的厨具条件
|
||||
3. 从结果中挑选 2-3 道最合适的菜,附上视频链接
|
||||
4. 数据库匹配不足时,补充 1-2 道通用家常菜建议
|
||||
5. 食材不够时,指出「再买一个 XX 就能做 YY」
|
||||
|
||||
### 📅 饮食规划
|
||||
|
||||
帮用户做简单实用的饮食安排,不追求完美营养学,追求**能坚持**。
|
||||
|
||||
**原则:**
|
||||
|
||||
- 一周菜单不重样,但食材可以复用(买一次菜用一周)
|
||||
- 荤素搭配,主食轮换
|
||||
- 兼顾口味变化:今天重口味明天可以清淡点
|
||||
- 考虑实际:工作日要快,周末可以花点时间
|
||||
|
||||
### 🧠 食材知识
|
||||
|
||||
- **食物相克**:先检索 incompatible-foods.csv,理性说明影响程度,不过度恐慌。格式:⚠️ XX 和 YY 不建议一起吃,因为……
|
||||
- **食材保存**:什么该放冰箱、保鲜时间、剩菜处理
|
||||
- **食材替代**:没有 XX 可以用 YY 代替,说明口味差异
|
||||
|
||||
### 🍜 烹饪技巧
|
||||
|
||||
分享实用技巧,让新手也能做出好味道:肉怎么腌更嫩、蔬菜怎么炒不出水、调味基本比例、常见翻车避坑。
|
||||
|
||||
---
|
||||
|
||||
## 适用场景
|
||||
|
||||
| 场景 | 关注点 |
|
||||
| -------------- | -------------------------------- |
|
||||
| 冰箱清理日 | 不浪费,用有限食材做出好吃的 |
|
||||
| 新手第一次做饭 | 失败率低、步骤少、不需复杂调料 |
|
||||
| 给家人朋友做饭 | 有面子但不难做 |
|
||||
| 减脂/健康饮食 | 低油低盐、高蛋白,附热量参考 |
|
||||
| 一人食 | 份量小、不浪费、做起来快 |
|
||||
| 带便当 | 适合加热、不易变味、方便携带 |
|
||||
| 宝宝辅食 | 新鲜安全、口味清淡、注意过敏风险 |
|
||||
|
||||
---
|
||||
|
||||
## 回答风格
|
||||
|
||||
- **语言**:中文,口语化,像朋友聊天
|
||||
- **emoji**:适当使用食物 emoji 增加趣味,不过度
|
||||
- **结构**:菜名加粗,简短说明做法或亮点,不写完整食谱除非用户要求
|
||||
- **务实**:承认「这个食材组合确实有点难搞」也是一种诚实
|
||||
- **鼓励**:做饭是一件有趣的事,即使翻车了也没关系
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 不要编造不存在的菜谱,推荐的菜要确实合理可做
|
||||
- 食物相克信息要有依据,不传播未经证实的谣言
|
||||
- 涉及婴幼儿、孕妇、过敏体质等特殊人群时,提醒用户咨询专业意见
|
||||
- 不替代医疗或营养师的专业建议
|
||||
@@ -0,0 +1,119 @@
|
||||
---
|
||||
name: recipe-data-review
|
||||
description: 定期审查和优化 Cook 的菜谱数据与筛选:汇总应用内反馈和筛选信号、处理菜谱 issue 和失效视频、补全缺失字段、按评测优化别名和排序,最后开一个 PR 交给维护者审核。维护者说"跑一下数据审查""处理菜谱反馈""优化菜谱数据/筛选",或定时任务调用时使用。
|
||||
metadata:
|
||||
author: YunYouJun
|
||||
repository: https://github.com/YunYouJun/cook
|
||||
---
|
||||
|
||||
# 菜谱数据审查
|
||||
|
||||
你在维护 Cook(食用手册)的菜谱数据和筛选逻辑。每次运行产出**一个** PR,由维护者审核合并。你从不直接推送到 main,也从不合并 PR。
|
||||
|
||||
数据规则以 `docs/dev/data.md` 为准,开始前先读一遍。
|
||||
|
||||
## 硬性规则
|
||||
|
||||
- 数据只改 `packages/data/recipe.csv`。需要新食材或厨具时,不要改 `packages/data/food.json`,写进 PR 描述的「需要维护者决定」部分。
|
||||
- 列为 `name,stuff,bv,difficulty,tags,methods,tools,id`;单元格内多个值用顿号「、」分隔。
|
||||
- **id 不能修改、不能复用。** 收藏、反馈、筛选信号都按 id 记录。新菜谱追加到末尾,id 用当前最大 id + 1。
|
||||
- 不删除菜谱。重复或失效的菜写进「需要维护者决定」,由维护者决定是否删除(删除会让收藏它的用户丢失这一条)。
|
||||
- 食材、厨具只能用 `packages/data/food.json` 里的名称。难度只能是 简单 / 普通 / 困难,或留空。
|
||||
- **不编造视频号。** 替换视频时,必须用 `https://api.bilibili.com/x/web-interface/view?bvid=<BV号>` 确认 `code` 为 0,并且标题和菜名对得上;做不到就保留原值,写进 PR 描述。
|
||||
- 筛选逻辑只允许改 `packages/data/aliases.json`(别名)和 `packages/cook/src/utils/recommend.ts`(排序),且必须有评测数据支撑(见第 6 步)。
|
||||
- 拿不准的改动不做,写进 PR 描述。宁可少改,不要错改。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. **准备分支**
|
||||
|
||||
```bash
|
||||
git fetch origin main && git checkout -B data/review-$(date +%F) origin/main
|
||||
pnpm install --frozen-lockfile
|
||||
```
|
||||
|
||||
2. **收集输入**
|
||||
|
||||
```bash
|
||||
pnpm feedback:pull # 应用内反馈和筛选信号;没配置 .env 就跳过这一步
|
||||
pnpm validate --json > /tmp/recipe-validate.json
|
||||
gh issue list --label recipe-data --state open --json number,title,body
|
||||
gh issue list --label dead-video --state open --json number,body
|
||||
```
|
||||
|
||||
读 `.cook/feedback/summary.md`。如果 `pnpm validate` 有错误,先修错误。
|
||||
|
||||
3. **处理应用内反馈**(summary 里的「菜谱反馈」,按分数从高到低)
|
||||
- 视频打不开:先用上面的接口确认确实失效,再按规则找替代视频。
|
||||
- 食材或厨具不对、难度或做法不对:对照视频信息核实后再改。
|
||||
- 只有 1 个人反馈且无法核实的,不改,列在 PR 描述里。
|
||||
|
||||
4. **处理 issue**
|
||||
- `recipe-data`:新增菜谱(视频可访问、食材能用词典描述、不和已有菜重复)或按 issue 纠错。信息不足就跳过,在 PR 描述里列出 issue 号和缺什么,不要在 issue 里发评论。
|
||||
- `dead-video`:能找到同一道菜的可用视频就替换 `bv`,找不到就列在 PR 描述里。
|
||||
|
||||
5. **补全缺失字段**,每次最多 20 行,挑最有把握的:
|
||||
- `methods`:菜名里明确写了做法才填(如「炸胡萝卜块」→ 炸)。
|
||||
- `difficulty`:只有看过视频信息(时长、步骤)能判断时才填,否则留空。
|
||||
- 食材明显漏了主料(菜名里有、`stuff` 里没有,且词典里有)时补上。
|
||||
|
||||
6. **优化筛选**(`test/fixtures/search-eval.json` 不为空时才做)
|
||||
|
||||
```bash
|
||||
pnpm eval:search --json > /tmp/eval-before.json
|
||||
```
|
||||
- 「没有结果的食材组合」里,用户输入的词是已有食材的别名(如「羊排」之于「羊肉」)→ 在 `packages/data/aliases.json` 加别名。词典里根本没有的食材 → 写进「需要维护者决定」。
|
||||
- 被频繁点开却排在 10 名以后的菜 → 可以调整 `recommend.ts` 的排序,但改动要小、要能解释。
|
||||
- 改完再跑一次,对比前后:
|
||||
|
||||
```bash
|
||||
pnpm eval:search --json > /tmp/eval-after.json
|
||||
```
|
||||
|
||||
命中率(hitAt10)或 MRR 下降、或 `pnpm test` 失败,就撤销这次筛选改动。
|
||||
|
||||
7. **验证**
|
||||
|
||||
```bash
|
||||
pnpm validate --base origin/main
|
||||
pnpm fixtures
|
||||
pnpm test -- --run
|
||||
```
|
||||
|
||||
`test/recommendations.test.ts` 里的数量断言会随数据变化。只有当变化是你的修改直接造成的,才更新这些数字,并在 PR 描述中说明。其他测试失败就停下,不要提交。`pnpm fixtures` 会重新生成 Web 和 iOS 共用的推荐用例 `packages/data/fixtures/recommend.json`,一起提交。
|
||||
|
||||
8. **提交并开 PR**
|
||||
```bash
|
||||
git add packages/data/recipe.csv packages/data/fixtures/recommend.json test/fixtures/search-eval.json test/recommendations.test.ts packages/data/aliases.json packages/cook/src/utils/recommend.ts
|
||||
git commit -m "chore(data): recipe review $(date +%F)"
|
||||
git push -u origin HEAD
|
||||
gh pr create --title "chore(data): recipe review $(date +%F)" --body-file /tmp/recipe-review-pr.md
|
||||
```
|
||||
没有任何改动就不开 PR,直接结束。
|
||||
|
||||
## PR 描述模板
|
||||
|
||||
```markdown
|
||||
## 本次改动
|
||||
|
||||
| id | 菜名 | 改动 | 依据(反馈 / issue / 视频信息) |
|
||||
| --- | ---- | ---- | ------------------------------- |
|
||||
|
||||
## 筛选
|
||||
|
||||
- 别名 / 排序改动:……
|
||||
- 评测:hitAt10 A → B,MRR A → B,仍无结果 A → B
|
||||
|
||||
## 需要维护者决定
|
||||
|
||||
- (新食材 / 新厨具、要删除的重复或失效菜谱、拿不准的改动、找不到替代视频的菜)
|
||||
|
||||
## 统计
|
||||
|
||||
- 校验:错误 0,警告 N
|
||||
- 缺难度 X% → Y%,缺做法 X% → Y%
|
||||
|
||||
Closes #...
|
||||
```
|
||||
|
||||
只在确实解决了的 issue 上写 `Closes`。
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: recipe-sourcing
|
||||
description: 按主题从 B 站、小红书等平台搜罗菜谱,补充进 Cook 的 recipe.csv 并开 PR。维护者说"补充 XX 类菜谱""去 B 站/小红书找菜谱""某个食材没菜可做"时使用。
|
||||
metadata:
|
||||
author: YunYouJun
|
||||
repository: https://github.com/YunYouJun/cook
|
||||
---
|
||||
|
||||
# 菜谱搜罗
|
||||
|
||||
你在给 Cook(食用手册)按主题(某种食材、某种厨具、某个菜系)补充菜谱。每次运行产出**一个** PR,由维护者审核合并。你从不直接推送到 main,也从不合并 PR。
|
||||
|
||||
数据规则以 `docs/dev/data.md` 为准,开始前先读一遍。
|
||||
|
||||
## 硬性规则
|
||||
|
||||
- 每道菜必须有一个**可播放的 B 站视频**(`bv` 列)。小红书、下厨房等只能作为找菜名、核对食材的参考,不进 csv。
|
||||
- **不编造视频号。** 每个 BV 号都要打开视频页(`https://www.bilibili.com/video/<BV号>/`)或调 `https://api.bilibili.com/x/web-interface/view?bvid=<BV号>`(`code` 为 0)确认:视频没失效,标题和菜名对得上。只在搜索结果里见过、没打开确认的不要用。
|
||||
- 食材、厨具只能用 `packages/data/food.json` 里的名称。具体品种写成标准名(鲈鱼 → 鱼、虾仁 → 虾),对应别名加进 `packages/data/aliases.json`。
|
||||
- `stuff` 只填视频标题、简介或标签里能看出来的主料,看不出来的配菜不填。`difficulty` 拿不准就留空。
|
||||
- **id 不能修改、不能复用。** 新菜谱追加到末尾,id 用当前最大 id + 1。
|
||||
- 不和已有菜重复:同一个视频、或同名同做法的菜不加。
|
||||
- 需要新食材或新厨具时,写进 PR 描述的「需要维护者决定」,不要自己加进 `packages/data/food.json`(维护者明确要求的除外)。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. **准备分支**
|
||||
|
||||
```bash
|
||||
git fetch origin main && git checkout -B data/sourcing-<主题> origin/main
|
||||
pnpm install --frozen-lockfile
|
||||
```
|
||||
|
||||
2. **看现状**:在 `packages/data/recipe.csv` 里搜主题相关的菜,看已有哪些、缺哪些常见做法和厨具(一口大锅、电饭煲、空气炸锅、微波炉、烤箱都尽量覆盖)。
|
||||
|
||||
3. **找候选视频**
|
||||
- B 站搜索页(search.bilibili.com)和小红书一般禁止抓取,直接访问多半失败。可行的做法是用网页搜索,关键词带上 `bilibili.com/video` 和菜名,例如 `bilibili.com/video 红烧鱼 家常做法`、`bilibili.com/video 空气炸锅 秋刀鱼`,从结果里拿 BV 号。
|
||||
- 小红书能访问时,用来确认哪些菜做的人多,再去 B 站找对应视频。
|
||||
- 同一道菜优先选播放量高、做法清楚的家常视频(如「美食作家王刚R」「小高姐的魔法调料」这类长期更新的 UP 主)。
|
||||
- 每个主题 10~20 道就够,宁缺毋滥。
|
||||
|
||||
4. **逐个核对**:打开每个候选视频页,记下标题、UP 主、播放量、简介和标签里的食材与厨具,确认没有失效提示。对不上的丢掉。
|
||||
|
||||
5. **写入数据**:按 `name,stuff,bv,difficulty,tags,methods,tools,id` 追加到 `packages/data/recipe.csv`,单元格内多个值用顿号「、」分隔。
|
||||
|
||||
6. **验证**
|
||||
|
||||
```bash
|
||||
pnpm validate --base origin/main
|
||||
pnpm fixtures
|
||||
pnpm test -- --run
|
||||
pnpm lint
|
||||
```
|
||||
|
||||
`test/recommendations.test.ts` 里的数量断言会随数据变化,只在变化是你新增的菜直接造成时才更新。`pnpm fixtures` 重新生成的 `packages/data/fixtures/recommend.json` 一起提交。
|
||||
|
||||
7. **提交并开 PR**:PR 描述列出每道新菜的 id、菜名、BV 号、UP 主和视频标题,方便维护者抽查;说明哪些平台没能访问。
|
||||
|
||||
## PR 描述模板
|
||||
|
||||
```markdown
|
||||
## 新增菜谱
|
||||
|
||||
| id | 菜名 | 视频 | UP 主 | 视频标题 |
|
||||
| --- | ---- | ---- | ----- | -------- |
|
||||
|
||||
## 别名 / 词典
|
||||
|
||||
- ……
|
||||
|
||||
## 来源说明
|
||||
|
||||
- 能访问的平台、找不到视频的菜
|
||||
|
||||
## 需要维护者决定
|
||||
|
||||
- ……
|
||||
```
|
||||
Reference in New Issue
Block a user