气雾栽培咖啡的
系统一判断层
v0.1 草案的定位是对的:不做聊天机器人,做判断层。但要让它在真实温室里跑起来,还缺四样东西 —— 批次谱系(否则隔离半径算不出来)、置信度校准(否则 0.82 没有意义)、执行闭环(否则决策落不到阀门上)、 延迟标签管线(否则模型永远学不到东西)。本页把草案补成一套可实施的全栈规格,并附三个可亲手拨动的判断器。
设计评审:v0.1 的判断是对的,工程还差一层
评审用四个维度切入:可判定性(输入够不够判)、可执行性(判完能不能落地)、可学习性(落地后能不能变强)、可交付性(上线能不能撑住)。v0.1 在「可判定性」上完成度最高,缺口集中在后三项。
1.1 五条原则 → 五条机制 原则不落到机制上,就只是一句话
| 原则 | v0.1 的表述 | v1.0 落地机制 | 验收信号 |
|---|---|---|---|
| 决策原子化 | 拆成是/否、选一、打分三类节点 | 14 节点状态机 + 判断器注册表;每个节点只允许一个 jev_type,输出枚举闭合、禁止自由文本 | 单节点输出枚举 ≤4 个 |
| 快慢分离 | 高频快判,低置信度升级专家 | 三级路由:端侧快判 → 云端集成 → 专家/慢模型;升级由策略引擎决定,不由模型自述 | 快判覆盖率 ≥85% |
| 结构化输出 | 只输出决策、分数、置信度、标记 | JSON Schema 强校验 + reason ≤80 字 + 强制 evidence_refs(图像/传感器快照哈希) | 无证据的决策直接 400 |
| 低成本高频 | 事件触发,边缘批量推理 | 事件触发 + 微批 + INT8 量化 + 端侧常驻;云端只做争议样本 | 单次成本 <$0.001 |
| 反馈校准 | 用成活率/污染率回流标签 | 延迟标签表(label_ready_at)+ 校准层 + ECE 监控 + 主动学习队列 + 影子评估 | ECE <0.05,且复核一致率 ↑ |
1.2 十二条缺口 按「不补会怎样」排序,不按好看程度排序
只有 stage,没有批次谱系
可执行性stage 是个字符串,但污染一旦发生,真正要回答的是「隔离哪些盘、受影响几层架、哪批母株要停用」。没有 batch_id → 母株 → 托盘 → 架层 → 雾培槽 的谱系图,隔离半径算不出来,只能整温室停摆——这是雾培最贵的失败模式。blast_radius 作为独立候选动作进入 Choice(隔离多少盘本身就是一个决策)。置信度没有定义,也没有校准
可交付性confidence: 0.82 直接来自模型 softmax。视觉模型在训练分布外普遍过度自信(深度网络 ECE 常在 0.1–0.2),于是 0.82 可能对应真实 0.55 的正确率。用它做阈值,等于用一个没有刻度的仪表盘做手术。「污染」二元判定太粗,判对了也可能做错
可判定性true,下游只能靠人的记忆补全。标签是延迟到达的,管线里没有位置放它
可学习性label_ready_at + 回填任务)+ 双轨标签:训练用终局标签,监控用代理标签。传感器本身不可信,但没有质量闸门
可交付性sensor_health(漂移率 / 响应时间 / 双探头交叉校验 / 更换周期),任一 <0.6 → 决策降级为 need_more_info 或弃权,绝不静默使用。「建议调整营养雾」落不到阀门上
可执行性没有黄金集与回放,改阈值就是赌博
可学习性human_review 是个布尔,没有落地的地方
可执行性true 之后呢?谁看、多久内看完、不同意的怎么记?没有队列和理由分类,复核数据等于扔掉——而这恰恰是最贵的标签。objective 有权重,但没有成本函数
可交付性{survival, cost, quality} 权重有了,但没有东西去度量 cost。新农场/新品种没有冷启动方案
可学习性合规、审计与数据主权没进架构
可交付性0.7 / 80 / 60 这些阈值没有来源
可判定性τ_cost = C_FP /(C_FP + C_FN),再与运营下限取大 τ_hi = max(τ_cost, τ_min)——否则纯成本解会退化成「几乎全部隔离」;三区间(处置 / 复核 / 放行)替代二元;用决策曲线分析看净收益。1.3 三处必须修正的技术判断 不是补充,是方向性纠偏
C1 「低置信度才升级」这个规则本身有漏洞 高
只按置信度抽样,会系统性漏掉高置信度的错误——那才是真正贵的错误:模型对一整类新出现的螨害很确信地判成「健康」。
修正:升级策略必须加入与置信度正交的三个维度 —— OOD 分数、每日随机盲复核(抽 20 条高置信度决策)、分品类精度告警。要监控的是静默错误率,不是平均置信度。
C2 「<300ms」不能作为全系统 SLA 中
端侧图像判断可以 300ms 内;但一次营养雾 Choice 要融合时序、成本、约束与多目标,云端 p95 就是 1.5–2s;专家复核是小时级。用一个数字承诺全链路,第一次演示就会失信。
修正:分三级 SLA —— 端侧快判 ≤300ms(p95)、云端集成 ≤2s(p95)、专家升级 ≤24h(SLA 而非时延)。每级独立监控、独立告警。
C3 「2000 张图像」不足以训练污染判断 高
污染是稀有事件(3–8%),2000 张里只有 60–160 个正例,分到 5 个病类后每类十几张——连验证集都撑不住,更别说校准。
修正:5–8k 图像起步 + 主动学习挑边界样本 + 雾/结露/反光的合成增强 + LIMS 记录做弱监督(「该盘被销毁」也是标签);顺序上先影子运行 30 天再谈上线。
保留清单(v0.1 里不该动的东西)
① 不做聊天机器人、只做判断层——这个取舍是整个设计里最值钱的一句话。② Noul / Choice / Score 三分法——足够表达 90% 的农艺决策,且天然可校验。③ 结构化 JSON 契约——让判断层能被编排、被回放、被审计。④ 「关键动作保留人工闸门」——在生物制造场景里,这不是保守,是产品竞争力。
七层全栈:快路径、慢路径、一条账本
草案的六层是对的,但把「执行」和「反馈」放在了同一个括号里。真实系统里这是两条不同的物理链路:一条要在 300ms 内落到泵阀上并回读验证,另一条要等 30–45 天标签到齐才能启动。把它们分开设计,是这套架构和草案最大的结构差异。
2.1 逐层拆解 点左侧任意一层,看职责、组件、时延预算与失效模式
2.2 端侧时延预算 「<300ms」需要拆开才可执行
| 环节 | 内容 | 预算 | 压不下来的原因 |
|---|---|---|---|
| 曝光 + 传输 | 相机触发、MIPI/USB 取图 | 25 ms | 物理限制;用触发式拍摄避免运动模糊 |
| 质量闸门 | 模糊/结露/过曝/遮挡检测 | 8 ms | 小模型或纯 CV 指标即可,必须在推理前跑 |
| 预处理 | 裁切、白平衡校正、归一化 | 12 ms | 固定 ROI 可省掉检测步骤 |
| 推理(INT8) | 污染分类 / 根系分割 / 叶色回归 | 45–70 ms | 三个模型串行;并行可降到 70ms 内 |
| 校准 + 弃权 | 温度缩放、conformal 集、OOD 分 | 2 ms | 纯查表与标量运算 |
| 策略 / 状态机 | 阈值、三区间、升级标记 | 5 ms | 规则在本地,不依赖网络 |
| 回传 + UI | MQTT 上行 + 控制台刷新 | 40 ms | 局域网内可忽略;跨区域要单独算 |
| 合计 | p50 ≈ 147ms / p95 ≈ 210ms | ≤300 ms | 留 30% 余量给 GC、散热降频、批量排队 |
2.3 技术选型与理由 给「为什么不用 X」留档,避免半年后重新吵一次
| 能力 | 首选 | 备选 | 选择理由 |
|---|---|---|---|
| 边缘盒子 | Jetson Orin Nano 8GB | RPi5 + Hailo-8L | 要同时跑 2–3 个视觉模型且功耗 <15W;不需要大模型,但需要稳定供货 |
| 消息与流 | EMQX(MQTT) + Redpanda | Kafka / NATS | 断网必须能本地缓冲;单机 Kafka 协议兼容,省运维 |
| 时序库 | TimescaleDB | InfluxDB | SQL 能一次 JOIN 气象、根区、批次;连续聚合做降采样方便 |
| 对象存储 | MinIO(农场本地) | S3 / OSS | 原始图像不出境,是数据主权的第一道闸 |
| 谱系与元数据 | Postgres + 递归 CTE | Neo4j / Apache AGE | 谱系深度 ≤8 层,递归查询足够;不引入第二个数据库 |
| 推理服务 | Triton | ONNX Runtime Server | 多模型、动态批处理、INT8/FP16 切换成熟 |
| 状态机 | Temporal | 自研(Postgres 驱动) | 流程长达 30–45 天,需要持久定时器与重试语义 |
| 校准存储 | 自研 Calibration Store | — | 每「农场 × 品种 × 判断器」一套温度参数与阈值,无现成组件 |
| 审计账本 | Postgres 追加表 + 哈希链 | 只读对象存储 + 外部时间戳 | 可离线验证、可导出交检,不引入区块链 |
| 联邦学习 | Flower | 自研梯度聚合 | 只交换梯度/统计量;真要做时再引入,MVP 不需要 |
2.4 三种部署拓扑 同一个判断层,三种交付形态
T1 单农场 MVP
边缘盒子 ×2(主备)+ 农场本地服务器(MinIO + Timescale + 编排)。云只在模型分发时出现,推理与决策全部本地。
代价:无跨场学习;收益:断网可运行 72h、数据零出境、部署一天完成。
T2 区域多农场 规模化
农场保留采集与快判;区域云承担集成判断、跨场谱系(同一母株库供苗)与集中复核队列。图像留场,特征与决策上云。
代价:区域云运维;收益:新农场靠共享先验冷启动,复核人力集中。
T3 跨境联邦 出口
数据分级:L0 原始图像(不出境)、L1 特征向量(可出境)、L2 模型参数(受管)。联邦聚合只搬 L1/L2,本地模型注册表各自晋级。
代价:工程复杂度;收益:满足数据主权与品种权审查,同时共享全球经验。
三条横切能力(每一层都要有,不是某一层的活)
- 安全互锁:EC/pH/压力/占空比的硬限位在 PLC,软件层只发意图;任何越界指令在网关侧直接拒绝并记事件。
- 可观测性:每个决策带
trace_id,贯穿采集→推理→策略→执行→复核;指标按「判断器 × 品种 × 农场」切片。 - 可审计:决策、输入快照哈希、模型版本、SOP 版本、复核结果全部入链;账本只追加,导出即凭证。
十四个决策节点:从一粒外植体到一杯可交付的豆
链条的真正难点不在两端,在中间那道衔接闸门:组培苗从「无菌、恒温、高湿」的世界,进入「有菌、变温、要自己蒸腾」的世界。这一步的失败率通常最高,也最适合用一个 Score 判断器去卡。点任意节点看它的契约。
3.1 为什么这三处标星 驯化 readiness 是整条链的「汇率」
⑥ 驯化 readiness 衔接
它是组培与雾培之间的唯一汇率:定得太松,雾培端承担高死亡率;定得太紧,组培端压货、成本堆在瓶里。这个阈值会同时改变两条产线的经济性,所以必须由下游成活率反标定,而不是由组培车间自己定。
⑦ 移栽闸门 不可逆
出瓶是不可逆操作:污染一旦带进雾培槽,就是整槽风险。所以这里默认 human_review=true,AI 只负责「建议 + 排序 + 挑出不该移的」,不负责放行。首次移栽的新品种一律强制人工。
⑧ 营养雾配方 高频
一天可能触发几十次,是最适合「快判」的节点,也是最容易出事故的节点(EC 拉高 20 分钟就能烧根尖)。设计要点:硬限位在 PLC、软件只发意图,且每次调整必须能回滚。
3.2 状态机的四个迁移闸门 「当前在哪一阶段」本身就是一个需要判断的问题
| 迁移 | 放行条件(全部满足) | 回退条件(任一触发) |
|---|---|---|
| 无菌建立 → 增殖 | 连续 2 次观察无污染;褐化面积 <15%;有可见芽点 | 出现任一污染类;培养基 pH 偏移 >0.3 |
| 增殖 → 生根 | 增殖系数 ≥3;无玻璃化;株高 ≥2cm | 连续两代增殖系数 <2;玻璃化率 >20% |
| 生根 → 驯化 | 根数 ≥3;根尖褐变 <30%;无污染 | 根尖褐变突增;出现根腐气味记录 |
| 驯化 → 雾培 人工 | readiness ≥80;失水测试合格;根团完整;菌检阴性 | readiness 连续 7 天下降;菌检阳性 |
判断器实验室:三个判断器,拨一下就知道它在想什么
三个判断器分别对应 Noul / Score / Choice。重点看两件事:阈值是怎么被成本结构推动的(A 面板拨动 C_FP / C_FN),以及硬闸门如何覆盖加权分(B 面板把根数拉到 2,看分数被压在 55 以下)。
输入 · 无菌建立 / 继代观察
事件触发三个判断器共用的「三区间」判据 含一个反直觉的结论
A 面板里你会看到两件事。第一:把 CFN 调高(污染扩散更贵),τcost 会下降——同样的概率,从「放行」变成「处置」。第二件更重要:按 40 美元 / 900 美元算出来的 τcost 只有 4.3%,意味着几乎每一盘都该隔离,现场根本执行不了。所以真实系统必须再加一个「运营下限」(每周能承受多少误隔离),把阈值抬回可执行区间。
把 τmin 从 0.15 拖到 0.30,你会看到同样的输入从「处置」退回「复核」——这就是 AI 与运营产能之间的谈判桌。任何把这个谈判藏在代码常数里的系统,最后都会被人绕过去。
接口契约:一个端点,三种判断,零自由文本
下面的 Playground 不是 mock:它调用本页内置的同一套引擎,按 stage 路由到对应判断器,缺字段时真的会返回 need_more_info。你可以改 JSON 直接试。
请求
响应
—5.1 字段契约 字段名一旦定下,LIMS / 边缘盒 / 控制台三端共用
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
variety | string | ✅ | 品种/品系,如 Arabica-Caturra。决定使用哪一套校准参数与基线 |
region | string | ✅ | 产区/农场 ID。用于层次化基线与数据主权路由 |
stage | enum | ✅ | 状态机节点,决定路由到哪个判断器(见 5.2) |
sensors | object | ✅ | ec, ph, vpd, temp 必填;rh, do, droplet_um, water_temp, days_in_culture 选填 |
image_ref | string | 条件 | 图像对象引用(S3/MinIO)。视觉类判断必需;纯传感器判断可空 |
batch_history | object | 条件 | contamination_rate:批次历史污染率,用作先验 |
reading | object | 条件 | 判断器专属读数:vision_p, quality, roots, browning, shoot_cm, leaf_color, stomata_wax, water_loss_pct |
costs | object | 否 | fp / fn:误隔离与漏检成本(当地货币)。缺省时用农场配置 |
objective | object | 否 | survival / cost / quality 权重;缺省 0.5 / 0.2 / 0.3 |
mode | enum | 否 | live(默认)或 shadow:只判断不执行,返回 would_decide |
5.2 响应字段与状态语义
响应头等字段
decision— 单值枚举,不含自然语言confidence— 校准后置信度(见 7.2),不是 softmax 原值scores— 判断器内部关键量(p、τ、readiness、utility…),用于事后归因options[]— 候选动作、可行性、效用、概率human_review+review_reasons[]— 布尔之外还要说为什么reason— ≤80 字,只解释不看数据的人为什么该信/该疑evidence_refs[]— 图像/传感器快照哈希,支撑可追溯audit_id— 哈希链账本索引,出问题能回放
四种「不决策」也是正式输出
need_more_info— 字段缺失或传感器 health 不足。200 返回,不是 400abstain— 校准后仍在复核区且无法补证(conformal 集含两个以上类别)stop_and_review— 所有候选动作都违反硬约束,不允许系统自己选defer_to_human— 首次场景/新品种/高价值批次,按策略强制
把「不决策」做成合法输出,比逼模型给一个答案更省钱——这是判断层和聊天机器人的分界线。
人工复核:把人放在正确的价位上,不是放在每个环节
草案说「关键动作必须人工确认」,这句话要变成工程,需要三样东西:触发条件的矩阵(谁该被叫醒)、带证据的队列(他凭什么 30 秒内判断)、可回灌的记录(他的判断变成下一次训练的样本)。
6.1 升级策略矩阵 按「错了会有多贵」排序,而不是按置信度排序
| 触发条件 | 动作 | SLA | 为什么这样设 |
|---|---|---|---|
| 校准置信度 < 0.70 | 进入复核队列 | 4 h | 低于此值模型与人的判断力相当,继续自动化没有收益 |
| p 落在复核区 [τlo, τhi) | 安排镜检/切片 | 24 h | 不是「不确定所以问问」,而是用一次 20 元的镜检换掉一次 900 元的赌注 |
| OOD 分数超限 / 新品种 / 首次场景 | 强制人工 + 影子运行 | 24 h | 分布外部的高置信度最危险,必须由人先兜住 |
决策 ∈ transplant_now / discard_batch / stop_and_review | 双人签核 | 8 h | 不可逆或高损失动作,单人无权放行 |
| 将突破硬约束(EC/pH/压力) | 阻塞 + 现场告警 | 即时 | 这一条不经过人,直接由 PLC 拦;人只收到通知 |
| 批次价值 > 阈值(如 5000 苗) | 主管确认 | 4 h | 同样的概率,金额不同,风险偏好就该不同 |
| 传感器 health < 0.6 | 返回 need_more_info | 即时 | 输入不可信时,不生成决策比生成后再复核便宜一个数量级 |
| 每日盲抽样 20 条高置信度决策 | 盲复核(不告知模型结论) | 48 h | 唯一能发现「系统性自信错误」的手段,见 1.3 / C1 |
6.2 复核队列 可点击:采纳 / 改判 / 补证,三条路径都会写进账本
RV-2411 · 批次 AP-0713 · 480 苗 复核区
待复核AI 建议:delay_adjust(readiness 79,距 80 差 1 分)· 置信度 0.71
证据:根数 7 · 根尖褐变 28% · 气孔关闭 62% · 失水 11.2%/4h;4 天前同批次褐变 19%,呈上升趋势。
需要人判断的点:趋势恶化 vs 绝对分数达标——模型只看当天截面,人看得到斜率。
RV-2412 · 批次 TC-118 · 96 瓶 OOD
待复核AI 建议:review_microscopy(p=0.078,落在复核区 [τlo, τhi) = [0.060, 0.099))· 方向置信度 0.92,但图像质量触发 OOD
证据:图像质量 0.52(培养瓶结露)+ 该品种历史污染率样本量 < 30 → 触发 OOD;视觉分 0.38 与温湿度先验 0.06 冲突。
需要人判断的点:是擦掉结露重拍,还是直接镜检——补一张好图的成本远低于一次误判。
RV-2413 · 雾培槽 A3 · 240 株 全部候选不可行
待复核AI 输出:stop_and_review(无可行候选动作)· 置信度 0.96
证据:pH 读数 5.24,低于硬限位 5.3;同时该 pH 电极响应时间 38s(阈值 20s)、已连续使用 41 天 → 疑似探头失效,而非真的酸败。
需要人判断的点:先修仪表还是先调液——这正是「数据质量闸门」要拦在推理之前的原因(见 G05)。
6.3 决策账本 只追加、哈希串联:导出即为可交检的凭证
最近决策
seq / ts / audit_id / prev / hash。演示用的是 FNV-1a 32×2 简化哈希(hash = h(prev + payload)),不是 SHA-256;生产环境必须换成 SHA-256,并把 hash 定期锚定到外部时间戳服务,防止整链重写。
学习闭环:标签晚到 45 天,那就把闭环设计成异步的
这是草案里最容易被跳过、也最容易让系统在半年后失效的一节。核心思想:不要试图让模型「实时学习」,而是让每一个判断都留下可结算的凭证,等标签到齐后批量结算。
7.1 五步闭环
① 结算 7–45 天
决策事件自带 label_ready_at。污染 14 天、生根 21 天、移栽成活 45 天,到期由定时任务回填终局标签。
没有终局标签之前,样本标记为 pending,不参与训练——这是防止标签噪声污染校准的闸门。
② 校准 每周
在验证集上拟合温度参数 T(每「农场 × 品种 × 判断器」一套),监控 ECE 与可靠性图。ECE > 0.05 触发重新拟合。
③ 漂移 每日
三个层次:输入漂移(PSI/KL 于传感器与图像特征)、预测漂移(决策分布)、结果漂移(污染率/成活率)。前两个当天可见,第三个要等 45 天。
④ 影子 ≥30 天
新模型与新农场并行跑,只记录不执行。对比 AI 与人工的一致率、分歧样本分布,分歧不是错误,是信息。
⑤ 晋级 季度
门槛:成本加权净收益不降 且 ECE 不升 且 复核一致率不降。三者任一不满足,不上线——哪怕准确率更高。
主动学习队列
优先标注三类样本:复核区分歧(模型与人都犹豫)、OOD 命中、高置信度错误。这三类每 100 条的信息量约等于随机 1000 条。
7.2 校准:为什么 0.82 不能直接用 可靠性图上的那条弯线,就是「自信」和「正确」的差
三个动作,按成本从低到高
- 温度缩放(最便宜):
p' = σ(logit(p)/T),一个标量参数,几乎不改变排序,只改变可信度刻度。 - Isotonic / 分箱校准:非参数,适合样本量大(>2000)的单判断器;小样本容易过拟合。
- Conformal 弃权:不校概率,直接给「这个样本的答案集合有多大」。集合含 ≥2 个类别 → 弃权升级。这是唯一有有限样本保证的方法。
工程上三者叠加:温度缩放管刻度,conformal 管边界,OOD 管「这套刻度在这里根本不适用」。
注意:阈值不能只由成本算。纯成本解会给出 4% 这种「几乎每盘都隔离」的答案——必须有运营下限(每周可承受的误隔离量)把它抬起来,这也是 A 面板里 τ_cost 与 τ_hi 分开显示的原因。
7.3 延迟标签表 整个闭环的地基,一张表就够
CREATE TABLE decision_outcome ( audit_id TEXT PRIMARY KEY, -- 与决策账本同键 farm_id TEXT NOT NULL, variety TEXT NOT NULL, stage TEXT NOT NULL, judger TEXT NOT NULL, -- contamination | readiness | fog_choice decided_at TIMESTAMPTZ NOT NULL, decision TEXT NOT NULL, p_calibrated REAL, model_id TEXT NOT NULL, sop_version TEXT NOT NULL, -- 标签侧 label_ready_at TIMESTAMPTZ NOT NULL, -- 决定何时可以结算 label_state TEXT DEFAULT 'pending',-- pending | settled | void outcome TEXT, -- contaminated | clean | survived | died ... outcome_at TIMESTAMPTZ, proxy_label TEXT, -- 当天可见的代理标签(仅用于监控) reviewer_id TEXT, -- 人工复核者,用于一致率统计 reviewer_action TEXT -- accept | override | need_evidence ); -- 每日任务:结算所有 label_ready_at <= now() 且 state='pending' 的行
7.4 漂移监控指标 每一条都要有「谁看、看到怎么办」
| 监控项 | 计算方式 | 告警阈值 | 处置动作 |
|---|---|---|---|
| 输入漂移 | 特征 PSI(分箱) | > 0.2 | 检查传感器/镜头;暂停该农场自动处置权限,转复核 |
| 预测漂移 | 决策分布 JS 散度 | > 0.15 | 看是否新品种/新季节;必要时回退上一版模型 |
| 校准漂移 | 滑动窗口 ECE | > 0.05 | 重拟合温度参数(小时级,可自动) |
| 结果漂移 | 污染率/成活率 CUSUM | 连续 3 周同向 | 启动根因复盘(节点 14),不要直接改模型 |
| 复核一致率 | 人机一致 / 复核总数 | < 0.85 | 检查是否 SOP 变了而非模型坏了(这是最常见的假警报) |
| 静默错误率 | 盲抽样中的高置信度错误率 | > 2% | 分级告警;立即收缩自动处置范围 |
指标与经济性:先算清「一次误判值多少钱」
气雾栽培的成本结构和土培完全不同:电是最大变动成本,人工巡检占比很小,而一次整槽污染损失极大。所以判断层的价值不只在「判得准」,还在「敢于为了省电而不开雾」。
8.1 KPI 分层 前四个是业务指标,后四个是系统指标;都标了基线来源
| 指标 | 定义 | 示例基线 | M3 | M6 | 守护条件(防止刷指标) |
|---|---|---|---|---|---|
| 污染漏检率 | 真污染被判为放行的比例(最贵的错) | ~12% | ≤6% | ≤3% | 误隔离率不得同时上升 >5pp |
| 人工复核率 | 进入队列的决策占比 | 100% | ≤35% | ≤15% | 复核一致率不得低于 0.85 |
| 雾培移栽成活率 | 移栽后 30 天存活/移栽总数 | ~72% | 80% | 86% | 不能靠延长驯化期换取(看周转天数) |
| 单株能耗 | kWh/株/周期(雾化+补光+除湿) | — | −8% | −15% | 成活率不得下降 |
| 决策时延 p95 | 从事件到输出决策 | 1.2 s | ≤400ms | ≤210ms | 不能靠降低模型规模换 |
| 校准误差 ECE | 置信度与正确率的平均偏差 | 0.14 | ≤0.07 | ≤0.05 | — |
| 单次决策成本 | (一次性投入/3 + 年运维 + 复核人工) ÷ 年决策数 | $0.15 | ≤$0.07 | ≤$0.04 | 复核人工必须单列,不能藏进「其他」 |
| 账本完整率 | 有 audit_id 且链验证通过的决策占比 | 0 | 100% | 100% | —(这是合规项,不是优化项) |
基线为示例值,需用贵方历史批次数据替换后再冻结为考核口径;M3/M6 为目标值,不是承诺值。
8.2 经济性计算器 改数字看回收期;算式在下方逐项列出
输入(可改)
示例算式
怎么读这个结果 决策建议
—
价值来源(按可验证性排序)
- 污染扩散阻断:最可验证,因为损失是离散事件,能逐笔对上
- 移栽成活率提升:需要 45 天观察期,但金额最大
- 能耗优化:靠雾化占空比与分时电价,见效快但幅度小
- 人工巡检替代:容易被高估——人并没有被裁掉,只是换了工作内容
不要用来算的东西
- 「品质溢价」:除非有合约或杯测数据支撑,否则不要写进 ROI
- 「避免的品牌损失」:无法计量,写进 PPT 可以,写进预算不行
- 「人力节省 80%」:复核率降到 15% 不等于省 85% 的人,人还要做补证与纠偏
规模门槛
把年出圃量调到 6 万株:年挽回损失约 $3,900,还不够付 $4,800 的年运维,回收期为无穷。这不是模型的问题,是固定成本被摊薄得不够。
结论:小农场不要自建,应走 T2 区域共享 拓扑,用别人的边缘盒子 + 自己的数据。
90 天:先做三个判断器,但顺序反过来
理由是:模型可以在第 3 个月迭代很多次,但标签管线一旦前 60 天没建好,那 60 天的数据就永久废掉了。先建管道,再建模型,是唯一不能压缩的顺序。
9.1 三道验收闸门 每道闸门不过,就不进下一段
D30 · 数据闸门
- ≥30 天连续传感器日志,缺失率 <2%
- 决策账本上线,链验证通过率 100%
- 延迟标签表有 ≥10 条已结算样本(走通全流程)
- 相机标定与雾/结露质量指标上线
不过关的表现:账本里只有决策没有结果 → 说明标签回填链路是断的。
D60 · 模型闸门
- 污染 Noul 在留出集上 FN 率 <8%(成本加权)
- ECE ≤0.08;conformal 弃权率 <25%
- 驯化 Score 的排序能力:与人工评分的 Spearman ρ >0.7
- 营养雾 Choice 的候选集覆盖率 100%(总有一个可行解)
D90 · 上线闸门
- 影子期 30 天,人机一致率 ≥0.85
- 复核队列 SLA 达成率 ≥90%
- 端侧 p95 ≤300ms,断网 72h 可运行
- 成本加权净收益 ≥0(在影子数据上回放)
四道全过才允许把 mode 从 shadow 切到 live。
9.2 全球本地化 一个模型不能同时懂云南和哥伦比亚
| 本地化维度 | 具体做法 | 常见坑 |
|---|---|---|
| 品种 / 品系 | 品种级共享先验 + 品系级偏移;Caturra / Geisha / 杂交种分别建基线 | 用阿拉比卡整体均值代替品系,导致小粒种被系统性低估 |
| 水质与营养 | 本地水源分析(硬度、碱度、氯)进入配方选择;EC 目标随碱度修正 | 照搬 SOP 的 EC 值,在硬水地区直接把 pH 推离缓冲 |
| 气候与 VPD | 按海拔与季节建 VPD 曲线;高湿地区重点防结露与霉病 | 用温带温室参数套热带高原,雾化占空比永远偏高 |
| 电力与成本 | 分时电价进入 Choice 成本向量;缺电地区降低雾化频率并接受产量折损 | 成本模型不本地化,推荐的方案在当地根本付不起电费 |
| 法规与检疫 | 种苗跨境需检疫证书;营养液排放氮磷限值;农药 MRL 按目的国 | 把「技术上可行」当成「法律上可交付」 |
| 数据主权 | 原始图像留境;跨境只传特征与模型参数(T3 拓扑) | 为省事把所有图像传回总部,出口时被卡 |
9.3 试点怎么证明有效 把「感觉变好了」变成一个可预注册的检验
90 天路线图交付的是系统,不是证据。要让老板或投资人签字,需要事先定好设计、样本量、终点与止损规则—— 允许事后挑指标的系统,永远「有效」。
① 影子比对 D60–D90 · 30 天
不改动任何操作,只记录「AI 建议 vs 农艺师判断」。产出的是判断质量证据,不是损失证据。
主指标:人机一致率、分歧样本仲裁结果。这一步不能省——它能在烧钱之前暴露「模型和老师傅根本不在一个频道」。
② 分层随机对照 D90–D180 · 两个批次
按架层整群随机:A 组执行 AI 建议,B 组执行现行 SOP。同一母株库、同一营养液批次、同期对照。
主指标:污染率、移栽成活率。这是唯一能支撑 ROI 的设计。
③ 常态化 D180+
全量启用,同时保留每日 20 条高置信度决策的盲抽样,持续监控静默错误率。
没有这一步,系统会在某个你没注意的周里悄悄变差,而你只会看到一张好看的月度报表。
| 终点 | 基线 → 目标 | 每组独立样本 | 整群随机(设计效应 1.5) | 周期与说明 |
|---|---|---|---|---|
| 污染率 | 8% → 4% | ≈ 550 盘 | ≈ 830 盘 | 按 14 天/批,约 3 批可攒够;这是最贵也最值得测的终点 |
| 移栽成活率 | 72% → 80% | ≈ 450 株 | ≈ 680 株 | 需等 45 天观察期;建议与污染率同期启动,省一个季度 |
| 单次决策成本 | 查账即可 | — | — | 不需要统计检验,账本里逐笔可核 |
n = (zα/2·√(2p̄q̄) + zβ·√(p₁q₁+p₂q₂))² / (p₁−p₂)² ,α=0.05 双侧,power=0.8
止损规则(写进合同,不留在口头)
- 对照组污染率连续 3 周高于实验组 2 倍 → 提前终止对照,全量切换(不能为了统计功效继续让人吃亏)
- 账本断链、审计导出失败 → 立即停用自动处置权限,合规优先于效果
- 复核 SLA 连续两周达成率 <80% → 暂停自动处置,恢复全量复核
- 盲抽样静默错误率 >2% → 收缩自动处置范围,直到复核一致率恢复
混杂控制:四个最容易犯的错
- 比「去年 vs 今年」——季节、电价、品种全变了,结论没有意义。必须同期对照。
- 按单盘随机——同一架层的雾、温、湿度高度相关,按盘随机会把处理效应泄漏到对照组。随机化单位应是架层。
- 同期换两样东西——一边上 AI 一边换营养液配方,最后无法归因。
- 把人机一致率当效果指标——一致率只说明「像人」,不说明「比人准」。
一致率陷阱:如果 AI 与师傅只有 70% 一致,但 AI 更准怎么办?
这是影子期最常见的僵局。正确做法不是「以人为主」,而是第三方盲评仲裁:把 200 条分歧样本打乱顺序,交给两位不知情的农艺师独立判定,用仲裁结果而不是一致率下结论。若 AI 在分歧样本上胜率 >60%,说明它带来的正是增量信息;若 <40%,说明模型学的是噪声。
这一步花不了几千块,却能避免两种昂贵的错误:上线一个没人信的模型,或者否掉一个比人强的模型。
风险、合规与「不做清单」
农业 AI 项目失败很少因为模型不够准,多数因为没人信、没人用、算不过账、出一次事故就停摆。下表把这三类风险分开列,并给出可观测的触发信号。
| # | 风险 | 触发信号(可观测) | 影响 | 缓解措施 |
|---|---|---|---|---|
| R1 | 传感器漂移/生物膜 | 探头响应时间变长、双探头偏差 >0.1、校准漂移量上升 | 高 | health 闸门 + 双探头交叉校验 + 固定更换周期;不健康即 need_more_info |
| R2 | 标签噪声与延迟 | 结算样本的复核一致率下降、ECE 上升 | 高 | 双轨标签、pending 不训练、结算前人工抽检 5% |
| R3 | 过度自动化 | 复核率被 KPI 逼着下降、SLA 接近 100% 但一致率下降 | 高 | 硬限位下沉 PLC;不可逆动作双人签核;影子期不得跳过 |
| R4 | 生物安全与检疫 | 跨场调苗无检疫凭证、销毁记录缺失 | 高 | 隔离流程 + 销毁凭证入账本 + 门禁与人员动线记录 |
| R5 | 品种权与授权繁殖 | 谱系中缺失授权标记、外植体来源不明 | 中 | 谱系强制带 license_id;系统只做标注不做合法性判定 |
| R6 | 数据主权与跨境 | 原始图像出现在境外存储桶 | 中 | 数据分级 + 本地 MinIO + 出境白名单(仅特征/参数) |
| R7 | 供应商锁定 | 推理栈只能用某云 SDK | 中 | 模型以 ONNX 为中间表示,保留双运行时(Triton / ORT) |
| R8 | 组织阻力 / 不信任 | 农艺师绕过系统手工记录、复核意见长期与 AI 不一致 | 高 | 第一版只做「帮人排序」,不做「替人决定」;把分歧做成可讨论的界面,而不是隐藏掉 |
| R9 | 电价与投入品波动 | 单位成本曲线反转、ROI 为负 | 中 | 成本向量可配置,默认取保守值;分时电价接入调度判断(节点 13) |
| R10 | 关键人依赖 | 只有一个人知道为什么阈值是 0.7 | 中 | SOP 编码化为 sop_version;每个阈值带来源注释;决策可回放 |
10.1 不做清单 写下来的「不做」,比写在路线图上的「要做」更能保护项目
❌ 不做无人监管的阀门控制
判断层输出意图,执行层受 PLC 硬限位约束,人保留总开关。这一条不因模型变准而改变。
❌ 不做病害治疗处方
只做「识别 + 隔离 + 送检建议」。农药/杀菌剂的具体剂量与用法必须由持证农艺师决定,涉及 MRL 与法规。
❌ 不替代杯测与品质定级
糖度、风味、瑕疵是人的感官判断;判断层最多做「采收窗口排序」,不做最终等级评定。
❌ 不做品种权合法性的自动判定
系统能标注「缺授权凭证」,不能下结论说「这个品种可以繁殖」。
❌ 不做跨农场原始数据集中
共享的是特征与参数,不是图像与批次明细。这条既保护客户,也保护自己。
❌ 不先做「通用农业大模型」
咖啡单品类做穿之后再说。多品类扩展会把有限的标注预算摊成一张谁也喂不饱的网。
附录:枚举、提示词、参考实现、变更日志
A. 枚举与本体 三端共用,一旦冻结只能加不能改
| 枚举 | 取值 | 备注 |
|---|---|---|
stage | intake, aseptic_establishment, callus, proliferation, rooting, acclimation, transplant_gate, aeroponics_nutrition, root_zone_check, flowering, harvest_window, quarantine, power_dispatch, retro_review | 14 个节点,与决策地图一一对应 |
decision | continue, isolate_and_sample, review_microscopy, transplant_ready, delay_adjust, continue_acclimation, sop_baseline, lower_ec, raise_do, adjust_ph, dry_back, flush_reservoir, stop_and_review, need_more_info, abstain | 闭合枚举,禁止自由文本 |
jev_type | noul, score, choice, anomaly | anomaly 用于根区异常的无监督检测 |
review_reason | low_confidence, boundary_zone, ood, first_time_scene, irreversible_action, value_threshold, sensor_unhealthy, constraint_conflict, gate_capped, zone_precondition | 复核数据按此分类回流,是主动学习的采样依据 |
| 污染子类 | bacterial, fungal, vitrification, mite, viral, abiotic_stress | 每个子类绑定一套动作模板(见 G03) |
B. 系统提示词 在 v0.1 版本上加了「不决策」与「不越界」两类约束
输出约束(硬性)
1. 只输出 JSON,字段严格遵循 schema;
decision 必须取自枚举,禁止新造值。2. 证据不足 →
decision="need_more_info" 并列出 missing;不要猜测填充。3.
confidence 必须是校准后的值;无法校准时置 null 并设 human_review=true。4. 以下任一成立时
human_review 必须为 true:置信度 <0.70;decision ∈ {transplant_now, discard_batch, stop_and_review};首次场景或新品种;将突破 EC/pH/压力硬限位;批次价值超阈值。5.
reason ≤80 字,只说明「为什么是这个结论」与「最该让人看一眼的是什么」;禁止罗列优化方向、种植建议、免责声明。6. 不得推荐超出 SOP 的农药/激素剂量;不得对品种权与检疫合法性下结论,只能标注「需人工核验」。
7. 必须引用
sop_version;不得引用未提供的 SOP 条款。8. 弃权是合法输出:
abstain 与 stop_and_review 都优于一个勉强的答案。
C. 参考实现 与 04 实验室同一套数学;完整版见 coffeejev/service/
from math import exp, log
def _logit(p: float) -> float:
p = min(max(p, 1e-4), 1 - 1e-4)
return log(p / (1 - p))
def _sigmoid(x: float) -> float:
return 1.0 / (1.0 + exp(-x))
def judge_contamination(vision_p, quality, temp, rh, days_in_culture,
batch_hist_rate, cost_fp=40.0, cost_fn=900.0, t=1.35):
"""Noul 判断器:三区间 + 成本推导阈值。返回 (decision, p_cal, tau_hi, tau_lo)。"""
prior = min(max(batch_hist_rate, 1e-3), 0.5)
blend = (quality * _logit(vision_p) # 图像越清晰,越信模型
+ (1 - quality) * _logit(prior) # 图像越糊,越信先验
+ 0.35 * (temp - 24) / 3 # 温度偏高 = 污染友好
+ 0.25 * (rh - 65) / 15
+ 0.12 * (days_in_culture - 14) / 7)
p_cal = _sigmoid(blend / t) # 温度缩放:把刻度拉回现实
tau_cost = min(max(cost_fp / (cost_fp + cost_fn), 0.02), 0.5) # 成本推导
tau_hi = min(max(tau_cost, tau_min), 0.5) # 两段式:再与运营下限取大(CH-15)
tau_lo = max(0.06, 0.45 * tau_hi)
if p_cal >= tau_hi:
decision = "isolate_and_sample"
elif p_cal >= tau_lo:
decision = "review_microscopy"
else:
decision = "continue"
return decision, p_cal, tau_hi, tau_lo
ROUTES = { # 与 14 节点 stage 枚举一一对应
"intake": "contamination",
"aseptic_establishment": "contamination",
"callus": "contamination",
"proliferation": "contamination",
"root_zone_check": "contamination",
"rooting": "readiness",
"acclimation": "readiness",
"transplant_gate": "readiness", # 移栽闸门先看 readiness,再看菌检
"aeroponics_nutrition": "fog_choice",
"harvest_window": "fog_choice",
}
def decide(req: dict) -> dict:
missing = validate(req) # variety / region / stage / sensors.*
if missing:
return {"decision": "need_more_info", "missing": missing,
"human_review": True} # 200,不是 400:这是合法输出
judger = ROUTES[req["stage"]]
verdict = JUDGERS[judger](req)
reasons = review_policy(verdict) # 见 6.1 的矩阵
verdict["human_review"] = bool(reasons)
verdict["review_reasons"] = reasons
verdict["audit_id"] = ledger.append(verdict) # 哈希链,只追加
return verdict
D. v0.1 → v1.0 变更日志 每一条改动背后都有一个具体的失败场景
| 编号 | 变更 | 触发场景 |
|---|---|---|
| CH-01 | 新增批次谱系与隔离半径 | 一次霉菌污染,因为不知道同批苗分布在哪三层架,只能整室停摆两周 |
| CH-02 | 置信度改为校准值 + conformal 弃权 | 模型在新增的补光条件下自信地把整批玻璃化苗判为健康 |
| CH-03 | 污染由二元改五类 + 时间维度 | 把螨害当真菌处理,多喷了两轮杀菌剂,问题反而扩散 |
| CH-04 | 新增延迟标签表 | 上线三个月后发现没有任何一条决策能被事后结算,模型无法迭代 |
| CH-05 | 新增传感器 health 闸门 | pH 电极生物膜导致读数偏低,系统连续三天下调 pH,根尖烧伤 |
| CH-06 | 新增执行闭环(ACK/回读/回滚) | 指令发出但计量泵空转,系统以为已执行,后续判断全部建立在错误状态上 |
| CH-07 | 新增黄金集与决策回放 | 阈值从 0.7 调到 0.6 后无人能证明是变好还是变坏 |
| CH-08 | 新增复核队列与理由分类 | 复核记录散落在聊天群里,无法回流成训练数据 |
| CH-09 | Choice 引入成本向量与帕累托前沿 | 系统为了成活率建议全程开雾,电费涨了 40%,账算不过来 |
| CH-10 | 阈值由成本比推导,废弃 0.7 硬编码 | 高价值品种与普通品种用同一阈值,一边浪费一边出事 |
| CH-15 | 阈值再加运营下限 τ_min,两段式 max(τ_cost, τ_min) | 纯成本解算出 4.3% 的阈值,试运行第一周就隔离了 60% 的盘,现场直接停用系统 |
| CH-11 | 新增哈希链审计账本 | 客户质疑「当时为什么判可移栽」,拿不出当时的输入与模型版本 |
| CH-12 | 新增层次化基线与 OOD | 新农场第一批苗全部被误判,因为模型没见过当地水质 |
| CH-13 | 新增节点 12 隔离半径、节点 13 能耗调度 | 污染处置与电费优化本来就在发生,只是没人把它当决策 |
| CH-14 | SLA 拆为 300ms / 2s / 24h 三级 | 对外承诺「全链路 300ms」,第一次演示就露馅 |