输入:《飞书赋能场景探讨-粉料交付》(2026-08-20,7 页,立邦 IT 与业务共拟)+ SRM 系统既有资产(2026-08-23 实读) 输出:把 PPT 里的「四个场景 + 飞书解法」还原成需求,补出没说出口的部分,给出可排期的系统开发方案(自建系统功能,不用多维表格)
本文事实分三档,逐条标注,别混着读(沿用 01 号文档 的纪律):
标记 含义 原话 PPT 上的原文,一个字没改 实查 在 SRM 仓库读过代码/文件,带路径。结论会过期,落地前重扫 文档 取自 SRM 设计文档的转述,未复核代码。当线索用,不当依据用 推导 我按粉料(干粉砂浆/腻子/防水粉料/粉末涂料)供应链常识推出来的,立邦侧零验证。按 01 号文档定下的做法:不做成问卷,直接按推导填满并显式标注,让业务方指着反驳 ⚠️ 本文最重要的两句话:
- §1:四个场景不是四件事,是一条链上的四个断点。APS 排产(场景一)是果,另外三个是因。先做因,果才有可能。
- §6.3:手写 OCR 当主录入路径是这个项目最贵的一个坑——它错了不报错,只是把达成率换成另一个数。
0. 一页话结论
PPT 描述的四个痛点,业务感受是四种,病因只有一个:
立邦粉料的计划系统(APS/SAP MRP)跑在一份「时间上滞后、口径上不统一、来源上靠人转述」的数据上。
- 库存滞后 → 因为签收和过账是两个时点(场景二)
- 产出滞后 → 因为 130 家厂的实际入库靠纸质日报和群聊(场景三、场景四)
- 交期不实 → 因为 TUB 请求交期靠沟通、TUC 月底集中过账(场景一自己写了)
所以 PPT 的愿景「让机器学会排产」方向对,但排在第一位是错的。给一辆没油的车换发动机,换不出速度。
我的方案主张三句话:
| # | 主张 | 反对的是什么 |
|---|---|---|
| 1 | 先修数据入口,再谈智能排产。落地顺序是 场景二 → 场景四 → 场景三 → 场景一 | 反对按 PPT 顺序做(先啃 APS) |
| 2 | OCR 是稽核路径,不是主录入路径。结构化录入(扫码+选择+数字键盘)才是主路径 | 反对「拍照 OCR 直接入账」 |
| 3 | 四个场景共用一套主数据和一个执行链,不是四个看板 | 反对四张多维表格 + 四个机器人 |
1. ⭐ 四个场景不是四件事
PPT 第 7 页写「用飞书打通 APS 排产、签收同步、风险识别、入库达成四大场景」——「打通」这个词用对了,但四个场景在 PPT 里被画成了并列的四块。它们的真实关系是:
┌──────────────────────────────┐
│ 场景一 · APS 排产(决策层) │
│ 开单 → 排产 → 同步 SAP │
└───────▲──────▲──────▲────────┘
│ │ │
①库存准不准 │ │ │ ③交期/产能参数准不准
┌─────────────┘ │ └──────────────┐
│ ②产出准不准 │
│ │ │
┌───────────┴────────┐ ┌────────┴─────────┐ ┌─────────┴──────────┐
│ 场景二 · 签收同步 │ │ 场景四 · 入库达成 │ │ 场景三 · 交付风险 │
│ 纸质签收单→SAP过账 │ │ 车间日报→达成率 │ │ 130 家厂进度与异常 │
└────────────────────┘ └──────────────────┘ └────────────────────┘
(入的事实) (产的事实) (执行的事实)
三条箭头,每一条都是当前断开的:
| 箭头 | 现状原话 | 对场景一的毒害推导 |
|---|---|---|
| ① 库存 | 「签收与 SAP 存在时间差,库存滞后影响排产决策」 | MRP 跑的时候看到的可用库存偏低 → 净需求虚高 → 重复排产 / 重复采购。而且这个错不报错:MRP 算得出结果,只是结果是按错的库存算的 |
| ② 产出 | 「数据分散在群聊中,无法汇总分析,达成率核算滞后」 | 上一轮实际产出没进系统 → 下一轮排产的期初在制品是错的;且产能参数(单缸产量、小时产能)永远是配置值,从来没被实际校准过 |
| ③ 执行 | 「工厂分散各地,交付进度与异常依赖人工汇总上报」「风险信息严重滞后」 | 委外厂的实际交付能力不进系统 → 排产时把订单派给一家已经排不下的厂,而系统不知道 |
结论:场景一的四条「全自动排产受阻的根源」——交期数据不准、异常频发、覆盖不全、协调成本高——没有一条是排产算法问题。四条里有三条是场景二/三/四的输出。
所以顺序是:P1 场景二 + 场景四(数据入口,收益确定、无 AI 依赖)→ P2 场景三(执行闭环)→ P3/P4 场景一(决策层)。详见 §9。
1.1 顺带解决 PPT 没提的一件事
场景四的日报里有「原料异常」和「设备异常」两个字段原话。PPT 只把它们当成"需要登记的字段"。它们的真实价值是:
- 原料异常 → 是供应商质量的一手数据(结块、水分超标、批次不符)→ 喂给供应商绩效
- 设备异常 → 是产能参数的校准依据 → 回头修正场景一「车间档案」里那些没人维护的静态产能值
这条闭环是 PPT 完全没有的,但它是「入库达成」这份数据的最高价值用途:让 APS 的产能参数从"配置的"变成"实测的",直接打掉场景一「配置体系庞大且缺乏灵活性」的一半。
2. 为什么不能用多维表格——以及飞书该干什么
用户已经定了「要开发系统功能」。但这个决定需要能对着立邦 IT 讲出理由,否则第一次评审就会被"先用多维表格快速试一下"带回去。以下是五条理由,按杀伤力排序。
2.1 多维表格是第二本账,而这四个场景的病根恰恰是"账不止一本"
130 家厂的入库数进了多维表格,SAP 的库存还是错的,MRP 还是算不准。 于是场景一永远解决不了,而所有人都以为"我们已经数字化了"——因为看板上有数。
⚠️ 这是本项目最危险的失败形态:它不报错,它交付一个漂亮的看板,然后病根原封不动。 文档SRM 40 号文档里同一条经验的原话:「算错不会报错,只会给出一个像模像样的错数。而 BI 图表的消费场景是拿去开会——一个看起来专业的错数比没有这张图更贵。」
2.2 没有主数据,达成率永远算不对
车间纸上写「3号磨机」,另一个厂写「3#磨」,第三个厂写「磨3」。
多维表格里这是三行不同的数据;在系统里这必须是同一个 equipment_id。
同理:物料编码、工厂编码、班次编码、异常码。 没有主数据的 OCR,识别得越准,垃圾进得越快。
2.3 没有状态机,异常就只是"填了一行"
场景三要的是「从被动上报到主动预警」原话。 但预警之后呢?谁处置、多久内、超时升级给谁、处置结论回写到哪张单?
文档SRM 21 号文档定过一条判据,这四个场景全部适用:
闭环成立的四个要件,缺一条就退化成"会聊天的机器人": ① 收敛目标(什么算办完了)/ ② 双向通道(发得进去,也读得到回复)/ ③ 多轮记忆(跨天记得问过什么、还差什么)/ ④ 结果落点(结论写回哪张表,谁批准这次写入)
「第 ④ 条是最容易被跳过、也最致命的。如果 agent 聊完了采购还得自己填交期,那只省了一半——而且是不痛的那一半。」
多维表格 + 机器人能做到 ①②,做不到 ③④。
2.4 OCR 没有比对对象,等于把人眼换成机器眼
这是 01 号文档 §4·N2 已经写过的一条,在本项目里再次成立:
识别出来的字段,必须有东西可比对,否则判定还是人在做——一分钱不省。
场景二的正确形态不是"读懂这张签收单",而是**"这张单对应我系统里哪张 ASN?读出来的每一行和我的行对不对得上?"** 有比对对象,候选集从「所有物料」缩到「这张单上的 5 行」,准确率和可验证性同时上一个台阶(§4.4)。
多维表格的 OCR 是通用识别,天然没有比对对象。
2.5 先做表格 = 给自己排两次工期
权限分级(130 家外部厂 + 内部区域 + 集团)、审计留痕、SAP 幂等过账、并发与性能、 异常队列与重试——这些在多维表格里一个都做不了,业务一跑起来就得重做一遍。
2.6 那飞书该干什么——三件事,且只干这三件
不要把"不用多维表格"误读成"不用飞书"。飞书在这个方案里很重要,但边界要划死:
| ✅ 飞书该干 | 为什么 |
|---|---|
| 通知与交互的最后一公里:卡片、按钮、@人、审批 | 实查SRM 已有生产在跑的双向通道:入站长连接 modules/integration/feishu/FeishuEventClient.java,群里回复 → 路由到在办任务 → 推进状态机 → 回写单据 |
| 身份与组织:H5 免登、通讯录、群 | 文档SRM 41 号 M3:POST /auth/feishu/h5,code → user_access_token → open_id |
| 移动端容器:现场作业 H5 的宿主 | 不用装 App,扫码即用 |
| ❌ 飞书不该干 | 失败形态 |
|---|---|
| 存业务数据 | 第二本账(§2.1) |
| 算指标 | 口径散落在 130 个表格公式里,没人知道哪个对 |
| 做状态机 | 异常报了没人处置,而现场以为报上去了 |
| 当权威源 | SAP 和飞书的数不一致时,没有仲裁规则 |
⭐ 一条必须原样搬过来的安全口径文档SRM 41 号 M3: 飞书认证成功 ≠ 可以登录系统。 中间必须隔一次显式绑定(
app_user.feishu_open_id), 查不到就拒绝,绝不自动建号——否则任何能进这个飞书企业的人(外部联系人、实习生、 未配权限的新人)都自动有了内部账号。立邦这个项目里这条更要紧:场景三要拉 130 家外部委外厂进来, 一旦自动建号,外部厂的人就有了内部系统账号。
且四种拒绝要分开说,因为下一步动作完全不同:未配置 503(部署问题)/ code 无效 401(可重试)/ 没绑定 403(重试一万次也没用,要去找人) / 停用 403。
场景一 · APS 排产之困
3.1 PPT 说了什么原话
七步流程,步步需人:
| 环节 | 原话 |
|---|---|
| 开单模块 | 新建 MRP 后需人工选择工厂、读取 SAP 数据,核心环节人工判断和修改不可或缺 |
| 排产模块 | MTO/MTS 创建工单后仍需人工介入调整,智能排产初始化后也要人工判断和修改(细排) |
| 同步环节 | 排产结果同步至 SAP,需要人工选择工厂和 APS 排产单号 |
全自动排产受阻的四个根源:
| 原话 | |
|---|---|
| 期 | 交期数据不准:TUB 请求交期每单需沟通;TUC 要货日期不准,且月底集中过账 |
| 异 | 异常频发:订单集中下达、加急、销售备货;无有效 BOM 需反复沟通 |
| 覆 | 覆盖不全:自产 SKU 多且杂,防水产品尚未实现 APS 排产 |
| 调 | 协调成本高:包材原料采购异常、专用助剂替代、无货源沟通均需人工处理 |
配置体系庞大且缺乏灵活性:
| 配置 | 原话 |
|---|---|
| 全览表 | 工厂与 SKU 别配置工作量大,不完成配置则无法推进下一步 |
| 切换表 | 集团统一配置,不支持工厂别、设备别的个性化差异 |
| 半成品放量 | 需按工厂别单独配置,依赖各厂作业习惯 |
| 车间档案 | 工厂与设备别需逐一设定单缸产量、单双班、日产能、小时产能 |
愿景:① 界面整合为开单与排产两大模块,人工判断处停顿,机械操作自动跳转执行;② 通过机器学习掌握开单调整与排产调整技能,覆盖 MRP 修改记录、备货学习、排产结果学习、月排产日历及交期与切换成本统筹约束;③ 进一步实现原物料与包材的智能采购决策。
3.2 还原:七步背后其实是三个问题,只有一个和排产有关
推导把七步拆开看,"人工"出现在三种完全不同的位置上,它们的解法互不相同,混在一起谈就永远得不出方案:
| 类型 | 七步里的位置 | 本质 | 该怎么解 | 需要 AI 吗 |
|---|---|---|---|---|
| A · 机械操作 | 「人工选择工厂」「读取 SAP 数据」「人工选择工厂和 APS 排产单号」 | 流程编排缺失:上下文明明已知(这次跑的就是华东厂),却要人再选一次 | 上下文透传 + 自动跳转 | ❌ 不需要 |
| B · 数据补洞 | 「无有效 BOM 需反复沟通」「TUB 请求交期每单需沟通」「无货源沟通」 | 主数据/前置数据缺失,人在用沟通补系统的洞 | 把洞堵上(BOM 有效性闸门、可承诺交期引擎、货源主数据) | ❌ 不需要 |
| C · 真判断 | 「细排」「加急插单怎么让」「专用助剂替代用不用」 | 多目标权衡:交期 vs 切换成本 vs 产能 vs 库存 | 建议引擎 + 人拍板 + 留痕 | ✅ 这里才需要 |
⭐ 这张表是本场景最值钱的一句话: PPT 的愿景第 ① 条(「人工判断处停顿,机械操作自动跳转执行」)说的就是把 A 类消灭掉。 而 A 类不需要机器学习,也不需要动排产算法一行代码——它是纯粹的流程编排工作。
它应该第一个做,理由有三:技术风险为零、收益立刻可测(一次排产从 N 分钟降到 M 分钟)、 而且它产出的操作留痕正好是 C 类建议引擎的训练料(§3.5·A2)。
反过来说:先做 C(机器学习排产)而不做 A/B,等于在一堆洞上面盖智能。
3.2.1 B 类的三个洞,逐个点名推导
| 洞 | 现在靠什么补 | 系统里应该长什么样 |
|---|---|---|
| BOM 无效 | 「反复沟通」 | BOM 生效日期 + 版本 + 有效性闸门:无有效 BOM 的 SKU 不进排产池,且在开单时就红牌提示,而不是排到一半才发现 |
| 请求交期不作数 | 「每单需沟通」 | 可承诺交期(CTP)引擎:系统按产能+物料+切换给出可承诺日期;人可以覆盖,但必须填理由并留痕(§3.5·A4) |
| 无货源 | 「沟通」 | 物料-供应商-工厂的货源主数据(Source List)+ 齐套检查:排产前先算齐套,不齐套的工单不许进冻结版 |
3.2.2 「覆盖不全」的真相:不是 APS 不支持防水,是配置没做完推导
原话「防水产品尚未实现 APS 排产」+「全览表:不完成配置则无法推进下一步」
这两句连起来读,结论很清楚:防水产品没进 APS,大概率不是技术不支持,是那几百个 SKU × 工厂的配置没人配完。
而「不完成配置则无法推进下一步」这句话背后有一个更糟的事实:配置完成度是不可见的。 没人知道还差多少、差的这些卡住了哪些订单,于是这件事永远排不进优先级。
→ 方案见 §3.5·A3:配置完备度闸门 + 看板。这是个不起眼但立刻见效的功能。
3.3 ⚠️ 被写在纸上、却没被当回事的一句话:月底集中过账
原话「TUC 要货日期不准,且月底集中过账」
这半句话被放在四个根源的第一条里,一笔带过。它的严重性远超 PPT 给它的篇幅:
推导月底集中过账意味着系统里的时间戳不是业务真实发生的时间。它至少毒害四件事:
| 被毒害的 | 怎么坏的 |
|---|---|
| MRP 的时间分桶 | 需求全堆在月末那几天 → 排产看到的是一个假的尖峰 → 产能显示不够 → 加班/外发决策是按假需求做的 |
| 达成率(场景四) | 分子分母不在同一个时间窗里,月中看到的达成率永远偏低,月底突然拉满 |
| 交付风险预警(场景三) | 「应到未到」这类信号全部失真——系统以为晚了,其实只是没过账 |
| ⭐ 「机器学习掌握排产技能」(愿景 ②) | 模型学到的是"月底会有一波",而不是真实需求节奏。 用失真的时间序列训练出来的建议,会把这个失真固化成规则 |
所以在 §9 的路线里,「过账时效治理」被列为 P0 的一部分,而不是某个功能的副产品。
治理手段不是发文要求"及时过账"(发过的文不会改变行为),而是让延迟可见且有归属: 系统记录每一笔的「业务发生时间」和「系统过账时间」两个字段, 按厂/按人出过账时延分布,进月度运营例会。 场景二(签收→过账分钟级闭环)本身就是这条治理的最大抓手——见 §4。
3.4 「让机器学会排产」该怎么理解——以及一条必须守住的红线
愿景 ② 原话:「通过机器学习掌握开单调整与排产调整技能,覆盖 MRP 修改记录、备货学习、排产结果学习、月排产日历及交期与切换成本统筹约束」
推导这句话里其实混了两种完全不同的东西:
| 「学会」的对象 | 技术形态 | 风险 | |
|---|---|---|---|
| ① | 切换成本 / 交期 / 产能的统筹 | 这是优化求解(带切换成本的并行机排程),不是机器学习。求解器 + 约束建模 | 低。约束写错了会算不出解或解很差,会被发现 |
| ② | 计划员的调整习惯(MRP 修改记录、备货学习、排产结果学习) | 这是从历史操作里提炼规则——SRM 已有生产实现 | ⚠️ 高。见下 |
⛔ 红线:不做「自动学习自动生效」
文档SRM 27 号文档 §7,原话可以一字不改地搬到排产场景:
技术上完全可以:跑完自动提炼、自动存、下次自动用。刻意不做。
在一个能真发邮件、真发布寻源单的系统里,让 agent 从反馈里自动学是危险的—— 学错了没人知道它是什么时候开始错的,而错误会以"我一直是这么做的"的形态固化下来。 更糟的是它不报错:只是某天开始,某类单据都少走了一步。
所以三件事都要显式:显式保存、显式编辑、显式版本。
在排产场景里这条只会更硬,因为排产错了的失败形态是:某天开始,某类订单都晚了一天—— 没有报警、没有异常、没有人被问责,只是客户满意度慢慢往下走。
落地形态(照搬 SRM 27/44 号已实现的三阶段):
- 采集:计划员每一次调整都落
plan_decision(改了什么、从哪到哪、为什么) - 挖掘:定期从留痕里挖出高频序列,做成候选规则卡(不是自动生效)
- 授权:计划主管显式确认才变成
ACTIVE规则,有版本、有作者、可停用、可回滚
实查SRM 侧这三阶段已有代码在跑:
app/backend-java/src/main/java/com/huguixi/srm/modules/memory/(ActionTraceInterceptor采集 →TraceSequenceMiner挖掘 →TraceSkillDrafter起草), 前端app/frontend-vue/src/pages/AgentSkills.vue。 采集层是一个拦截器、零 Controller 改动——这个形态在立邦这边可以原样复制。
还有一条:建议必须给依据
推导排产建议如果只给结论("建议把 W2408 挪到周三"),计划员第二次就不看了。 必须给:「上次同样是深色系换浅色系,你把它挪到了周三,因为周二要洗缸(切换 90 分钟)。参考:2026-06-12 的 W2251」。
理由:排产是责任岗,计划员要为交期负责。不能追溯依据的建议,他不敢用,也不该用。
3.5 系统方案(A1–A6)
A1 · 排产工作台:把七步收成两屏 + 一串决策卡 P3-a
一句话:实现愿景 ①——机械操作自动跳转,人只在真判断处停。
页面形态推导:
┌─ 开单台 ──────────────────────────────────────────────────┐
│ 上下文条:工厂[华东粉料厂 ▾] 期间[2026-09] 版本[v3 草稿] │ ← 选一次,全程透传
├───────────────────────────────────────────────────────────┤
│ ① 拉取需求 ✅ 自动 (TUB 42 / TUC 118 / 备货 7) │
│ ② 读 SAP 库存与在制 ✅ 自动 [数据时点 09-01 08:12] │ ← 时点必须显示
│ ③ BOM 有效性检查 ⚠️ 6 个 SKU 无有效 BOM → [处理] │ ← 停顿点
│ ④ 齐套检查 ⚠️ 3 个工单缺助剂 HX-207 → [替代/延期/催料] │ ← 停顿点
│ ⑤ 生成建议工单 ✅ 自动 (MTO 88 / MTS 34) │
│ ⑥ 交期承诺 ⚠️ 11 单系统交期晚于请求交期 → [逐单裁决] │ ← 停顿点
└───────────────────────────────────────────────────────────┘
↓ 一键推进(无停顿点时直接跳)
┌─ 排产台(甘特 + 冲突面板)──────────────────────────────────┐
│ 设备泳道 / 拖拽细排 / 切换成本实时计算 / 冲突高亮 │
│ 右侧:建议面板(Top3 + 依据) · 变更留痕(改了什么、为什么) │
├───────────────────────────────────────────────────────────┤
│ [冻结本版] → 生成 plan_freeze(达成率的分母,见 §6.2) │
│ [同步 SAP] ✅ 自动带上工厂与 APS 排产单号 │
└───────────────────────────────────────────────────────────┘
四条设计纪律:
- 所有"能推导的"一律不问人:工厂来自上下文、APS 单号系统生成、SAP 数据自动拉。
判据:从"开单"到"同步 SAP",人工点击次数 ≤ 停顿点数量 + 3。这是可测的,写进验收。
- 停顿点是一等实体,不是弹窗。每个停顿点有:类型、触发原因、可选动作、SLA、责任人。
- 数据时点必须显示在界面上。「SAP 库存 09-01 08:12」——不显示时点,人就会以为是实时的。
⚠️ 这条防的是一个静默失败:拉数失败时页面显示上一次的缓存,看起来一切正常。
- 同步 SAP 失败要进队列,不能只弹个 toast。见 §4.5·B4 的同一套过账适配器。
接口(示意):
POST /aps/session建一次排产会话(工厂+期间+版本)GET /aps/session/{id}/steps返回七步的状态与停顿点POST /aps/session/{id}/step/{n}/advance推进(无停顿点则连跳)POST /aps/session/{id}/freeze冻结版本POST /aps/session/{id}/sync-sap幂等同步
A2 · 计划决策留痕:机器学习的唯一原料 P3-a(和 A1 同期,不可延后)
一句话:把"人工判断"这件事本身变成可采集的数据。
⚠️ 这是整个场景一里最容易被砍掉、砍掉后最贵的一条。 现在计划员每一次修改都发生在界面上、留在人脑里。没有这份数据,愿景 ② 无从谈起, 而它需要先跑够 6–12 个月才有统计意义。所以它必须和 A1 同期上线,而不是等做 AI 时再补。
表设计:
-- 决策点:每一次"系统建议 vs 人怎么做"的对照
CREATE TABLE plan_decision (
id UUID PRIMARY KEY,
session_id UUID NOT NULL, -- 哪次排产
plant_id VARCHAR(32) NOT NULL,
decision_type VARCHAR(32) NOT NULL, -- BOM_MISSING/SHORTAGE/DATE_CONFLICT/SEQUENCE/QTY_SPLIT/URGENT_INSERT/SUBSTITUTE
subject_ref VARCHAR(64), -- 工单号/需求单号
system_proposal JSONB, -- 系统建议了什么(可为 null:本期还没有建议引擎)
human_action JSONB NOT NULL, -- 人实际做了什么
reason_code VARCHAR(32), -- 码表:CUSTOMER_URGENT/CHANGEOVER_SAVE/MATERIAL_SHORT/EQUIP_DOWN/SALES_STOCK/OTHER
reason_text TEXT, -- 选 OTHER 时必填
decided_by VARCHAR(64) NOT NULL,
decided_at TIMESTAMPTZ NOT NULL,
elapsed_ms INT -- 这个决策花了多久(用来找最费时的停顿点)
);
CREATE INDEX ON plan_decision (plant_id, decision_type, decided_at);两条纪律:
reason_code是必填,但不能只有一个"其他"兜底。码表要能覆盖 80% 的真实理由, 否则所有人都点"其他",这张表就废了。上线后第一个月看 OTHER 占比,超过 30% 说明码表设计错了,要改码表而不是要求人多写字。elapsed_ms不是为了考核人,是为了找出哪个停顿点最费时——那就是下一个该自动化的地方。⚠️ 这条要在系统里显式说明用途并对计划员讲清楚。否则第一次有人拿它做绩效,这份数据就会被"优化"成假的。 文档SRM 44 号有对应的两个开关(知情与授权),可以照抄。
A3 · 主数据三层继承 + 配置完备度闸门 P3-a
打掉的原话:「切换表:集团统一配置,不支持工厂别、设备别的个性化差异」
推导这不是功能缺失,是主数据层级建模错了:现在是"集团统一 或 各厂各配"的二选一, 正确形态是三层继承 + 显式覆盖:
CREATE TABLE config_profile (
id UUID PRIMARY KEY,
config_key VARCHAR(64) NOT NULL, -- CHANGEOVER_MINUTES / SEMI_RELEASE_RATIO / SHIFT_MODE / VAT_YIELD ...
scope_level VARCHAR(16) NOT NULL, -- GROUP | PLANT | EQUIPMENT
scope_id VARCHAR(32), -- GROUP 时为 null
dimension_key VARCHAR(128), -- 如切换表的 "from_group→to_group",SKU 别配置的 sku
value_json JSONB NOT NULL,
effective_from DATE NOT NULL,
effective_to DATE,
version INT NOT NULL,
overrides_id UUID, -- ⭐ 指向被它覆盖的上层配置,覆盖关系可查
override_reason TEXT, -- ⭐ 覆盖必须说明理由
created_by VARCHAR(64),
created_at TIMESTAMPTZ
);
CREATE UNIQUE INDEX ON config_profile (config_key, scope_level, scope_id, dimension_key, version);取值规则:EQUIPMENT → PLANT → GROUP,取第一个命中的。界面上必须显示这个值是从哪一层来的
(「本值继承自集团,未覆盖」/「本厂已覆盖集团值,理由:3# 磨机筛网换型需额外 20 分钟」)。
⚠️ 不显示来源的失败形态:某厂的人改了集团值以为只改了自己厂,实际改的是集团层, 130 家厂全跟着变,而没有任何报错。
配置完备度闸门与看板(打掉「不完成配置则无法推进下一步」):
GET /aps/config-readiness?plant=华东粉料厂&period=2026-09
→ {
"readyPct": 0.83,
"blocking": [ ← ⭐ 关键:不只说"缺",要说"缺的挡住了谁"
{"configKey":"VAT_YIELD","missing":14,"blockedSkus":["FD-2201","FD-2207",...],
"blockedDemandQty": 860, "blockedOrders": 23},
{"configKey":"CHANGEOVER_MINUTES","missing":7,"blockedOrders": 5}
],
"byCategory": {"防水粉料": 0.31, "腻子": 0.97, "瓷砖胶": 0.89} ← 一眼看出防水是短板
}
「防水产品尚未实现 APS 排产」这句话,在这个看板上会变成一个具体的数字:防水品类配置完备度 31%,缺 14 项车间档案,挡住 23 张订单。 能被数出来的缺口才会被补上。
A4 · 可承诺交期(CTP)引擎 P3-b
打掉的原话:「TUB 请求交期每单需沟通」「TUC 要货日期不准」
推导现在的「请求交期」是一个可填、但不作数的自由字段——填了也没人按它排,真正的交期在电话和群里谈。 这就是"交期数据不准"的机制:不是人填错了,是这个字段从设计上就没有约束力。
改法:
- 需求单落库时,系统按「可用库存 + 在制 + 产能空档 + 切换时间 + 齐套齐不齐」算出
committed_date - 界面上三个日期并排:
requested_date(业务要的)/committed_date(系统能给的)/final_date(最终承诺) final_date ≠ committed_date时,必须选理由码并留痕(进plan_decision)- 承诺兑现后回算:
actual_datevsfinal_date→ 承诺兑现率,按厂/按品类/按人出
⚠️ 不许静默取一个(文档SRM 41 号 §3 原话): 「两边数不一致时不许静默取一个——两个数并排显示 + 进异常队列。 静默取一个的失败形态是'给你一个像样的错数',没有任何异常会提示你取错了。」
在这里就是:绝不能因为
committed_date算出来晚了,就悄悄把它显示成requested_date。
A5 · 排产建议引擎 P4(必须在 A2 攒够留痕之后)
三条硬约束:
- 只给建议,不自动执行。Top3 + 每条的依据与历史案例(§3.4)
- 建议来自两个来源,分开标注:
OPTIMIZER(求解器,带切换成本的排程)/LEARNED(从plan_decision提炼的规则)。混在一起标"AI 建议",出错时无法归因是约束写错了还是规则学歪了。
- 规则显式授权、有版本、可停用(§3.4 红线)。规则引用的字段/设备下线 → 标
STALE,不进建议清单,但不拒绝服务启动。文档SRM 27 号 §5.2 的原话:「这道闸门不能拒绝启动……技能是用户数据——生产上一条坏技能不该把服务拖住,那是把用户的输入变成了可用性风险。降级标记 + 不注入 + 在 UI 上显眼地告诉主人。」
A6 · 切换成本矩阵作为一等主数据 P3-b
推导粉料生产的切换成本是真金白银:换品类要清机、深色转浅色要洗缸/换筛网、含特殊助剂的批次后面要空跑。 现在这些知识在老师傅脑子里和「切换表」里(而切换表还是集团统一的)。
CREATE TABLE changeover_matrix (
id UUID PRIMARY KEY,
scope_level VARCHAR(16), -- GROUP/PLANT/EQUIPMENT,走 A3 的继承
scope_id VARCHAR(32),
from_group VARCHAR(64) NOT NULL, -- 品类/色系/助剂族
to_group VARCHAR(64) NOT NULL,
minutes INT NOT NULL,
need_wash BOOLEAN, -- 是否洗缸
need_screen_change BOOLEAN, -- 是否换筛网
purge_qty_kg NUMERIC(12,3), -- 空跑损耗(粉料的"洗车料")
source VARCHAR(16), -- CONFIG(人配) | MEASURED(从日报反算) ⭐
sample_count INT, -- MEASURED 时的样本量
updated_at TIMESTAMPTZ
);⭐
source和sample_count两列是关键:有了场景四的日报数据,切换时间可以从实际产出反算。 界面上「配置 90 分钟 / 实测 137 分钟(样本 23)」并排显示,偏差超阈值给提醒。 文档SRM 42 号的原话:「界面上每一维显示的是0 分 / 85.71%(7)——0 批的 100% 和 50 批的 100% 不是一回事。」样本量必须跟着数走。
3.6 场景一的失败形态清单
| # | 失败形态 | 为什么静默 |
|---|---|---|
| 1 | 先做机器学习排产,不做 A1/A2/A3 | 建议是基于失真数据算的,看起来很专业。错了只表现为"某类订单开始晚一天" |
| 2 | A2 决策留痕被当成"二期再说" | 一期不采,二期就没有历史数据,二期只能再等一年 |
| 3 | reason_code 码表设计得太粗 |
所有人点"其他",表里全是空理由,但表看起来是有数据的 |
| 4 | 配置三层继承做成了"复制一份到工厂层" | 集团改了值,已复制的工厂不跟着变,且没有任何提示说这份已经脱钩了 |
| 5 | CTP 算出来的晚交期被"友好地"隐藏 | 界面好看了,交期还是靠沟通,一切照旧 |
| 6 | 月底集中过账没治 | 所有基于时间的分析和学习全部失真,而每张报表都算得出数 |
场景二 · 签收单识别与同步
4.1 PPT 说了什么原话
| 当前瓶颈 | 飞书路径 |
|---|---|
| 签收单以纸质/PDF 流转,需逐行人工录入 SAP | 飞书上传照片,OCR 自动识别供应商、物料、数量等关键字段 |
| 单据量大、格式杂,录入耗时长、易出错 | 人工确认后,自动同步至 SAP 完成收货 |
| 签收与 SAP 存在时间差,库存滞后影响排产决策 | 减少人工环节,实现签收到收货分钟级闭环 |
4.2 还原:三个痛点里,第三个才是真的
推导
| 原话 | 字面痛点 | 还原后的真实痛点 | 值多少钱 |
|---|---|---|---|
| 「录入耗时长」 | 人力成本 | ⚠️ 可能被高估。一天 200 行录入约 1–2 人时,一年不到 0.5 个人头。它构不成立项理由 | 低 |
| 「易出错」 | 数据质量 | 中:录错的数会一路错到对账和 MRP,且发现得晚 | 中 |
| ⭐「签收与 SAP 存在时间差,库存滞后影响排产决策」 | 时效 | 🔴 这是真正的钱。这条直接连着场景一 §1 的箭头 ① | 高 |
所以这个项目的立项理由应该写成「把签收→过账的时延从 X 天压到分钟级」,而不是「省录入工时」。 前者可测、和场景一的收益连着;后者一算 ROI 就撑不住,第一次预算评审就会被砍。
P0 要先测出 X 是多少(§9·P0):取近 3 个月的收货凭证,算
过账时间 − 实际签收时间的 P50/P90。 推导按「月底集中过账」的描述,P90 大概率在 10 天以上。这个数字本身就是最强的立项材料。
4.2.1 PPT 没说出口的两条
| # | 没说出口的需求 | 为什么没说 |
|---|---|---|
| ⑥ | 签收单原件影像是法律凭证,必须与单据行强绑定、可追溯调阅 | 录入的人只关心"数抄进去了"。但对账争议、货损索赔、审计时,拿出来的是那张签了字的纸,不是系统里的数字。推导立邦对委外厂/承运商的索赔,第一份证据就是它 |
| ⑦ | 过账会失败,且失败是常态不是例外 | PPT 写「人工确认后自动同步 SAP 完成收货」,把过账当成了一个必成功的动作。真实世界里:PO 已关闭 / 超收超容差 / 批次不存在 / 库位不对 / 会计期间已关 / 物料被冻结——每一条都会让 MIGO 失败 |
⚠️ ⑦ 的失败形态非常具体:现场点了"确认",页面提示"已提交",SAP 那边报错了没人看见, 于是库存还是没加上,而现场以为收完了。 这比不做还糟——它制造了一个"已完成"的错觉。
文档SRM 41 号 §7·七 有一条一模一样的教训,原话可以直接搬: 「回执里的
inAlertConsole会如实说进没进——null藏在日志里的话没人知道这条没进去。」
4.3 ⭐ 本场景最重要的设计主张:OCR 的输出不是"一张单",是"对一张已知单据的核对结果"
推导PPT 的路径是:照片 → OCR 识别供应商/物料/数量 → 人确认 → 推 SAP。 这条路径有一个致命的空缺:它没有比对对象。
「格式杂」这三个字,如果按"读懂每一种版式"去解,工作量是无限的——供应商/委外厂各有各的单据模板, 而且会一直新增。走版式模板匹配的路,模板库会长到没人维护。
正确的形态是把问题反过来问:
❌ PPT 的问法:这张单上写了什么? (开放域,候选集 = 全部物料主数据)
✅ 应该的问法:这张单对应我系统里哪张 ASN? (闭合域,候选集 = 那张单上的 5 行)
读出来的每一行,和我的行对不对得上?
差别有多大:
- 候选集从「几万个 SKU」缩到「这张单上的 5 行」→ 识别难度骤降,且可验证
- 输出从「一堆字段」变成「逐行三态结论」→ 有东西可比对,人只需要看不一致的那几行
- 「格式杂」不再是问题——不管什么版式,我要找的就是那 5 行的数量对不对
前置条件:系统里得先有那张 ASN。所以 B1(到货通知先行)是 B2(签收识别)的前置, 不是可选项。这条决定了排期顺序。
这与 01 号文档 §4·N2 的结论是同一条: 「没有『内部规则』的落点,识别出来的字段没有东西可比对……没有它,视觉识别只是把人眼换成机器眼,判定还是人在做——一分钱不省。」
4.3.1 逐行三态,以及"读不出"必须是一等结论
每一行的核对结论只能是三种,不许压成两种:
| 结论 | 含义 | 下一步动作 |
|---|---|---|
✅ MATCH |
OCR 值 = ASN 值 = 实收值 | 直接进过账队列 |
⚠️ MISMATCH |
三个值里有不一致 | 三个值并排显示,人裁决,落差异记录 |
❓ UNREADABLE |
遮挡/污损/反光/手写不清 | 重拍 或 人工补录;绝不许归到 MATCH |
⚠️ 文档SRM 33 号验证过的模型行为纪律,直接搬:「被遮挡必须拒答」—— 宁可拒答,不许猜。猜错的那次没有任何标记,比拒答难处理一个数量级。
4.3.2 三个数并排,不许静默取一个
一行上会同时存在三个数:ASN 数(供应商说发了多少)、OCR 数(单子上印的多少)、实收数(现场点的多少)。
三列都要落库、都要显示。 文档SRM 41 号 §3 原话:
「两边数不一致时不许静默取一个——两个数并排显示 + 进异常队列。」
过账用的是哪个?——实收数。 这条要写死在口径里(§4.6)。
4.4 权威源口径:SAP 是库存权威源,本系统是它的前置作业层
推导这条必须第一个定死,否则做出第二本账。
| 谁持有 | |
|---|---|
| 库存余额、物料凭证、会计凭证 | SAP。本系统一行都不持有 |
| 到货通知、签收作业事实、影像、差异、过账状态与重试 | 本系统 |
四条边界(文档照搬 SRM 41 号 §3 的四条,按立邦口径调整):
- 界面上的"已入库"永远取 SAP 回读值,不取本系统的"已提交过账"。
- 过账成功要回写本系统的作业单,把 SAP 物料凭证号存下来(
mat_doc_no+posting_date)。 - ⚠️ 本系统实收数与 SAP 过账数不一致时不许静默取一个——并排显示 + 进异常队列。
- 时区口径全链路统一。
文档SRM 41 号栽过一次的原话:「跟催回写用本地午夜、看板按 UTC 渲染,于是供应商承诺 29 号,采购看到 28 号,两边都不报错。」
4.5 系统方案(B1–B6)
B1 · 到货通知(ASN)先行 P1-a —— B2 的前置
一句话:让供应商/委外厂在发货时先在系统里报一张 ASN,给签收一个比对对象。
- 入口:H5 一屏(飞书/企微免登 或 短链 + 手机号验证码),不装 App
- 内容:PO 行 → 本次发多少 / 批号 / 生产日期 / 车牌 / 预计到达
- 不强制:没报 ASN 也能收(否则现场会被卡死),但无 ASN 的签收走"盲收"分支,
逐行需人工录入 + 标记
no_asn = true,并进供应商协同率指标⭐ 用指标推行,不用闸门推行。闸门会让现场绕过系统;指标会让采购去找供应商谈。
- 实查SRM 侧已有
asn_line且带batch_no/production_date/shelf_life_days/pack_size(V189__asn_vehicle_and_production_date.sql、V22__asn_pack_label.sql),字段可直接对齐
B2 · 签收作业移动端 P1-a
┌─ 今日到货 ─────────────────────────┐
│ [扫码/输单号] 或 [拍签收单] │ ← 两条路都留,扫码优先
├────────────────────────────────────┤
│ ASN-20260901-014 华东力强建材 │
│ ┌────────────────────────────────┐ │
│ │ 行1 腻子粉 FD-2201 25kg │ │
│ │ ASN 400 OCR 400 实收[400 ]✅ │ │ ← 三个数并排
│ │ 行2 瓷砖胶 CT-118 20kg │ │
│ │ ASN 200 OCR 180 实收[180 ]⚠️ │ │ ← 不一致:黄条 + 必填原因
│ │ 行3 防水粉 WP-330 25kg │ │
│ │ ASN 120 OCR ❓ 实收[120 ] │ │ ← 读不出:不阻断,标记来源=人工
│ └────────────────────────────────┘ │
│ [+ 拍照留证] [+ 报异常] │
│ 签名区 ▭▭▭▭▭ [确认签收并过账] │
└────────────────────────────────────┘
四条纪律:
- ⛔ 报异常不挡收货。
文档SRM 41 号 §7·七 原话:「货在门口、车在等着走,挡住不会让破损的箱子消失,只会让整车卡住。真实结果是——为了报一个异常,人干脆不报。」 照实收(少收就少收、拒收填 0),异常单独记一笔。这句话要印在页面底部。
- 触控与输入尺寸:文档SRM 41 号 §7·五踩过的两个数字直接抄—— 按钮 48px(戴手套)、输入框字号 16px(低于它 iOS 会自动缩放整页)。粉料车间戴手套是常态。
- 离线可用:仓库和委外厂常在信号差的位置。本地暂存 + 联网补传,补传状态要显式可见。
- 签名:电子签名图 + 时间 + GPS + 设备号,与影像一起绑到作业单。
B3 · 单据–影像–行项三级绑定 P1-a
CREATE TABLE receipt_task ( -- 一次签收作业
id UUID PRIMARY KEY, asn_id UUID, po_no VARCHAR(32), plant_id VARCHAR(32),
supplier_id VARCHAR(32), no_asn BOOLEAN DEFAULT FALSE,
signed_by VARCHAR(64), signed_at TIMESTAMPTZ, -- ⭐ 业务发生时间
signature_img VARCHAR(256), gps VARCHAR(64), device_id VARCHAR(64),
posting_status VARCHAR(16), -- DRAFT/QUEUED/POSTED/FAILED/PARTIAL
mat_doc_no VARCHAR(32), posted_at TIMESTAMPTZ -- ⭐ 系统过账时间
);
CREATE TABLE receipt_line (
id UUID PRIMARY KEY, task_id UUID NOT NULL, line_no INT,
material_id VARCHAR(32), batch_no VARCHAR(32),
asn_qty NUMERIC(14,3), ocr_qty NUMERIC(14,3), actual_qty NUMERIC(14,3), -- ⭐ 三列并存
ocr_confidence NUMERIC(4,3), match_status VARCHAR(16), -- MATCH/MISMATCH/UNREADABLE
value_source VARCHAR(16), -- OCR_CONFIRMED / MANUAL / SCAN
diff_reason_code VARCHAR(32)
);
CREATE TABLE receipt_image ( -- 一次作业多张图,独立子表
id UUID PRIMARY KEY, task_id UUID NOT NULL, line_id UUID, -- 可绑到具体行
image_type VARCHAR(16), -- SIGN_SHEET/GOODS/DAMAGE/LABEL
path VARCHAR(256), ocr_raw JSONB, taken_at TIMESTAMPTZ
);⚠️ 照片必须是独立子表,不能是一列逗号分隔的路径。 文档SRM 41 号原话:「删其中一张要做字符串切分,而切错了不会报错,只会少一张照片。」
⭐ signed_at 与 posted_at 两个时间戳分列——这两列的差值就是 §3.3 要治的「过账时延」,
也是本场景 KPI 的直接来源(§4.5·B6)。只存一个 create_time 的话,这个指标永远算不出来。
B4 · SAP 过账适配器 P1-b
CREATE TABLE erp_posting (
id UUID PRIMARY KEY,
idem_key VARCHAR(64) UNIQUE NOT NULL, -- ⭐ 幂等键 = task_id + 行指纹,重试不会重复过账
task_id UUID NOT NULL,
payload_json JSONB, request_at TIMESTAMPTZ,
status VARCHAR(16), -- QUEUED/POSTING/POSTED/FAILED/GAVE_UP
sap_msg_type VARCHAR(4), sap_msg_no VARCHAR(8), sap_msg_text TEXT, -- ⭐ 原样存 SAP 报文
mat_doc_no VARCHAR(32), retry_count INT, next_retry_at TIMESTAMPTZ
);五条纪律:
- 幂等键必填。网络超时后不知道过没过账,重试是必然的;没有幂等键就会重复收货。
- SAP 的报错原文要存下来(
sap_msg_*),不要翻译成"过账失败"。「PO 已关闭」和「会计期间已关」的下一步动作完全不同:前者要找采购,后者要找财务。
- 失败要有归属和队列:
失败队列页面,按失败原因分组,每类给一个处置入口。 - ⭐ 现场要能看见结果:签收完成页显示「已过账 ✅ 凭证号 5000012345」或「过账失败 ⚠️ 原因:…,已通知 XX」。 绝不能只弹 toast(§4.2·⑦)。
- 只推增量、不推全量;
GAVE_UP状态要人工介入,不许无限重试。
技术选型推导:优先 SAP OData / RFC(BAPI_GOODSMVT_CREATE);退路是 IDoc(MBGMCR)。 ⛔ 绝不直连 SAP 数据库表——绕过 SAP 的业务校验写库,是所有 ERP 集成里最贵的错误。
B5 · 差异与异常闸门 P1-b
- 差异(少收/多收/错料/批号不符)→ 落
receipt_diff,绑定影像,自动生成一条对供应商的待处理项 - 货损/包装异常 → 接 01 号文档 的
receipt_exception+receipt_exception_photo设计 实查SRM 侧已存在V170__receipt_exception.sql,异常类型含DAMAGED/SHORT/WRONG_ITEM/LABEL_MISMATCH - ⭐ 索赔时效闸门:异常创建时按合同/QAA 的索赔窗口算出
claim_deadline, 临期未处置主动推送。这一条是 01 号文档 §2·B 认定的"最贵且最隐形"的成本
B6 · 时效看板:本场景的 KPI,也是场景一的输入质量指标 P1-b
| 指标 | 定义 | 为什么是它 |
|---|---|---|
| ⭐ 签收→过账时延 | posted_at − signed_at 的 P50 / P90 / P99 |
本项目的头号 KPI。基线在 P0 测(§9) |
| ASN 覆盖率 | 有 ASN 的签收 / 全部签收 | B1 的推行进度;也是 OCR 准确率的上限 |
| 逐行一次通过率 | MATCH 行 / 全部行 |
识别质量 + 供应商发货准确性,两者要能拆开看 |
| 过账一次成功率 | POSTED / QUEUED |
集成健康度 |
| UNREADABLE 率 | 按供应商分组 | ⭐ 高的那几家,去改他们的单据模板比改模型便宜十倍(同 §6.3) |
4.6 场景二要写死的口径
| 口径 | 默认取值(按此设计,若立邦不同则改这里) |
|---|---|
| 库存权威源 | SAP;本系统是前置作业层,不持有库存余额 |
| 过账数量取哪个 | 实收数(actual_qty);ASN 数和 OCR 数只作核对,永不直接过账 |
| 无 ASN 能否签收 | 能,走盲收分支并计入协同率指标,不做硬闸门 |
| 差异容差 | 按物料组配(粉料建议 ±0.5% 或 ±1 包,取大者);容差内自动过账,容差外必须人工裁决 |
| 签收的法律时点 | signed_at(现场签字时刻),不是 posted_at |
| 影像保留期 | ≥ 索赔窗口 + 审计要求;建议 3 年 |
场景三 · 交付风险之盲(130 家工厂)
5.1 PPT 说了什么原话
| 困境 | 飞书赋能方向 |
|---|---|
| 130 家工厂分散各地,交付进度与异常依赖人工汇总上报 | 多维表格搭建交付风险看板,统一采集进度、异常、资源瓶颈数据 |
| 风险信息严重滞后,问题发现时常错过最佳干预窗口 | 飞书机器人自动识别风险信号,实时推送至相关负责人 |
| 区域反馈汇总至企微文档,缺乏实时预警与主动推送 | 从被动上报到主动预警 |
5.2 ⚠️ 「被动上报 → 主动预警」这句话里藏着一个陷阱
推导主动预警的前提是系统里有能算出风险的数据。
如果数据仍然靠人上报,那所谓"主动预警"只是把"人报了之后"变成"自动推送"—— 风险信号的产生时点没有提前一秒。PPT 的方案(多维表格采集 + 机器人推送)恰好落在这个陷阱里: 它优化的是"报上来之后"的那一段,而痛点原话写的是「问题发现时常错过最佳干预窗口」—— 干预窗口是在报上来之前就错过的。
所以真正的主动预警,必须建立在「不依赖人上报的信号」上。
5.2.1 不依赖人上报的六类信号推导——本场景的核心内容
| # | 信号 | 数据来源 | 为什么它比人工上报早 |
|---|---|---|---|
| 1 | 应发未发 / 应到未到 | 场景二的 ASN 与签收 | 计划里写着今天该发,到点没有 ASN → 当天就知道,不用等周报 |
| 2 | 应产未产 / 产出不足 | 场景四的日报 | 昨天该产 20 吨,日报只有 12 吨 → 次日 08:00 就知道 |
| 3 | ⭐ 静默:这家厂连续 N 天没有任何数据 | 全域 | 「没有消息」是最强的风险信号,而人工上报体系恰恰永远不会上报"我今天什么都没做" |
| 4 | 节拍偏离:订单该进入某节点却没进 | 执行链状态机 | 不需要人判断,状态机自己知道 |
| 5 | 齐套缺口:委外厂缺关键原料 | 原料齐套 + 场景四的"原料异常" | 缺料是最常见的延期主因,且发生在延期前 3–7 天 |
| 6 | 历史行为:这家厂的承诺兑现率 / 响应时长 | factory_response_profile |
不是预测某一单,是给同样的延迟信号加不同的权重 |
⭐ 第 3 条(静默检测)是本场景我最想强调的一条,因为它成本极低、效果极好,而几乎没人做。 实现只要一张表 + 一个定时任务:
CREATE TABLE factory_silence_watch ( plant_id VARCHAR(32) PRIMARY KEY, last_signal_at TIMESTAMPTZ, -- 任何一类信号(ASN/日报/回复/过账)都刷新它 expected_interval_hours INT, -- 按厂分层配:A 类 24h,B 类 72h,C 类 168h silence_level VARCHAR(8) -- OK / WARN / ALERT );文档SRM 24 号文档对定时与触发的区分可以直接搬: 「定时 vs 触发是两种东西,别混」——静默检测天然是定时(没有事件可触发, 因为"什么都没发生"本身就不产生事件)。这是它容易被漏掉的原因。
5.3 一个"风险看板"不够:要四层,看板只是第三层
推导PPT 把这件事压成了一个看板。看板会被看两周,然后没人看——这是数字化项目最常见的死法。
正确的形态是四层,每层都有明确的下一步动作:
① 信号 risk_signal ← 六类来源,机器产生,不需要人
↓ 规则引擎(可配阈值、三态、带样本量)
② 风险事件 risk_event ← 有等级、有责任人、有 SLA
↓ 派单
③ 处置任务 risk_action ← 状态机:待响应→已响应→措施中→已闭环/升级
↓ 超时
④ 升级链 ← 对接人 → 区域经理 → 品类负责人 → 供应链总监
文档SRM 21 号的升级策略原话可以照搬,只把角色换掉:
第 1 轮:群里 @ 对接人 → 24h 未回 第 2 轮:群里再问 + @ 对方主管 → 24h 未回 第 3 轮:转邮件 → 24h 未回 升级:挂给区域经理 + 标记该厂"响应差" → 喂给绩效模块并且原文的这句话在立邦这里同样成立: 「把"催不动"变成可量化的绩效数据,而不是采购心里的怨气。 这是传统 SRM 做不到、agent 天然能做的事——它记得每一次催了几轮、几点回的。」
5.3.1 风险规则要三态 + 带样本量
文档照搬 SRM 42 号 §六「没有数据 ≠ 坏消息」三条闸,在这里就是:
- 某维度无数据时按
SKIP从分母去掉,不按 0 分算 hasRealData = false时一条预警都不报hasRealData = false时不给风险评级(null,显示"数据不足")
⚠️ 第 3 条是靠真数据才发现的坑,原话: 「一家本月一次货都没送的供应商得分率恰好 0.80 → 评成 B 级……"没数据"就这样被悄悄换成了"表现良好"。」
在立邦这里的等价失败:一家新接入、还没有任何数据的委外厂,风险看板显示绿色。 而它恰恰是最该盯的那一家。"数据不足"必须是一个和"低风险"长得不一样的颜色。
5.4 ⭐ 130 家不能一视同仁:分层是本场景最重要的管理决策
推导PPT 想对 130 家建一个统一看板。这会把有限的管理带宽摊薄到没用。
粉料行业的典型分布(推导,P0 用真实数据校准):前 20 家厂承担 70% 以上的量。
| 层 | 家数推导 | 管理颗粒度 | 数据要求 | 静默阈值 |
|---|---|---|---|---|
| A 类(战略/大量/独家品类) | ~20 | 订单级 + 日跟踪 | 每日日报 + ASN 必报 | 24h |
| B 类(常规) | ~50 | 周跟踪 + 异常即报 | 每日日报,ASN 尽量报 | 72h |
| C 类(小量/备份/季节性) | ~60 | 异常才管 | 只要求异常上报 | 168h |
分层依据(可配权重):近 12 月交付额 × 品类关键性 × 可替代性 × 历史风险分。每季度重算一次并留痕。
这一条要写进方案,因为它是"咨询"该给的东西,而不是"开发"该给的东西: 系统能做到对 130 家全都日跟踪,但组织做不到。做了也没人看, 结果是全体降级为没人看——分层不是妥协,是让 A 类真的被盯住的唯一办法。
5.5 ⚠️ 一条 PPT 完全没考虑、但决定成败的现实:委外厂在企微,不在飞书
原话「区域反馈汇总至企微文档」
这句话透露了一个关键事实:外部工厂/区域用的是企业微信,而立邦内部要上飞书。
推导这意味着:
- 不能假设 130 家厂都会进立邦的飞书。让 130 家外部企业为了报个数装/切一个 IM,推行成本极高
- 实查SRM 49 号文档实测过外部飞书群的一堆约束(成员 open_id、群主、置顶卡片、 「外部用户必须和群主已成为飞书好友」这条至今未闭合),说明外部协同走 IM 群是有真实摩擦的
所以工厂侧的接入必须是多通道的,且入口要极轻:
| 通道 | 适用 | 形态 |
|---|---|---|
| H5 短链(首选) | 全部 130 家 | 一屏、免登或短信验证码、扫码填数。不装 App、不切 IM |
| 企微群机器人 | 已有企微群的区域 | 定点问一句,回复即入库 |
| 飞书群 | 内部区域/品类团队 | 复用 SRM 已跑通的双向通道 |
| 短信 / 电话代填 | C 类、信息化最弱的厂 | 区域助理代填,标 entered_by_proxy = true |
⭐ 设计上的落点:抽一个
CollaborationChannel适配层,飞书/企微/短信各一个实现, 上层的风险事件与处置任务不感知通道。这样"未来要不要全切飞书"变成一个配置问题, 而不是一次重构。文档SRM 21 号 §3.1 做过同样的事:「把飞书能力从'审批'里抽出来」—— 原来
FeishuApprovalNotifier(264 行) 把 token 管理/发消息/审批卡片组装焊在一起。别再焊一次。
5.5.1 委外厂凭什么配合?——三个抓手
推导这是最实际的落地问题。系统做得再好,130 家厂不填就是零。
| 抓手 | 做法 |
|---|---|
| 入口轻到不需要培训 | 一个短链、一屏、三个数字键盘输入框、10 秒填完。任何需要培训的方案在 130 家规模上都会失败 |
| 给他们也有用 | H5 上同时显示:立邦给他的订单、结算进度、对账差异。让他有理由主动打开 |
| 和商务挂钩 | 数据协同率进入委外厂月度评级,评级影响配额分配与结算优先级。⭐ 这是唯一真正有效的一条,但要业务侧愿意用 |
5.6 系统方案(C1–C6)
C1 · 交付执行主数据 P2-a
CREATE TABLE plant ( -- 130 家 + 自有厂,一张表
id VARCHAR(32) PRIMARY KEY, name VARCHAR(128),
plant_type VARCHAR(16), -- OWNED 自有 | TOLL 委外 | THIRD_PARTY 第三方仓
region VARCHAR(32), province VARCHAR(32), lng NUMERIC, lat NUMERIC,
tier VARCHAR(2), -- ⭐ A/B/C 分层(§5.4)
tier_reason JSONB, tier_reviewed_at DATE,
category_capability JSONB, -- 能做哪些品类:腻子/瓷砖胶/防水粉料/…
contact_json JSONB, -- 对接人 + 主管 + 各通道 id
channel_pref VARCHAR(16), -- H5 | WECOM | FEISHU | SMS
status VARCHAR(16)
);C2 · 信号采集层 P2-a
CREATE TABLE risk_signal (
id UUID PRIMARY KEY,
signal_type VARCHAR(32) NOT NULL, -- LATE_SHIP/LATE_ARRIVE/UNDER_OUTPUT/SILENCE/NODE_STUCK/SHORTAGE/PROFILE
source VARCHAR(16) NOT NULL, -- ⭐ SYSTEM 机器算的 | REPORTED 人报的
plant_id VARCHAR(32), order_ref VARCHAR(64),
observed_at TIMESTAMPTZ, -- ⭐ 业务观察时刻,不是入库时刻
detail JSONB, severity_hint VARCHAR(8),
dedup_key VARCHAR(128) -- ⭐ 同一事实反复产生信号时去重
);⭐
source分列的意义:上线半年后要能回答「我们的预警里有多少是机器先发现的」。 如果 90% 还是REPORTED,说明"从被动到主动"这件事根本没做成——而看板照样每天都有数。 这个比率本身就是本场景的头号验收指标。
C3 · 风险规则引擎 P2-b
- 规则可配(阈值、生效范围走 §3.5·A3 的三层继承)、可版本、可停用
- 输出三态:
风险 / 正常 / 数据不足——三个颜色,绝不两个 - 每条风险带
sample_count与data_completeness
C4 · 风险事件与处置任务 P2-b
CREATE TABLE risk_event (
id UUID PRIMARY KEY, plant_id VARCHAR(32), level VARCHAR(8), -- P1/P2/P3
title VARCHAR(256), signal_ids UUID[],
owner VARCHAR(64), sla_due_at TIMESTAMPTZ,
status VARCHAR(16), -- OPEN/ACKED/ACTING/CLOSED/ESCALATED
root_cause_code VARCHAR(32), impact_orders JSONB,
closed_at TIMESTAMPTZ, close_note TEXT
);
CREATE TABLE risk_action (
id UUID PRIMARY KEY, event_id UUID, action_type VARCHAR(32),
channel VARCHAR(16), -- 走哪个通道发出去的
round INT, -- ⭐ 第几轮催
sent_at TIMESTAMPTZ, replied_at TIMESTAMPTZ, reply_text TEXT,
extracted JSONB, -- ⭐ 从回复里抽出的结构化结论(新交期/新数量)
write_back_ref VARCHAR(64) -- ⭐ 结论回写到了哪张单
);⭐ 最后两列是 §2.3 那条「闭环四要件」的第 ④ 条落点。 没有
extracted+write_back_ref,这套东西就是一个会自动发消息的群机器人。
C5 · 分层看板(三级下钻)P2-b
集团/区域 → 工厂 → 订单/批次。每一级都显示 数据完整度 和 样本量。
C6 · 工厂响应画像 P2-c
回复及时率 / 承诺兑现率 / 数据协同率 / 异常主动上报率
→ 三个去处:① 分层依据(C1.tier)② 风险权重(C3)③ 场景一 CTP 引擎的交期可信度系数(A4)
5.7 场景三的失败形态
| # | 失败形态 | 为什么静默 |
|---|---|---|
| 1 | 做成一个只有 REPORTED 信号的看板 | 数据天天有,但风险发现时点一天没提前 |
| 2 | 新接入的厂显示绿色 | "数据不足"被画成了"低风险"(§5.3.1) |
| 3 | 130 家一视同仁 | 每天 200 条预警,两周后全员静音 |
| 4 | 预警只推送不闭环 | 「我已上报」的错觉;文档SRM 41 号原话「那比不让报更糟」 |
| 5 | 假设 130 家都进飞书 | 推行卡在 IM 上,系统再好也没有数据 |
| 6 | 静默检测没做 | 最该报警的那家厂,因为什么都没发生,所以什么都没报 |
场景四 · 入库达成之盲
6.1 PPT 说了什么原话
| 当前瓶颈 | 飞书路径 |
|---|---|
| 车间人员纸质填写排产入库数据,拍照发群,计划员逐条追踪 | 飞书拍照上传,OCR 自动识别纸质表格中的排产入库数据 |
| 需登记字段多:日期、设备、班次、排产量、入库量、原料异常、设备异常等 | 结构化录入多维表格,达成率自动计算,异常字段高亮标记 |
| 数据分散在群聊中,无法汇总分析,达成率核算滞后 | 计划员实时查看各车间达成率看板,异常自动推送,无需逐群翻找 |
6.2 ⭐ 做 OCR 之前,先把「达成率」的定义写死
推导这是本场景第一优先级的事,PPT 一个字没提。
「达成率 = 入库量 / 排产量」看起来无需定义,实际上每一项都有歧义,而不同选法会得出完全不同的数:
| 歧义点 | 选法 A | 选法 B | 后果 |
|---|---|---|---|
| ⭐ 分母:哪一版排产量 | 每日冻结版(plan_freeze) |
最后一次调整后的值 | 选 B 的达成率永远接近 100%——因为计划员会把计划改成实际。这是全行业最经典的达成率造假机制,而且没有人在造假,它是系统默认行为 |
| 分子:入库还是产出 | 入库量(过账数) | 产出量(下线数) | 粉料有尾料/返粉/回用/包装损耗,两者能差 1–3% |
| 跨班次批次 | 按批次完工时刻归属 | 按开始时刻归属 | 夜班跨零点的批次,两种算法差一天 |
| 返工/复筛批次 | 只计一次 | 重复计入 | 达成率虚高 |
| 停机/无排产日 | 从分母 SKIP |
计 0 | 文档SRM 42 号「没有数据 ≠ 坏消息」的同一个坑 |
建议的默认口径(写进系统,界面上显示口径版本号):
日达成率 = Σ(当日入库过账量) / Σ(当日 08:00 冻结版排产量) · 分母取 plan_freeze,冻结后**不可改**;调整只能产生新版本,且新版本不改历史达成率 · 分子取 SAP 入库过账量(与场景二同源),不取车间自报量 · 批次按完工时刻归属自然日;跨零点批次归到完工那天 · 返工批次不重复计入分子 · 当日无冻结排产 → SKIP,不计 0⚠️ 「冻结后不可改」这一条会有人反对,理由是"计划本来就要调整"。 应对:允许调整,但调整产生新版本
v2,而达成率永远对v1算,同时新增一个 **「计划变更次数/幅度」**指标。这样"改计划"这件事本身变得可见, 而不是被藏进一个 100% 的达成率里。
6.2.1 分子取 SAP 而不是车间自报——这条要专门说
推导用车间自报的入库量算达成率,等于让被考核的人提供考核数据。 取 SAP 过账量则天然有第三方校验(要有实物、要有凭证)。
代价:SAP 过账有延迟(这正是场景二在治的事)。
处理:日报里的自报量照收,但它的角色是 预报值,和 SAP 过账值并排显示,
不一致进异常队列——又是那条「不许静默取一个」。
6.3 ⚠️ 本项目最贵的一个坑:手写 OCR 当主录入路径
推导PPT 的路径是:车间继续纸质填写 → 拍照 → OCR → 入库。
这里的 OCR 和场景二的 OCR 不是一个难度等级:
| 场景二 签收单 | 场景四 车间日报 | |
|---|---|---|
| 字体 | 印刷 / 打印 | ⚠️ 手写 |
| 有无比对对象 | ✅ 有(ASN 行) | ⚠️ 有一半:排产量可比(冻结版有),入库量没有——那正是要采的新事实 |
| 错了会被发现吗 | 会(过账时 SAP 校验、对账时供应商找上门) | ❌ 不会。一个「8」读成「3」不报错,只是达成率变成另一个数 |
| 关键字段 | 数量(可容差校验) | 数量(无校验对象)+ 设备/班次(可枚举,相对安全) |
⭐ 文档SRM 40 号那句原话在这里是精确适用的: 「算错不会报错,只会给出一个像模像样的错数。 而 BI 图表的消费场景是拿去开会—— 一个看起来专业的错数比没有这张图更贵。」
达成率就是拿去开会的数。
6.3.1 我的主张:把 OCR 从主录入路径降级为存档与稽核路径
❌ PPT 路径:纸 → 拍照 → OCR → 达成率
✅ 建议路径:
主路径:班末 5 分钟,班组长在移动端【扫码选设备 + 选班次 + 数字键盘填数 + 选异常码】
副路径:纸质单照拍存档(合规与习惯不变),OCR 只用于 ① 影像归档索引 ② 抽样稽核一致性
为什么这样更好:
| 结构化录入 | 手写 OCR | |
|---|---|---|
| 错误形态 | 输错了,但当场能校验(超产能提醒、与冻结版偏差过大提醒) | 静默错误 |
| 设备/班次 | 扫码/下拉,天然是主数据 id | 「3号磨机」「3#磨」「磨3」三种写法(§2.2) |
| 异常字段 | 码表下拉,可分析 | 自由文本,OCR 出来还是文本,不可分析 |
| 耗时 | 班末 2–3 分钟 | 拍照 10 秒 + 后端纠错若干分钟 + 出错后追溯若干小时 |
| 上线速度 | 快(无模型依赖) | 慢(要样本、要调、要评估) |
6.3.2 ⭐ 最省钱的一条建议:改表单,而不是改模型
如果因为现实约束(防爆区不许带手机、老师傅不接受手机录入)必须保留纸质主路径, 那么正确的投入方向是重新设计那张纸,而不是提高识别模型:
- 数字用方格框(一格一位),不是横线
- 设备/班次/物料预印 + 打勾或涂黑,不是手写名称
- 每张表贴唯一二维码(含日期+厂+线),一扫就知道这是哪张
- 排产量预印(从冻结版打印出来),车间只填入库量和异常
⭐ 这一条同时把「排产量」这个字段从"要识别"变成"已知",识别范围直接砍掉一半
改表单的成本是一次印刷;提高手写识别准确率的成本是一个持续投入的模型项目。 这条建议在 §4.5·B6 的
UNREADABLE 率按供应商分组里是同一个道理。
6.3.3 如果一定要走 OCR,四条闸门
- 关键数字字段低置信度 → 强制人工确认才能入库
- 拒答而不是猜:读不出必须落
UNREADABLE,不许填 0,也不许填空后被当成 0「读不出来」和「当天没产」在数据库里长得一样的话,达成率会被静默拉低
- 每个字段回一段图上原文片段供人核对(文档SRM 33 号已验证过的做法)
- 手写划改取改后值(同上,SRM 33 号实测有效)
6.4 「原料异常 / 设备异常」两个字段:本场景的隐藏价值
推导PPT 只把它们当"需要登记的字段"。它们其实是两条闭环的起点,而这两条闭环是场景四真正的价值所在:
原料异常 ──→ 供应商质量事件 ──→ 供应商绩效 ──→ 采购/寻源决策
(结块、水分超标、批次不符、来料不足)
设备异常 ──→ ① 设备维护工单(TPM)
└─→ ② ⭐ 产能参数校准 ──→ 修正场景一「车间档案」的静态产能值
(堵料、筛网破损、计量秤故障、停电、频繁跳停)
⭐ 第 ② 条是我最想强调的:场景一抱怨「车间档案需逐一设定单缸产量、单双班、日产能、小时产能」—— 这些值配一次就再没人维护,而实际产能在变(设备老化、配方改动、人员熟练度)。 有了日报,这些参数可以从实际产出反算:
界面上:3# ACM 磨机 · 小时产能 配置 1.2 t/h | 实测 0.94 t/h(近 30 天,样本 61 班次) ⚠️ 偏差 -22%,建议复核 [采纳实测值] [保持配置值并说明理由]这就是"配置体系庞大且缺乏灵活性"的解药:不是让人配得更快,是让系统告诉人哪几项配错了。
6.4.1 异常码表——本场景该交付的第一份东西
自由文本的异常字段永远无法汇总分析。必须给码表。以下是推导的初版,P0 与车间共同校准:
| 原料异常 | 设备异常 |
|---|---|
RM_SHORT 来料不足/断料 |
EQ_JAM 磨机/输送堵料 |
RM_CAKING 结块 |
EQ_SCREEN 筛网破损/堵塞 |
RM_MOISTURE 水分超标 |
EQ_SCALE 计量秤故障/漂移 |
RM_BATCH_MISMATCH 批次/牌号不符 |
EQ_MIXER 混合机故障 |
RM_FINENESS 细度/粒径不符 |
EQ_DUST 除尘系统故障 |
RM_PACKAGE 包装破损/受潮 |
EQ_POWER 停电/电气故障 |
RM_SUBSTITUTE 使用替代料 |
EQ_CHANGEOVER 切换超时 |
RM_OTHER 其他(必填说明) |
EQ_PM 计划保养占用 |
EQ_OTHER 其他(必填说明) |
⚠️ 上线后第一个月盯
OTHER占比。超过 30% 说明码表不覆盖真实场景, 要改码表,不是要求车间多写字(同 §3.5·A2 的reason_code纪律)。
6.5 系统方案(D1–D6)
D1 · 生产日报移动端(结构化录入)P1-a
┌─ 生产日报 · 华东力强 2026-09-01 白班 ──────┐
│ [扫设备码] 3# ACM 磨机 │
│ 班次 ● 白班 ○ 夜班 日期 2026-09-01 │
├────────────────────────────────────────────┤
│ 冻结排产量 18.0 t ← 系统带出,不可改 │ ⭐ 分母预置,不用填
│ 实际入库量 [ 15.6 ] t │
│ ⚠️ 偏差 -13%,请选择原因(必填) │ ⭐ 偏差超阈必须给理由
│ 原料异常 [+ 添加] 已选:RM_CAKING 结块 ×1 │
│ 设备异常 [+ 添加] 已选:EQ_SCREEN 筛网 ×1 │
│ 停机时长 [ 95 ] 分钟 │
│ 备注 ______ [拍照存档] [提交] │
└────────────────────────────────────────────┘
离线可用 · 补传状态显式可见 · 按钮 48px · 输入框 16px
三条纪律:
- 分母由系统带出,车间只填分子。少填一个字段,还消灭了一个错误来源
- 偏差超阈值必须选原因码——这是把「异常字段」从可选变成有约束
- 提交后不可自行修改,改要走"更正记录"(新增一条,原记录保留)。
⚠️ 允许静默改的失败形态:月底达成率不好看时,前几天的数被改了,而没有任何痕迹
D2 · 排产版本冻结与达成率引擎 P1-a
CREATE TABLE plan_freeze (
id UUID PRIMARY KEY, plant_id VARCHAR(32), line_id VARCHAR(32),
biz_date DATE NOT NULL, version INT NOT NULL,
frozen_at TIMESTAMPTZ NOT NULL, frozen_by VARCHAR(64),
planned_qty NUMERIC(14,3), plan_detail JSONB,
UNIQUE (plant_id, line_id, biz_date, version)
);
CREATE TABLE daily_report (
id UUID PRIMARY KEY, plant_id VARCHAR(32), line_id VARCHAR(32),
equipment_id VARCHAR(32), biz_date DATE, shift VARCHAR(8),
freeze_id UUID, -- ⭐ 钉死用的是哪一版分母
reported_qty NUMERIC(14,3), -- 车间自报(预报值)
posted_qty NUMERIC(14,3), -- ⭐ SAP 过账量(权威),异步回填
downtime_min INT,
entry_mode VARCHAR(16), -- STRUCTURED / OCR / PROXY ⭐ 录入方式要留
entered_by VARCHAR(64), entered_at TIMESTAMPTZ,
metric_version VARCHAR(16) -- ⭐ 用哪一版达成率口径算的
);⭐
metric_version这一列:口径一定会改。改了以后历史数据要能说清是按哪版算的, 否则"上个月还是 92%,怎么变成 87% 了"这个问题永远答不清。
D3 · 异常分流 P1-b
原料异常 → 供应商质量事件(接场景二的 receipt_exception / 供应商绩效)
设备异常 → 维护工单 + 产能校准样本池(接 D5)
两条都要有"去向"字段并在界面显示,否则车间会觉得"报了也没用",第二个月就不报了。
D4 · 影像存档与稽核 P1-b
纸质单拍照存档(按 plant/date/shift 索引);每周抽 5% 做人工一致性稽核,
稽核差异率进"数据质量"指标。OCR 在这里的作用是加速稽核,不是入账。
D5 · 产能参数反算 P3(回流场景一)
按设备近 30/90 天的实际产出(剔除异常班次)反算小时产能/单缸产量,
与 config_profile 的配置值并排,偏差超阈提醒。不自动改配置——给建议,人采纳(同 §3.4 红线)。
D6 · 达成率看板 P1-b
按 厂 / 线 / 班次 / 品类 / 日周月 下钻。每格必须带样本量:87.3%(11 班次)。
文档SRM 42 号原话:「0 批的 100% 和 50 批的 100% 不是一回事。」
6.6 场景四的失败形态
| # | 失败形态 | 为什么静默 |
|---|---|---|
| 1 | 分母取"调整后的排产量" | 达成率永远 95%+,看板很好看,没人在造假 |
| 2 | 手写 OCR 直接入账 | 一个数字读错,达成率变成另一个数,没有任何报错 |
| 3 | UNREADABLE 被当成 0 |
「读不出」和「没产」长得一样,达成率被静默拉低 |
| 4 | 异常字段是自由文本 | 数据有了,永远汇总不出"哪种异常最多" |
| 5 | 日报可自行修改且不留痕 | 月底数据被"优化"过,且不可发现 |
| 6 | 原料/设备异常没有去向 | 车间报了没人管 → 第二个月开始随手乱填 → 整份数据作废 |
7. 跨场景架构
7.1 一张总图
┌───────────────────────────────────────────────────────────────────────┐
│ 接入层 飞书(内部) · 企微(区域/委外) · H5短链 · 短信 · PC Web │
│ └── CollaborationChannel 适配层(上层不感知通道,§5.5) │
├───────────────────────────────────────────────────────────────────────┤
│ 应用层 │
│ 计划域 收货域 执行域 风险域 │
│ 排产工作台 到货通知 ASN 生产日报 信号采集 │
│ 决策留痕 ⭐ 签收作业 达成率引擎 规则引擎 │
│ CTP 交期 过账适配器 异常分流 事件与处置 ⭐ │
│ 配置完备度 差异与索赔 产能反算 ⭐ 升级链 │
├───────────────────────────────────────────────────────────────────────┤
│ 主数据层 工厂/产线/设备 · 物料/BOM · 配置三层继承 ⭐ · 切换矩阵 · │
│ 异常码表 · 理由码表 · 指标口径目录(含版本) │
├───────────────────────────────────────────────────────────────────────┤
│ AI 能力层(四个落点,四道闸门,§7.5) │
│ ①签收单核对 ②日报稽核 ③风险信号研判 ④排产建议与技能沉淀 │
├───────────────────────────────────────────────────────────────────────┤
│ 集成层 SAP(OData/RFC/IDoc,幂等+失败队列) · APS · WMS · 飞书/企微开放平台 │
└───────────────────────────────────────────────────────────────────────┘
↑ 权威源:库存与凭证在 SAP;作业事实、影像、留痕、风险在本系统
⭐ 打了星的四个是这套架构的骨头,砍掉任何一个,剩下的就退化成四个看板:
决策留痕 / 配置三层继承 / 风险事件与处置 / 产能反算回流。
7.2 与 SAP 的边界(一句话版)
SAP 持有"账",本系统持有"事"。 账 = 库存余额、物料凭证、会计凭证、成本。 事 = 谁在什么时候、在哪、对哪一批货、做了什么动作、拍了什么照、为什么这么判。
本系统从不持有库存余额,也从不绕过 SAP 直写库表。
三条集成纪律:
- 幂等键必填(§4.5·B4)
- SAP 报错原文原样存,不翻译成"失败"
- 失败进队列 + 有归属 + 现场可见
7.3 与飞书/企微的边界
见 §2.6:只做通知交互 / 身份组织 / 移动端容器三件事。 外部工厂优先走 H5 短链,不假设他们进飞书(§5.5)。
7.4 技术选型建议
| 层 | 选型 | 理由 |
|---|---|---|
| 后端 | Java / Spring Boot + PostgreSQL | 与 SRM 同栈(实查app/backend-java 下 1744 个 .java),大量模块可直接移植;PG 的 JSONB 正好装配置/明细/抽取结果 |
| 前端 | Vue 3(PC)+ H5(移动,非原生 App) | 实查SRM 已有 app/frontend-vue;移动端不装 App 是 130 家厂能推得动的前提 |
| 集成 | SAP OData 优先,RFC/IDoc 兜底;出站统一走 Outbox 表 | 幂等、可重试、可审计 |
| 定时/触发 | Spring @Scheduled 起步,量大再上调度中心 |
文档SRM 24 号:9 个类 13 个 @Scheduled 在生产跑,够用;定时与触发要分开建模 |
| AI | 受控调用,见 §7.5 | — |
7.5 ⭐ AI 的四个落点与四道闸门
| # | 落点 | 用法 | 风险等级 |
|---|---|---|---|
| ① | 签收单逐行核对(场景二) | 有比对对象的闭合域抽取 | 🟢 低(可验证) |
| ② | 日报稽核(场景四) | 只做抽样稽核,不做入账 | 🟡 中 |
| ③ | 风险信号研判(场景三) | 把多条信号归并成一个事件、给一段人话说明 | 🟡 中 |
| ④ | 排产建议与技能沉淀(场景一) | 建议 + 显式授权的规则 | 🔴 高 |
四道闸门,四个落点都适用(文档提炼自 SRM 27 号 §5 与 33 号):
| 闸门 | 内容 | 防的失败 |
|---|---|---|
| G1 拒答优先 | 读不出必须落 UNREADABLE,不许猜、不许填 0 |
猜错的那次没有任何标记 |
| G2 人工确认是必需闸门,不是体验优化 | 关键字段低置信度必须人确认才落库 | 文档SRM 33 号 §二原话 |
| G3 不自动学习、不自动生效 | 规则/技能显式保存、显式编辑、显式版本,可停用可回滚 | 「某天开始某类单据都少走一步」 |
| G4 AI 判定与人的决定分两个字段存 | 不一致时留痕;责任始终在人 | 01 号文档 §6·Q2:「AI 说对我就签了」成为免责话术 |
⚠️ 文档SRM 27 号 §5.1 有一句话必须记住: 「description 约束不了模型,只能约束读它的人。」 四道闸门要落在代码和夹具里,不能只写在提示词里。
8. 与 SRM 既有资产对表
实查2026-08-23 在
/Users/bytedance/Documents/claude/SRM系统实读。 ⚠️ SRM 自己的纪律:「已上生产」≠「在起作用」。下表只代表代码/文件存在,落地前逐条重扫 + 打真请求。
8.1 可直接复用(比预想的多)
| 立邦需求 | SRM 既有资产 | 位置实查 |
|---|---|---|
| 场景一 A2 决策留痕 | ⭐ 操作留痕采集层,一个拦截器零 Controller 改动 | modules/memory/ActionTraceInterceptor.java、ActionTraceCollector.java、ActionTraceService.java |
| 场景一 A5 建议规则提炼 | ⭐ 三阶段全在:采集 → 挖掘 → 起草 | modules/memory/TraceSequenceMiner.java、TraceSkillDrafter.java;前端 frontend-vue/src/pages/AgentSkills.vue |
| 场景一 A5 规则治理(版本/停用/STALE) | 技能表与工具引用表 + 四道闸门设计 | 文档27 号 §3、§5;repository/AgentSkillToolRefRepository |
| 场景二 B2 签收移动端外壳 | 移动端 /m + MobileLayout,48px 触控 / 输入框 16px |
文档41 号 §7·五 |
| 场景二 B2 扫码收货 | 两级码(单头+箱码)、箱级防重复扫、超收拦截、扫码查 COA | modules/po/ScanReceiveService.java、ScanQrCodec.java |
| 场景二 B1 ASN 字段 | asn_line 已有 batch_no/production_date/shelf_life_days/pack_size |
V189__asn_vehicle_and_production_date.sql、V22__asn_pack_label.sql |
| 场景二 B5 异常与影像 | receipt_exception + receipt_exception_photo(含 DAMAGED/SHORT/WRONG_ITEM/LABEL_MISMATCH) |
V170__receipt_exception.sql |
| 场景二 收货计划 | 今日/本周收货计划(三个桶 = 三种事实) | modules/warehouse/WarehouseReceiptPlanService.java |
| 场景二/四 图像抽取底座 | 生产在跑的多模态读图:证照/文档分类/证书/银行卡/报价单 5 个入口 | modules/ai/AiGatewayService.java |
| 场景二/四 模型行为纪律 | 遮挡拒答、手写划改取改后值、逐行给原文片段 | 文档33 号 §二 |
| 场景三 双向通道 | ⭐ 长连接入站生产跑通:群回复 → 路由到在办任务 → 推进状态机 → 回写单据,端到端 2 秒 | modules/integration/feishu/FeishuEventClient.java、modules/followup/ |
| 场景三 跟催内核与升级链 | 收敛目标 / 结论抽取 / 卡口分级 / 三轮升级 | 文档21 号 §2 |
| 场景三 外部群实测约束 | 6 条真机撞出来、文档查不到的坑 | 文档49 号 §6 |
| 场景三 C6 画像与绩效 | 可配置绩效体系(三态、样本量、SKIP、人工分单列) | 文档42 号;modules/performance/ |
| 全域 看板与指标 | ⭐ 受控语义层(AI 不碰 SQL,只在指标目录里挑) | modules/analysis/MetricProvider.java;文档40 号 |
| 全域 定时/触发 | 9 类 13 个 @Scheduled 生产在跑;定时 vs 触发分开建模 |
文档24 号 |
| 全域 飞书免登与绑定 | POST /auth/feishu/h5;查不到绑定就拒绝,绝不自动建号 |
文档41 号 M3 |
8.2 需要新建的
| 缺口 | 判断 |
|---|---|
| APS 排产工作台与七步编排 | 全新。SRM 是采购侧,没有生产排产 |
| 配置三层继承 + 完备度闸门 | 全新,但是最快见效的一块(§3.5·A3) |
| 切换成本矩阵 / 车间档案 / 产能反算 | 全新。SRM 有「供应商产能主数据」文档43 号,但那是供应商产能,不是设备产能 |
| CTP 可承诺交期引擎 | 全新 |
| SAP 收货过账适配器(主动推) | ⚠️ 文档41 号 §2.2 明写"主动推 ERP 未做",只做了对账那一半。这块要从零建,且是场景二的核心 |
达成率口径引擎与 plan_freeze |
全新 |
| 生产日报结构化录入 | 全新(移动端外壳可复用) |
| 异常码表 / 理由码表 | 全新,且是咨询交付物不是开发交付物 |
| 企微通道适配器 | 全新。SRM 只做了飞书 |
| 静默检测 | 全新,成本极低(§5.2.1) |
| 手写体识别 | ⚠️ SRM 的 5 个图像入口全是印刷体读字,手写命中 0。这是场景四的最大技术未知,P0 必须打真请求出读数 |
9. 落地路线
⚠️ 不要按 PPT 的顺序做(APS → 签收 → 风险 → 达成)。 那个顺序会先啃最难、依赖最多、且依赖的数据还不存在的一块。 正确顺序是把箭头倒过来:先修数据入口(场景二、四),再做执行闭环(场景三),最后做决策层(场景一)。
P0 · 口径拍板 + 可行性判定(约 3–4 周,不写业务代码)
照 SRM 33 号文档的做法:第 0 步先判定能不能做,打真请求、给读数,而不是推断。
| # | 事项 | 产出物 | 结论允许是"做不了" |
|---|---|---|---|
| 1 | ⭐ 测出签收→过账时延基线 | 近 3 个月 P50/P90/P99 + 按厂分布 | — |
| 2 | ⭐ 达成率口径拍板 | 一页纸口径书(§6.2),业务签字 | — |
| 3 | 权威源拍板 | SAP = 库存权威(§4.4) | — |
| 4 | 130 家分层 | A/B/C 名单 + 分层依据(§5.4) | — |
| 5 | 异常码表 / 理由码表初版 | 两张码表(§6.4.1、§3.5·A2) | — |
| 6 | ⭐ OCR 可行性:两套样本分开打读数 | 印刷签收单 / 手写日报 各一份读数报告 | ✅ 手写这一半允许结论是"做不了,改走结构化录入" |
| 7 | SAP 集成通道确认 | OData/RFC 权限能不能批、测试环境有没有 | ✅ 批不下来则整个场景二要改形态 |
| 8 | 飞书/企微权限确认 | 长连接事件订阅、H5 免登、外部群能力 | ✅ 实查SRM 49 号里「外部用户必须和群主已成为好友」这条至今未闭合 |
P0 的纪律(文档SRM CLAUDE.md 原话): 「「命中 0」有两种解释:真的不存在 / 搜错地方看少行——两种解释的结论是相反的。」 打真请求时,每个反向对照旁边必须并列一条正向对照,否则分不清 "模型读不出手写数字" 和 "我的请求根本没发对"。
两套 OCR 指标不许混着报:印刷单看"该拒答的拒没拒",手写看"数字误读率是多少"。 混着报会得出一个漂亮的平均数,然后把手写这条最危险的路放行。
P1 · 数据入口(约 2.5–3 个月)—— 收益确定,零 AI 依赖
| 期 | 内容 |
|---|---|
| P1-a | B1 ASN · B2 签收移动端 · B3 影像绑定 · D1 日报录入 · D2 冻结版与达成率引擎 |
| P1-b | B4 SAP 过账适配器 · B5 差异与索赔 · B6 时效看板 · D3 异常分流 · D4 影像稽核 · D6 达成率看板 |
这一期结束就能拿到的(可测):
- ⭐ 签收→过账时延 从 天/周级 压到 分钟级(头号 KPI)
- ⭐ 达成率有唯一口径,且分母不可被事后修改
- 场景一的两条毒害箭头(①库存 ②产出)被切断
- 异常有码表、有去向、有留证 → 索赔窗口不再静默流失
P2 · 执行闭环(约 2–2.5 个月)
C1 工厂主数据与分层 · C2 六类信号(含静默检测)· C3 规则引擎 · C4 事件与处置状态机 · C5 分层看板 · C6 响应画像
- 多通道适配层(H5 / 企微 / 飞书 / 短信)
验收头号指标:risk_signal 里 source = SYSTEM 的占比。
半年后如果还是 90%
REPORTED,说明"从被动到主动"根本没做成——而看板照样天天有数。
P3 · 排产前置层(约 3 个月)
P3-a:A1 排产工作台(七步收两屏)· A2 决策留痕(不可延后) · A3 配置三层继承与完备度看板 P3-b:A4 CTP 交期引擎 · A6 切换矩阵 · D5 产能参数反算回流
这一期打掉的原话: 「人工选择工厂」「人工选择 APS 排产单号」「不完成配置则无法推进下一步」「集团统一配置不支持工厂别」「TUB 请求交期每单需沟通」「车间档案需逐一设定」
P4 · 建议引擎与技能沉淀(约 3 个月,必须在 A2 攒够 6–12 个月留痕之后)
A5 排产建议(OPTIMIZER + LEARNED 分开标注)· 规则显式授权与版本 · 原物料/包材采购建议
⚠️ P4 的启动条件是数据量而不是日历时间。
plan_decision不足 N 条(建议 ≥ 2000 条有效决策、 覆盖 ≥ 2 个完整月排产周期)就启动 P4,等于在噪声上训练。这条要写进里程碑的准入条件。
9.1 整体节奏
P0 口径与判定 ████ (3–4 周)
P1 数据入口 ████████████ (2.5–3 月) ⭐ 收益在这里落袋
P2 执行闭环 ██████████ (2–2.5 月)
P3 排产前置层 ████████████ (3 月)
P4 建议与沉淀 ██████████ (3 月)
↑ 准入条件是留痕数据量,不是日期
10. 风险清单(按"发现得晚 + 代价高"排序)
| # | 风险 | 失败形态 | 缓解 |
|---|---|---|---|
| 🔴 1 | 四个场景被拆成四个独立项目/四个看板 | 每个都"上线了",病根一个没动;场景一永远做不成 | 一套主数据、一条执行链;立项时就把 §1 那张因果图挂在墙上 |
| 🔴 2 | 达成率口径没锁死就上线 | 每个厂一套算法,看板永远对不上,三个月后没人看;而且分母可改 = 达成率永远 95% | P0·#2 口径书业务签字;plan_freeze 冻结后不可改;metric_version 落列 |
| 🔴 3 | 手写 OCR 当主录入 | 静默错数,达成率变成另一个数,无任何报错 | 主路径结构化录入;OCR 降级为稽核(§6.3);P0 分开打读数 |
| 🔴 4 | 月底集中过账没治 | 所有基于时间的分析与学习全部失真,而每张报表都算得出数 | 双时间戳(signed_at/posted_at)+ 时延分布进月度例会(§3.3) |
| 🔴 5 | 130 家委外厂不配合 | 系统建好了没数据 | 入口极轻(H5 一屏)+ 给他们也有用 + 数据协同率进评级(§5.5.1) |
| 🟠 6 | 假设 130 家都进飞书 | 推行卡死在 IM 上 | 多通道适配层(§5.5);外部优先 H5 短链 |
| 🟠 7 | A2 决策留痕被当成"二期再说" | 二期没有历史数据,只能再等一年 | 与 A1 同期上线,写进 P3-a 的验收 |
| 🟠 8 | SAP 过账失败静默 | 现场以为收完了,库存没加上 | 幂等键 + 失败队列 + 现场可见回执(§4.5·B4) |
| 🟠 9 | AI 自动学习自动生效 | 「某天开始,某类订单都晚一天」 | G3 闸门:显式保存/编辑/版本(§7.5) |
| 🟡 10 | "数据不足"被画成"低风险" | 最该盯的新厂显示绿色 | 三态三色,hasRealData=false 不评级不报警(§5.3.1) |
| 🟡 11 | 码表设计太粗 | 全是"其他",表看起来有数据 | 上线首月盯 OTHER 占比,>30% 改码表 |
| 🟡 12 | 外部人员因飞书免登自动获得内部账号 | 权限越界,且无人察觉 | 显式绑定,查不到就拒绝,四种拒绝分开说(§2.6) |
11. 已按以下口径设计(若立邦口径不同,改动落在括号里的位置)
按 01 号文档 之后定下的做法:不产出问卷。 以下每条都给了默认取值,方案已按它往下做完;业务方看到后指出哪条不对,只改对应的那一处。
| # | 口径 | 默认取值 | 若不同,改哪里 |
|---|---|---|---|
| 1 | 「130 家工厂」是谁 | 委外/代工厂为主 + 少量自有粉料线(依据:分散各地、用企微、纸质日报) | 若全是自有厂 → §5.5 多通道可简化为只做飞书;§5.5.1 商务抓手改为内部考核 |
| 2 | 粉料品类 | 干粉砂浆族:腻子粉 / 瓷砖胶 / 防水粉料 / 保温砂浆(依据:PPT 提"防水产品"、"单缸产量"、"研磨/包装工序") | 若是粉末涂料 → §6.4.1 异常码表要换(挤出/压片/ACM 磨/静电喷涂相关);切换矩阵要按色系+树脂体系建 |
| 3 | TUB / TUC | 内部要货/调拨类单据:TUB 带请求交期(需沟通),TUC 是要货日期不准且月底集中过账的那类 | 若是客户订单类型 → §3.5·A4 的 CTP 要接销售侧承诺,范围扩大 |
| 4 | 库存权威源 | SAP | 若立邦要以 APS 或 WMS 为准 → §4.4 四条边界与 B4 适配器方向要重做 |
| 5 | 签收单场景 | 到货签收(原料/委外成品入厂),过账动作是收货(MIGO 101) | 若是销售出库签收 → 场景二的价值从"库存时效"变成"回单与应收",KPI 换 |
| 6 | 达成率分母 | 每日 08:00 冻结版,冻结后不可改 | 若业务坚持用调整后值 → 必须同时上"计划变更次数/幅度"指标,否则达成率无意义(§6.2) |
| 7 | 达成率分子 | SAP 入库过账量;车间自报为预报值并排显示 | 若 SAP 过账延迟无法在 P1 解决 → 临时用自报量,但必须标注口径且不进考核 |
| 8 | 车间录入方式 | 结构化录入为主,OCR 为稽核 | 若现场确实不能用手机(防爆区)→ 走 §6.3.2 改表单 + §6.3.3 四道闸门 |
| 9 | 委外厂接入通道 | H5 短链优先,企微次之,不强制飞书 | 若集团已强制全供应链上飞书 → §5.5 简化,但 §2.6 的绑定纪律不变 |
| 10 | AI 的法律地位 | 只提请,不决定;AI 判定与人的决定分两列存 | 这条建议不要改(文档01 号 §6·Q2:两种误判代价不对称,错误拒收不可逆) |
| 11 | 影像保留期 | 3 年 | 按立邦审计与索赔条款调整 |
| 12 | 差异容差 | 粉料 ±0.5% 或 ±1 包取大 | 按品类主数据配 |
12. 本文的自我限定
- §3.2、§4.2、§5.2、§6.2 的"还原"部分全部是推导,立邦侧零验证。 它们的价值是当设计主张用——摆出来让业务方指着反驳,比问他们"你们的痛点是什么"有效得多。
- §8 的"已有"是 2026-08-23 实读 SRM 仓库的结果。 SRM 自己的文档反复强调结论会过期——41 号起草时把"扫码收货"整条列成缺口,而它已经上生产了。 立项前重扫一遍,且打真请求,别读转述。
- §9 的工期是按 SRM 同栈、同规模团队的经验估的,没有立邦的团队规模与并行度输入, 是一个假设,不是承诺。
- §1 的因果图是本文的核心论点。如果立邦业务方否掉它(认为四个场景确实互不相关), 那么本文 §9 的整个排期都要重来——这是最该先被反驳的一条。
- ⚠️ 本文没有覆盖的:成本/费用侧(委外加工费结算)、质量体系(QMS/COA/IQC 判定)、 安全环保(粉尘防爆、危化)、销售侧需求预测。其中粉尘防爆会直接影响 §6.3 的移动端方案 (防爆区能不能带手机),P0 要顺带问一句。
附 · 一页话给立邦 IT 回话
你们 PPT 里的四个场景我们都能做,其中飞书双向闭环、现场移动端、多模态读图、 操作留痕与规则沉淀,我们已经有生产在跑的实现(SRM 系统)。
但有四点要先对齐:
这四个场景不是四件事,是一条链上的四个断点。 APS 排产(场景一)是果, 另外三个是因——你们自己列的"全自动排产受阻的四个根源"里,没有一条是排产算法问题。 所以做的顺序要倒过来:先签收同步和入库达成,再交付风险,最后 APS。
手写日报走 OCR 直接入账是最贵的一个坑。 它和签收单 OCR 不是一个难度等级, 而且读错了不报错,只是把达成率换成另一个数。建议主路径改成结构化录入 (扫码选设备 + 数字键盘),OCR 降级为存档与稽核。 如果必须保留纸,那改表单比改模型便宜十倍——方格框、预印排产量、贴二维码。
做 OCR 之前,先把「达成率」的定义写死。 分母如果取"调整后的排产量", 达成率永远 95%+,而没有任何人在造假。这一条不定,后面所有看板都是装饰。
多维表格会变成第二本账。 130 家厂的数进了表格,SAP 的库存还是错的, MRP 还是算不准,场景一永远解决不了——而看板上天天有数,所有人都以为做完了。 飞书该干三件事:通知交互、身份组织、移动端容器。存数、算指标、做状态机、当权威源, 这四件不该给它。
另外有 12 条口径我们已经按行业常识填了默认值并按它做完了方案(见 §11), 请业务方直接指出哪几条不对,我们只改那几处——不需要再做一轮调研。