文章用优惠券和点餐约束说明,组合决策不宜依赖大模型逐步算数。提出由模型解析意图和表达结果、脚本负责计算与确定性处理的分工模式。
你有两张 McDonald's 优惠券,但只能用一张:
你点了一个 ¥25 的汉堡:
满减券:还得再凑 ¥15 → 实付 ¥30
折扣券:25 × 0.88 = ¥22 → 折扣券更划算
现在,把汉堡的价格换成 ¥40:
满减券:实付 ¥30 → 满减券更划算
折扣券:实付 ¥35.2
哪张优惠券更省钱,完全取决于订单里有什么。不存在一个通用答案。
这还只是两张优惠券、一件商品。真实订单可能涉及三张优惠券、二十件商品,还要满足“两个人吃、不到 ¥50、控制在 1100 kcal 以内、蛋白质至少 35g”这样的约束。满足所有条件的组合,数量能达到几千种。
让 LLM 来解决,你会得到三个意料之中的结果:
慢——几千次乘加运算,都得逐个 token 生成。
贵——每一步都在消耗 token。
错——试过的人都知道,LLM 的算术就是这么回事。
所以,这个项目从一条原则出发:
LLM 负责理解和表达,脚本负责计算和确定性。
User speaks plainly
│ "two people, under ¥50, nothing too greasy"
▼
LLM (WorkBuddy) parses intent ──► hard constraints
│ max_payable=45, max_calories=1100, min_protein=35
▼
McDonald's MCP fetches real data ──► store menu / nutrition / coupons
│
▼
optimize_meal.py (local, no network) ──► enumerate + best-coupon match
│
▼
LLM turns results back into plain language ──► three plans
收益很直接:脚本只需几毫秒就能运行完,结果可复现,不消耗任何 token,而且绝不会算错金额。
枚举是算术问题,不是语言问题。它就是笛卡尔积加上约束过滤:1–2 份主食 + 0–1 份配餐 + 0–1 份饮料 + 0–1 份甜点。过程确定,没有歧义,也不需要什么“理解”。用概率模型做确定性计算,就是用错了工具。
优惠券匹配有一个模型容易忽略的约束:每笔订单只能使用一张优惠券。所以,你不能直接选面额最大的那张。你必须计算这笔具体订单到底能省多少:是否达到满减门槛、折后总价是多少、是否符合品类限制。只有枚举才能算对。
排序目标有三种。最便宜,按总价升序排列;最健康,按与目标的偏差升序排列;性价比最高,按每元钱能买到的蛋白质降序排列。三种排序都基于同一组候选方案。这是脚本该做的事。
分工的另一半,是减少模型的工作量,同时保留它的价值。
把模糊的语言转成明确的约束。“两个人吃” → 提高蛋白质目标。“别太油腻” → 可能是设置热量上限,也可能是排除油炸品类。“不到 ¥50” → max_payable = 45,为客户端看不到的配送费和包装费留出余量。脚本做不了这种映射,模型却很擅长。
把结构化输出解释清楚。脚本输出 JSON,模型负责说明为什么选这个方案,而不是另一个。
边界很清楚:模型负责转换和讲解,不负责计算,也不负责记忆。
这个项目有一条硬性规定:每个数字都必须来自 MCP,不能硬编码。LLM 记忆中的快餐菜单可能已经过时、并不完整,偶尔还会凭空编造。更重要的是:
同一家连锁品牌,不同门店提供的商品和优惠券也不一样。
所以,流程必须是:先确认门店,再获取菜单和优惠券。测试时,我差点直接通过关键词搜索选定一家门店,结果搜出来的全在火车站里。如果替用户选了其中一家,用户可能根本不在附近,订单也就白下了。这件事最终变成了 skill 中最严格的一条规则:门店必须由人确认,绝不能靠猜。
"type": "streamablehttp"
WorkBuddy 只接受 camelCase:
"type": "streamableHttp" // works
"type": "streamablehttp" // not recognized
我是通过查看 WorkBuddy 内置的 connector 列表,反向摸清这一点的——所有内置 connector 都使用 camelCase。当文档和客户端的行为不一致时,就拿内置配置来对照。
配置路径。很多教程说配置文件在 ~/.workbuddy/mcp.json。真正生效的路径却是 ~/.workbuddy-ai/mcp.json。~/.workbuddy/ 这个目录确实存在,只不过里面放的是 device-id 和日志,不是配置。
配置好不等于启用。写完配置后,你还得在自定义 connector 面板里启用这个 server,否则客户端不会加载它。
用一次原始 JSON-RPC 调用来验证,别只相信 UI——一次 tools/list 请求与响应返回了 35 个工具。
本地计算引擎算出的总价只是估算。配送费、包装费和门店促销信息,只存在于服务端。展示任何方案之前,都要把其中的商品编码交给计价工具,再核对价格——两边不一致时,以服务端为准。跳过这一步,用户就会发现你算出来的金额和实际付款金额对不上。
这个项目最有价值的部分,不是最便宜的套餐组合,而是这种分工:
LLM 负责理解和表达,脚本负责计算和确定性,MCP 负责提供可信数据。
如果你正在做任何需要决策的应用——选餐、选商品、排日程、比价格——这套三部分结构都可以直接借鉴。
代码仓库:minxin88/mcd-meal-optimizer
采用 MIT 许可证,只使用 Python 标准库,零依赖。运行 python scripts/optimize_meal.py --demo,就能体验枚举和优惠券匹配流程,不需要消耗 token——它使用的是随项目附带的离线示例数据,并不是真实门店的价格。
范围限制:不下单、不领券、不取消订单,门店选择始终需要人工确认。仅限个人、非商业用途。
如需采取进一步行动,你可以考虑屏蔽此人,和/或举报滥用行为。