- 问题背景
给制造业做系统集成,最常遇到的状况不是"接口调不通",而是接口全都调通了,业务还是靠 Excel。
典型现场:企业三年前上 ERP,排产依旧在 Excel 里做。为什么?因为排产需要四个输入------实时的可用产能、准确的库存、当前有效的 BOM、在制工单的进度------ERP 能给出其中零个可信用值。
这不是 ERP 的问题,是集成架构的问题。本文按数据流顺序拆解。 - 四套系统的职责边界:先定义"谁是主"
集成的第一步不是画接口,是定义主数据所有权。没定义清楚就开发,结果一定是双向写、互相覆盖、最后没人知道谁的数是对的。
按离散制造的通行做法:
系统
定位
主数据所有权
关键输出
PLM
产品定义
物料主数据、BOM、工艺路线、图纸版本
生效 BOM、工艺版本
ERP
计划与账务
客户/供应商、价格、库存账、财务凭证
销售订单、采购订单、生产工单、应付应收
MES
制造执行
工单执行状态、工序实绩、在制、设备状态
报工实绩、良率、工时
WMS
实物仓储
库位、批次/序列号、实物库存
出入库流水、库位变动
关键原则三条: - 主数据单点写入。物料主数据由 PLM(研发型)或 ERP(订单型)单点维护,另一端只读同步。双写是灾难的起点。
- 状态数据由产生方持有。工单状态归 MES,ERP 只订阅不修改;库存实物归 WMS,账面归 ERP,差异通过盘点对账而非双向覆盖来消除。
- 版本必须带生效条件。BOM、工艺路线不是"最新版",是"某时间点/某订单生效的版本",否则回传的历史实绩永远对不上成本。
- 主数据流:BOM 同步的幂等与版本控制
这是集成里最容易埋雷的一环。典型错误实现的伪代码:
反例:全量覆盖式同步
def sync_bom_from_plm(item_code):
bom = plm.get_bom(item_code) # 拿到"当前"BOM
erp.delete_bom(item_code) # 删掉旧的
for line in bom.lines:
erp.insert_bom_line(item_code, line)
三个问题:删除期间有窗口期导致下游读到空 BOM;无版本号导致无法追溯;失败无回滚导致半套 BOM。
正确做法要点:
- PLM 侧为每次 BOM 变更新增版本号与生效时间,ERP 按 (item_code, bom_version, effective_from) 唯一键写入,不做物理删除,只做失效标记。
- 同步接口设计为幂等:同一版本重复推送,结果一致。用内容哈希(如 sha256(normalized_bom_json))做去重键,比时间戳可靠。
- 变更走事件而非轮询:PLM 发布 bom_released 事件,携带 item_code / version / effective_from / hash,ERP 消费后回 ACK。轮询全量对比在十万级物料下不可用。
- 下游依赖方订阅变更:MRP 计算读取时按 effective_from <= 计算基准日 <= effective_to 取版本,而非取"最大版本号"。这一条不遵守,历史订单重算必错。
物料编码同理:一物一码,编码规则一旦发布不可变,属性变更走版本,不做编码变更。这条规则在项目启动会上就要定死,落地后再改的代价极高。
- 业务流:工单的下行与实绩的上行
一条工单的完整链路:
销售订单(ERP) → MRP运算(ERP) → 生产工单(ERP)
→ 下发MES(含BOM版本引用、工艺路线引用、计划数量、计划起止)
→ MES拆工序派工 → 报工(数量/工时/良率/报废)
→ 实绩回传ERP → 成本核算(材料+人工+制造费用)
← 同步 ← WMS领料/入库流水
下行接口的字段设计有两个易错点:
- 必须传 BOM 版本号和工艺版本号,不能只传物料号。否则 MES 领料按最新 BOM 扣,成本按旧 BOM 算,差异无从归因。
- 必须传计划起止与优先级,且约定"改单"的处理方式(撤回重发 / 增量修正是两种完全不同的实现,后者复杂得多)。建议一期只支持撤回重发,语义清晰。
上行接口(实绩回传)的事务边界是另一个坑: - 报工不是一次性完成的。同一工单同一工序会多次报工(早班/中班/加班),回传必须是增量语义,携带 report_id 做幂等,严禁"覆盖式回传总量"。
- 跨系统事务不可用。ERP 写成本凭证与 MES 写实绩无法放进同一个分布式事务。实践上用最终一致 + 对账:MES 维护待回传队列,失败重试(指数退避),每日跑一次工单实绩与成本归集的差异报表,差异超阈值告警。
- 完工判定要显式。reported_qty >= plan_qty 不等于完工,需 工单关闭 显式事件,否则超领、尾数处理会一直挂着。
- 库存一致性:账实不符的技术解法
"系统显示有、仓库翻不到"在技术上是账面与实物两条记录流没有唯一对齐锚点。
解法的核心不是加盘点频次,是加锚点:
- 库位 + 批次/序列号 构成最小库存单元(SKU-Location-Lot)。ERP 的库存余额表按此粒度建账,而非按物料汇总。
- 出入库必须由业务事件驱动,不允许手工调账。调账走独立的盘点单流程,留痕、需审核。
- WMS 每次变动发流水事件(stock_moved),携带变动前后数量与来源单据号,ERP 消费后生成凭证。流水是唯一事实来源,余额是派生物,可随时重算校验。
- 实时库存查询走缓存投影。ERP 直接查库存在高并发扫码场景下扛不住,用 WMS 侧的库存投影表(或 Redis)对外提供查询,与账务解耦。
账实相符率的工程指标建议:以"SKU-Location 维度账面与实盘一致的比例"计量,按周统计,低于目标值先查流程(是否扫码漏扫),不要先怀疑系统。
- 五个踩坑复盘
坑一:先上算法,后补数据。
给库存准确率 70% 的企业上智能排产,结果是排出来的计划没人敢用。顺序必须是:编码统一 → BOM 校准 → 库存准确率 → 现场报工 → 排产优化。跳过前置环节的算法投入,回收率接近于零。
坑二:用接口数量衡量集成度。
对接了 47 个接口,业务上仍需人工搬三次数据。有效的度量是人工介入点数量:一条工单从下单到成本结算,中间需要人工录入几次?目标是一次。这个指标比接口数诚实得多。
坑三:把 MES 做成 ERP 的填报终端。
只采报工数量、不采设备与工序状态,MES 退化成电子工票,排产依旧无数据可用。MES 的最小可用集是:工序级报工 + 设备状态 + 在制位置。
坑四:主数据双写。
研发在 PLM 改物料描述,采购在 ERP 也改了一版。三个月后两套数据对不上,追溯成本极高。双写必须禁止,同步方向单向,冲突时以所有者为准并告警。
坑五:忽略组织与核算维度。
多基地企业集成时,物料、客户、科目都要带组织维度。一期按单组织设计,二期扩多基地时几乎要重构。若企业有跨区域工厂,第一版就要把 org_id 放进所有主键。 - 集成健康度自检清单
可直接用于项目评审:
每类主数据的所有者是否唯一且文档化?
BOM / 工艺是否按版本 + 生效时间管理,而非"最新版"?
工单下行是否携带 BOM 版本与工艺版本?
报工回传是否为增量 + 幂等(report_id)?
跨系统失败是否有重试队列与差异对账报表?
库存余额是否可从事务流水完全重算?
是否存在任何人工调账入口?是否有审批留痕?
所有主子表是否带组织维度?
"一条工单人工录入次数"当前是多少,目标是多少? - 关于工业 AI 的落地判断
给一个工程视角的判据:AI 模块是否承担了一个原本由人做出的判定?
- 承担了:视觉质检判 OK/NG、排产给出可执行方案并被采纳、需求预测直接生成采购建议。这类可以进入主流程。
- 没承担:报表美化、看板动效、自然语言查询。这类属于 BI,不占用"AI 项目"的预算。
另外,AI 模块的输出必须可解释、可回退。排产建议要能说清约束冲突在哪,视觉质检的 NG 判定要能复核。不可解释的判定在车间不会被接受,这是工程现实,不是技术洁癖。
- 小结
系统集成的成败,90% 取决于集成架构设计之前的三件事:主数据所有权定义清楚、版本与生效机制设计到位、状态数据的产生方唯一。
技术选型(消息队列、ETL、iPaaS、还是直接点对点)反而是次要的。见过用最朴素的定时任务跑得极稳的系统,也见过堆了整套中台仍然靠 Excel 的工厂。
本文为工程实践总结,示例代码为示意性伪代码,不涉及任何商业产品实现细节。