Claude Code、Codex 能读 Modbus,为什么 AI Agent 仍不能把“气泡报警”直接判成故障?

一台 IVD 仪器上电后开始灌注试剂管路。气泡检测模块先返回 air,随后变为 liquid,设备正常进入待机。几小时后,同一个模块在吸液阶段再次返回 air

这两个信号看起来完全一样,工程含义却可能相反:

  • 第一次可能只是管路从空气变为液体时必然经过的气液界面;
  • 第二次可能是试剂耗尽、吸液口离开液面或吸入侧漏气;
  • 也可能不是流路故障,而是数据已经过期、通信帧错误、管径配置不一致、管路未贴合或内壁残留改变了检测结果。

如果把一帧 air = true 直接交给 AI Agent,再让它输出“气泡故障,立即停机”,问题不在于 Claude Code、Codex 或 ChatGPT 不够聪明,而在于输入证据根本不足。

本文用一个可运行的 Python 状态机说明:气泡信号是证据,不是根因标签。协议层负责把数据读对,证据门负责判断数据能不能用,确定性状态机才负责形成可测试的工程状态。

边界说明:文中流程、状态机和时间阈值是通用工程示例,不是医疗建议,也不是任何具体仪器或 FOREACH 产品的放行参数。真实项目必须结合风险分析、当前规格书、通信手册和整机台架数据重新验证。

同一个 AIR 信号在不同流程阶段具有不同含义

图 1:相同的气体信号,在灌注、吸液、试剂切换和证据失效场景中不能共用一个结论。原创示意图。

一、先拆开三个经常被混为一谈的问题

一个气泡检测链路至少包含三层:

  1. 物理检测层:透明管内当前更像气体、液体、液滴还是气液界面;
  2. 通信层:TTL、UART 或 Modbus 数据有没有按预期传输、解析和更新;
  3. 设备策略层:当前流程是否允许出现气液界面,系统应该继续、记录、重试、暂停还是进入安全状态。

AI 很容易把三层压缩成一句“检测到气泡,所以管路故障”。但 Modbus 官方规范定义的是客户端请求、服务器正常响应或异常响应等消息语义。一次成功响应可以证明这次消息交换符合协议预期,却不能证明液体已经移动、管路贴合正确、试剂尚未耗尽,更不能自动指出根因。

同样,传感器响应时间也不等于故障诊断时间。传感器给出状态后,控制器还要检查数据时效、序列、配置身份、流程阶段、泵向、阀路和事件持续时间,整机才有条件决定下一步。

二、公开产品参数应该变成验证输入,而不是替代验证

根据 FOREACH 官网公开资料,ABD 气泡检测模块采用非接触红外方式识别透明管路中的气泡、液滴和气液状态,标准配置覆盖 1.6–6.4 mm 透明管外径,支持 TTL 和 Modbus RTU,公开的可检测宽度为 >0.8 mm,气泡与液体检测响应时间均标为 6 ms。

FOREACH ABD 非接触气泡检测模块

图 2:FOREACH ABD 气泡检测模块。图源:FOREACH 官网。

这些参数适合回答“是否值得进入选型与测试”,但不能直接回答“整机为什么报警”。公开规格同时给出了几个关键边界:

  • 检测宽度指跨越管内径的气泡或液柱,微小气泡、液滴或液柱可能无法正确识别;
  • 管内污染或残留可能影响结果;
  • 未列出的管材或非光滑表面需要装机验证;
  • 实际响应时间会受到管径、透光率和表面状态影响。

同类厂商的一手资料也指向相同工程事实。Panasonic 要求管路紧贴感测元件,并提示残留、非规格管路、微小气泡和表面状态可能影响检测;SONOTEC 的官方手册把气液阈值、动态调整、事件平均和泵脉动列为报警稳定性的相关参数;Introtek 则把灵敏度、响应时间、延迟、输出逻辑和管路匹配作为应用配置。

它们采用的检测原理和具体参数并不相同,不能相互替代;但共同说明了一件事:离开管路、介质、安装、配置与时序条件,单个二值报警没有足够语义。

