开篇:为什么是 QMS 质量追溯

一、场景:一纸投诉,倒逼三天的纸质记录
做工业软件这些年,我几乎把同一个注塑厂从车间这头跟到了那头。第一年做 SCADA,8000 个点位、1 秒刷新,把 PLC 里的温度、压力、锁模力搬上大屏;第二年做 APS 智能排产,帮注塑车间的王主任把 Excel 里手排的 20 张工单、12 台注塑机、4 台 CNC 的排产,从下午 2 点压到 30 秒出结果。到第三年,王主任又把我叫去了——这次不是排产,是一纸投诉。
主机厂发来质量通报:上个月送过去的 P-1002 成品组件,装配后出现外壳开裂,主机厂要求 24 小时内书面回复六个问题:这批货用的原料是哪家供应商、哪个炉号?在哪个机台、哪个班次、什么时候生产的?同批原料还流向了哪些客户、哪些批次?检验记录呢——抽样方案是什么、抽了多少、判定结果是合格还是不合格、谁检的?
王主任把品质部三个人喊进会议室,桌上堆着半人高的纸质《来料检验记录》《过程检验记录》《出货检验记录》,每张单据手写,按日期装订,一个月的量。要从这几千张纸里找出一批货的料、机、人、检,只能一摞一摞翻。翻了整整三天,最后给出的回复还是"大概、可能、应该在"。主机厂不满意,扣了 3 万块的供应商质量保证金。
那天下午王主任跟我说了一句话,我到现在还记得:"排产排不好,顶多晚几天;质量追溯追不出来,是要赔钱、要丢客户的。"
问题就出在四个字上——记录是"死"的。纸质单据记录了每一个检验动作,但它们之间没有"关系"。这批成品用了哪批原料?不知道,要人去对日期、对工单号、对班次,靠记忆和猜测把两张纸关联起来。一旦关联靠人脑,追溯就是一门玄学。
后来我复了个盘:这次追溯一共花了 3 个人 × 3 天 = 9 个人天,最后给出的结论还带"大概"。如果这批料流向了 5 个客户,要把 5 个客户各自的那批货都圈出来,靠纸质记录基本不可能——因为"同批原料流向哪里"这个信息,在纸上是反着的:每张成品单据只写了"我用了一批料",但没有一个地方写"这批料被谁用了"。要回答正向的问题,得把几千张单据全翻一遍、人工建倒排索引。这就是纸质追溯的死穴。
二、问题分析:记录不是"没记",是"记了找不着"
我让品质部把最近一个月的记录摊开做了个统计,问题很清楚:
第一,记录之间没有链路。 来料检验单记了"原料批次 B-20261013-001,供应商 X 塑胶厂",过程检验单记了"成品批次 B-20261013-002",出货检验单记了"客户 A 的订单 WO-20261013-001"。三张单据上有三个编号,但没有任何一条记录说"B-002 是由 B-001 投料生产出来的"。追溯的时候,靠的是质检员回忆"那天上午领的是哪批料"。
第二,判定靠人。 抽样方案在质检员脑子里——"这个料一般抽 125 个,超 7 个就不合格"。为什么是 125?为什么是 7?没人说得清,因为那是老师傅的经验。换一个人、换一批货,可能就变成"抽 80 个,超 10 个"。判定标准不统一,出了争议没有依据。
第三,过程能力看不见。 外径这个尺寸的实测值散落在几千张纸上,没有人去画一条均值线、一条控制限。尺寸在慢慢漂移、刀具在慢慢磨损,谁也看不见,直到批量超差、整批报废,才发现"最近这周好像不太对"。这叫"事后把关",不叫"过程控制"。
第四,数据孤岛。 SCADA 里有每台注塑机的实时温度、压力,APS 里有每张工单的机台和班次,但质量数据在纸上。设备参数和质量结果之间,隔着一道墙——出了质量问题,你想查"那批货生产时 2 号机的模温是多少",查不到。
这四条归结起来,就是我前面两个项目都没解决的问题:SCADA 管"读数",APS 管"排活",但没有人把"料—机—人—检—果"这几条线串成一个可以往上往下走的谱系图。这就是 QMS 要补的那块。
再往下拆一层,这四条其实对应四个"必须数字化"的关键动作:链路要成图(否则追不动)、判定要成表(否则不可复现)、数据要成序列(否则画不出控制图)、事实要能对齐(否则设备参数和质量结果对不上)。这四件事,正好决定了后面章节要讲的四个引擎——追溯、AQL、SPC、以及把它们粘起来的批次模型。
三、QMS 和 SCADA、APS、MES 到底什么关系
同一家厂,同一个车间,我做了三个系统,经常被问"它们是不是重复了"。我的比喻是这样的——
| 系统 | 角色 | 一句话职责 | 回答的问题 |
|---|---|---|---|
| SCADA | 传感器 | 采集设备时序数据 | "这台机器此刻的模温是多少" |
| APS | 大脑 | 求解排产计划 | "这批活排在哪台机器的哪个时段" |
| MES | 手脚 | 派工、报工、在制品追踪 | "这张工单现在做到第几道工序了" |
| QMS | 守门人 + 记忆 | 检验判定、缺陷记录、批次谱系追溯 | "这批货合不合格,出了问题怎么往回追" |
这里要特别说清楚 QMS 和 MES 的边界,因为很多人把它们混为一谈。MES 是"执行层"——它关心工单跑到哪了、设备开没开、在制品卡在哪道工序。QMS 是"质量层"——它关心这批料合格不合格、缺陷是什么、处置怎么给、出问题怎么追。MES 会问"报工了吗",QMS 会问"检验判定是什么"。一家厂可以只有 MES 没有 QMS(那就靠质检员手记),也可以只有 QMS 没有 MES(那就靠纸质工单驱动),但质量追溯这件事,只能由 QMS 承担——因为追溯的对象不是工序进度,而是"物料批次之间的谱系关系",这是 MES 的二维工单视图装不下的。
和 APS 的区别更直接。APS 是"往前看"的——给定工单和资源,求一个未来的排产计划,是求解器。QMS 是"往回看"的——给定一个问题批次,沿着历史链路找出它的上下游,是图遍历。一个产出计划,一个沉淀事实。写 APS 连载时我说 APS 是"求解器 vs 管道"的对比,QMS 则要引入第三种视角:它是图的遍历,不是管、也不是解。
三个系统的数据流其实是一条线:SCADA 采集设备数据 → APS 决定这批活排在哪台机、什么时候做 → MES 派工报工、做出来的每一批料入库存档(建批次)→ QMS 收货检验、记录缺陷、维护批次谱系。换句话说,SCADA 和 APS 管的是"过程",QMS 管的是"结果和它的来龙去脉"。王主任排产排得再漂亮,做出来的货追不回去,一样要赔钱。
四、行业对比:Excel、纸质、商用 QMS、自研
决定自研之前,我把市面上的质量追溯方案摸了一遍,和当年对比 ThingsBoard、Demantra 是同一种尽职调查。
第一类:纸质 + Excel。 这就是王主任的现状。优点是零成本、上手门槛低;缺点是四个致命伤——检索慢(人工翻)、关联弱(靠人脑连)、判定随意(靠经验)、无法统计分析(画不出控制图)。对于出货量不大、客户要求不严的小作坊,纸质能凑合;但只要遇到主机厂、医药、食品这类"出事要 24 小时回复、要写 8D 报告"的客户,纸质直接出局。而且纸质追溯的成本是隐性的——平时看不出来,出事时一次性爆发(这次的 3 万块保证金 + 客户信任)。
第二类:商用 QMS 套件。 Siemens Opcenter Quality、SAP QM、MasterControl、ETQ Reliance、Pilgrim Quality。这些是行业标杆,功能极其完整——检验计划、抽样方案、SPC、FMEA、CAPA、8D、供应商协同、审计追踪,一套就是完整的质量信息化平台。优势是成熟、合规(符合 FDA 21 CFR Part 11、ISO 13485 等法规,有完整的电子签名和审计追踪)、可审计。缺点同样致命:贵(MasterControl 一套授权几十万起,SAP QM 更是绑在 S/4HANA 上,实施周期 3 个月起)、重(要专职 IT 运维,要配置化建模)、黑盒(追溯链路的实现你看不到,出了问题只能等原厂支持)。有一家医疗器械厂的朋友上 ETQ,光"批次谱系"这一块的配置和测试就做了两个月。中小注塑厂绝对用不起,也用不明白。
第三类:开源 QMS。 比如 openQMS、Kiwi QMS,还有一些基于 Odoo 的质量模块。这些便宜,但功能偏"台账化"——记录检验结果可以,做批次谱系追溯、做 SPC 控制图、做 AQL 自动抽样,基本都没有。它们解决的是"把纸电子化",而不是"把质量串成图"。
第四类:自研。 这是我最后选的。理由有三条——
- 追溯的核心是图遍历,不是功能堆砌。商用 QMS 卖的是"完整体系",但我们工厂真正卡住的只有一个点:沿着批次把料串起来。这个核心用一张邻接表 + 一个 BFS 算法就能解决,不需要一整套 8D/CAPA/FMEA 体系。
- 数据必须留在自己厂里。批次谱系里全是供应商、炉号、客户订单这些敏感信息,交给云端 SaaS 有合规风险,自己部署在厂内 Postgres 上最踏实。
- 和已有的 SCADA/APS 同栈。三个项目都用芋道(ruoyi-vue-pro)脚手架、都连 PostgreSQL、都是 Spring Boot + MyBatis-Plus,QMS 作为第三个模块加进去,运维、部署、认证是一套的。复用基础设施的价值,远大于直接买一套陌生的商用套件。
四类方案横着一比,结论其实很干净:
| 方案 | 成本 | 上线周期 | 追溯能力 | 数据归属 | 适合谁 |
|---|---|---|---|---|---|
| 纸质 + Excel | 近乎零 | 立即 | 靠人工、不可靠 | 纸质在厂 | 小作坊、客户无要求 |
| 商用 QMS 套件 | 几十万起 | 3 个月起 | 强但黑盒 | 本地或云端 | 大厂、强合规行业 |
| 开源 QMS | 低 | 几天 | 弱(多为台账) | 本地 | 只求电子化的小厂 |
| 自研(本系统) | 人力 | 数周 | 核心强、可控 | 本地 | 中小制造厂、单点痛点 |
还有个容易被忽略的对比维度:商用 QMS 卖的是"合规",我们买的是"效率"。MasterControl 的价值在审计追踪、电子签名、法规符合性——那是给 FDA、公告机构看的。而王主任卡住的是"能不能 24 小时追出来",是效率问题。用一套几十万的合规套件去解决一个效率问题,性价比极低。
五、取舍表:这张清单决定了整个系统长什么样
自研最大的风险是"越写越大"。所以动工前我先给自己立了一张取舍表,把"做什么、不做什么"钉死。这张表直接来自 README 的核心取舍:
| 取舍 | 决策 | 理由 |
|---|---|---|
| 谱系存储 | 邻接边表 `qms_trace_link` + 内存 BFS | 中小工厂批次规模下无需 Neo4j 等图数据库,关系库 + 应用层图遍历更轻、可运维 |
| 抽样方案 | 内置简化查表引擎(字码表 + AQL 主表) | GB/T 2828.1 主表有限,硬编码查表比引入规则引擎更快;商用需按标准全文补全 |
| SPC 计算 | 纯 Java 实现,不引入 commons-math3 | 均值/极差/标准差计算逻辑简单,少一个第三方依赖少一份升级风险 |
| 处置规则 | 规则引擎给出建议,人工/MRB 终审 | 致命缺陷不完全自动化,保留 MRB(物料评审)人工决策闭环 |
| 数据模型 | 6 张核心表 | 检验单/检验项/缺陷/批次/追溯链路/SPC 采样点,无多余关联表 |
这张表里我最有感触的是"谱系存储"那一条。第一反应一定是"用图数据库啊,Neo4j、JanusGraph 不是专门存图的吗"。但对一个批次规模在几十万条以内、追溯只做正反两跳的注塑厂,Neo4j 是杀鸡用牛刀——多一个数据库就多一套运维、备份、高可用、调优,而我们的 Postgres 里已经有 6 张表在跑。用邻接表 + Java 内存 BFS,代码不到 100 行,EXPLAIN ANALYZE 一看就走索引,够用、可控、可解释。技术选型的第一原则不是"先进",是"运维得动"。
第二条"抽样方案用查表不用公式"也值得先说一句。GB/T 2828.1 是个思想性的标准——它背后的统计学(二项分布 + 接收质量限)可以用公式推导,但标准规定的是查表,因为查表结果可复现、可审计、可对簿公堂。你要是用公式现算,客户问"为什么抽 125 个",你得当场算给他看;用表查,一句"GB/T 2828.1 一般检验水平 II,字码 J,AQL 2.5,Ac=2"就完事了。选查表,选的是可审计性。
六、6 张表,一张图讲清整个系统
系统最终落在 6 张 PostgreSQL 表上,全部 DDL 和种子数据在 yudao-module-qms/src/main/resources/sql/qms-init.sql。文件头部的注释就是整个系统的浓缩:
# -*- coding: utf-8 -*-
"""QMS 质量追溯系统:6 张核心表。
表关系(ER 极简图):
qms_batch ──(自引用 parent_batch_id)── qms_batch
│ │
│ ├──(N) qms_trace_link ──(from_batch_id / to_batch_id)── qms_batch
│ │
│ └──(N) qms_inspection_order ──(N) qms_inspection_item
│ └──(N) qms_defect
│
└──(N) qms_spc_sample (按 product_code + characteristic_code 关联,弱关联无外键)
"""
六张表按业务闭环排一排,就是一句话:产出入库建批次(qms_batch)→ 投料拼批写链路(qms_trace_link)→ 送检验收建检验单(qms_inspection_order)→ 录检测项与缺陷(qms_inspection_item / qms_defect)→ 采样子组跑控制图(qms_spc_sample)。批次是主角,链路是关系,检验是判定,缺陷是处置,SPC 是能力。
我特意把表数压到 6 张。商用 QMS 动辄三四十张表(检验计划、检验模板、特性库、抽样标准、FMEA、CAPA、评审、审计追踪……),那是因为它们要覆盖"从设计到售后"的全生命周期。我们只覆盖注塑厂最痛的那一段——来料、过程、成品、出货四个检验点 + 批次谱系 + 过程能力——所以 6 张表足够。表少的好处是:DDL 一眼看完、JOIN 层级浅、出了问题定位快。
每张表在系统里的定位,一句话就能说清:
qms_batch:批次/序列号,追溯的主体单元。一次投料、一次生产产出,就是一个批次。带parent_batch_id(单级父,快查)和attributes(JSONB,存供应商/炉号等行业扩展)。qms_trace_link:追溯链路,谱系图的边。from_batch_id → to_batch_id加link_type(投料/拼批/分拆/装配/返工),BFS 就靠它走。qms_inspection_order:检验单,一次检验活动的主记录。带抽样方案 n/Ac/Re 和最终判定。qms_inspection_item:检验项,检验单下的检测特性。外径、外观、性能,各带标准值和实测值。qms_defect:缺陷记录,检验中发现的具体缺陷。严重度、数量、责任工序、处置方式。qms_spc_sample:SPC 采样点,控制图的一个子组。子组原始测量值 + 均值 + 极差 + 控制限 + 判异命中。
注意第 6 张表和前面 5 张在关系上有个刻意的"疏远"——qms_spc_sample 不和 qms_batch 建外键,而是靠 product_code + characteristic_code 弱关。原因很简单:SPC 关心的是"某个产品的某个特性在时间轴上怎么漂",跟具体是哪一批没有强绑定;把 SPC 硬挂到批次上,会让采样点不得不先建批次才能录入,反而卡住现场。
七、三个引擎,才是这个系统的"魂"
6 张表是骨架,真正让 QMS 区别于"Excel 电子化"的,是 framework/qms/ 下的三个纯 Java 引擎。它们不依赖任何第三方算法库,全部手写:
- AQL 抽样方案引擎(
framework/qms/sampling/):按 GB/T 2828.1 一般检验水平 II,由检验批量落到样本量字码(A~Q),再由字码 × AQL 水平查出样本量 n、接收数 Ac、拒收数 Re。把"老师傅的脑子"变成"可复现的查表"。 - 批次谱系追溯引擎(
framework/qms/trace/):邻接表 + 广度优先遍历,正向查"我的料流向了哪些下游批次"(召回场景),反向查"这个不合格品用了哪些上游批次"(溯源场景),用 visited 集合防环。 - SPC 统计过程控制引擎(
framework/qms/spc/):X-Bar/R 控制图控制限(查 A2/D4/D3 系数)、Cp/Cpk 过程能力指数、Western Electric 判异规则,全部纯 Java 数值计算。
再加一个小的 不合格品处置规则引擎(framework/qms/rule/),按缺陷严重度给出"返工/返修/让步接收/报废/退货"的建议,作为 MRB 物料评审的人工决策输入。
三个引擎合起来,正好回答王主任那张投诉单上的六个问题:抽多少检了没有(AQL)、同批料流去哪了(正向追溯)、这批货的料从哪来(反向追溯)、过程能力稳不稳(SPC)。
写 APS 时我用"适配层 5 个类"来概括"理解了它们就理解了整个系统"。QMS 也一样——三个引擎的核心类就那么几个:SamplingPlanEngine、GenealogyGraph、SpcCalculator、DispositionRuleEngine,加起来大约 400 行 Java,却撑起了整个质量追溯的专业能力。后面每一章,我都会挑一个引擎,把它的数组、算法、边界一次讲透。
动工前我给这次 PoC 定了五条可验收的目标,也写在了心里当尺子:一,任何一批货,输入批次号,10 秒内给出它的上游料和下游去向(正反向追溯);二,任何一次送检,抽样方案由系统查表给出 n/Ac/Re,不再靠老师傅脑子;三,任何一次判定不合格,缺陷自动带上处置建议,并把批次状态联动到"不合格"或"冻结";四,任何一个关键尺寸,能随时拉出一条控制图和 Cpk;五,整套系统能塞进已有的芋道工程里,一个 jar 加几张表,不引入任何第三方算法依赖。这五条不是功能清单,是验收红线——做不到的不写,做得到的做扎实。
八、商用化检查清单(开篇版)
和 SCADA、APS 连载一样,每章末尾放一张上线前要过的检查清单:
- AQL 主表是否按 GB/T 2828.1-2012 全文补全?当前为简化表(箭头单元格已坍缩,商用必须逐格核对)。
- 批次谱系是否有环?GenealogyGraph 用 visited Set 防环,但脏数据形成的环要在录入侧拦截。
- 追溯查询全量加载 links 是否有性能风险?大批量场景改用 PostgreSQL 递归 CTE(
WITH RECURSIVE)。 - SPC 子组容量是否落在 A2/D3/D4 系数表范围内(n=2..10)?超范围需查表扩展。
- 判异规则是否命中需求?当前实现 4 条 Western Electric 规则,可按客户 SOP 增补。
- 致命缺陷处置是否强制走 MRB 评审?规则引擎只给建议,终审必须在 MRB 会议留痕。
九、下一章预告:6 张表怎么建模
到这里,整个 QMS 项目的定位讲清楚了——它是质量层的"守门人 + 记忆",不是 MES 的执行、不是 SCADA 的采集、更不是 APS 的求解;它用邻接表 + BFS 解决追溯、用查表解决抽样、用纯 Java 解决 SPC,把商用 QMS 的"全生命周期体系"砍成注塑厂最痛的那一段。
但所有引擎的前提,是领域模型建对了——批次为什么要有 parent_batch_id 这条自引用?追溯链路为什么不能用 qms_batch 里的父子字段硬扛、非要单开一张邻接表?attributes 和 values_json 为什么用 JSONB 而不是拆成字段或子表?和 APS 的 6 张表相比,QMS 的 6 张表又差在哪?
下一章我会把 6 张表从头到尾讲一遍,每张表的设计决策、踩过的坑、为什么这样设计而不是那样设计——和 APS 连载里"6 张表讲清 APS"是同一种结构,但 QMS 的表之间的关系是"谱系 + 判定 + 采样",比 APS 的"工单 → 工序 → 资源"多了一层历史回溯的味道。
