家庭菜谱适配器
把「想吃的菜」和「家里实际有的东西」对起来,输出一份能真正做得成的方案。
何时使用
在以下情况使用本技能:
- 用户说「家里只有 X、Y、Z,能做什么」「冰箱清空计划」「剩饭能做什么」
- 用户想做某道菜但缺某种调料,问「缺了能替代吗」「没有老抽怎么办」
- 用户有忌口(不吃辣、素食、不吃海鲜、对某食材过敏)需要过滤菜品
- 用户说「随便」「都行」「不知道吃啥」,需要从多个方向给候选
- 用户是厨房新手,需要知道这道菜难不难、新手能不能一次做成
执行步骤
步骤 1:判断交付形态
本技能交付的是单个 HTML 文件,不是脚本、不是文档。两种典型交付:
| 用户诉求 | 做法 |
|---|---|
| 「给我个菜谱适配工具」 | 直接产出 HTML 文件并用 present_files 交付 |
| 「我家只有 XX,做什么好」 | 按下方口径直接在对话里给出适配结论(必要时附 HTML) |
对话内直接回答时,按下面的输出结构组织内容,不要生搬硬套网页措辞。
步骤 2:解析用户输入
提取三类信息,缺哪类就按缺省处理,不要反复追问:
| 输入 | 解析规则 | 缺省 |
|---|---|---|
| 菜名 | 精确名 → 别名 → 包含匹配 | 命中「随便/都行/不知道」走推荐 |
| 现有食材 | 归一化后与菜谱用料池比对 | 视为全部齐备,只给步骤不做替换 |
| 忌口/偏好 | 映射到标签:辣、猪肉、牛肉、禽类、海鲜、蛋、奶、坚果、素食等 | 无忌口 |
菜名匹配顺序见 references/matching-rules.md。匹配不上就不要硬编做法,改为推荐相近菜谱。
步骤 3:输出适配结论
按固定结构输出,五段缺一不可:
- 菜名 + 新手友好度星级(1-5 星,必须标注,附一句星级含义)
- 缺料清单:区分「必需」与「可选」,可选的可省
- 替代方案:每个缺的核心调料给恰好 2 种替代,每种标注风味差异
- 调整后的步骤:在原步骤上标注改用替代、省略、或与忌口冲突需剔除
- 一句提示:材料齐备度百分比 + 是否可以直接开做
步骤 4:缺核心调料 → 2 种替代 + 风味差异
这是本技能的核心规则,每项缺的核心调料固定给 2 个替代方案,且每个都要写清风味差异。格式:
缺「冰糖」(核心调料)
替代 1:白砂糖 — 风味差异:甜度相同但缺少焦糖香,上色浅不发亮
替代 2:蜂蜜 — 风味差异:上色偏琥珀色、香气带花香,减量 1/4 使用
风味差异必须具体,不能写「差不多」「可以代替」。要落到:咸甜浓淡、上色深浅、香气类型、口感软硬、能否久煮、辣度增减、是否适合久炖。详见 references/substitution-rules.md。
替代方案要优先给常用的家用替代(生抽→普通酱油减量 1/3),不要给冷门货。
步骤 5:用户说「随便」→ 三方向各推一道
命中「随便 / 都行 / 你决定 / 不知道吃啥」时,从快手、下饭、清淡三个方向各推一道菜,每道都要说明推荐理由。
理由要基于真实数据生成,不是套话。可用的依据:
- 用时(
time字段,快手方向优先短的) - 现有食材命中率(命中数 / 核心材料数)
- 辣度与忌口是否匹配
- 新手友好度星级
- 菜的风味特点(
highlight字段)
三个方向的推荐不得推同一道菜。忌口命中的菜直接排除,不做「微辣版」妥协。
推荐时把星级和理由一起给用户,并说明「按这道菜出方案」可展开完整步骤。
步骤 6:标注新手友好度
每道菜都必须标注 1-5 星,无论来自匹配还是推荐。星级口径:
| 星级 | 含义 |
|---|---|
| ★ | 零基础也能做,步骤少、失败率极低 |
| ★★ | 容易上手,只需基本刀工和火候判断 |
| ★★★ | 有点讲究,关键在火候或腌料比例 |
| ★★★★ | 需要练手,对火候和时机有要求,容错率低 |
| ★★★★★ | 挑战级,步骤多考验基本功,不建议新手第一次做 |
星级是菜谱的固有属性(level 字段),不要因为用户是新手就擅自调低——调低会让用户低估难度。
资源清单
| 路径 | 用途 |
|---|---|
assets/家庭菜谱适配器.html |
主交付物:单文件菜谱适配工具,已适配桌面与移动端 |
assets/data/recipes.js |
数据层:40 道菜谱 + 72 项替代方案 + 忌口标签映射 + 食材清单 |
assets/data/adapter.js |
核心引擎:匹配、适配分析、三方向推荐,纯逻辑无 DOM 依赖 |
assets/icon/icon-512.png |
512×512 技能图标(发布到 SkillHub 时上传) |
assets/icon/icon-source.html |
图标的 SVG 源码,改配色后用 headless Chrome 重新渲染 |
references/substitution-rules.md |
替代方案编写规范:风味差异怎么写、写多细、常见坑 |
references/matching-rules.md |
菜名匹配与忌口映射规则、输出格式模板 |
scripts/verify_adapter.js |
33 项核心引擎单测(Node 直接跑,无需依赖) |
scripts/check_platform_compliance.py |
上传合规预检:ZIP 结构 + frontmatter + 图标 + 内容质量 |
发布指引.md |
发布到 SkillHub 的分步操作说明与常见退回原因 |
修改与扩展
新增一道菜
在 assets/data/recipes.js 的 DISHES 数组里加一条,字段必须齐全:
{
id: 'caiyousi', name: '菜油子炒饭', alias: ['菜炒饭'],
time: 15, level: 2, spice: 0, scene: ['快手','下饭'],
highlight: '一句话风味特点,用于生成推荐理由',
main: ['隔夜米饭','鸡蛋'], // 主料
seasoning: ['盐','葱','生抽'], // 核心调料,缺了要给替代
optional: ['火腿丁'], // 可选料,缺了只提示可省
steps: [ { t: '步骤文字', need: ['鸡蛋','盐'] }, ... ]
}
硬性约束(违反会被单测拦下):
steps[].need里的每个食材必须出现在main/seasoning/optional三者之一中- 每个
main和seasoning都要被至少一个步骤的need引用,否则会出现虚假缺料提示 level必须在 1-5 之间;scene至少含一个方向(快手/下饭/清淡/宴客)time为整数分钟
新增一项替代方案
在 SUBSTITUTE 里加键,值必须恰好是 2 个元素,每个元素含 name 和 diff:
'某调料': [
{ name: '替代品 A', diff: '咸度接近但香气更淡,适合快炒不适合久炖' },
{ name: '替代品 B', diff: '颜色偏深需要减量,回味带苦味' }
]
单测会强制校验「每项恰好 2 种」和「风味差异不少于 8 个字」,不要留空数组或只写 1 种。
调整忌口标签
改 INGREDIENT_TAGS(食材 → 标签)和 INGREDIENT_TAGS 中的别名。素食需要排除的荤类标签写在 adapter.js 的 VEGETARIAN_EXCLUDE。
验证改动
改动后必须做三件事:
node scripts/verify_adapter.js跑核心引擎单测(33 项)- 用 headless Chrome 截图检查 PC 与移动端两种视口
node --check或new Function()校验内联脚本语法
上传前再跑一次 python scripts/check_platform_compliance.py <zip路径>,确认合规检查全过。
截图陷阱:headless Chrome 加 --force-device-scale-factor=2 会把 CSS 视口翻倍,测移动端要用 --window-size=780(=390×2)而不是 390,否则截出来是桌面版。另外 Chrome 无头模式可能无法直接写入工作区目录,截图先渲染到临时目录再拷贝回来。
注意事项
- 不编造做法:菜谱库里没有的菜不要硬编步骤,改为推荐库里已有的相近菜
- 替代方案必须 2 种:缺一个核心调料只给 1 种替代是不合格的
- 风味差异必须具体:不能写「味道差不多」
- 星级不能虚高:新手友好度要反映真实难度(爆炒类不超过 3 星)
- 忌口零妥协:推荐和匹配都要排除忌口菜品,不做「少放点辣」的妥协
- 隐私:数据只存本地浏览器,不上传任何服务器
- slug 不可变:若本技能要发布到 SkillHub,
slug一经提交不可更改