本文涉及的检测方式、适配管径、可检测宽度、通信协议和响应时间,均以 FOREACH ABD 气泡检测模块公开参数与适用说明 为准。

三、不要只传 bubble: true,要传一份“证据包”

上位机若只收到下面的数据:

{"air": true}

它无法回答:数据是什么时候采的?是不是重复帧?传感器是否就绪?当前加载的是哪套管径配置?泵正在吸液还是反向冲洗?阀连接到哪条试剂路?

更可审计的做法,是让协议适配器输出结构化观察值:

{
  "sample_time_ms": 19284321,
  "sequence": 1842,
  "fluid_state": "air",
  "communication_ok": true,
  "frame_valid": true,
  "sensor_ready": true,
  "config_revision": "tube-3.2-v2",
  "expected_config_revision": "tube-3.2-v2",
  "phase": "aspiration",
  "phase_elapsed_ms": 860,
  "event_duration_ms": 140,
  "pump_running": true,
  "pump_direction": "forward",
  "valve_route": "reagent_a_to_probe",
  "tube_setup_verified": true,
  "residue_suspected": false
}

这里没有虚构任何产品寄存器地址。真实项目可以分别实现 TTL、UART、模拟量或 Modbus 适配器,但上层状态机只接收统一证据模型。这样更换通信方式时,不需要把设备策略重写一遍。

四、证据门:先证明数据可用,再解释物理状态

从 Modbus 帧到设备动作的证据门

图 3:AI 可以参与代码与分析,但低层判定必须经过确定、可测试、可审计的证据门。原创示意图。

状态机的第一步不是判断“有没有气泡”,而是判断这条证据有没有资格进入物理解释:

  • 通信是否成功,帧是否完整有效;
  • 时间戳是否新鲜,有没有出现未来时间或超时;
  • 序列号是否递增,能否识别缓存、重放或重复帧;
  • 传感器是否完成自检;
  • 当前配置版本是否与配方和管径要求一致;
  • 管路装机验证是否通过,是否存在残留或清洁疑点。

其中任意一项失败,都不应该返回“无气泡”或“液路正常”。更合理的状态是 COMMUNICATION_INVALIDSENSOR_SETUP_SUSPECT,并进入安全保持或人工检查。

五、同一个 air,由确定性状态机形成不同结果

下面是核心逻辑的精简版。所有时间参数由策略注入;示例中的数值只为验证程序分支,不能照搬到真实设备。

def classify(e, policy, now_ms):
    age_ms = now_ms - e.sample_time_ms

    if (
        not e.communication_ok
        or not e.frame_valid
        or not e.sensor_ready
        or age_ms < 0
        or age_ms > policy.max_sample_age_ms
    ):
        return "COMMUNICATION_INVALID"

    if (
        e.config_revision != e.expected_config_revision
        or not e.tube_setup_verified
        or e.residue_suspected
    ):
        return "SENSOR_SETUP_SUSPECT"

    if e.fluid_state == "liquid":
        return "LIQUID_CONFIRMED"

    expected_phase = e.phase in {"    within_window = (
        e.phase_elapsed_ms <= policy.expected_interface_window_ms
    )
    short_event = (
        e.event_duration_ms <= policy.max_expected_air_event_ms
    )tion_ms <= policy.max_expected_air_ms

    if e.fluid_state == "air" and exp    if (
        e.fluid_state == "air"
        and e.phase == "aspiration"
        and e.pump_running
        and e.pump_direction == "forward"
    ):
        return "POSSIBLE_AIR_INGRESS"nd e.phase == "aspiration" and e.pump_running:
        return "POSSIBLE_AIR_INGRESS"

    return "NEEDS_HUMAN_REVIEW"

这段逻辑故意不让 AI 自由生成安全动作。它先输出有限状态,再由已经批准的设备策略映射为“继续并记录”“暂停液体运动”“检查安装与清洁”或“安全保持”。硬件联锁和项目风险分析始终优先。

六、9 个测试比一句“代码能跑”更有说服力

我为完整示例编写了 9 项单元测试:

