
最近餐饮圈最火的一个词大概就是 AI 大厨了。从 30 秒出一杯拉花咖啡的机械臂到 3 分钟炒完一道菜的全自动炒菜机再到后厨大屏幕上实时滚动的智能调度看板AI 正在从概念走向真实的后厨操作间。作为开发者与其感叹“又要被 AI 抢饭碗了”不如趁这个机会拆一拆这套系统背后的技术栈。本文会从 AI 智慧厨房的整体架构出发聊清楚食材识别、菜谱推荐、出餐调度分别用了哪些技术然后带大家用 Python FastAPI 从零实现一个可运行的 AI 厨房 Demo。这个 Demo 会模拟完整的业务闭环输入一张食材照片系统识别食材、推荐菜谱、生成订单、调度出餐。不管你是做后端、做算法还是准备转行 AI 应用开发这篇文章都值得收藏读完可以直接把代码跑起来。1. AI 大厨来了智慧餐饮的技术全景1.1 什么是 AI 大厨和智慧厨房很多同学听到“AI 大厨”四个字第一反应是一个长得像阿童木的人形机器人在灶台前面颠勺炒菜。实际上这个画面只是大众传播里最夸张的一种想象。真实餐饮场景中的“AI 大厨”是一套软硬件协同的自动化系统它由多个独立模块组合而成视觉识别模块负责“看见”比如识别食材种类、判断菜品熟度、检查异物。设备控制模块负责“动手”比如控制机械臂、炒菜机、咖啡机、烤箱。调度决策模块负责“思考”比如订单先做谁、哪个设备空闲、怎么排产最快。数据与中台模块负责“记忆”比如库存变化、口味偏好、销量预测。从专业定义上看智慧厨房是以计算机视觉、机器人控制、物联网、运筹优化和 AI 算法为核心对传统后厨“人、机、料、法、环”进行数字化重构的一套系统。它不一定要有一个完整的机器人形态只要把某个环节用 AI 替代并提升了效率就可以算作智慧厨房的组成部分。这里要特别澄清一个容易混淆的概念AI 大厨不等于自动烹饪设备。传统自动炒菜机只是按照固定程序加热翻搅本质上是一个可编程的电器没有感知和决策能力。而 AI 大厨强调的是闭环设备从视觉和传感器获取状态算法根据状态动态调整策略再通过控制系统执行操作。简单说一个是“按剧本演”一个是“根据现场情况临场发挥”。1.2 智慧餐饮解决的三个核心问题餐饮行业是典型的劳动密集型行业后厨又是整个餐厅里成本最高的地方。智慧餐饮之所以在最近几年加速落地本质上是因为它同时切中了三个痛点。第一是人力成本。熟练厨师的培养周期长达数年而且流动性极高。一家连锁餐厅如果要保证每家分店口味一致只能靠店长反复培训和督导。AI 设备一旦调试完成可以在不休息、不离职、不发情绪的情况下持续生产边际成本很低。第二是标准化。人类厨师炒菜存在天然的随机性火候差几秒、调料差几克出品就不一样。AI 系统通过传感器和视觉反馈可以把温度、时间、投料量控制在一个很窄的区间内让“中央厨房的味道”复制到每一家门店。第三是出餐效率。高峰期订单集中涌入后厨一旦排产不当就会积压导致顾客投诉。AI 调度系统可以结合订单到达时间、每道菜的工序时长、设备占用情况实时给出最优排产方案。这就是标题里“3 分钟出餐、30 秒一杯咖啡”背后的工程支撑。下面用一张表快速对比传统厨房和智慧厨房的差异维度传统厨房智慧厨房出品一致依赖厨师经验依赖算法和传感器出餐效率高峰期容易积压调度系统动态排产人力投入高中后期明显下降数据沉淀几乎没有完整的过程数据扩张复制需要反复培训标准化部署故障处理厨师临场应变系统报警 人工接管1.3 当前主要的落地场景除了一锅一菜的中餐炒菜机器人AI 在餐饮领域的落地场景其实非常丰富以下是目前实际商用较多的几类智能咖啡机。机械臂配合视觉识别能完成磨豆、压粉、萃取、拉花全流程单杯出品时间可以压到 30 秒左右。部分设备还能通过视觉判断奶泡厚度实现“千人千面”的拉花图案。AI 炒菜机器人。通常由滚筒式炒锅、自动投料系统、温控系统和视觉熟度检测组成。中央厨房提前把调料封装成料包机器人按序投料预计熟度达到阈值后自动出锅。视觉识别结算台。食堂和快餐店最常见的 AI 应用摄像头识别餐盘中的菜品自动计算价格并完成结算不需要人工逐个输入。后厨智能调度系统。把订单、设备、厨师任务统一放进调度中心按最短加工时间、设备负载等规则自动派单后厨只需要按照屏幕指令执行。食材库存预测与采购优化。基于历史销量、天气、节假日等数据预测未来几天需求生成采购建议降低食材损耗。AI 点餐与推荐。结合会员画像和营养标签在点餐环节推荐菜品这部分越来越多地用到 NLP 和大模型能力。这些场景看起来分散但底层技术高度重合视觉、控制、调度、数据。这也是本文要把它们串起来讲的原因——你只要把一个闭环跑通其他场景基本就是换设备和换数据的问题。2. 核心技术栈AI 厨房背后有哪些技术2.1 计算机视觉让机器“看见”食材视觉是 AI 厨房最核心的感知手段。以食材识别为例它通常走的是目标检测路线先检测出图像中的每个食材再分类出具体品种。目前工程上常用 YOLO 系列、RT-DETR、MMDetection 等框架模型输出的是目标框坐标、类别和置信度。但在真实后厨场景食材识别比停车场车牌识别难很多番茄有红黄绿多种颜色土豆表面带着泥土牛肉纹理千差万别再加上后厨灯光偏暖、蒸腾的水汽、砧板上残留的汁液都会干扰模型。因此工程上通常不会只依赖一个通用模型而是组合多条视觉链路目标检测模型负责定位和粗分类辅助分类模型负责细分比如把牛肉区分为牛腩、牛里脊、肥牛颜色直方图和纹理特征用于判断新鲜度和熟度异常检测模型用于识别异物、焦糊、生熟混放等安全隐患。在本文的 Demo 里为了让大家不依赖 GPU 也能跑起来我会先用 OpenCV 的颜色范围检测做一版简化实现并在代码注释中说明如何替换成 YOLO 等真实检测模型。2.2 机器人与自动化设备控制感知到食材之后下一步是执行。机械臂要完成“拿取食材—投料—翻炒—出锅”这一连串动作涉及运动规划、轨迹插补、力控制和末端执行器设计。运动规划听起来很高深但在工业界已经相当成熟。机械臂通常使用 ROS 2 或者厂商自带的 SDK 进行控制核心计算包括逆运动学求解、避障路径规划和速度控制。对于炒菜机器人来说真正的难点不是机械臂本身而是如何与厨具、灶具、排风系统配合什么时候开火、火开多大、什么时候投料、翻炒频率多少这些都需要 PLC可编程逻辑控制器与机器人控制器协同完成。设备通信层常用协议包括 Modbus、OPC-UA、MQTT设备状态通过传感器上传到边缘网关再转发给调度系统。这里有一个很实际的工程问题机械臂厂家、锅具厂家、灶具厂家往往来自不同供应商协议各不相同。所以智慧厨房项目通常要有一个设备接入层统一把各厂商的 API 封装成标准接口屏蔽底层差异。2.3 推荐与决策算法有了食材信息之后系统需要回答“能做什么菜”。最基本的方案就是基于食材覆盖率的匹配把菜谱需要的食材和当前库存做集合运算覆盖率高就优先推荐。更进一步可以引入线性规划或约束求解在库存、保质期、价格、营养、口味偏好等多个目标之间求最优解。举个实际的例子某连锁餐厅剩了 20 份鸡胸肉、15 份西兰花、8 份洋葱第二天还有一批牛肉到货。系统要决定今晚的推荐菜和半成品加工顺序使得食材损耗最小、人力排班最均匀。这类问题可以建模为一个带约束的优化问题用 OR-Tools 或 PuLP 求解。最近大模型也进入了这个领域。基于大模型的菜谱生成可以根据用户输入的口味、忌口、剩余食材生成新的菜谱和做法步骤也可以结合语音识别实现“对着一台咖啡机说一句话就下单”的交互体验。不过大模型输出存在幻觉问题生成结果必须经过规则校验才能进入生产流程尤其是涉及食品安全时不能盲目相信模型输出的所有内容。2.4 调度系统与任务编排后厨高峰期的核心矛盾是订单多、设备少、每道菜工序时长不同。调度系统负责把订单安排到合适的设备和时间段上。调度问题在计算机领域有大量的研究成果常见策略包括先来先服务适合订单量平稳的场景最短加工时间优先适合追求出餐速度的场景优先级调度VIP 订单、外卖订单可以插队多设备负载均衡避免一台炒菜机排队太长、另一台空转。在复杂的门店调度系统还要考虑实际约束荤素要分锅避免串味同一订单的多道菜要尽量同时出餐某个设备在高峰期前需要清洁保养。所以真正上线的调度系统不是一个简单的队列而是一个实时事件驱动的任务编排引擎通常用消息队列 状态机实现。从工程视角看这个调度器和 AI Agent 的思路非常像Agent 感知环境状态订单、设备、库存通过策略做出动作分配任务、调整顺序最后收集反馈并更新队列。这也是目前 AI Agent 开发热潮中大家常拿“餐厅调度”当例子来讲解的原因。2.5 IoT 与数据中台闭环的最后一公里AI 厨房如果没有数据反馈就只是一个远程控制的自动化设备。真正让系统变聪明的是数据闭环每一次出餐时间、温度曲线、顾客评价、食材损耗都被记录算法在这些数据上持续迭代。传感器负责采集温度、湿度、油烟浓度、设备开关状态边缘网关负责数据预处理和低延迟控制云端负责模型训练、库存分析和门店间的数据对比。这里推荐采用“边缘优先 云端增强”的架构实时控制逻辑放在边缘批量分析和模型训练放在云端避免因网络抖动导致设备失控。3. 环境准备与版本说明在动手写代码之前先把本地环境准备好。本文运行环境以 Python 3.10 为例如果你本地是 3.8 或 3.11大部分代码也能直接运行但建议尽量使用 3.10 及以上版本避免类型注解语法不兼容。需要安装的核心依赖如下FastAPI提供 Web API 服务UvicornASGI 服务器用于启动 FastAPIPydantic数据模型和参数校验OpenCV-Python图像识别示例NumPy数组与矩阵运算Python-Multipart部分请求体解析需要。安装命令pip install fastapi uvicorn[standard] pydantic opencv-python numpy python-multipart如果你的网络环境安装较慢可以指定国内镜像源pip install fastapi uvicorn[standard] pydantic opencv-python numpy python-multipart -i https://pypi.tuna.tsinghua.edu.cn/simple版本方面以上依赖在 2024 年之后的版本都能正常工作。实际项目上线时建议锁定固定版本号避免间接依赖升级导致行为变化。本文示例代码以 fastapi 0.100、pydantic 2.x 兼容写法为主如果你使用 pydantic 1.x需要把部分模型定义稍微调整一下。为了方便阅读下面给出我们即将创建的项目目录结构ai_kitchen/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 入口 │ ├── config.py # 全局配置 │ ├── data/ │ │ ├── __init__.py │ │ └── recipes.py # 菜谱种子数据 │ ├── models/ │ │ ├── __init__.py │ │ ├── ingredient.py # 食材数据模型 │ │ └── recipe.py # 菜谱数据模型 │ └── services/ │ ├── __init__.py │ ├── recognizer.py # 食材识别服务 │ ├── recommender.py # 菜谱推荐服务 │ └── scheduler.py # 出餐调度服务 ├── requirements.txt └── README.md4. 实战案例从零实现一个 AI 智慧厨房 Demo4.1 项目目标与整体流程我们这个 Demo 的目标是模拟一个完整的智慧厨房业务闭环整个流程可以拆成四步用户上传一张食材照片或者直接指定一批食材识别服务输出食材清单推荐服务基于食材清单匹配可制作的菜谱用户选择菜谱下单调度服务按时间片模拟出餐。虽然真实项目里的视觉识别和机械臂控制非常复杂但 Web 服务这一层的逻辑是完全一致的。我们把这一层做透后续替换视觉算法和设备通信模块就是水到渠成的事。4.2 定义数据模型与菜谱种子数据先在app/models/ingredient.py中定义食材模型# 文件路径ai_kitchen/app/models/ingredient.py from typing import Optional from pydantic import BaseModel, Field class Ingredient(BaseModel): 食材信息 id: Optional[int] None name: str Field(..., description食材名称) category: str Field(蔬菜, description食材分类) stock: int Field(0, description库存数量) unit: str Field(份, description计量单位)然后在app/models/recipe.py中定义菜谱模型# 文件路径ai_kitchen/app/models/recipe.py from typing import List from pydantic import BaseModel class Recipe(BaseModel): 菜谱信息 id: int name: str ingredients: List[str] time_seconds: int difficulty: int 1 # 难度 1-5 category: str 中餐菜谱种子数据放在app/data/recipes.py中这里我准备了六道常见菜品和饮品覆盖快手菜、家常菜、荤菜和咖啡类# 文件路径ai_kitchen/app/data/recipes.py from app.models.recipe import Recipe RECIPES [ Recipe(id1, name番茄炒蛋, ingredients[番茄, 鸡蛋, 盐], time_seconds180, difficulty1, category快手菜), Recipe(id2, name青椒土豆丝, ingredients[青椒, 土豆, 醋], time_seconds240, difficulty2, category家常菜), Recipe(id3, name黑椒牛柳, ingredients[牛肉, 洋葱, 黑胡椒], time_seconds300, difficulty3, category荤菜), Recipe(id4, name蒜蓉西兰花, ingredients[西兰花, 大蒜, 盐], time_seconds210, difficulty2, category素菜), Recipe(id5, name美式咖啡, ingredients[咖啡豆, 水], time_seconds30, difficulty1, category饮品), Recipe(id6, name拿铁, ingredients[咖啡豆, 牛奶, 水], time_seconds45, difficulty2, category饮品), ]这里的time_seconds是标准制作时间实际项目中应该由设备上报的真实数据替换而不是写死在配置里。4.3 实现食材识别服务食材识别模块是整个系统里最像“AI”的部分。为了让 Demo 更容易跑起来我提供两种模式mock模式直接返回预置的食材列表适合没有摄像头的场景cv模式使用 OpenCV 的颜色范围检测识别食材适合本地有图片文件的场景。完整代码如下# 文件路径ai_kitchen/app/services/recognizer.py 食材识别服务 - mock 模式无图像依赖直接返回预置食材适合快速体验流程 - cv 模式使用 OpenCV 颜色范围做简单识别生产环境建议替换为目标检测模型。 from typing import List # 预置食材颜色特征表使用 BGR 颜色空间的 [下限, 上限] # 注意真实场景需要基于标注数据训练目标检测模型这里只是演示 COLOR_PROFILES { 番茄: ((0, 50, 140), (60, 130, 255)), 青椒: ((40, 60, 50), (90, 200, 180)), 土豆: ((20, 100, 140), (80, 200, 230)), 鸡蛋: ((20, 90, 140), (60, 180, 230)), 牛肉: ((0, 20, 50), (60, 100, 160)), 西兰花: ((40, 80, 60), (90, 200, 160)), } MOCK_INGREDIENTS [番茄, 鸡蛋, 青椒, 土豆] class IngredientRecognizer: 食材识别器 def __init__(self, threshold: float 0.02): self.threshold threshold def recognize(self, image_path: str , mode: str mock) - List[dict]: 识别图片中的食材 :param image_path: 图片路径cv 模式必填 :param mode: mock 或 cv :return: 食材列表如 [{name: 番茄, confidence: 0.95}] if mode mock: return [{name: name, confidence: 0.95} for name in MOCK_INGREDIENTS] return self._recognize_by_color(image_path) def _recognize_by_color(self, image_path: str) - List[dict]: 基于颜色直方图的简化识别实现 try: import cv2 import numpy as np except ImportError: raise RuntimeError(使用 cv 模式前请安装 opencv-python) image cv2.imread(image_path) if image is None: raise ValueError(f无法读取图片: {image_path}) height, width image.shape[:2] total_pixels height * width results [] for name, (lower, upper) in COLOR_PROFILES.items(): mask cv2.inRange( image, np.array(lower, dtypenp.uint8), np.array(upper, dtypenp.uint8), ) ratio cv2.countNonZero(mask) / total_pixels if ratio self.threshold: # 简单映射颜色占比越高置信度越高 confidence round(min(ratio * 5, 0.99), 2) results.append({name: name, confidence: confidence}) return results这里需要解释几个关键点。第一cv2.inRange的作用是把图像中位于指定颜色范围内的像素标为白色其他区域标为黑色然后通过countNonZero统计白色像素数量再除以总像素得到颜色占比。第二颜色阈值是我基于常见食材在普通摄像头下的颜色经验值设定的不同灯光条件下偏差会很大因此这套实现只适合演示。第三真实项目中的视觉模块应该使用 YOLO 等目标检测模型检测菜板上的食材位置和类别同时配合数据增强来解决灯光、遮挡、泥土干扰等问题。4.4 实现菜谱推荐服务菜谱推荐服务的核心逻辑是计算“食材覆盖率”。所谓覆盖率就是菜谱所需食材中有多少比例是当前已有的。覆盖率越高说明这道菜越容易立刻制作。# 文件路径ai_kitchen/app/services/recommender.py from typing import List from app.data.recipes import RECIPES class RecipeRecommender: 菜谱推荐服务 def recommend(self, available_ingredients: List[str], max_difficulty: int 5) - List[dict]: 根据已有食材推荐菜谱 :param available_ingredients: 当前可用食材列表 :param max_difficulty: 最大难度用于过滤 :return: 排序后的推荐列表 available_set set(available_ingredients) results [] for recipe in RECIPES: if recipe.difficulty max_difficulty: continue need_ingredients set(recipe.ingredients) matched need_ingredients available_set coverage len(matched) / len(need_ingredients) # 覆盖率低于 50% 的菜谱不推荐避免推荐成品率太低 if coverage 0.5: continue results.append({ id: recipe.id, name: recipe.name, coverage: round(coverage, 2), missing: list(need_ingredients - available_set), time_seconds: recipe.time_seconds, difficulty: recipe.difficulty, }) # 优先推荐覆盖率高的覆盖率相同时推荐耗时短的 results.sort(keylambda x: (-x[coverage], x[time_seconds])) return results推荐结果里包含missing字段这个字段很有用。门店端看到“番茄炒蛋”只缺“盐”可以直接补货或者提示顾客供应链端可以把所有订单的缺失食材汇总生成采购清单。这其实就是推荐系统在实际业务里的价值延伸。不过也要注意覆盖率只是最基础的推荐策略。真实系统还需要考虑食材保质期、库存成本、营养搭配和顾客口味。比如食品快到保质期时推荐算法应该适当提高包含该食材的菜谱权重糖尿病患者下单时应该过滤高糖菜品。这些可以看作约束条件叠加在覆盖率排序之上。4.5 实现出餐调度服务调度服务模拟的是后厨的排产过程。我用一个先进先出队列保存订单每次“调度步进”给每个订单分配一个时间片默认 30 秒订单的剩余时间减到 0 就表示出餐完成。实现代码如下# 文件路径ai_kitchen/app/services/scheduler.py import time from collections import deque from typing import Dict, List class Order: 订单模型 def __init__(self, order_id: str, dish_name: str, time_seconds: int, created_at: float): self.order_id order_id self.dish_name dish_name self.time_seconds time_seconds self.remaining time_seconds self.created_at created_at self.status pending class KitchenScheduler: 出餐调度器时间片轮转模拟 def __init__(self): self.queue deque() self.order_counter 0 def add_order(self, dish_name: str, time_seconds: int) - str: 新订单加入调度队列 self.order_counter 1 order_id fO{self.order_counter:04d} order Order(order_id, dish_name, time_seconds, time.time()) self.queue.append(order) return order_id def run_step(self, time_slice: int 30) - Dict: 执行一轮调度每个订单最多消耗一个时间片 :param time_slice: 时间片长度秒 :return: 本轮完成和等待中的订单 finished [] for _ in range(len(self.queue)): order self.queue.popleft() order.remaining - time_slice if order.remaining 0: order.status done finished.append({ order_id: order.order_id, dish_name: order.dish_name, actual_time: order.time_seconds, status: done, }) else: order.status cooking self.queue.append(order) waiting [ { order_id: o.order_id, dish_name: o.dish_name, remaining: o.remaining, status: o.status, } for o in self.queue ] return {finished: finished, waiting: waiting} def run_full(self, time_slice: int 30, max_steps: int 100) - Dict: 模拟执行到所有订单完成返回每一步的结果 steps [] step_index 1 while self.queue and step_index max_steps: result self.run_step(time_slice) result[step] step_index steps.append(result) step_index 1 return {steps: steps, total_steps: len(steps)} def get_queue(self) - List[dict]: 查看当前队列状态 return [ { order_id: o.order_id, dish_name: o.dish_name, remaining: o.remaining, status: o.status, } for o in self.queue ]这里使用的是最简单的时间片轮转算法它的优点是公平缺点是可能不是最优。比如一份美式咖啡只要 30 秒一份黑椒牛柳要 300 秒如果黑椒牛柳先到美式咖啡就会被一直排在后面。真实场景里我们应该用最短加工时间优先或带优先级的调度策略把饮品这类短工序订单插到前面避免顾客等咖啡等太久。这一点我会在第五节和第六节详细展开。4.6 编写 FastAPI 入口最后把三个服务串起来对外提供 HTTP 接口。app/main.py完整代码如下# 文件路径ai_kitchen/app/main.py from typing import List, Optional from fastapi import FastAPI from pydantic import BaseModel from app.services.recognizer import IngredientRecognizer from app.services.recommender import RecipeRecommender from app.services.scheduler import KitchenScheduler app FastAPI(titleAI 智慧厨房 Demo, version0.1.0) recognizer IngredientRecognizer() recommender RecipeRecommender() scheduler KitchenScheduler() class RecognizeRequest(BaseModel): image_path: str mode: str mock class RecommendRequest(BaseModel): ingredients: List[str] max_difficulty: int 5 class OrderRequest(BaseModel): dish_name: str time_seconds: Optional[int] None app.get(/) def index(): return {message: AI 智慧厨房服务运行中} app.post(/recognize) def recognize(req: RecognizeRequest): 食材识别 ingredients recognizer.recognize(req.image_path, modereq.mode) return {ingredients: ingredients} app.post(/recommend) def recommend(req: RecommendRequest): 菜谱推荐 recipes recommender.recommend(req.ingredients, req.max_difficulty) return {recipes: recipes} app.post(/order) def create_order(req: OrderRequest): 创建订单并加入调度队列 # 如果前端没有传标准时长则根据菜谱数据自动匹配 time_seconds req.time_seconds if time_seconds is None: from app.data.recipes import RECIPES match [r for r in RECIPES if r.name req.dish_name] if match: time_seconds match[0].time_seconds else: time_seconds 300 order_id scheduler.add_order(req.dish_name, time_seconds) return {order_id: order_id, status: pending} app.post(/schedule/step) def schedule_step(time_slice: int 30): 执行一轮调度 return scheduler.run_step(time_slice) app.post(/schedule/run) def schedule_run(time_slice: int 30): 模拟执行直到所有订单完成 return scheduler.run_full(time_slice) app.get(/queue) def get_queue(): 查看当前调度队列 return {queue: scheduler.get_queue()}接口设计上我把识别、推荐、下单、调度拆成了四个独立接口这样每个环节都可以单独测试。实际生产系统中一般会把这些操作编排到一个流程引擎里用一个事务 ID 串联整个链路方便追踪问题。4.7 安装依赖并启动服务按照前面给出的依赖清单安装完成后在项目根目录执行uvicorn app.main:app --reload --port 8000启动成功后终端会显示类似下面的日志INFO: Uvicorn running on http://127.0.0.1:8000 INFO: Application startup complete.这时浏览器访问http://127.0.0.1:8000/docs就能看到 FastAPI 自动生成的 Swagger 接口文档页面。所有接口都可以直接在页面上点击调试这也是 FastAPI 适合快速开发工具类服务的重要原因。4.8 接口验证与效果演示我们先调用识别接口模拟“视觉模块识别出番茄、鸡蛋、青椒、土豆”curl -X POST http://127.0.0.1:8000/recognize \ -H Content-Type: application/json \ -d {mode: mock}预期返回{ ingredients: [ {name: 番茄, confidence: 0.95}, {name: 鸡蛋, confidence: 0.95}, {name: 青椒, confidence: 0.95}, {name: 土豆, confidence: 0.95} ] }然后把识别出的食材传给推荐接口curl -X POST http://127.0.0.1:8000/recommend \ -H Content-Type: application/json \ -d {ingredients: [番茄, 鸡蛋, 青椒, 土豆], max_difficulty: 3}预期返回中番茄炒蛋覆盖率为 1.0优先排在前面青椒土豆丝覆盖率为 0.67排在后面黑椒牛柳因为缺牛肉和黑胡椒覆盖率不足 50%不会被推荐。接着创建两个订单模拟高峰期场景curl -X POST http://127.0.0.1:8000/order \ -H Content-Type: application/json \ -d {dish_name: 黑椒牛柳} curl -X POST http://127.0.0.1:8000/order \ -H Content-Type: application/json \ -d {dish_name: 美式咖啡}最后执行完整的模拟调度curl -X POST http://127.0.0.1:8000/schedule/run?time_slice30返回结果会展示每一轮的调度过程。可以看到美式咖啡虽然下得晚但因为工序短比黑椒牛柳更早出餐完成。如果把时间片调成 10 秒每一步的粒度更细能更清楚地看到“排队—制作—出餐”的推进过程。5. 常见问题与排查思路在实际开发这类系统时大家遇到的问题往往比 Demo 里的业务逻辑复杂得多。下面是几个高频问题及排查思路。问题现象常见原因解决思路识别不出食材颜色阈值不匹配、模型训练数据不足检查灯光环境重新标定阈值替换为目标检测模型识别结果置信度虚高颜色区域重合或背景干扰增加背景分割统计目标框内像素而非全图推荐结果缺关键食材覆盖率阈值设置过高下调阈值或把“可替代食材”纳入匹配逻辑排队订单堆积调度策略不适合短工序优先改用最短加工时间优先或优先级队列菜品同时出餐需求不满足没有按订单维度聚合调度时按“订单”分组而非按单道菜排队机械臂控制超时网络抖动或设备协议不兼容增加超时重试统一设备接入层协议模型推理速度慢模型太大或没有用 GPU/加速框架模型蒸馏、量化使用 TensorRT 或 ONNX Runtime下面挑选两个最典型的场景展开说明。第一个是“识别不出食材”。如果你用的是 Demo 里的 OpenCV 颜色检测最常见的坑是后厨灯光偏暖色