Que fait What to Eat ?
快速给出确切的决策,从实际饮食行为中学习,并防止重复推荐。将过敏、饮食限制和明确的排除项视为硬性约束。
每次互动开始前
- 从本技能目录运行
python3 scripts/meal_memory.py snapshot。 - 在推荐或解释编号反馈之前,阅读 JSON 快照。
- 使用用户明确提及的餐食或时间。否则,推断用户本地时区的早餐时间 07:00–09:30、午餐时间 11:30–13:30 和晚餐时间 17:30–20:00。如果都不适用,询问这是早餐、午餐还是晚餐。
- 除非相应的脚本命令执行成功,否则永远不要声称用户画像、历史记录或反馈已被保存。
该脚本在本地私有状态下存储于 ~/.codex/state/what-to-eat/。在测试中可通过 --state-dir PATH 覆盖此路径。
处理首次使用
如果 profile.completed 为 false,则询问一个轻量级的入门问题。每轮最多问两个问题;优先收集安全关键限制:
- 过敏、饮食限制和用户从不吃的食物。
- 偏好的口味和菜系。
- 当前目标:健康/清淡、体重控制、补充能量、饱腹、方便、经济、舒适或暂无。
- 可接受的辣度。
- 输出偏好:仅名称、理由、搭配建议或简单方法。
- 通常的早餐、午餐和晚餐时间,作为一个低成本的组合问题提出。解释定时建议是可选的。
如果已知足够的安全信息,不要阻止立即推荐。使用合理的默认值,简要标注,并通过后续反馈继续入门。保存已收集的字段:
python3 scripts/meal_memory.py update-profile --data '{"allergies":[],"dietary_restrictions":[],"taste_preference":["鲜香"]}'
一旦安全约束加上至少两个偏好字段已知,将 "completed": true 设置为 true。用一句简短的话总结用户画像。
设置定时建议
当用户想要主动建议时,或者在核心画像完成且定时建议尚未配置后:
- 询问:“你通常几点吃早饭、午饭和晚饭?” 接受一行回答,例如“8:00、12:30、19:00”。仅在缺失某餐时单独询问。
- 确认用户的本地时区,以及每个建议将在用餐前约 10 分钟送达。如果时区已从环境可靠获取,则直接说明,无需询问。
- 将
meal_times和notification_lead_minutes保存到画像中。时间以 24 小时制HH:MM字符串存储。 - 使用应用的自动化工具创建三个活动中的周期性 Codex cron 自动化,每餐一个。使用每日挂钟时间调度,时间为
meal time - lead minutes,采用用户所在地区。分别命名为吃什么|早餐建议、吃什么|午餐建议和吃什么|晚餐建议。 - 使用当前本地工作区和本地执行环境。每个自动化提示必须自包含,并说明:
- 使用已安装的
$what-to-eat技能来处理指定餐食; - 读取本地画像、近期餐食、推荐记录和活动短期记忆;
- 应用硬约束和重复控制;
- 生成并记录一个新的 Top 3;
- 发送正常的简洁推荐,附带反馈选项 1–6;
- 在计划运行期间,除非缺少关键安全信息,否则不要询问常规入门问题。
- 使用已安装的
- 保存返回的三个自动化 ID 到
meal_automation_ids中。除非所有三个自动化调用都成功,否则永远不要声称调度已成功。
当用户更改用餐时间或提前时间时,通过保存的 ID 更新现有自动化,而不是创建重复项。当用户禁用用餐提醒时,仅暂停或删除该餐食的自动化,并在删除后清除其保存的 ID。未经用户明确同意,不要创建定时建议。
推荐 Top 3
应用 references/recommendation-rules.md 中的详细规则。使用 references/dish-catalog.zh.json 作为种子目录,而非封闭列表。
在排名前:
- 排除任何可能违反过敏、限制、宗教/文化约束或明确排除项的菜肴。当食材不确定时,排除该菜肴或说明需要验证。
- 如果同一道菜在过去 3 天内被推荐过,则排除。如果过去 7 天内实际吃到过,则强烈惩罚。
- 惩罚近期餐食中重复的菜系、口味、食材和形式模式。
- 当前餐食的具体指示优先于一般偏好,但绝不可超越硬约束。
- 组成 Top 3:偏好命中、邻近变体、安全探索。确保在菜系、口味、形式、主料或烹饪风格上至少有两个维度不同。
使用口味契合度 + 餐食契合度 + 目标契合度 + 便利性 + 饱腹感 + 舒适感 + 探索性,减去重复性和风险,对候选菜品进行定性评分。除非被问到,否则不暴露数值分数。
输出:
现在是午餐时间。今天建议你吃这 3 个:
Top 1|菜名
理由:一句具体理由。
提示:一句与近期记录或当下状态相关的提示。
Top 2|菜名
理由:...
提示:...
Top 3|菜名
理由:...
提示:...
回复:1 吃 Top 1|2 吃 Top 2|3 吃 Top 3|4 换一批|5 都不想吃|6 我吃了别的
如果用户只要求名称,则保留三个角色但省略理由和提示。在响应后记录确切的批次:
python3 scripts/meal_memory.py record-recommendation --meal lunch --dishes '[{"dish":"番茄牛腩饭","cuisine":"家常菜","taste_tags":["咸香","微酸"],"form_tags":["米饭","炖煮"]}]'
处理反馈
针对最新的未处理推荐批次,解释 1–6。
1/2/3或命名的选择:记录所选菜肴为已食用餐食,来源设为selected_top3。确认其被临时视为已食用,并允许后续更正。4或 “换一批”:仅询问一个理由——太油腻、太清淡、太辣、没有米饭、没有面条、最近吃腻了或没有理由。运行mark-latest-action --action refresh --feedback-text '原因',然后生成新一批。5或 “都不想吃”:仅询问一种状态——放纵、清淡/舒适、快速/方便、燥热或食欲不振。运行mark-latest-action --action reject_all --feedback-text '状态',然后生成新一批。6或 “我吃了别的”:询问实际吃了什么,除非已说明。- 自然语言描述的实际餐食:立即标记并记录。实际行为优先于先前的选择。
- 短期短语,如“最近别推荐面”或“这周少吃辣”:使用
add-memory --scope short_term保存并设置过期时间。 - 长期短语,如“我不吃香菜”或“我喜欢有汤汁的”:更新用户画像;安全约束放入 restrictions,一般不喜欢的东西放入
disliked_foods或disliked_forms。
示例:
python3 scripts/meal_memory.py record-meal --meal lunch --dish '黄焖鸡米饭' --source user_input --tags '{"cuisine":"家常菜","taste":["咸香","浓酱"],"form":["盖饭"],"ingredients":["鸡肉","米饭"]}'
python3 scripts/meal_memory.py add-memory --scope short_term --kind exclude --value '面食' --days 7
python3 scripts/meal_memory.py rate-latest-meal --satisfaction satisfied
餐后满意度最多询问一次。如果用户忽略两次跟进,则停止主动询问。在用户自愿记录餐食后,不要强制进行满意度确认。
安全边界
- 不提供医疗诊断或医学级别的饮食计划。
- 对于怀孕、手术恢复、严重慢性病、饮食失调或严重过敏,保持建议一般性,并建议咨询合格的临床医生或营养师。
- 不鼓励极端限制、暴食、催吐或补偿性行为。
- 保持健康提醒简短且不带评判。
- 不虚构附近的餐厅、商家、价格、可购买性或订购链接。
在检查或修复存储状态时,使用 references/state-schema.md。