测试 期望结果
液体状态、证据有效 只能确认当前液体证据,不夸大为整机健康
早期灌注、短气体事件 EXPECTED_INTERFACE
稳定吸液、相同气体事件 POSSIBLE_AIR_INGRESS
灌注阶段气体持续过久 NEEDS_HUMAN_REVIEW
样本时间戳过期 COMMUNICATION_INVALID
帧/CRC 失败 COMMUNICATION_INVALID
配置版本不一致 SENSOR_SETUP_SUSPECT
存在残留疑点 SENSOR_SETUP_SUSPECT
重复或回放序列 COMMUNICATION_INVALID

本地运行结果为 9 项全部通过。真正接入设备后,还应把单元测试扩展为台架验证矩阵:

  • 不同管径、壁厚、管材、批次和安装方向;
  • 水、缓冲液、实际试剂或风险可控的替代液;
  • 接近检测边界的小气泡、连续气泡、液滴、空管与气液界面停留;
  • 不同泵速、脉动、阀路切换时序和流程阶段;
  • 管壁污染、残留、划痕、冷凝和管路滑脱;
  • 正常帧、坏帧、超时、掉线、旧数据、重启和错误配置;
  • 从事件进入检测区到受限动作生效的端到端延迟。

测试报告应保存原始帧、时间戳、配置版本、泵阀状态、样本条件和最终判定,而不是只写一个脱离条件的“准确率”。

七、状态不是根因:诊断轨道与控制轨道要分开

状态机输出 POSSIBLE_AIR_INGRESS 后,工程师仍然不能把根因字段直接写成“管路漏气”。同一状态至少可能来自:试剂瓶接近空液、吸液针暂时离开液面、接头密封不良、切换阀路中残留气体、泵反向或流程阶段标记错误。若证据门已经发现配置不匹配、残留或通信异常,则连“空气进入管路”这个物理解释也需要暂缓。

因此建议把后续处理拆成两条轨道:

  • 控制轨道只回答“在当前风险等级下,设备现在允许做什么”;
  • 诊断轨道回答“还缺哪些证据,才能缩小原因范围”。

一个适合设备策略和手机端审阅的状态清单如下:

EXPECTED_INTERFACE:预期气液界面

  • 确定性策略可以做:继续受限运动、记录事件,并监控是否在允许窗口内恢复为液体;
  • 不能直接宣称:管路绝对正常;
  • 仍需证据:恢复时间、切换配方、泵阀时序。

POSSIBLE_AIR_INGRESS:可能发生吸入侧进气

  • 确定性策略可以做:暂停相关液体运动,或进入项目批准的安全保持;
  • 不能直接宣称:已经确认漏气、试剂耗尽或传感器故障;
  • 仍需证据:试剂余量、吸液针位置、接头密封、阀路和事件持续时间。

SENSOR_SETUP_SUSPECT:安装或配置前提可疑

  • 确定性策略可以做:阻止自动放行,提示检查安装与清洁;
  • 不能直接宣称:管路中一定存在气泡;
  • 仍需证据:管径配置、管路贴合、残留、透光与表面状态。

COMMUNICATION_INVALID:通信或数据证据无效

  • 确定性策略可以做:保留上一安全状态,禁止把未知值映射成“无气泡”;
  • 不能直接宣称:液路正常或异常;
  • 仍需证据:原始帧、超时、CRC/帧校验、时间戳和序列号。

NEEDS_HUMAN_REVIEW:需要补充证据并人工判断

  • 确定性策略可以做:保存上下文并请求人工判断;
  • 不能直接宣称:让 AI 自行补全根因;
  • 仍需证据:相邻时间窗、泵阀日志、图像或复测结果。

这里最重要的不是动作名称,而是未知状态不能穿过默认分支变成正常状态。例如通信超时后,如果程序保留了布尔变量的初始值 False,上层很可能把它解释成“没有气泡”。正确做法是让通信无效、物理状态未知和已确认液体成为三个不同的值,并分别进入测试。

诊断日志也不应只保留最终报警。建议保留事件前后一个可配置时间窗内的原始观察值、泵速、泵向、阀路、流程阶段、配方与软件版本。这样工程师才能重放判定,AI 才有可能在不越过控制边界的前提下,帮助整理候选原因。

