| name | mcd-solver |
|---|---|
| description | 麦当劳点单决策求解器。当用户提到想吃麦当劳、问麦当劳怎么点划算、控卡/控钠怎么吃麦当劳、给我配一个 XX 大卡以内的麦当劳套餐、预算 XX 元吃麦当劳、麦当劳营养搭配时使用。在预算、热量、钠、蛋白质的约束下,求解满足感最高的组合,并给出省钱派/嘴馋派/均衡派三套方案。 |
今天麦什么 · 麦当劳点单求解器
一句话说明白:给我预算、热量上限和一个心情,我给你麦当劳的最优解。
不是菜单查询,不是领券脚本。它把「怎么点」建模成一个带约束的优化问题—— 预算、热量、钠、蛋白质是约束,目标函数是满足感,而不是「最便宜」。
何时使用
- 用户说「想吃麦当劳,但今天只能吃 800 大卡」
- 用户关心咸不咸、钠高不高(例如血压敏感、健身控钠)
- 用户有预算上限,想知道这点钱怎么点最爽
- 用户在几个套餐之间犹豫,想要一个带理由的建议
不适用:领券、查积分、查历史订单,那是麦当劳 MCP 其他工具的事。
下单可以在给出方案后通过 cli.py --quote --place 完成。
快速开始
无需 MCP Token 也能跑(营养数据来自麦当劳官网公开营养计算器):
python cli.py --max-kcal 800 --max-sodium 2000 --persona all
新人第一次用,或环境看起来不对(比如提示数据缺失)时,先跑一键体验, 它会自动建营养快照并连跑三个示例:
python scripts/quickstart.py
怀疑改动破坏了什么时跑离线自检(26 项,无需 Token):
python scripts/selftest.py
有 Token 时先校准真实价格,预算约束才会生效:
export MCD_MCP_TOKEN=你的Token
python scripts/fetch_menu.py # 抓取在售菜单与价格 -> data/menu.json
python scripts/verify_prices.py # 校准官方结算价 -> data/prices_verified.json
python scripts/coupons.py --calibrate # 折算券后价 -> data/prices_coupon.json(有券时)
python cli.py --budget 45 --max-kcal 1200 --persona all
注意:菜单列表里的 price 字段可能是「起价」,实测有商品标 ¥9.9 而
实际结算 ¥23.0。跳过 verify_prices.py 会让预算系统性低估,所以只要用了
--budget,就该先跑一次校准。
首次使用需先建营养快照(约 2 分钟,无需 Token):
python scripts/fetch_nutrition_web.py
参数
| 参数 | 说明 |
|---|---|
--budget | 预算上限(元)。需要价格数据,否则不生效 |
--max-kcal | 热量上限(千卡) |
--max-sodium | 钠上限(毫克)。中国居民膳食指南推荐每日不超过 2000mg |
--min-protein | 蛋白质下限(克),健身场景用 |
--max-items | 最多几件,默认 5 |
--persona | value 省钱派 / indulge 嘴馋派 / balance 均衡派 / all |
--coupons | 逐张试算卡包里的券,输出本单最优用券与加购建议(需 Token) |
--quote | 用 MCP calculate-price 复核官方券后价(需 Token) |
--place | 复核后创建真实订单(需 Token,且需人工确认) |
--city / --store-code | 复核与下单用的城市 / 指定门店 |
--json | 机器可读输出,便于接入其他 Agent |
券优化
用户问「我有什么券」「用哪张券划算」「要不要凑单」时走这里:
python scripts/coupons.py --city 常州 # 查看可领券 / 卡包 / 本店可用券
python scripts/coupons.py --city 常州 --bind # 一键领取(账号写操作,需用户授权)
python scripts/coupons.py --city 常州 --calibrate # 折算券后价,供求解器直接使用
python cli.py --budget 45 --persona all --coupons # 求解并逐张试算券
仓库内置的 menu / price 快照来自 常州市 · 麦当劳常州万象城餐厅。 换城市时三个脚本都要用同一个
--city重跑一遍。
两个必须讲清的点:
- 券接口不返回面额,只给
couponId。所以「这张券值多少钱」只能带着couponId去问calculate-price。别试图从券名里猜金额。 - 券要先折算成券后价再求解,而不是求解完再挑券。后者几乎永远命中不了, 因为方案里恰好没有那件商品。
--bind 会改变用户账号状态(领券),属于写操作,动手前先问一句。
复核与下单
# 求解并让官方复核总价(推荐:求解器的估算是按单价累加的,真实券后价只有官方知道)
python cli.py --budget 45 --persona all --quote
# 确认后下单。默认只试算,--place 会要求手动输入金额才放行
python cli.py --budget 45 --persona balance --quote --place
create-order 创建的是真实订单,但麦当劳的流程是创建后仍需用户自己在
APP 或支付链接完成付款——本 Skill 不会代为支付。向用户说明时务必讲清这点。
三种人设
同一套模型,不同权重:
- 省钱派
value—— 性价比权重最高,把钱花在刀刃上 - 嘴馋派
indulge—— 口感层次与温度反差权重最高,预算内吃爽 - 均衡派
balance—— 健康惩罚权重最高,控钠控油
满足感是怎么算的
S = 固有满足度 # 每个单品的口感愉悦分,来自 taste.py 的口味先验
+ 口感层次奖励 # 酥脆/多汁/冰爽/奶香…覆盖维度越多越爽,边际递减
+ 温度反差奖励 # 热汉堡配冰可乐 > 全是热食
+ 结构完整奖励 # 主食/小食/饮料/甜品的齐备度;没主食不成一顿饭
- 同类堆叠惩罚 # 三个汉堡不叫一顿饭
- 健康软惩罚 # 钠与脂肪,渐进扣分(钠占每日推荐一半起就开始罚)
+ 性价比愉悦 # 省得越多越开心(需价格)
求解用分层束搜索:按主食 → 小食 → 饮料 → 甜品逐层扩展, 每层只保留最有希望的部分分支;热量、钠、花费单调累加,超约束当场剪枝。 菜单展开后有上百个可选项,穷举不可行,束搜索秒级出解。
向用户解释结果时注意
- 说清每个方案为什么被选中,而不只是报菜单
- 强调钠:很多人以为鸡腿堡比牛肉堡健康,实际上板烧鸡腿堡钠 1041mg, 比巨无霸的 961mg 还高。这类反直觉结论最有用。
- 给出边际建议:「再加 2 元可以换成…」比单纯报价格更有说服力
- 营养数据以麦当劳官方公布为准,实际出品可能存在差异,需说明
边界
- 本 Skill 主要做决策,下单须用户明确要求并自行确认金额
- 价格随地区、时段、活动浮动,以门店实际为准
- 数据范围为麦当劳中国大陆,不含港澳台
- 营养数据只作决策辅助,不构成医疗或营养建议