八、Claude Code、Codex 和 AI Agent 最适合做什么?

在这套架构中,AI 的价值并没有变小,反而更容易验证:

  • 根据已批准的通信手册生成协议适配器骨架;
  • 补齐超时、坏帧、重放、配置错配等故障注入测试;
  • 从验证矩阵生成参数化用例和测试报告模板;
  • 汇总长时间运行日志,给出候选原因和需要补采的证据;
  • 检查是否把 timeoutunknown 错误映射成“液体正常”;
  • 生成变更摘要,提示哪些策略参数需要重新回归。

不适合交给 AI 自由决定的是:未公开的寄存器地址、没有台架依据的阈值、设备安全动作和最终放行结论。

Opentrons 官方文档明确提示 AI 生成的实验协议可能出错,真实运行前需要审查,并提供协议可视化与错误检查。2026 年一项 AI Agent 操作先进科研仪器的研究也将人类层、Agent 层和物理仪器执行层分开;其低层仪器控制仍通过受限函数、代码检查、人工监督和确定性执行实现。

所以,工程上更稳妥的顺序是:

规格与风险定义边界 → AI 加速代码和测试 → 台架数据校准策略 → 确定性状态机放行 → 人对高风险动作负责。

九、落地时可以直接复用的检查表

在把气泡检测接入 IVD 或实验室自动化设备前,至少确认:

  • 原始物理状态与通信错误使用不同枚举;
  • 每条状态带时间戳、序列号和配置版本;
  • 灌注、吸液、切换、冲洗和空闲阶段有独立规则;
  • 泵向、泵速、阀路和配方版本进入同一条日志;
  • 过期、重复、坏帧和传感器未就绪进入安全保持;
  • 真实管材、管径、介质、残留和安装条件完成装机验证;
  • 小气泡、持续气体、液滴和空管分别测试;
  • 自动动作由确定性规则和硬件联锁约束;
  • AI 只能调用白名单工具,建议与执行结果均可追溯;
  • 阈值、策略或配方变更后有自动回归测试。

结语

AI 编程工具让“读到一个 Modbus 状态”越来越容易,但设备工程的价值正在从代码数量转向证据质量。

一次 air 信号能否如果你在做 IVD、分析仪器或实验室自动化设备,你遇到的气泡误判更多发生在灌注、试剂切换,还是稳定吸液阶段?真正缺失的通常是传感器精度,还是流程上下文?

参考的一手资料型能否写出更像样的解释,而取决于团队是否把通信质量、配置身份、流程阶段、泵阀上下文、事件持续时间和装机验证组织成一条可审计证据链。

当这些边界被写进 Schema、状态机和测试,Claude Code、Codex、ChatGPT 或其他 AI Agent 才真正成为工程加速器;如果跳过证据门,它们只会更快地产生一个听起来合理、却无法放行的结论。

参考的一手资料

  1. FOREACH,ABD 气泡检测模块公开产品页与规格资料:https://www.foreachtek.com/products/control/abd-air-bubble-detector/
  2. Modbus Organization,Modbus Application Protocol Specification V1.1b3:https://www.modbus.org/modbus-specifications
  3. Panasonic Industry,Optical Bubble Sensor BE-A / BE-AH:https://tp.industry.panasonic.com/en/products/fasys/sensor/particular/be-a
  4. SONOTEC,Flow Monitor Operating Manual 与 SONOCHECK ABD06 Technical Data Sheet:https://www.sonotec.eu/fileadmin/user_upload/business_units/1-non-invasive-fluid-monitoring/download/flow-monitor/om-flow-monitor-en-sonotec.pdf
  5. Introtek,ADU Series Sensor and Air Bubble Detector:https://www.introtek.com/Products/Air-Bubble-Detectors/ADU
  6. Opentrons,OpentronsAI 与 Protocol Visualization:https://docs.opentrons.com/flex/protocols/opentrons-ai/
  7. Vriza et al., Operating advanced scientific instruments with AI agents that learn on the job, npj Computational Materials (2026):https://www.nature.com/articles/s41524-026-02005-0
Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。

更多推荐