chore: 清理生成视频和 AI 临时文件

This commit is contained in:
z.zhang 2026-09-08 11:24:04 +08:00
parent 68a8b4c7e2
commit f9873ee870
69 changed files with 30 additions and 1714 deletions

18
.gitignore vendored
View File

@ -57,3 +57,21 @@ artifacts/
apps/*.dxf
tests/golden/_*.json
beihai-shipyard-aps-data/
# ---- Generated presentation and media drafts (do not commit) ----
/video/
/_refs/
*.mp4
*.mov
*.avi
*.mkv
*.webm
*.wmv
*.m4v
*.mp3
*.wav
/APS智能体演讲稿*.md
/APS智能体演示讲解稿.md
/Pi-Agent兜底能力详细方案.md
/Pi-Agent接入计划.md
/Pi-Agent接入详细计划.md

Binary file not shown.

View File

@ -1,131 +0,0 @@
# 从"人排产"到"智能体排产"
## —— APS 计划排产智能体 演示讲解稿(边讲边演,约 15–18 分钟)
> 使用说明:【讲】为面向领导的讲解词,【演】为系统实际操作。演示口令均已在系统中验证可用;建议演示前完成数据导入并确认服务已启动(Web 端 http://localhost:5173)。
---
## 开场(只讲不演,约 2 分钟)
【讲】各位领导,大家好。今天我不放 PPT,直接让系统自己说话。接下来十五分钟,我将用我们真实的工厂数据,现场演示 APS 计划排产智能体的完整工作过程。
先交代背景。排产是制造业数字化最后一块硬骨头:约束复杂、变化频繁、决策高度依赖老师傅的个人经验。传统排产软件把成百上千个参数推给用户,最后往往沦为摆设。
而大模型的成熟给了我们一条新路——**让机器理解人的意图,让算法完成繁重的计算,让人专注于判断与决策**。这就是各位现在看到的这套系统:用自然语言驱动、用可视化确认、用门禁审计约束的计划排产智能体。
下面开始演示。
---
## 第一幕:数据准备——把工厂"搬"进系统(约 2 分钟)
【讲】一切智能的前提是数据。各位请看,这是我们真实的工厂数据目录——订单、物料、BOM、工艺路线、设备台账,就是最常见的 Excel 表格。
【演】打开左侧「新工厂排产项目」,展示导入结果卡片(订单 5 行、物料 45 行、工艺路线 15 行、设备 15 行),点击「根据这些数据排产」。
【讲】请注意刚才发生了什么:系统自动识别了每一张表的角色——哪张是订单、哪张是 BOM、哪张是设备——完成表头映射与校验,写入主数据。传统 APS 实施中最耗时的"数据初始化",在这里是一次导入完成的。
---
## 第二幕:一句话排产——听得懂(约 2 分钟)
【讲】数据就绪。现在,我不点任何菜单,只跟它说一句话。
【演】在对话输入框输入:**「试排一版交期优先」**,回车。等待右侧甘特图刷新,切换到负荷、交期两个视图各看一眼。
【讲】各位看到的是完整的智能体闭环:系统理解我的意图,调用排产引擎真实求解,几秒钟产出一个排产版本,右侧沙盘同步呈现——这是甘特图,每个订单在哪台设备、什么时间、哪道工序,一目了然;这是设备负荷,哪台设备超载一眼可见;这是交期看板,哪张订单有延期风险清清楚楚。
特别强调一点:**这些数字全部来自运筹学引擎的确定性计算,大模型只负责听懂我的话,制度上不允许它编造任何一个数字。**
---
## 第三幕:多策略对比——算得全(约 2 分钟)
【讲】排产从来没有唯一解,只有适合当下经营目标的解。我让系统把几种思路同时算一遍。
【演】输入:**「对比几种策略」**。等待方案卡片出现,指着 KPI 逐项差异讲,然后点击最优方案的「采用此方案」。
【讲】系统在我们看不到的地方,把同一份订单用交期优先、产能均衡、换型最小化等不同策略并行试排——这叫沙盒对比,试排期间正式数据不受影响。每张卡片上的准时率、换型次数、设备利用率逐项对照,最优项高亮。我看中哪个,一键采用,右侧沙盘立即刷新。
过去计划员凭经验只能想一种排法,现在是**机器穷举、人来拍板**。
---
## 第四幕:紧急插单与动态调度——应变得快(约 2 分钟)
【讲】计划永远赶不上变化。现在模拟最常见的突发:客户来电话,一张急单要插进来。
【演】输入:**「插单快评」**(或在订单面板操作插单向导),展示影响评估结果;再演示:**「设备故障怎么办」→ 展示 L1 池内换机建议**。
【讲】请注意系统的处理方式:它不是把急单硬塞进去引发连锁延期,而是先做局部修复、评估影响面——影响小,池内秒级换机;影响大,逐级升级为窗口重排、日重排乃至全局重排。这就是我们的 **L1 到 L4 分级动态调度**。
而且每一步重排建议都带着影响评估和确认卡——**重排是智能体的建议,拍板权永远在人**。
---
## 第五幕:柔性排产——我们的差异化能力(约 2 分钟)
【讲】多品种、小批量的工厂,设备未必永远属于某条产线。这是我们与市面上产品最大的不同。
【演】打开「柔性工作台」,输入:**「三模式对比」**,展示正排、倒排、瓶颈锚定三种模式的对比结果与产能池仪表盘。
【讲】系统建立了**工序能力池和虚拟产线**机制:排产时按订单需求,从能力池里动态组合设备、预占资源、用完释放,连设备移动耗时、模具换型时间都精确计算。正排保开工、倒排保交期、瓶颈锚定保产能利用率,三种模式自由切换。
瓶颈工序的产能是实时重算的——设备一停机,全线产能预测即刻更新,四小时、一天、一周的负载预警自动色标。
---
## 第六幕:图纸智能解析——AI 的另一只手(约 2 分钟)
【讲】排产的上游是技术资料。工程图纸里的物料和工艺信息,过去要靠人一个个抄进系统。
【演】打开右侧「工程图纸」工作区,输入一张 DXF 图纸路径(例如 `%RUIYANG_DEMO_DIR%\5060102101-001-e(1).dxf`),点击「解析图纸」,展示图号版本识别结果、SVG 预览与物料/BOM/工艺候选清单。
【讲】系统直接读懂了这张 CAD 图纸:自动识别图号和版本,九千多个图元逐一解析,把图纸里的物料、BOM 引用、工艺信息提取成结构化的候选清单。请注意"候选"两个字——**图纸是证据,不是命令**,这些信息必须经过人工确认才会写入主数据。这就是我们的原则:AI 负责提取,人负责批准。
---
## 第七幕:发布与门禁——管得住(约 2 分钟)
【讲】方案满意了,能不能一键生效?能,但要过一道门。
【演】输入:**「发布这个版本」**。展示弹出的 P2 确认卡,点击批准。然后输入:**「清空数据重新初始化」**(仅展示确认卡,不批准,点驳回或取消)。
【讲】各位刚才看到的是系统的**四级门禁**:只读查询随便看,试排对比轻提示,但发布、回滚这类关键动作,必须经确认卡人工点头;涉及 MES 下发等外部系统的动作,要二次确认。刚才那个清空数据的危险操作,我不批准,它就永远执行不了。
同时,每一次操作都记入哈希链式审计台账——谁决定的、依据是什么、系统当时看到了什么,随时可查、不可篡改。**智能体的每一步"想动",都要经过人的"放行"。**
---
## 第八幕:存档、回放与报告——经验沉淀为资产(约 2 分钟)
【演】输入:**「存个档」**,展示时间线检查点;点击某个历史检查点演示回滚(展示确认卡即可)。然后输入:**「打开仪表盘」**展示 KPI 汇总;最后输入:**「生成日报」**或导出 Word 排产报告。
【讲】最后三样东西,送给管理者。其一,**时间线**:每个决策节点自动存档,随时回滚到任何一个"如果当初"。其二,**仪表盘**:利用率、准时率、在制、延误,一屏汇总。其三,**报告**:一键生成排产日报和正式的 Word 排产报告——订单交付明细、瓶颈工序、冲突清单、MES 下发状态全部在案,数字直接来自冻结快照,不经过任何 AI 改写。
---
## 收尾(只讲不演,约 1 分钟)
【讲】各位领导,刚才十五分钟,我们从一份 Excel 开始,走完了**数据导入、智能排产、多策略对比、插单应变、柔性组线、图纸解析、门禁发布、存档报告**的完整闭环。
这套系统的价值,可以归结为三句话:
**第一,让排产听得懂人话**——计划员从深夜的 Excel 中解放出来;
**第二,让决策算得清利害**——机器穷举、人来拍板,每个决定都有计算作底气;
**第三,让经验沉淀为资产**——老师傅的智慧变成组织的系统能力,越用越聪明。
它对标西门子 Opcenter 完成了主体能力覆盖,行业适配不靠定制开发、换一套数据即可运转——不仅能解决我们自己的问题,更具备产品化输出的潜力。
我的演示到此结束,恳请各位领导批评指正,谢谢大家。
---
### 演示前检查清单(不给领导看)
- [ ] 后端 API(:8000)与前端(:5173)均已启动,浏览器已登录
- [ ] 当前项目为「新工厂排产项目」,数据已导入(订单/物料/工艺/设备行数正常)
- [ ] 已设置 `RUIYANG_DEMO_DIR`,其中 DXF 图纸路径可复制粘贴
- [ ] 演示口令依次试跑一遍:试排一版交期优先 → 对比几种策略 → 插单快评 → 三模式对比 → 发布这个版本 → 存个档 → 打开仪表盘 → 生成日报
- [ ] 提前存一个"干净"检查点,演示中翻车可一键回滚
- [ ] 「清空数据重新初始化」仅用于展示门禁,**切勿批准**

View File

@ -1,86 +0,0 @@
# 让排产听懂人话(功能对照版)
## —— APS 计划排产智能体产品演讲稿(约 10 分钟)
---
各位领导、各位同仁:
大家好。今天我向大家介绍的产品,是 **APS 计划排产智能体**——一款用自然语言驱动、用可视化确认的高级计划排产系统。
今天我不讲概念,而是对照系统的真实功能,一个模块一个模块地向大家汇报:它到底能做什么,以及每一项能力在工厂里意味着什么。
整款产品可以用一句话概括:**左手说意图,右手出结果,关键操作过门禁。** 下面,我们沿着生产计划的真实工作流,从数据到订单、从计划到排产、从发布到执行,完整走一遍。
## 一、主数据:先把工厂搬进系统
一切排产的前提是数据真实。系统的主数据模块覆盖了工厂建模的全部要素。
**第一,资源建模。** 从工厂、车间、产线到工位、设备,一棵通用资源树完整承载;产线可以编辑、可以停用,停用的产线自动退出排产,不留人为疏漏。
**第二,物料与工艺。** 物料库存、BOM 明细用量、关键物料标记、工艺步骤工时、外协工序标记,全部可视化维护。
**第三,日历与维保。** 班次、日历、设备维保计划进入排产计算,维保时段自动避让,设备不会在保养时被排上任务。
**第四,数据导入与集成。** Excel、CSV 一键导入,表头映射、校验、确认三步落库;与 ERP 的订单库存同步、与 MES 的开工完工回写,都已打通标准流程。
特别值得一提的是两项行业级能力:一是**换型矩阵**——产品族之间的切换时间精确到矩阵级管理,排产时自动叠加换型耗时;二是**柔性资源档案**——设备的能力集合、可移动属性、移动耗时、模具适配清单全部建档,这是后面柔性排产的地基。
## 二、订单:从一张订单到一套制造方案
订单模块回答三个问题:接什么、谁先谁后、如何落地。
**订单全生命周期管理**——新建、编辑、取消、完成,状态过滤后自动进入排产范围。**订单池与审核**——订单须经过提交、批准的状态机流转,只有已批准订单才能进排产,从制度上杜绝"先干后批"。**优先级管理**——客户等级权重直接参与排产排序,一句话"提高 VIP 权重",全局排序即刻调整。
针对制造业最头疼的两个场景,系统给出了专门答案:**紧急插单**,有快评与局部修复机制,先评估影响再决定是否采用,而不是硬塞进去引发连锁延期;**预测订单**,单独建账、默认不进正式排产,需要时可以纳入试排、可以一键转正。
还有两项能力值得单独说明。**订单钉扎溯源**:从销售订单到工单、到物料、到设备负荷,一条链条正查反查都畅通。**订单分解(MRP)**:一张订单按 BOM 与工艺自动展开,自制部分进排产、采购部分给出净需求与前置期倒排建议、外协工序单独标记——从商务订单到制造需求,语义清晰、各司其职。
## 三、计划层:把答案给在问题发生之前
传统排产软件解决"怎么排",我们向前多走一步,先回答"能不能"。
**时间分桶计划**,把近期按日、中期按周、远期按月混合建模;**粗能力评估**,有限产能与无限产能双模式对照;**可行性分析**,在正式排产之前明确告知:哪些订单能按期、缺口在哪一周、缺口有多大。**库存投影**则画出未来库存曲线,断料风险与安全库存告警提前浮出水面。
发现产能超载之后,**产能平衡**给出削峰建议——哪些任务可以提前、哪些可以挪到空档;挪不动怎么办?**产供决策**给出结构化的三级路径:先加班、再扩线、最后外协,每一条建议都有数据支撑。**交期承诺模拟**更是销售部门的利器:一张询单插进来,乐观、中值、悲观三个交期区间连同资源缺口一并呈现,让每一次对外承诺都经得起推敲。
## 四、排产引擎:多引擎、多策略、多约束
这是系统的心脏。
**引擎层面**,规则引擎、约束规划引擎、遗传算法、混合求解、NSGA-II 多目标优化全部内置,按问题规模与精度要求自动适配。
**策略层面**,交期优先、先进先出、产能均衡、换型最小化、成本优先、综合评分六大模板开箱即用;多方案沙盒并行计算,方案卡片逐项对比 KPI,最优项自动高亮。
**约束层面**,十三类约束全部进入注册表:物料齐套三态校验、模具寿命到限锁定、班组技能并发上限、顺序相关换型叠加——每一项都可以在配置中心启停、可以设定软硬。硬约束守住发布底线,任何人都无法把一张违反硬约束的计划发布出去。
针对高级场景,系统还提供:**战役合并排产**,同产品交期窗口自动合并,减少换型损耗;**滚动时域排产**,从实时一小时到七天长期,多级窗口逐级细化;**正排、倒排、瓶颈锚定**三种模式,配合能力池动态组建虚拟产线——设备从池中选取、预占、用完释放,模具换型与移动耗时分毫必较。
## 五、动态调度:异常发生时的从容应对
工厂里没有一成不变的计划。系统把异常处置分为四级:**L1 池内换机**——设备故障,秒级切换到备用设备;**L2 短窗重排**——局部扰动局部消化;**L3 日窗重排**——影响扩大时重排当日;**L4 全局重排**——重大变化时整体优化。每一级都出确认卡,重排不是系统的自作主张,而是人的知情决策。
## 六、结果与执行:从沙盘到车间
排产版本经确认后**一键发布**,下发 MES 执行;**报工数据实时回流**,进度偏差在订单上自动呈现,形成完整闭环。
在执行监控上,系统提供:甘特图支持**拖拽调程**,边拖边校验、十五分钟吸附,拖动即生成新版本;**冲突解决中心**,按冲突类型给出修复建议,一键应用;**方案对比表**,固定策略与柔性三模式矩阵式对照;**KPI 仪表盘**,利用率、准时率、在制、延误一屏汇总;**产能池仪表盘**,四小时、一天、一周的负载预测,瓶颈自动色标预警。
## 七、对话与治理:智能的边界,信任的基石
最后讲这套系统与众不同的地方——它如何驾驭 AI,又如何约束 AI。
**对话层**,意图识别采用"正则快路 + 大模型精解"两级管线,断网时自动降级,永不失语;**知识问答**基于企业 SOP 与制度文档检索作答,引用必附出处,查不到就明说查不到,绝不编造。
**治理层**,三道防线缺一不可:其一,**数字不经大模型**——所有排产结果与 KPI 全部来自引擎的确定性计算,AI 只负责理解与表达;其二,**P0 至 P3 四级门禁**——只读自由、试排轻提示、关键写操作必须确认、外部系统动作二次确认,智能体的每一步动作都要经过人的放行;其三,**审计哈希链**——全程留痕、防篡改、可校验、可回放,任何时候都能回答:谁决定的、依据是什么、系统当时看到了什么。
## 结语
各位同仁,从主数据到订单、从计划层到排产引擎、从动态调度到执行闭环,这套系统的每一项功能,都对应着工厂里一个真实的痛点。它的行业适配不靠定制代码,靠的是主数据与知识库的配置;它的智能不取代人的判断,而是让人的每一个决定,都有计算作底气、有图形作印证、有记录作凭据。
**当排产听得懂人话,当变化能够被从容应对,计划员将从深夜的 Excel 中解放出来。** 这,就是 APS 智能体交付给中国制造的答卷。
我的汇报到此结束,谢谢大家。
---
*(全文约 2600 字,正常语速演讲约 9–10 分钟;各模块时长可按听众侧重灵活裁剪)*

View File

@ -1,162 +0,0 @@
# 从"人排产"到"智能体排产"
## —— APS 计划排产智能体 系统功能与流程架构汇报(领导汇报版,约 20–30 分钟)
> 使用说明:本稿面向领导汇报,主讲**系统功能与整体流程架构**,全程可纯讲不演;标注【可插演示】处如时间允许可现场操作(口令均经系统验证)。全文约 6500 字,正常汇报语速 22–25 分钟;每节标注时长与压缩点,压到 20 分钟或加演示拉到 30 分钟均可。
---
## 〇、开场(约 2 分钟)
各位领导:
大家好。今天向各位汇报的,是我们自主研发的 **APS 计划排产智能体**。我的汇报分四个部分:**第一,为什么做;第二,系统的总体架构——它是怎么运转的;第三,业务功能全流程——从一张订单到车间执行,系统完整走一遍;第四,它为什么可信、目前验证到什么程度。**
先说为什么。这些年我们在 ERP、MES 上的投入不小,但有一个环节始终依赖"老师傅"——计划排产。原因有三:约束太复杂,物料齐套、设备产能、模具寿命、班组技能、换型耗时,牵一发而动全身;变化太频繁,插单、故障、物料延期,计划永远赶不上变化;决策太依赖人,一个资深计划员要培养五年以上,经验却无法沉淀、无法复制。传统 APS 软件把成百上千个参数原样推给用户,最后软件沦为摆设,计划员重新回到 Excel。
而大语言模型的成熟给了我们一条新路:**让机器理解人的意图,让运筹学引擎完成繁重的计算,让人专注于判断与决策。** 这套系统用一句话概括——**用自然语言驱动、用可视化确认、用门禁审计约束的计划排产智能体。**
---
## 一、总体架构:一句话如何从"说"变成"排产结果"(约 4 分钟)
先向各位领导交代系统的整体架构。系统分五层,我用一次真实请求把五层串起来。
**第一层,表现层。** Web 浏览器与 Electron 桌面端共用同一套界面:左边是对话窗,右边是排产沙盘,我们称之为**"左说右动"**。桌面端数据落本地,无需服务器托管界面,可以发安装包独立运行。
**第二层,接入与智能体核心。** 所有请求先经网关,进入**意图识别两级管线**:常用指令走"规则快路",毫秒级响应;复杂表达走大模型精解;断网时自动降级、永不失语。意图被翻译成结构化命令后,必须先过一道**权力判定(Harness)**——这是架构的铁律:**任何写操作都必须经过权力判定,没有例外。**
**第三层,业务域。** 工作流编排、沙盒试排、视图投影、报告生成都在这里。特别说明"沙盒":试排和方案对比全部在沙盒里进行,**试排期间正式数据不受任何影响**,架构上写死了"沙盒不得写主干"。
**第四层,引擎层。** 排产引擎、知识库、世界状态。这里要特别强调:**所有排产结果、所有 KPI 数字,全部来自运筹学引擎的确定性计算,大模型只负责理解与表达,制度上不允许它碰任何一个数字。**
**第五层,数据与契约层。** 前后端共用一套 JSON Schema 契约,接口版本严格校验;版本不兼容,系统在挂载前显式阻断,不会出现"前端新、后端旧"的脏状态。
现在,请各位随我看一句话的完整旅程——这就是系统的**请求主链路**:
> 计划员输入"试排一版交期优先" → 网关接收 → 意图管线理解成结构化命令 → 工作流编排 → **权力判定**:只读和试排直接放行(P0/P1),发布、回滚这类关键动作挂起,弹出确认卡等人点头(P2),涉及 MES 下发等外部系统动作要二次确认(P3)→ 执行器调用引擎真实求解 → 同时写入**审计哈希链** → 结果投影成甘特图、负荷图、交期看板,回到右侧沙盘。
这条链路里有三道闸门是架构级焊死的:**写主干必过权力判定;沙盒不得写主干;报告数字只能来自冻结快照。** 后面讲功能时大家会发现,每一个功能都跑在这条链路上,没有旁路。
---
## 二、业务功能全流程:从一张订单到车间执行(约 11 分钟,汇报主体)
下面沿着生产计划的真实工作流,把功能完整走一遍:**数据 → 订单 → 计划 → 排产 → 调度 → 执行 → 回流**,七个环节环环相扣。
### 2.1 数据:先把工厂"搬"进系统(约 1.5 分钟)
一切智能的前提是数据。系统支持订单、物料、BOM、工艺路线、设备、模具、工序的 **Excel/CSV 一键导入**——表头自动映射、校验、确认三步落库,传统 APS 实施中最耗时的数据初始化,在这里一次完成。与 ERP 的订单库存同步、与 MES 的开工完工回写,也已打通标准集成流程。
主数据建模覆盖工厂全要素:**资源树**(工厂—车间—产线—工位—设备)、物料 BOM 与工艺工时、**班次日历与设备维保**(维保时段自动避让)、**换型矩阵**(产品族之间切换时间精确到矩阵级)、模具寿命与班组技能档案。还有一项地基性能力——**柔性资源档案**:每台设备的能力集合、可移动属性、移动耗时、模具适配清单全部建档,这是后面柔性排产的前提。
【可插演示:展示真实工厂数据目录,输入「分析一下数据文件」,系统自动识别表角色并完成导入——订单 5、物料 45、工艺 15、设备 15、BOM 42。】
### 2.2 订单:从商务订单到制造需求(约 1.5 分钟)
订单进入系统后,先过**订单池审核**:提交、批准、驳回的状态机流转,**只有已批准的订单才能进入排产**,制度上杜绝"先干后批"。客户等级权重直接参与排产排序,一句"提高 VIP 权重",全局排序即刻调整。
接着是 **MRP 订单分解**:一张订单按 BOM 和工艺自动展开——自制部分进排产、采购部分给出净需求与前置期倒排建议、委外工序单独标记,商务订单与制造需求语义分离、各司其职。分解建议经人工确认后下达,采购单自动补全预计到料日。
针对两个高频痛点有专门机制:**紧急插单**走"快评 + 局部修复",先评估影响面再决定是否采用,而不是硬塞进去引发连锁延期;**预测订单**单独建账、默认不进正式排产,需要时可纳入试排、一键转正。此外**订单钉扎溯源**打通从销售订单到工单、物料、设备负荷的完整链条,正查反查都畅通。
【可插演示:输入「执行MRP分解」→ 展示自制建议与采购建议;输入「下达MRP建议单」→ 展示确认卡批准过程。】
### 2.3 计划层:把答案给在问题发生之前(约 2 分钟)
传统排产软件只解决"怎么排",我们向前多走一步,先回答"**能不能**"。
- **时间分桶计划**:近期按日、中期按周、远期按月混合建模;
- **粗能力评估**:有限产能与无限产能双模式对照;
- **可行性分析**:正式排产之前明确告知哪些订单能按期、缺口在哪一周、缺多少;
- **库存投影**:画出未来库存曲线,断料风险与安全库存告警提前浮出水面;
- **产能平衡**:超载时给出削峰建议,哪些任务提前、哪些挪到空档,前后负荷对照呈现;
- **产供决策**:缺口挪不动时给出结构化三级路径——先加班、再扩线、最后外协,每条建议都有数据支撑;
- **交期承诺模拟**:销售询单进来,系统给出乐观、中值、悲观三个交期区间连同资源缺口——**让每一次对外承诺都有计算依据**,这是销售部门的利器。
### 2.4 排产引擎:系统的心脏(约 3 分钟)
这是技术含量最高的部分,从三个维度汇报。
**引擎维度:多引擎真实求解。** 内置规则引擎、约束规划引擎(CP)、遗传算法(GA)、混合求解(规则出初解、CP 求精)、NSGA-II 多目标优化,按问题规模与精度自动适配。注意——是**真正的数学求解**,不是让大模型"猜"一张排产表。算不出来怎么办?系统会给出**最小冲突集与中文归因**,明确告诉计划员"卡在哪、为什么",而不是报一个看不懂的错误。
**策略维度:六大策略模板 + 沙盒对比。** 交期优先、先进先出、产能均衡、换型最小化、成本优先、综合评分开箱即用,另有战役合并策略把同产品交期窗口自动合并、减少换型损耗。同一份订单多种策略**沙盒并行试排**,方案卡片上准时率、换型次数、设备利用率逐项对照、最优项高亮,一键采用。过去计划员凭经验只能想一种排法,现在是**机器穷举、人来拍板**。系统还会从计划员的采用记录中归纳偏好,越用越懂这家工厂。
**约束维度:十三类约束全部进注册表。** 物料三态齐套、模具寿命到限锁定、班组技能并发上限、顺序相关换型叠加、设备日历维保避让、工艺先后硬约束……每一项都可在配置中心启停、设定软硬:**软约束服务优化,硬约束守住底线——违反硬约束的计划,任何人都发布不出去。** 企业自己的 SOP 制度文件,也能编译成排产约束沉淀进系统。
**还有一项最突出的差异化能力——柔性排产。** 多品种小批量的工厂,设备未必永远属于某条产线。系统打破"设备固定属于产线"的传统假设,建立**工序能力池 + 虚拟产线**机制:排产时按订单需求从能力池动态组合设备、预占资源、用完释放,连设备移动耗时、模具换型时间都精确计算。**正排、倒排、瓶颈锚定**三种模式自由切换;**滚动时域**从实时一小时到七天长期逐级细化;瓶颈工序产能实时重算——设备一停机,全线产能预测即刻更新。
【可插演示:输入「对比几种策略」→ 方案卡逐项讲 KPI 差异 → 一键采用;柔性工作台输入「三模式对比」→ 展示正排/倒排/瓶颈锚定与产能池仪表盘。】
### 2.5 动态调度:异常发生时的分级响应(约 1.5 分钟)
工厂里没有一成不变的计划。系统把异常处置分为四级:**L1 池内换机**——设备故障秒级切换备用设备;**L2 短窗重排**——局部扰动局部消化;**L3 日窗重排**——影响扩大重排当日;**L4 全局重排**——重大变化整体优化。缺料事件也打通了端到端闭环:WMS 缺料信号进来,自动触发重排方案、确认、下发、回执。
每一级重排都带着影响评估和确认卡——**重排是智能体的建议,拍板权永远在人。**
### 2.6 执行与回流:计划不止于纸面(约 1.5 分钟)
排产版本经确认后**一键发布**,下发 MES 执行——外部系统动作走最高等级二次确认;**报工数据实时回流**,进度偏差在订单上自动呈现,计划—执行—反馈形成完整闭环。
执行监控四件利器:**甘特图拖拽调程**(边拖边校验、十五分钟吸附,拖动即生成新版本)、**冲突解决中心**(按冲突类型给出修复建议,一键应用)、**方案对比表**(固定策略与柔性三模式矩阵式对照)、**KPI 仪表盘与产能池仪表盘**(利用率、准时率、在制、延误一屏汇总,四小时/一天/一周负载预测自动色标预警)。
【可插演示:输入「发布这个版本」→ P2 确认卡;输入「打开仪表盘」→ KPI 汇总;输入「存个档」→ 时间线检查点与回滚。】
---
## 三、智能体治理与多智能体编排:智能的边界,信任的基石(约 3 分钟)
让机器参与生产决策,信任是前提。系统设计了三道防线,这也是我们与市面上"AI+排产"概念产品的本质区别。
**第一道,数字不经大模型。** 所有排产结果与 KPI 全部来自引擎确定性计算,AI 只负责理解与表达,从制度上杜绝编造。知识问答基于企业 SOP 检索作答,**引用必附出处,查不到就明说查不到**。
**第二道,P0 到 P3 四级门禁。** 只读查询自由、常规试排轻提示、发布回滚必须人工确认、外部系统动作二次确认。**智能体的每一步"想动",都要经过人的"放行"。**
**第三道,全程留痕可审计。** 从一句指令到一次发布,全部记入哈希链式审计台账,防篡改、可校验、可回放,并有归档密封与篡改检测。任何时候都能回答三个问题:**谁决定的、依据是什么、系统当时看到了什么。**
在此之上,系统还具备**多智能体编排**能力:可以按需创建不同角色的智能体——数据解析、MRP 分解、柔性排产、报告生成——挂上目标后,看门狗按能力边界自动分发任务、监控执行,智能体之间通过消息总线接力协作;任务超期自动收回重排,**失败时诚实上报、绝不假装成功**,全部完成自动结案。这为多车间、多工厂协同排产预留了架构空间。
---
## 四、工程底座与验证情况(约 2 分钟)
**工程底座三句话:** Web 与桌面双形态,同一套代码;前后端契约严格版本对齐,杜绝接口漂移;全量黄金回归测试**一千零四十二个用例全部通过**,每次改动都有自动化测试守住底线。
**验证情况三件事:** 其一,已用真实工厂数据完成全流程验证——Excel 导入、订单池审核、MRP 分解、柔性排产、MES 下发、报工回流完整闭环跑通;其二,工程图纸 DXF 文件可直接解析,自动识别图号版本、提取物料与工艺候选,经人工确认后写入主数据——**图纸是证据不是命令,AI 负责提取,人负责批准**;其三,以西门子 Opcenter APS 为基准逐项对标,排产引擎、柔性资源模型、计划层能力已实现主体覆盖,自然语言交互与图纸智能解析是我们的独有优势。
**可复制性:** 行业适配不靠定制开发,靠主数据与知识库配置——重工、轻工、电子、装备制造,同一套引擎换一套数据即可运转;小厂单线开箱试排,大厂可扩展多工厂多级排程。这意味着它不仅能解决我们自己的问题,更具备**产品化输出**的潜力。
---
## 五、收尾(约 1 分钟)
各位领导,回顾刚才的汇报:一套五层架构、一条焊死三道闸门的请求主链路、一段从数据到回流的七环节业务闭环、三道信任防线——这就是 APS 计划排产智能体的完整图景。
它的价值归结为三句话:
**第一,让排产听得懂人话**——计划员从深夜的 Excel 中解放出来;
**第二,让决策算得清利害**——机器穷举、人来拍板,每个决定都有计算作底气;
**第三,让经验沉淀为资产**——老师傅的智慧变成组织的系统能力,越用越聪明。
**让排产听得懂人话,让决策算得清利害,让过程经得起审计。** 这是 APS 智能体已经交出的答卷,也是我们对智能制造下一程的承诺。
汇报完毕,恳请各位领导批评指正,谢谢大家!
---
## 附一:时长控制表
| 章节 | 标准时长 | 压到 20 分钟 | 拉到 30 分钟 |
| --- | --- | --- | --- |
| 〇 开场 | 2 min | 1.5 min | 2 min |
| 一 总体架构 | 4 min | 3 min(链路举例讲快) | 4 min |
| 二 业务全流程 | 11 min | 8 min(计划层、执行节压缩一半) | 15 min(插入全部 4 段演示) |
| 三 治理与多智能体 | 3 min | 2.5 min | 4 min(多智能体现场演示) |
| 四 底座与验证 | 2 min | 1.5 min | 2 min |
| 五 收尾 | 1 min | 1 min | 1 min |
| 合计 | ~23 min | ~18–20 min | ~28–30 min |
## 附二:演示口令速查(如现场加演示)
依次试跑:`分析一下数据文件` → `执行MRP分解` → `下达MRP建议单` → `试排一版交期优先` → `对比几种策略` → `插单快评` → `三模式对比` → `发布这个版本` → `存个档` → `打开仪表盘` → `生成日报`。
演示前检查:后端(:8000)与前端(:5173)已启动;项目数据已导入且行数正常;提前存一个"干净"检查点,演示翻车可一键回滚;「清空数据重新初始化」仅用于展示门禁,**切勿批准**。

View File

@ -1,68 +0,0 @@
# 从"人排产"到"智能体排产"
## —— APS 计划排产智能体汇报演讲稿(领导汇报版,约 12 分钟)
---
各位领导:
大家好。今天向各位汇报的,是我们在智能排产方向上的核心成果——**APS 计划排产智能体**。
这不是对传统排产软件的界面改良,而是排产工作方式的一次范式升级。我的汇报分四个部分:为什么做、做成了什么、能力有多深、价值在哪里。
## 一、为什么做:排产是制造业数字化最后一块硬骨头
各位领导都清楚,这些年我们在 ERP、MES 上的投入不可谓不大,但有一个环节始终依赖"老师傅"——**计划排产**。
原因有三。其一,**约束太复杂**:物料齐套、设备产能、模具寿命、班组技能、换型耗时、工艺先后,任何一个因素变化都会牵一发而动全身。其二,**变化太频繁**:紧急插单、设备故障、物料延期,计划永远赶不上变化。其三,**决策太依赖人**:一个资深计划员的培养需要五年以上,而他的经验无法沉淀、无法复制、更无法传承。
传统 APS 软件为什么没能解决?因为它们把复杂性原封不动地推给了用户——成百上千个参数、层层嵌套的菜单,最后软件沦为摆设,计划员重新回到 Excel。
**而大语言模型的成熟,给了我们一条全新的路:让机器理解人的意图,让算法完成繁重的计算,让人专注于判断与决策。** 这就是 APS 智能体的出发点。
## 二、做成了什么:一个"听得懂、算得准、管得住"的排产智能体
我用一句话定义这款产品:**用自然语言驱动、用可视化确认、用门禁审计约束的计划排产智能体。**
它具备智能体的完整闭环——**感知、决策、执行、留痕**。
**感知层**,计划员用母语直接下达指令:"试排一版交期优先""对比几种策略,哪个换型最少""这张急单插进来影响多大"。系统采用"规则快路 + 大模型精解"的双级意图管线,毫秒级响应,断网时自动降级,永不失语。
**决策层**,意图被翻译成结构化命令,驱动真正的运筹学引擎计算——注意,是真正的数学求解,不是让大模型"猜"一个排产表。
**执行层**,结果以甘特图、设备负荷图、交期看板三视图实时呈现;多方案并排对比,准时率、换型次数、产能利用率逐项对照,最优项自动高亮。我们称之为**"左说右动"**——左边对话表达意图,右边沙盘验证结果。
**留痕层**,每一次试排、每一次发布、每一次回滚,全部进入哈希链式审计台账,可校验、可回放、防篡改。
## 三、能力有多深:六大能力体系
下面向各位领导重点汇报能力深度,这也是我们与市面上"AI+排产"概念产品的本质区别。
**第一,多引擎求解体系。** 系统内置五大引擎:规则引擎、约束规划引擎(CP)、遗传算法(GA)、混合求解(规则出初解、CP 求精)、NSGA-II 多目标优化。六大策略模板开箱即用——交期优先、先进先出、产能均衡、换型最小化、成本优先、综合评分。同一份订单,多种策略沙盒并行试排,方案卡片逐项对比,一键采用。不可行时,系统还能给出最小冲突集与中文归因,明确告诉计划员"卡在哪、为什么"。
**第二,全要素约束体系。** 十三类约束全部进入注册表、可配置可启停:物料三态齐套、模具寿命到限锁定、班组技能并发上限、顺序相关换型矩阵、设备日历维保避让、工艺先后硬约束……软约束服务优化,硬约束守住底线——违反硬约束的计划,任何人都无法发布。企业自己的 SOP 制度文件,也能编译成排产约束沉淀进系统。
**第三,柔性排产体系——这是我们最突出的差异化能力。** 面向多品种、小批量,系统打破"设备固定属于某条产线"的传统假设,建立**工序能力池 + 虚拟产线**机制:排产时按订单需求从能力池动态组合设备,预占资源、用完释放,连设备移动耗时、模具换型时间都精确计算。正排、倒排、瓶颈锚定三种模式自由切换,滚动时域从实时一小时到七天长期逐级细化。
**第四,计划层与交期承诺体系。** 把答案给在问题发生之前:时间分桶计划、有限/无限产能双模式粗评估、可行性分析、库存投影、产能削峰建议、加班—扩线—外协三级产供决策。尤其值得一提的是**交期承诺模拟**——销售询单进来,系统给出乐观、中值、悲观三个交期区间和资源缺口,让每一次对外承诺都有计算依据。
**第五,动态调度体系。** 异常处置分级响应:L1 设备故障秒级池内换机,L2 短窗口局部重排,L3 日窗重排,L4 全局重排。每一级都生成影响评估和确认卡——**重排是智能体的建议,决策权永远在人**。
**第六,可信治理体系。** 三道防线:其一,**数字不经大模型**——所有排产结果与 KPI 全部来自引擎确定性计算,AI 只负责理解与表达,制度上杜绝编造;其二,**P0 到 P3 四级门禁**——只读自由、试排轻提示、关键写操作人工确认、外部系统动作二次确认;其三,**全程审计哈希链**——随时能回答三个问题:谁决定的、依据是什么、系统当时看到了什么。
## 四、价值在哪里:已验证、可对标、可复制
**已验证。** 系统已完成真实工厂数据的全流程验证:主数据 Excel 一键导入,订单池审核、MRP 自动分解、柔性排产、MES 下发、报工回流完整闭环;工程图纸 DXF 文件可直接解析,自动识别图号版本、提取物料与工艺候选,经确认后写入主数据。
**可对标。** 我们以西门子 Opcenter APS 为基准做了逐项功能对标,排产引擎、柔性资源模型、计划层能力已实现主体覆盖,部分能力——如自然语言交互、图纸智能解析——是我们的独有优势。
**可复制。** 行业适配不依赖定制开发,靠主数据与知识库配置实现:重工、轻工、电子、装备制造,同一套引擎,换一套数据即可运转。小厂单线开箱试排,大厂可扩展至多工厂多级排程。这意味着它不仅能解决我们自己的问题,更具备产品化输出的潜力。
各位领导,排产智能体的意义,不止于效率提升。它把计划员从深夜的 Excel 中解放出来,把个人经验沉淀为组织能力,把"老师傅退休就断层"的风险,变成"系统越用越聪明"的资产。
**让排产听得懂人话,让决策算得清利害,让过程经得起审计。** 这是 APS 智能体已经交出的答卷,也是我们对智能制造下一程的承诺。
汇报完毕,恳请各位领导批评指正,谢谢大家。
---
*(全文约 2700 字,正常语速汇报约 11–12 分钟;第三部分是能力主体,可按领导关注点取舍压缩至 10 分钟)*

View File

@ -1,66 +0,0 @@
# 让排产听懂人话
## —— APS 计划排产智能体产品演讲稿(约 10 分钟)
---
各位领导、各位同仁:
大家好。今天,我向大家介绍的,不是一款普通的软件,而是一种全新的生产计划工作方式——**APS 计划排产智能体**。
在正式开始之前,请允许我先描述一个几乎所有制造企业都熟悉的场景。
## 一、从一个真实困境说起
清晨七点,计划员走进办公室,等待他的是这样一幅图景:销售部昨夜临时追加了一张紧急订单,要求三天内交付;三号线的一台关键设备凌晨报警停机;而仓库刚刚反馈,某个关键物料的到货时间比预期晚了两天。桌面上摊着 Excel 表格,屏幕上开着三四个系统,电话此起彼伏。他必须在几小时内回答三个问题:这张急单能不能接?接了以后哪些订单会延期?设备停了,今天的生产怎么重新安排?
这不是某一位计划员的困境,而是整个离散制造业的集体困境。订单越来越碎,交期越来越短,变化越来越快,而排产决策所依赖的,仍然是人的经验、人的记忆力,以及深夜里一次次的推翻重来。
**APS 智能体要解决的,正是这个问题。**
## 二、它是什么:左手对话,右手沙盘
如果用一句话概括这款产品——**它是一个用自然语言驱动、用可视化确认的计划排产智能体**。
这句话包含两个关键词。
第一个关键词是"自然语言驱动"。计划员不需要学习复杂的菜单和参数,只需要像对一位资深同事说话那样下达指令:"试排一版交期优先的方案""对比几种策略,看看哪个换型最少""这张急单插进来,影响有多大"。系统理解意图之后,立即调用排产引擎进行真实计算。
第二个关键词是"可视化确认"。系统从不让一个黑箱结果直接生效。每一个方案都以甘特图、设备负荷图、交期达成看板三种视图完整呈现;每一次多策略对比,都生成并列的方案卡片,准时率、换型次数、产能利用率逐项对照,最优项一目了然。计划员看懂之后,一键采用,右侧的排产沙盘即刻刷新。
我们称之为**"左说右动"**:左边是对话,右边是沙盘;语言负责表达意图,图形负责验证结果。人始终站在决策的中心。
## 三、它能做什么:从订单到执行的完整闭环
这款产品的能力,覆盖了生产计划的全价值链,我用四个层次向大家说明。
**第一层,排产引擎——把"排得出来"变成"排得最优"。** 系统内置规则引擎、约束规划引擎、遗传算法与多目标优化引擎,支持交期优先、产能均衡、换型最小化、成本优先等多种策略模板。物料齐套、模具寿命、班组技能、设备日历、换型矩阵——凡是真实工厂里存在的约束,都在引擎的考量之内。十三类约束全部可配置、可启停,硬约束守住底线,软约束服务优化。
**第二层,柔性排产——让产能摆脱固定产线的束缚。** 在多品种、小批量的生产模式下,设备未必永远属于某条产线。系统为此建立了"工序能力池"与"虚拟产线"机制:排产时按订单需求,从能力池中动态组合设备、预占资源、用完释放,连设备移动耗时、模具换型时间都纳入计算。正排、倒排、瓶颈锚定三种模式自由切换,瓶颈工序的产能实时重算。
**第三层,计划与承诺——把答案给在问题发生之前。** 在正式排产之前,系统已经可以完成粗能力评估、可行性分析与库存投影:未来几周产能够不够?缺口在哪一周、缺多少?能否按期交付?对于销售询价,系统能给出乐观、中值、悲观三个交期区间,让每一次承诺都有依据。插单快评、分级重排则让异常处置有章可循——设备故障时,系统自动建议池内换机;影响扩大时,逐级升级为窗口重排、日重排乃至全局重排,每一步都留下决策痕迹。
**第四层,执行与闭环——计划不止于纸面。** 排产版本经确认后一键发布,下发 MES 执行;报工数据实时回流,进度偏差自动呈现;检查点时间线支持随时存档、随时回滚,每一次"如果当初那样排"的假设,都可以安全地验证。
## 四、它为何可信:三道安全防线
让机器参与生产决策,信任是前提。为此,产品设计了三道防线。
**第一道,数字不经大模型。** 大语言模型在这套系统中只负责理解意图与组织语言,所有排产结果、所有 KPI 数字,全部来自运筹学引擎的确定性计算。AI 可以翻译,但绝不允许编造。
**第二道,操作分级门禁。** 系统将所有操作按风险分为四级:只读查询自由进行;常规试排轻量提示;发布、回滚等关键动作必须经确认卡人工点头;涉及外部系统的动作需要二次确认。智能体的每一步"想动",都要经过人的"放行"。
**第三道,全程留痕可审计。** 从一句指令到一次发布,每个环节都记入哈希链式审计台账,防篡改、可校验、可回放。出了问题,能精确回答三个问题:谁决定的、依据是什么、系统当时看到了什么。
## 五、它的边界与诚意
最后,我想坦率地说明这款产品的定位边界。它不是要取代 MES 的执行管理,也不是要取代计划员的专业判断;它的行业适配不依赖定制代码,而是通过主数据与知识库的差异配置实现——重工、轻工、电子、装备制造,同一套引擎,换一套数据即可运转。小厂可以单线开箱试排,大厂可以走向多工厂的多级排程。
我们始终相信:**技术的价值,不在于替人做决定,而在于让人的每一个决定,都有计算作底气、有图形作印证、有记录作凭据。**
当排产听得懂人话,当变化能够被从容应对,计划员将从深夜的 Excel 中解放出来,把经验用于真正的判断。这,就是 APS 智能体想要交付给中国制造的一份答卷。
我的介绍到此结束,谢谢大家。
---
*(全文约 2450 字,正常语速演讲约 9–10 分钟)*

View File

@ -1,172 +0,0 @@
# Pi Agent 兜底能力 · 详细实施方案
> 版本 v2.0 · 2026-09-02 · 取代:`Pi-Agent接入计划.md` / `Pi-Agent接入详细计划.md`(那两份是"接入通道"定位,本方案是"**全系统兜底能力**"定位,范围显著扩大)
> 依据:`plan.md` §2.1/§2.2/§3、`PROJECT_OPERATING_RULES.md`、`docs/architecture/harness.md`、`docs/architecture/skills.md`、`docs/architecture/overview.md`
> 现状代码锚点:`server/aps_domain/workflow.py:2875`(当前 unknown 意图兜底 = 纯话术回复,**无能力**)、`server/agent_core/harness.py`(`_POWER_MAP` 62 项登记 + 未登记默认 P3 拒绝)、`server/agent_core/tool_runtime.py`(唯一执行入口)、`server/agent_core/mcp_bus.py`、`server/agent_core/feature_flags.py`(FF-01 开关机制)、`apps/desktop/sidecar.cjs`(子进程环境清洗/看门狗,Pi runtime 可直接复用这套模式)
---
## 1. 定位重述:什么是"兜底能力"
**现状**:用户说一句系统听不懂的话,走到 `workflow.py:2875` 的 `assistant.reply/unknown` 分支——LLM 回一段话术,**事情没办成**。已登记意图执行失败(求解器 fatal、数据缺字段、接口超时)也只有报错,没有自救。
**目标态**:Pi Agent 成为 APS 的**通用能力后备层**——产品化路径"不能办"或"办砸了"时,由 Pi 这个具备读/写/执行能力的通用智能体,在 Harness 划定的围墙内把事办成,并且全程可审计、可回滚、可熔断。
```
用户请求 → 意图管线
├─ 命中已登记意图 → 产品化路径(现状,快/稳/确定性)
│ └─ 执行失败 ──┐
└─ 未识别/未登记 ───┤
▼
【受治理的兜底车道 Governed Fallback Lane】
Pi 分析任务 → 产出《执行计划草稿》(P1,只读可直通)
→ 确认卡呈人类审批 (P2 起)
→ 批准后 Pi 在沙箱内执行(工具桥只暴露登记过的能力)
→ 执行后世界状态 diff 验证 + 报告
→ 全程审计链 + 证据链 + 可回滚 checkpoint
```
**一句话:Pi 是被 Harness 雇佣的临时工——有手艺,但进厂要登记、干活要批条、动设备要有人在场、出活要验收。**
## 2. 与产品宪法的冲突分析与消解
这是本方案最关键的一节。兜底能力天然想"什么都能干",宪法要求"未经授权什么都不能干"。逐条消解:
| 宪法红线(PROJECT_OPERATING_RULES 原文) | 表面冲突 | 消解设计 |
|---|---|---|
| 「动作必须经 `_POWER_MAP` 白名单登记,未登记默认 P3 拒绝」 | 兜底场景恰恰是"未登记意图" | 新增 3 个**元意图**登记进 `_POWER_MAP`:`agent.fallback.propose`=P1(产出计划草稿,沙盒语义)、`agent.fallback.execute`=P2(执行已批准计划)、`agent.fallback.execute.highrisk`=P3(涉主干写/外部系统,逐字段人工确认或默认拒绝)。Pi 从未"直接做事",它做的事都被这三个登记动作包裹 |
| 「LLM 只有提议权」(tool_runtime) | Pi 是 LLM 驱动的执行体 | Pi 的**计划**是提议;**执行**走 `/api/actions/confirm` 唯一通道。Pi 能调用的工具本身就是经过登记的意图封装(见 §4.3 工具桥),物理上无法直写 store/DB |
| 「不得引入未设计的隐式副作用」 | Pi 自由执行副作用不可枚举 | 沙箱围墙(§4.2):文件系统圈禁在 run 专属目录、网络只通 APS loopback、shell 白名单、环境变量清洗(复用 sidecar.cjs 的 allowlist 模式)。墙内副作用显式枚举,墙外物理不可达 |
| 「写前必须建 checkpoints 成对快照」 | Pi 执行前后状态未知 | 兜底车道**强制**执行前 checkpoint、执行后 world diff 验证报告,diff 摘要进确认卡和审计 |
| 「失败必须显式报告」 | LLM 倾向"圆场" | Pi 输出契约强制 `status: success|partial|failed|blocked`;`partial/failed/blocked` 必须附未竟事项清单;gateway 侧校验缺失字段即判 failed |
| 「mock/stub 不得进入产品路径」 | Pi 可能"假装"调用了工具 | 工具桥每次调用返回真实调用凭证(callId),Pi 报告中引用 callId 可被审计对账;无 callId 支撑的成果声明判无效 |
## 3. 场景矩阵(10 类兜底场景 × 治理策略)
| # | 场景 | 触发条件 | 权力 | 治理策略 | 验证方式 | Pi 干不了时的降级 |
|---|------|---------|------|---------|---------|------------------|
| S1 | **意图未识别**(新说法/新需求口令) | 意图管线产出 `unknown` | propose=P1 / execute=P2 | 计划草稿确认卡必出 | 执行后 diff + 用户确认回执 | 退回话术 + "已记录需求"工单 |
| S2 | **已登记意图执行失败**(求解器 fatal、数据缺字段) | handler 抛错/返回失败 | P1 诊断只读 / 修复=P2 | 诊断报告直通;修复动作出卡 | 重跑原意图成功即为验证 | 显式报错原文 + 诊断附件 |
| S3 | **新数据格式接入**(客户给了没人写过 importer 的 Excel/CSV/JSON) | data.import 解析失败或用户直接给文件 | P2(导入写主干) | 计划含字段映射表,确认卡呈现映射供审 | 导入后行数/金额对账 + 抽样比对 | 输出《手工整理指引》 |
| S4 | **缺算法/策略**(某工艺无现成排产策略) | flex.schedule 无匹配 skill 或用户明示"试个新策略" | P1(沙盒试排) | 仅沙盒语义,产物为草稿版本 | 沙盒 KPI 对比基线版本 | 明确告知"超出兜底能力" |
| S5 | **ad-hoc 分析/报告**("帮我看看哪条线最容易拖期") | report.generate/data.analyze 覆盖不了的自由分析 | P1 | 只读工具桥 + 沙盒计算 | 报告数字必须引用冻结快照字段(宪法既有规则) | 返回原始数据 + 分析失败说明 |
| S6 | **外部集成故障**(MES/WMS 接口挂了,要手工补录/对数) | integrations 调用失败告警 | P2 | 补录动作逐笔出卡 | 与外部系统恢复后对账 | 生成待补录清单(Excel)交人工 |
| S7 | **现场运维诊断**(support 工程师查日志/修配置) | 运维人员在运维入口显式发起 | P2;改配置 P3 | 仅运维角色可见入口;全程录屏级审计 | 修复后健康检查绿 | 输出诊断报告 + 建议人工操作 |
| S8 | **演示/售前救场** | 演示中任何上述场景 | 同对应场景 | 无特殊豁免(宪法) | 同对应场景 | 话术降级 |
| S9 | **批量数据处理**(一次性清洗/转换 5000 行工单) | 用户发起且无对应产品功能 | P2 | 计划含抽样预览(前 20 行变换结果)出卡 | 全量校验规则 + 抽样人工确认 | 分批+断点,失败批次显式列出 |
| S10 | **Pi 自身失败**(模型不可用/超时/超预算/死循环/部分写入) | 熔断器触发 | — | 超时(默认 10min)/步数(50)/token 预算三重熔断;部分写入由 checkpoint 回滚 | 回滚后 diff 为空即验证 | 显式失败报告 + 已回滚声明 |
**矩阵结论**:10 类场景中 S1/S2/S3/S5/S9 是价值主干(覆盖 80% 真实需求),S4/S6/S7 价值高但风险也高(放后期),S10 是必须设计的元场景。
## 4. 详细设计
### 4.1 组件清单(新增 4 个可重生模块 + 1 个外部进程)
| 组件 | 位置 | moduleId | 职责 |
|------|------|----------|------|
| FallbackLane 编排器 | `server/agent_core/fallback_lane.py`(新增,~600 行) | `core-fallback-lane` | 触发判定 → 任务简报 → 调 Pi → 收计划 → 出卡 → 执行 → 验证 → 审计 |
| Pi 工具桥 | `server/integrations/pi_bridge.py`(新增,~400 行) | `integ-pi-bridge` | 向 Pi 暴露围墙内工具集(§4.3),每次调用发 callId 凭证 |
| 兜底验证器 | `server/agent_core/fallback_verify.py`(新增,~300 行) | `core-fallback-verify` | 执行后 world diff、规则校验、报告生成(数字只许来自冻结快照) |
| 熔断与预算 | 并入 fallback_lane(~150 行) | 同上 | 超时/步数/token 三重熔断 + audit_alerts 联动 |
| Pi runtime 进程 | Node 进程(`pi-agent-core` headless 模式) | — | 被编排器以子进程拉起,生命周期管理**复用 sidecar.cjs 的 SidecarManager 模式**(端口/nonce/环境清洗/看门狗/日志轮转全套照搬) |
### 4.2 沙箱围墙(自内向外四层)
```
L1 工具层:Pi 只能看见工具桥暴露的工具(§4.3),没有裸 fs/shell/net
L2 文件层:cwd 圈禁 ~/.aps/fallback/<runId>/(Web 态 server/data/fallback/<runId>/);
可读注入区(用户上传文件副本)、可写工作区、产物出口目录三区分离
L3 网络层:仅允许 127.0.0.1:<gateway port>;模型 API 出口走 gateway 代理(可关)
L4 进程层:环境变量清洗(CONDA/Python 变量剥离,照搬 buildChildEnv)、
父进程看门狗、taskkill 进程树回收、10MiB 日志轮转
```
> 说明:Pi 官方支持 Gondolin/Docker 沙箱,但工业现场 Windows 离线机器上 Docker 不可靠,故以 L1-L4 进程级围墙为主,Docker 沙箱作为 Web/服务器部署的可选加强项。
### 4.3 工具桥暴露面(围墙内 Pi 的全部"手艺")
| 工具 | 包装自 | 权力 | 说明 |
|------|--------|------|------|
| `aps_invoke(intent, params)` | `/api/agent/invoke`(即 handle_intent) | 随意图 | **Pi 写世界的唯一方式**,内部仍过 _POWER_MAP/确认卡 |
| `aps_query(sql_like)` | master.query / data.analyze 只读集 | P0 | 世界状态只读视图 |
| `knowledge_query(q)` | `/api/rag/query`(ragScopes 鉴权) | P0 | 知识库 |
| `fs_read/fs_write(path)` | 沙箱 L2 三区 | — | 物理圈禁,越界即 EACCES |
| `shell_run(cmd)` | 白名单(python 脚本、xlsx 处理等显式登记命令) | — | 每条命令正则白名单 + 参数审查 |
| `checkpoint_create()` | state checkpoints | — | Pi 可主动建回滚锚点 |
| `report_emit(md)` | fallback_verify | — | 产物唯一出口,强制走验证器 |
### 4.4 意图与权力登记(harness 变更)
```python
# _POWER_MAP 新增 3 项(harness.md 权力矩阵同轮更新)
"agent.fallback.propose": "P1", # 产出执行计划草稿(沙盒语义,不写主干)
"agent.fallback.execute": "P2", # 执行已批准计划 → 确认卡
"agent.fallback.execute.highrisk": "P3", # 涉外部系统/主干批量写 → 默认拒绝,白名单放行
```
确认卡内容(P2 出卡时必须冻结):计划步骤清单、每步工具与权力、预计影响面(目标实体清单)、`evidenceRefs`、执行前 checkpoint id、回滚方式。**卡片上的承诺即执行上限**——执行时逐步比对,Pi 偏离计划即熔断(计划外工具调用 → blocked)。
### 4.5 证据链与审计
- 每次兜底运行:`runId` 贯穿 propose→confirm→execute→verify 全链;
- Pi 每步工具调用:TOOL 审计(actor=`pi-fallback:<runId>`、callId、入参摘要、结果摘要);
- 确认卡批准/拒绝:GATE 审计(既有机制);
- 验证报告:REPORT 审计 + 产物落 `~/.aps/fallback/<runId>/report.md`;
- 全链可通过既有 `/api/gov/audit` 按 runId 过滤回放。
### 4.6 开关与熔断(复用 FF-01)
- `features.json` 新增 `"fallback": false`——**默认全关**,现场按需开;开关本身 P2 确认卡管理;
- 熔断三闸:单次运行超时 10min / 步数 50 / token 预算(可配);日维度累计预算;
- 触发熔断 → 显式失败 + checkpoint 回滚 + audit_alerts 通知。
## 5. 部署形态(两个大坑,提前说)
| 形态 | 方案 | 坑 |
|------|------|-----|
| **Web/服务器部署** | docker-compose 增加 `pi-runtime` 服务(Node 22 + pi-agent-core) | 小,标准做法 |
| **桌面端打包** | PyInstaller sidecar 之外再加 Node runtime(~60-80MB)打进安装包,或做成**可选组件**首次使用时下载 | ① 体积恶化(与 Tauri 瘦身诉求矛盾,两事更该串行决策);② **离线工厂没有模型 API 出口**——兜底重度依赖 LLM,断网即瘫。对策:模型出口走 gateway 代理可配内网模型网关;无模型时 fallback 开关强制关闭且 UI 明示原因(失败显式,不装死) |
## 6. 阶段计划(修订版,替代 v1.0 计划)
| 阶段 | 内容 | 工期 | 出口标准 |
|------|------|------|---------|
| **P0 PoC** | 单场景 e2e 打穿:S5(ad-hoc 分析)。Python 编排器拉起 Pi headless → 计划 → 假确认 → 沙箱执行 → 报告。**不碰产品路径**,全部在 `poc/` | 4-5 人日 | 一个真实分析任务从发起到报告全链跑通;四层围墙验证有效(故意越狱测试被拒) |
| **P1 只读兜底** | S1(只读类)/S5/S9-只读部分 进产品路径;fallback_lane + pi_bridge 转正;`agent.fallback.propose` 登记;FF-01 开关接入 | 7 人日 | 意图未识别时用户能拿到"办成的事"而非话术;越狱/注入黄金测试 10 例全拦 |
| **P2 沙盒写兜底** | S2/S3/S9 写路径;`agent.fallback.execute`=P2 出卡;checkpoint 强制 + diff 验证器;熔断三闸 | 10-12 人日 | 新格式 Excel 导入从"给文件"到"对账通过"全链路演示绿;计划偏离熔断测试通过 |
| **P3 高风险与运维** | S4/S6/S7;`execute.highrisk`=P3;运维入口与角色门禁;集成故障对账流 | 7-10 人日 | MES 断连补录场景验收;运维全程审计可回放 |
| **P4 评估与硬化** | 兜底质量 golden 集(30+ 场景用例:成功率/误写率/确认轮次/token 成本四指标);prompt 注入防护集(工单备注藏指令等 20 例);离线降级演练 | 8 人日 | golden 集成功率 ≥85% 且误写率 0;注入集 100% 拦截 |
| **P5 验收发布** | 全量黄金(1071+ 基线)、桌面打包冒烟(含可选组件)、文档同轮、现场 runbook | 5 人日 | 发布门禁全绿;康尼数据集真实验收 |
| **合计** | | **41-47 人日(1 人约 8-10 周)** | |
### 里程碑视图
```
W1 W2-3 W4-6 W7-8 W9-10 W11
[P0] → [P1 只读] → [P2 写兜底] → [P3 高风险] → [P4 硬化] → [P5 发布]
↑go/no-go ↑已可演示价值 ↑核心能力闭环 ↑按需可裁剪 ↑质量门禁
```
## 7. 风险登记册(兜底定位特有)
| # | 风险 | 等级 | 对策 |
|---|------|------|------|
| F1 | **非确定性**:同一请求两次兜底结果不同 | 🔴 | 计划审批制(人看的是计划不是黑盒)+ golden 集回归 + 产物必须经验证器,不靠 Pi 自述 |
| F2 | **Prompt 注入**:订单备注/导入文件里藏"忽略之前指令" | 🔴 | 注入防护 golden 集(P4);用户数据进 Pi 前包裹隔离标记;工具桥不认 Pi 的"用户已确认"自述——确认只信 gateway 会话内的真实确认卡 |
| F3 | **部分写入**:执行到一半熔断 | 🟡 | checkpoint 强制前置 + 回滚验证(diff 为空才算回滚成功) |
| F4 | **成本失控**:LLM token 烧穿预算 | 🟡 | 三闸熔断 + 日预算 + audit_alerts |
| F5 | **离线工厂无模型出口**,兜底变废铁还误导用户 | 🟡 | 无模型时开关强制关 + UI 明示原因;支持内网模型网关地址配置 |
| F6 | **Node runtime 进桌面包** | 🟡 | 可选组件化;与 Tauri 决策串行 |
| F7 | **"兜底兜不住还装兜住"**(LLM 圆场) | 🔴 | 输出契约强制 status 字段 + callId 对账(§2 最后一行),圆场在网关层被物理判失败 |
| F8 | 团队对"治理下通用智能体"的调试经验不足,问题定位难 | 🟡 | 全程 runId 可回放 + Pi trace 落盘;P0 即建立调试工具链 |
| F9 | 范围蔓延:兜底太好用 → 产品化路径荒废 | 🟢 | 治理指标:兜底触发率应随产品化下降;触发率周报,高的场景反哺产品化立项 |
## 8. 与 v1.0 接入计划的关系
v1.0 的 `/api/agent/` 适配层、Agent Token、MCP 总线登记**全部保留**——它们在本方案中变成工具桥的基础设施(`aps_invoke` 就是走那层面)。外向接入(人在 Pi 终端里用 APS)成为 P1 完成后的副产品,不再单独排期。
## 9. 三条决策建议
1. **先 P0 后承诺**:4-5 人日的 PoC 直接验证最危险的两个未知数(围墙有效性、计划审批可用性),PoC 不过则退回 v1.0 纯接入定位;
2. **S 场景分批上线**:P2 之后每批场景单独灰度(FF-01 开关粒度到场景),不一锅端;
3. **与 Tauri 串行已定**,再强调一次:F6 意味着如果未来迁 Tauri,Node runtime 的打包方案要一起重设计。

View File

@ -1,83 +0,0 @@
# Pi Agent 接入集成计划(结合现有架构与产品规范)
> 2026-09-02 · 依据:`plan.md` §2.1/§2.2(Gateway 层"Pi Agent 接入"职责)、`PROJECT_OPERATING_RULES.md`、`docs/architecture/harness.md`、`skills.md`、`overview.md`、现状代码(`server/agent_core/`:tool_runtime / mcp_bus / skills / harness / audit)
>
> **对象界定**:Pi Agent = badlogic 开源 Pi(`pi-coding-agent` CLI + `pi-agent-core` runtime + npm 技能包扩展生态)。若实际指内部自研 Agent 或其它产品,P0-P2 阶段不变,仅 P1 的接插件形态替换。
---
## 1. 接入方向决策(先定方向,再谈工期)
| | 方向 A:**外向接入**(推荐) | 方向 B:内向嵌入 |
|---|---|---|
| 含义 | APS 暴露稳定 API/MCP 面,Pi 作为**外部客户端智能体**通过技能包调用 APS 能力 | 把 `pi-agent-core` 嵌入 APS,作为通用执行 runtime |
| 与宪法兼容性 | ✅ 完全符合:Gateway 是接入层本职;写操作仍过 Harness,「LLM 只有提议权」不破 | 🔴 高风险:引入第二个工具执行通道,与 `tool_runtime`(唯一执行入口)、`_POWER_MAP`(未登记默认 P3 拒绝)直接冲突 |
| 技术栈 | 现有 FastAPI 面 + 一个 npm 技能包(TypeScript) | 需内嵌 Node runtime 或 IPC 桥,桌面 sidecar 复杂度大增 |
| 工期量级 | **5-7 周全量,2-3 天见 PoC** | 8 周以上且要重审门禁体系 |
**结论:选方向 A。** plan.md 把 Pi Agent 接入放在 Gateway 而非 Agent Core,本身就说明意图是"接入通道"而非"换引擎"。
## 2. 架构落位(与现有层一一对应)
```
Pi CLI(用户终端)
└─ pi-aps 技能包(npm,新开发) ← 唯一新增的外部组件
└─ HTTPS → Gateway (BFF) ← 既有面,加 /api/agent/* 适配
├─ 认证:Agent Token(新,基于既有 JMS/租户体系签发)
├─ 只读意图 → tool_runtime 只读白名单(已存在)✅ 零改动
├─ 写意图 → _POWER_MAP 登记 → P2/P3 确认卡 ✅ 既有机制
│ └─ Pi 侧权限钩子 ← 确认卡状态轮询/SSE
└─ 审计:actor="pi-agent:<device>",全链路证据链 ✅ 既有机制
治理面:Pi 接入在 mcp_bus 登记为插件(tool 级 allow/deny、健康探测、启停)✅ 总线已有
```
**核心原则:不为 Pi 开任何后门。** 所有写路径复用 `/api/actions/confirm` 唯一执行通道;Pi 只是"另一个 UI 入口",和 Web 前端同权同级。
## 3. 分阶段计划与工期估算
### P0 · 验证性 PoC(2-3 天)
- 跑通 Pi 扩展机制:开发最小技能包 `pi-aps`,调通 `GET /api/health`(校验 `interfaceVersion`)+ `GET /api/world/summary`
- 验证三件事:① Pi 技能包的工具注册/权限钩子 API 形态;② 认证链路(先用开发态 token);③ SSE 会话流在终端的呈现方式
- **产出**:PoC demo(终端里问"当前 KPI"→ 真实数据)+ go/no-go 报告
- 人力:1 人 × 2-3 天
### P1 · 只读接入(1 周)
- Gateway 新增 `/api/agent/` 适配层:把只读意图白名单(`order.pool`/`plan.buckets`/`conflict.list`/`knowledge.query` 等 19 个)封装为 agent 友好的 JSON-RPC 风格端点
- Agent Token 签发与吊销(P2 确认卡管理,落 `~/.aps` 或租户库;scope 到只读)
- `pi-aps` v0.1:查询类命令全集 + 错误透传(遵守规范:失败显式报告,不泛化确认)
- 黄金测试:agent 端点契约 + token 越权 fail-closed
- 人力:1 人 × 1 周
### P2 · 写操作过门禁(1-2 周)
- P1/P2 意图(如 `flex.schedule` 试排草稿、`skill.enable`)接入:确认卡在终端呈现为 Pi 权限确认钩子,批准后走 `/api/actions/confirm`
- 证据链贯穿:Pi 发起的 P2/P3 写同样冻结 `evidenceRefs`/`beforeSnapshot`,审计 `actor=pi-agent` 可独立过滤
- **关键约束**(来自 PROJECT_OPERATING_RULES):不得引入隐式副作用;DRAFT/未批准状态不得当事实返回给 Pi
- 人力:1 人 × 1-2 周(确认卡异步交互在 CLI 的 UX 是主要变数)
### P3 · MCP 总线治理化(1-2 周)
- Pi 接入面在 `mcp_bus` 登记为正式插件:manifest + 工具契约(input/output JSON Schema + P0-P3 权力标注)+ tool 级 allow/deny + 健康探测 + 启停
- 三方契约同步:`shared/schemas/` ↔ `contracts.py` ↔ 技能包类型定义,纳入 `test_contract_sync.py` 门禁
- 管理台:SkillConsole 同款 UI 呈现 Pi 插件(概览/健康/审计/日志)
- 人力:1 人 × 1-2 周
### P4 · 验收与发布门禁(1 周)
- 全量黄金测试(当前基线 1071 项)+ agent 专项;文档同轮(harness.md 端点备案、skills.md、CHANGELOG)
- 安全评审:token 泄漏面、桌面态 nonce 与 agent token 的并存策略
- 桌面端打包冒烟(sidecar 不变,风险低)
- 人力:1 人 × 1 周
**合计:1 人约 5-7 周;P0+P1(只读可用版)2 周内可演示。**
## 4. 风险与规范映射
| 风险 | 等级 | 规范依据与对策 |
|------|------|---------------|
| 第二个执行通道绕过 Harness | 🔴 | 铁律:所有写走 `tool_runtime`/`/api/actions/confirm`;加黄金测试断言"agent 端点无直写 store" |
| 确认卡在 CLI 的异步 UX | 🟡 | P2 阶段先做同步轮询版;超时自动拒绝(fail closed) |
| Agent token 权限蔓延 | 🟡 | scope 最小化(先只读);签发/吊销走 P2 确认卡;审计独立 actor |
| Pi 上游版本漂移 | 🟡 | 技能包锁定 Pi 版本范围;`min_bus_version` 同款兼容声明 |
| 与 Tauri 迁移抢人力 | 🟡 | 两者都动 Gateway/sidecar 周边——**建议串行**:先 Pi 接入 P0-P1(不动壳),Tauri 决策等 WebView2 调查 |
## 5. 建议的下一步
先跑 **P0(2-3 天)**:成本最低,直接验证"Pi 技能包 ↔ 现有 Gateway"的匹配度,产出 go/no-go。P0 不过,后面全部不用谈;P0 过了,P1 的估算就有实测依据了。

View File

@ -1,216 +0,0 @@
# Pi Agent 接入 · 详细实施计划
> 版本 v1.0 · 2026-09-02 · 配套摘要文档:`Pi-Agent接入计划.md`
> 依据:`plan.md` §2.1/§2.2、`PROJECT_OPERATING_RULES.md`、`docs/architecture/harness.md`、`docs/architecture/skills.md`
> 现状代码基线:`server/agent_core/`(harness `_POWER_MAP` 62 项登记、tool_runtime 只读白名单 19 项、mcp_bus、skills、audit)、`server/auth/`(JMS provider + 许可证 token + 租户)、`server/gateway/app.py`
>
> **对象界定**:Pi Agent = badlogic 开源 Pi(pi-coding-agent CLI + pi-agent-core + npm 技能包生态)。方向 A:外向接入,Pi 作为外部客户端智能体经 Gateway 调用 APS 能力,不开第二个执行通道。
---
## 0. 总览
| 阶段 | 名称 | 工期(人日) | 出口标准(Go/No-Go 门禁) |
|------|------|------------|--------------------------|
| P0 | 验证性 PoC | 2-3 | 终端内完成真实查询往返;Pi 扩展 API 三个未知数全部有答案 |
| P1 | 只读接入 | 5 | 只读意图 19 项全部可经 agent 端点调用;token 越权测试 fail-closed |
| P2 | 写操作过门禁 | 5-10 | P1/P2 意图经确认卡执行;CLI 侧确认/拒绝/超时三态可演示 |
| P3 | MCP 总线治理化 | 5-10 | Pi 插件入总线清单;契约三方同步门禁通过;管理台可见 |
| P4 | 验收与发布门禁 | 5 | 全量黄金测试绿;文档同轮完成;安全评审签字 |
| **合计** | | **22-33 人日(约 5-7 周/1 人)** | |
**串行前提**:与 Tauri 迁移不并行(都动 Gateway/sidecar 周边);FF-01 基线已提交(8b7063f)。
---
## P0 · 验证性 PoC(2-3 人日)
### 目标
用最小成本验证"Pi 技能包 ↔ 现有 FastAPI Gateway"匹配度,产出 go/no-go。
### 任务分解
| # | 任务 | 产出 | 工时 |
|---|------|------|------|
| P0-1 | 安装 Pi(`npm i -g` pi-coding-agent),跑通官方 hello 技能包,确认扩展 API 形态(工具注册签名、权限钩子、配置落点 `~/.pi/`) | 笔记 + 截图 | 0.5d |
| P0-2 | 起本地 APS server(`.venv` 固定 CPython,`python -m uvicorn server.main:app --port 8000`),确认 `/api/health` 返回 `interfaceVersion=1.0` | 环境就绪 | 0.5d |
| P0-3 | 写最小技能包 `pi-aps`(单文件):注册 2 个工具 `aps_health` / `aps_summary`,调 `/api/health` 与 `/api/world/summary`,结果原样透传 | PoC 技能包 | 1d |
| P0-4 | 验证 SSE:终端订阅 `/api/chat` 会话流或等价端点,确认流式事件在 CLI 可读(决定 P2 确认卡用轮询还是 SSE) | 技术结论 | 0.5d |
| P0-5 | go/no-go 报告:三个未知数(扩展 API 形态 / 认证链路 / SSE 呈现)+ P1 估算修正 | 报告 | 0.5d |
### PoC 技术约束(防止 PoC 污染产品路径)
- PoC 技能包只读、不进仓库 `apps/` 或 `server/`;放 `poc/pi-aps/`;
- 认证用开发态临时方案(环境变量 token),**不写** token 签发产品代码——那是 P1 的事;
- 遵守规范:工具失败显式报错,不包装成泛化成功回复。
### 出口标准(全部满足才进 P1)
1. 在 Pi 终端输入自然语言/命令 → 返回真实 APS 数据(非 mock);
2. Pi 权限钩子能在工具调用前拦截(P2 确认卡的技术前提);
3. 无明显阻塞性限制(如技能包无法持久化配置、无法发 HTTPS 到自签证书内网服务器等)。
---
## P1 · 只读接入(5 人日)
### 目标
Pi 用户可完成全部只读场景:查订单池、KPI、分桶计划、冲突、知识库。
### API 设计(新增 `/api/agent/` 适配层)
设计原则:**薄适配,零业务逻辑**(Gateway 职责边界:不含排产算法/LLM 决策)。复用 `handle_intent`,不复制逻辑。
```
POST /api/agent/invoke
请求:{ "intent": "order.pool", "params": {...}, "requestId": "uuid" }
响应:{ "ok": true, "intent": "...", "power": "P0", "data": {...},
"evidenceRefs": [...], "interfaceVersion": "1.0" }
错误:{ "ok": false, "error": { "code": "INTENT_NOT_REGISTERED" |
"POWER_DENIED" | "CONFIRM_REQUIRED" | "UPSTREAM_FAILED", ... } }
GET /api/agent/intents # 列出该 token scope 可调用的意图目录(从白名单/_POWER_MAP 派生)
GET /api/agent/intents/{name} # 单意图参数 schema(供 Pi 动态生成工具签名)
```
行为规则:
- 只读意图(tool_runtime 白名单 19 项 + `_POWER_MAP` 中 P0 项)→ 直通执行;
- P1/P2/P3 → P1 阶段一律返回 `CONFIRM_REQUIRED`/`POWER_DENIED`(P2 阶段才接通);
- **未登记意图 → 拒绝 + 审计**(与 tool_runtime 同语义,fail closed)。
### 任务分解
| # | 任务 | 涉及文件 | 工时 |
|---|------|---------|------|
| P1-1 | `/api/agent/*` 三个端点:参数校验(Pydantic)、intent 登记检查、委托 handle_intent、统一错误码 | `server/gateway/app.py`(新增路由段,<150 行) | 1d |
| P1-2 | Agent Token:基于 `server/auth/` 既有体系签发长期 token(type="agent",scope=["read"]),绑定租户 + device;签发/吊销登记 P2 意图 `agent.token.issue` / `agent.token.revoke` 入 `_POWER_MAP` | `server/auth/`(新增 `agent_tokens.py`)、`harness.py` 登记 2 项 | 1.5d |
| P1-3 | 审计:`actor="pi-agent:<deviceId前8位>"`,全部调用落 TOOL/AGENT 审计事件,可按 actor 过滤 | `server/agent_core/audit.py`(复用,仅扩展 actor 约定) | 0.5d |
| P1-4 | `pi-aps` v0.1:从 `/api/agent/intents` 动态生成工具集;配置项(server URL、token、超时)落 `~/.pi/aps.json`;错误码 → 人类可读终端输出 | `poc/pi-aps/` → 转正为独立 npm 包 | 1.5d |
| P1-5 | 黄金测试:端点契约、未登记意图拒绝、token 无效/越权/吊销 fail-closed、审计落链断言 | `tests/golden/test_agent_gateway.py`(新增) | 0.5d |
### 出口标准
- 只读意图 100% 可调;非只读一律显式拒绝;
- token 六种异常(缺失/伪造/过期/吊销/scope 越界/跨租户)全部 fail-closed 且有审计;
- `pytest tests/golden/test_agent_gateway.py` 全绿;`test_contract_sync.py` 不受影响。
---
## P2 · 写操作过门禁(5-10 人日)
### 目标
Pi 可发起 P1/P2 意图(试排、登记 skill 等),确认卡在终端完成人机确认。
### 确认卡交互设计(CLI 三态)
```
Pi 发起 flex.schedule(P1 草稿类)→ 直通执行,返回 evidenceRefs(含 schedule-version)
Pi 发起 schedule.publish(P2)→ /api/agent/invoke 返回 CONFIRM_REQUIRED + cardId
→ Pi 权限钩子向用户呈现确认卡摘要(动作/影响/evidenceRefs 指纹)
→ 用户批准:POST /api/actions/confirm { cardId, approved: true }(既有唯一执行通道 ✅)
→ 用户拒绝/超时(默认 5min):fail closed,审计留痕
```
### 任务分解
| # | 任务 | 工时 |
|---|------|------|
| P2-1 | invoke 端点接通 P1 意图(沙盒/草稿语义直通,返回 evidenceRefs) | 1d |
| P2-2 | invoke 端点接通 P2:生成确认卡(复用 harness 出卡逻辑,冻结 evidenceRefs/beforeSnapshot),返回 cardId + 摘要 payload | 1.5d |
| P2-3 | token scope 升级:`read` → `read+write`(签发改 P2 确认卡;scope 与意图权力交叉校验:P2 意图必须 write scope) | 1d |
| P2-4 | pi-aps v0.2:确认卡终端 UI(摘要渲染 + y/n + 超时倒计时);批准后轮询/SSE 拿执行结果;失败显式呈现 | 1.5-3d |
| P2-5 | 证据链黄金测试:Pi 发起的 P2 写,审计含 beforeSnapshot + evidenceRefs + `verify_pending_evidence` 缺项拒绝 | 1d |
| P2-6 | 超时/并发边界:一 token 同时仅一张 pending 卡;卡过期自动拒绝 | 1d(含测试) |
### 出口标准
- 演示脚本全绿:试排→发布→回滚三链路在 Pi 终端闭环;
- 安全测试:无卡直调 confirm、伪造 cardId、过期卡、跨 token 用卡——全部拒绝 + 审计;
- 变数说明:P2-4 的 CLI 交互若 Pi 权限钩子能力受限(P0-4 结论),可能退化为"Web 确认 + CLI 只读结果",工期取下限。
---
## P3 · MCP 总线治理化(5-10 人日)
### 目标
Pi 接入面成为 `mcp_bus` 正式插件,享受统一治理(契约、权限、健康、启停、审计、管理台)。
### 插件 manifest(落 `server/data/mcp_plugins/plugins.json`)
```json
{
"plugin_id": "pi-agent-gateway",
"name": "Pi Agent 接入面",
"version": "1.0.0",
"min_bus_version": "1.0",
"endpoint": "self:///api/agent",
"tools": [
{"name": "order.pool", "power": "P0", "input_schema_ref": "shared/schemas/..."},
{"name": "flex.schedule", "power": "P1", "input_schema_ref": "shared/schemas/..."},
{"name": "schedule.publish", "power": "P2", "input_schema_ref": "shared/schemas/..."}
],
"ragScopes": []
}
```
### 任务分解
| # | 任务 | 工时 |
|---|------|------|
| P3-1 | 把 `/api/agent/intents` 目录生成为 MCP manifest(自动生成 + 版本化),注册进 mcp_bus | 1.5d |
| P3-2 | tool 级 allow/deny 配置面:按现场可裁剪 Pi 可用意图(deny 优先,fail closed) | 1d |
| P3-3 | 三方契约同步:`shared/schemas/agent_invoke.schema.json` ↔ `server/contracts.py` ↔ pi-aps 类型定义;入 `test_contract_sync.py` 门禁 | 1.5d |
| P3-4 | 管理台:SkillConsole 复用双面板模式呈现 Pi 插件(概览/健康/审计/日志页签) | 2d |
| P3-5 | 健康探测:agent 端点纳入总线探测历史(最近 20 次) | 0.5d |
| P3-6 | 文档同轮:harness.md 端点备案、skills.md 增补、CHANGELOG | 0.5d |
### 出口标准
- 总线清单可见、可启停(P2 确认卡)、审计可按插件过滤;
- 契约漂移测试阻断生效(故意改一端 → CI 红)。
---
## P4 · 验收与发布门禁(5 人日)
| # | 任务 | 工时 |
|---|------|------|
| P4-1 | 全量黄金测试(基线 1071 项 + 新增 agent 专项)固定 CPython 运行时全绿 | 1d |
| P4-2 | 安全评审:token 存储(`~/.pi/aps.json` 权限 600)、传输(内网 HTTP → 建议 HTTPS 或 SSH 隧道指引)、桌面态 nonce 与 agent token 并存策略 | 1.5d |
| P4-3 | 真实场景验收:康尼数据集上跑"查询→试排→确认发布"全链路 5 轮 | 1d |
| P4-4 | 发布物料:pi-aps npm 包版本化 + 安装文档 + 现场部署 runbook | 1d |
| P4-5 | 回顾:估算偏差分析,更新本计划为 v1.1 | 0.5d |
---
## 6. 横切约束(每阶段都必须遵守,来自 PROJECT_OPERATING_RULES)
1. **无后门**:任何写路径不得绕过 `tool_runtime`/`/api/actions/confirm`;P1 起加黄金测试断言"agent 端点代码无直接 store 写调用"(import 扫描级)。
2. **失败显式**:工具失败/为空/中止 → 结构化错误码透传到终端,禁止泛化确认。
3. **状态诚实**:DRAFT/未批准/失败状态在 agent 响应中显式标注 `status` 字段,不得当完成事实。
4. **证据链**:P2/P3 写全部携带 `beforeSnapshot` + `evidenceRefs`;审计 append-only。
5. **契约三方同步**:改契约必须三端同改 + `test_contract_sync.py`。
6. **文档同轮**:每阶段收尾同步 harness.md / CHANGELOG;`docs/README.md` 铁律。
7. **运行时**:所有验证用 `.venv` 固定 CPython,禁用 PATH 上的 Anaconda python(WinError 127 前科)。
8. **提交纪律**:未经用户授权不提交/不推送;每阶段一个独立 commit,conventional 中文提交信息。
## 7. 风险登记册
| # | 风险 | 概率 | 影响 | 触发阶段 | 对策 |
|---|------|------|------|---------|------|
| R1 | Pi 权限钩子不支持异步确认交互 | 中 | P2 降级为"CLI 发起 + Web 确认" | P0-4 暴露 | PoC 即验证;降级方案可接受 |
| R2 | token 长期持有泄漏 | 低 | 数据外泄 | P1 后 | scope 最小化 + 吊销通道 + 审计告警(audit_alerts 既有) |
| R3 | Pi 上游 API breaking change | 中 | 技能包失效 | 长期 | 技能包锁版本范围;manifest `min_bus_version` 同款声明 |
| R4 | 与现场交付(康尼/徐工)抢人力 | 高 | 双方延期 | 全程 | P0/P1 先行(可演示价值),P2+ 按交付间隙排 |
| R5 | 内网无 npm registry,技能包分发难 | 中 | 现场装不上 | P4 | 离线 tarball 分发 + runbook 写明 |
| R6 | 与 Tauri 迁移冲突 | 低 | 返工 | — | 已约定串行 |
## 8. 关键依赖与前置
- ✅ FF-01 基线已提交(8b7063f)
- ⬜ P0 需要:本机可装 Pi(npm 网络)、APS server 本地可起
- ⬜ P1 需要:确认 agent token 在桌面态(sidecar nonce 门禁)与 Web 态(JMS 登录)两种部署下的统一策略——**建议 P0 期间出结论**
- ⬜ P4 需要:康尼数据集可用
## 9. 里程碑视图
```
W1 W2 W3-4 W5-6 W7
[P0 PoC]→[P1 只读]→[P2 写门禁]→[P3 治理化]→[P4 验收]
↑go/no-go ↑可演示 ↑安全评审预备 ↑发布门禁
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

View File

@ -1,7 +1,7 @@
# Pi Agent 兜底能力发布与现场运行手册
> 角色:Agent-D(P5 发布实现)· 成文日期:2026-09-04
> 依据:`Pi-Agent兜底能力详细方案.md` §5/§6/§7、`poc/pi-fallback/P4-P5-DESIGN.md` §5、`poc/pi-fallback/P4-P5-AUDIT.md`、`docs/architecture/fallback.md` 与当前代码。
> 依据:`poc/pi-fallback/P4-P5-DESIGN.md` §5、`poc/pi-fallback/P4-P5-AUDIT.md`、`docs/architecture/fallback.md` 与当前代码。
> 本文只写运行与发布准备边界,不替代 `CHANGELOG.md`/`fallback.md`;那两份由主管统一更新。
## 1. 启用前提与 fail-closed 开关

View File

@ -1,6 +1,6 @@
# pi-aps:Pi Agent 访问 APS Gateway 的 PoC 包
本目录对应 `Pi-Agent接入详细计划.md` 的**方向 A(外向接入)**:Pi CLI 作为外部
本目录实现 **方向 A(外向接入)**:Pi CLI 作为外部
客户端智能体,通过新增的 `/api/agent/*` 适配层调用 APS 业务能力,不在 Pi 侧另开
排产执行通道。

View File

@ -1,7 +1,7 @@
# GOAL:Pi Agent 兜底能力 · P4/P5 收口(多 agent 协同 · 第五轮)
> 本文件是本轮协同的协调板。每个 sub agent 开工前必读;完工后在最终报告里给交接物。
> 目标文档:根目录 `Pi-Agent兜底能力详细方案.md`。
> 目标文档:`P4-P5-DESIGN.md` 与 `P4-P5-AUDIT.md`。
## 主管已核实基线(2026-09-04)

View File

@ -6,7 +6,7 @@
## 目标(Go/No-Go 判据)
按 `../../Pi-Agent兜底能力详细方案.md` §P0:在 `poc/pi-fallback/` 内(**不碰任何产品代码**):
本轮 P0 在 `poc/pi-fallback/` 内完成(**不碰任何产品代码**):
1. Python 编排器能拉起 Pi headless 进程并下发一个真实 ad-hoc 分析任务;
2. 四层围墙骨架生效:工具白名单 / 文件圈禁 / 网络限制 / 进程回收;

View File

@ -1,7 +1,7 @@
# NOTES-architecture — Pi 兜底能力 P0 PoC 骨架说明(Agent-B)
> 日期:2026-09-02。作者:Agent-B(架构师)。
> 前置阅读:`GOAL.md`、`NOTES-pi-runtime.md`(Agent-A)、《Pi-Agent兜底能力详细方案.md》§4.1–4.4。
> 前置阅读:`GOAL.md`、`NOTES-pi-runtime.md`(Agent-A)、`docs/architecture/fallback.md`。
> 状态:mock 模式全流程跑通,3 项围墙自检 PASS;`--real` 路径冒烟通过(无网关时 stopReason=error 显式失败)。
## 1. 骨架结构

View File

@ -2,7 +2,7 @@
> 设计员:Agent-D · 日期:2026-09-02 · 协调板:`GOAL-P1.md`
> 施工员(Agent-E)照本文件施工;测试文档员(Agent-F)按 §6 测试矩阵与 §1 文档清单执行。
> 前置已读:GOAL-P1.md、《Pi-Agent兜底能力详细方案.md》§4/§6、P0 三份 NOTES、
> 前置已读:GOAL-P1.md、docs/architecture/fallback.md、P0 三份 NOTES、
> harness.py / workflow.py / tool_runtime.py / feature_flags.py / audit.py / aps_home.py /
> gateway/app.py 聊天段 / contracts.py / intent.py / assistant.py / dialog.py / poc 骨架。

View File

@ -2,7 +2,7 @@
> 设计员:Agent-I · 日期:2026-09-03 · 协调板:`GOAL-P2.md`
> 实施员(Agent-J)照本文件施工;验证员(Agent-K)按 §8 测试矩阵与 §7 冒烟规格执行。
> 前置已读并源码核实:GOAL-P2.md、《Pi-Agent兜底能力详细方案.md》§2/§3/§4.4/§4.5、
> 前置已读并源码核实:GOAL-P2.md、docs/architecture/fallback.md、
> P1-DESIGN.md / P1-IMPL-NOTES.md / P1-SMOKE.md、fallback_lane.py(823 行)/ pi_bridge.py(261 行)、
> harness.py(852 行)/ state/checkpoints.py(201 行)/ state/store.py / tool_runtime.py /
> async_jobs.py(204 行)/ workflow.py execute_confirmed(499 起)与 import.commit 分支(836 起)/

View File

@ -2,7 +2,7 @@
> 设计员:Agent-L · 日期:2026-09-03 · 协调板:`GOAL-P3.md`
> 实施员(Agent-M)照本文件施工;验证员(Agent-N)按 §8 测试矩阵与 §9 冒烟规格执行。
> 前置已读并源码核实:GOAL-P3.md、《Pi-Agent兜底能力详细方案.md》§3(S4/S6/S7 行)/§6 P3 段、
> 前置已读并源码核实:GOAL-P3.md、docs/architecture/fallback.md、
> P2-DESIGN.md / P2-IMPL-NOTES.md / P2-VALIDATION.md、
> fallback_lane.py(1735 行:propose_reply 745 / _PLAN_SCENARIOS 1013 / validate_plan 1075 /
> check_step_request 1218 / execute_plan 1514 / _stage_plan_confirmation 1686)、

View File

@ -1,7 +1,7 @@
# P4-P5-DESIGN(Agent-A 最小可用版)
> 设计员:Agent-A | 日期:2026-09-04 | 协调板:poc/pi-fallback/GOAL-P4.md
> 依据:Pi-Agent兜底能力详细方案.md、docs/architecture/fallback.md、P1/P2/P3 设计与验证、P4-P5-AUDIT.md、fallback_lane/pi_bridge/fallback_verify 与 tests/golden/test_fallback_*.py。
> 依据:docs/architecture/fallback.md、P1/P2/P3 设计与验证、P4-P5-AUDIT.md、fallback_lane/pi_bridge/fallback_verify 与 tests/golden/test_fallback_*.py。
> 本轮只新增本文件;未 commit/push;未跑全量测试。
## 1. 现状缺口

View File

@ -3,7 +3,7 @@
orchestrator.py — Pi Agent 兜底能力 P0 PoC:Python 编排器
=========================================================
职责(对应《Pi-Agent兜底能力详细方案.md》§4.1 FallbackLane 编排器 + §4.6 熔断):
职责(对应 `docs/architecture/fallback.md` 的 FallbackLane 编排与熔断设计):
1. 以子进程拉起 Pi headless(`node .../cli.js -p --mode json`),逐行解析 JSONL 事件流;
2. 三重熔断:超时 / 步数上限 / 输出体量上限,触发即杀进程树(Windows taskkill /T /F)

View File

@ -3,7 +3,7 @@
sandbox.py — Pi Agent 兜底能力 P0 PoC:四层围墙骨架
====================================================
对应《Pi-Agent兜底能力详细方案.md》§4.2「沙箱围墙(自内向外四层)」:
对应 `docs/architecture/fallback.md` 的沙箱围墙设计:
- L1 工具层:由 tool_bridge.py 的工具白名单 + orchestrator 启动参数 `--tools read,grep,find,ls`
实现(pi 只看得见白名单工具,且本 PoC **不装 bash/edit 给真实路径**,见下);

View File

@ -3,7 +3,7 @@
tool_bridge.py — Pi Agent 兜底能力 P0 PoC:工具桥与 callId 凭证
================================================================
对应《Pi-Agent兜底能力详细方案.md》:
对应 `docs/architecture/fallback.md` 与 `P1-DESIGN.md`:
- §4.3 工具桥暴露面:定义围墙内工具白名单注册表(名称 / 权力等级 P0-P2 /
参数 schema / 是否需确认)。产品态里这些工具经由 HTTP 桥暴露给 Pi;

View File

@ -1,202 +0,0 @@
from __future__ import annotations
import copy
import random
from typing import Any, Callable
from server.aps_domain.constraints import hard_blocking_conflicts
from server.contracts import ScheduleResult
from server.engines import get_engine
from server.engines.base import EngineParams
from server.timeutil import add_minutes, fmt_date, today0
World = dict[str, Any]
DEFAULT_MONTE_CARLO_SEED = 20260731
DEFAULT_MONTE_CARLO_TRIALS = 24
def _counter() -> Callable[[str], int]:
values: dict[str, int] = {}
def next_id(kind: str) -> int:
values[kind] = values.get(kind, 3000000) + 1
return values[kind]
return next_id
def _bounded_normal(rng: random.Random, mean: float, sigma: float, low: float, high: float) -> float:
return max(low, min(high, rng.gauss(mean, sigma)))
def _perturb_world(
world: World,
rng: random.Random,
*,
reset_schedule_products: bool,
) -> tuple[World, dict[str, Any]]:
sandbox = copy.deepcopy(world)
if reset_schedule_products:
sandbox["scheduleVersions"] = []
sandbox["productionOrders"] = []
sandbox["workOrders"] = []
sandbox["conflicts"] = []
quantity_scale = _bounded_normal(rng, 1.0, 0.10, 0.80, 1.20)
efficiency_scale = _bounded_normal(rng, 1.0, 0.08, 0.75, 1.25)
for order in sandbox.get("salesOrders") or []:
for item in order.get("items") or []:
quantity = float(item.get("quantity") or 0.0)
if quantity > 0:
item["quantity"] = max(1, int(round(quantity * quantity_scale)))
for line in sandbox.get("lines") or []:
base = float(line.get("efficiencyFactor") or 1.0)
line["efficiencyFactor"] = round(base * efficiency_scale, 6)
capacity_shock_line = None
lines = sandbox.get("lines") or []
if lines and rng.random() < 0.15:
shocked = lines[rng.randrange(len(lines))]
shocked["efficiencyFactor"] = round(float(shocked.get("efficiencyFactor") or 1.0) * 0.55, 6)
capacity_shock_line = shocked.get("id")
return sandbox, {
"quantityScale": round(quantity_scale, 6),
"efficiencyScale": round(efficiency_scale, 6),
"capacityShockLineId": capacity_shock_line,
}
def _percentile(values: list[float], percentile: float) -> float:
if not values:
return 0.0
ordered = sorted(values)
position = (len(ordered) - 1) * percentile
lower = int(position)
upper = min(lower + 1, len(ordered) - 1)
fraction = position - lower
return round(ordered[lower] * (1.0 - fraction) + ordered[upper] * fraction, 4)
def run_monte_carlo(
world: World,
*,
strategy: str = "COMPREHENSIVE",
engine_type: str = "RULE",
trials: int = DEFAULT_MONTE_CARLO_TRIALS,
seed: int = DEFAULT_MONTE_CARLO_SEED,
baseline_kpi: dict[str, Any] | None = None,
planning_horizon_days: int = 14,
start_date: str | None = None,
delivery_buffer_ratio: float | None = None,
freeze_window_hours: float | None = None,
constraints: dict[str, bool] | None = None,
reset_schedule_products: bool = False,
) -> dict[str, Any]:
"""Re-solve fixed-seed demand/capacity perturbations in isolated sandboxes.
经统一 Explore 通道执行(矩阵 55 行):fn 只拿深拷贝沙盒,主干永不外泄写引用;
每 trial 的 _perturb_world 再在沙盒上做独立扰动,互不污染。
"""
from server.aps_domain.explore_boundary import run_explore
return run_explore(world, lambda sandbox: _monte_carlo_impl(
sandbox,
strategy=strategy, engine_type=engine_type, trials=trials, seed=seed,
baseline_kpi=baseline_kpi, planning_horizon_days=planning_horizon_days,
start_date=start_date, delivery_buffer_ratio=delivery_buffer_ratio,
freeze_window_hours=freeze_window_hours, constraints=constraints,
reset_schedule_products=reset_schedule_products,
))
def _monte_carlo_impl(
world: World,
*,
strategy: str,
engine_type: str,
trials: int,
seed: int,
baseline_kpi: dict[str, Any] | None,
planning_horizon_days: int,
start_date: str | None,
delivery_buffer_ratio: float | None,
freeze_window_hours: float | None,
constraints: dict[str, bool] | None,
reset_schedule_products: bool,
) -> dict[str, Any]:
"""Monte Carlo 核心实现(在统一通道沙盒内运行)。"""
sample_count = max(1, min(500, int(trials)))
baseline = baseline_kpi or {}
baseline_tardiness = max(0.0, float(baseline.get("totalTardiness") or baseline.get("tardiness") or 0.0))
baseline_conflicts = max(0, int(baseline.get("conflictCount") or baseline.get("conflicts") or 0))
criteria = {
"maxTotalTardiness": round(baseline_tardiness + max(1.0, baseline_tardiness * 0.10), 4),
"maxConflictCount": baseline_conflicts,
"requireNoHardViolations": True,
}
rng = random.Random(int(seed))
start = start_date or fmt_date(add_minutes(today0(), 24 * 60))
outcomes: list[dict[str, Any]] = []
for trial in range(sample_count):
sandbox, perturbation = _perturb_world(
world,
rng,
reset_schedule_products=reset_schedule_products,
)
params = EngineParams(
orderIds=[],
engineType=engine_type,
strategyTemplate=strategy,
planningHorizonDays=planning_horizon_days,
startDate=start,
deliveryBufferRatio=delivery_buffer_ratio,
freezeWindowHours=freeze_window_hours,
name=f"mc-{seed}-{trial + 1}",
constraints=constraints or EngineParams().constraints,
)
result: ScheduleResult = get_engine(engine_type).solve(sandbox, params, _counter())
hard_rows = hard_blocking_conflicts(sandbox, result.versionId, track="fixed")
hard_ids = {row.get("id") for row in hard_rows}
critical_unmapped = [
row for row in sandbox.get("conflicts") or []
if row.get("versionId") == result.versionId
and row.get("severity") == "CRITICAL"
and row.get("id") not in hard_ids
]
hard_count = len(hard_rows) + len(critical_unmapped)
accepted = (
hard_count == 0
and float(result.totalTardiness) <= criteria["maxTotalTardiness"] + 1e-9
and int(result.conflictCount) <= criteria["maxConflictCount"]
)
outcomes.append({
"trial": trial + 1,
**perturbation,
"totalTardiness": round(float(result.totalTardiness), 4),
"conflictCount": int(result.conflictCount),
"hardViolationCount": hard_count,
"accepted": accepted,
})
accepted_count = sum(1 for outcome in outcomes if outcome["accepted"])
tardiness = [float(outcome["totalTardiness"]) for outcome in outcomes]
return {
"method": "fixed-seed-monte-carlo",
"seed": int(seed),
"trials": sample_count,
"acceptanceCriteria": criteria,
"acceptedTrials": accepted_count,
"robustness": round(accepted_count / sample_count, 6),
"distribution": {
"tardinessP50": _percentile(tardiness, 0.50),
"tardinessP90": _percentile(tardiness, 0.90),
"tardinessP95": _percentile(tardiness, 0.95),
"tardinessMax": round(max(tardiness, default=0.0), 4),
"meanConflicts": round(
sum(outcome["conflictCount"] for outcome in outcomes) / sample_count, 4
),
},
"outcomes": outcomes,
}

View File

@ -1,277 +0,0 @@
# ============================================================
# 主控参数敏感性分析(moduleId: domain-sensitivity, SC-06,可重生 ✅)
# 沙盒 one-at-a-time 扰动 + 固定种子蒙特卡洛;永不写主干
# ============================================================
from __future__ import annotations
import copy
import uuid
from typing import Any
from server.aps_domain.params import get_schedule_params
from server.aps_domain.robustness import run_monte_carlo
from server.contracts import UIBlock
from server.engines import get_engine
from server.engines.base import EngineParams
from server.timeutil import add_minutes, fmt_date, today0
World = dict[str, Any]
def _sandbox_counter():
counters: dict[str, int] = {}
def next_id(kind: str) -> int:
counters[kind] = counters.get(kind, 0) + 2000000
return counters[kind]
return next_id
def _kpi_from_result(result, sandbox: World) -> dict[str, float]:
ver = sandbox["scheduleVersions"][-1] if sandbox.get("scheduleVersions") else {}
return {
"tardiness": round(float(result.totalTardiness), 2),
"conflicts": float(result.conflictCount),
"utilization": round(float(result.avgUtilization), 4),
"changeoverMin": float(ver.get("totalChangeoverMin") or 0),
"poCount": float(result.poCount),
"woCount": float(result.woCount),
}
def _run_sandbox(
world: World,
*,
strategy: str,
horizon: int,
start: str,
vip_weight: float | None = None,
delivery_buffer: float | None = None,
freeze_hours: float | None = None,
efficiency_scale: float | None = None,
) -> dict[str, float]:
sandbox = copy.deepcopy(world)
sandbox["scheduleVersions"] = []
sandbox["productionOrders"] = [p for p in sandbox.get("productionOrders", []) if p.get("status") == "PUBLISHED"]
sandbox["workOrders"] = [w for w in sandbox.get("workOrders", []) if w.get("status") not in ("PENDING", "DRAFT", None)]
# 清空草稿工单/PO,避免干扰;简化:只保留非本沙盒相关——种子通常无已发布,直接清空排产结果
sandbox["productionOrders"] = []
sandbox["workOrders"] = []
sandbox["conflicts"] = []
sp = sandbox.setdefault("scheduleParams", {})
if vip_weight is not None:
levels = dict(sp.get("customerLevelWeights") or {})
levels["VIP"] = float(vip_weight)
sp["customerLevelWeights"] = levels
if efficiency_scale is not None and efficiency_scale > 0:
for ln in sandbox.get("lines") or []:
base = float(ln.get("efficiencyFactor") or 1.0)
ln["efficiencyFactor"] = round(base * float(efficiency_scale), 4)
params = EngineParams(
orderIds=[],
engineType="RULE",
strategyTemplate=strategy,
planningHorizonDays=horizon,
startDate=start,
deliveryBufferRatio=delivery_buffer,
freezeWindowHours=freeze_hours,
name=f"sensitivity-{uuid.uuid4().hex[:6]}",
constraints={
"materialKit": False, "equipment": True, "personnel": True, "changeover": True,
"capacity": True, "dueDate": True, "tooling": True, "freeze": True,
},
)
result = get_engine("RULE").solve(sandbox, params, _sandbox_counter())
return _kpi_from_result(result, sandbox)
def run_sensitivity(
world: World,
*,
strategy: str = "COMPREHENSIVE",
) -> dict[str, Any]:
"""
SC-06:Tornado 单因子排序 + 固定种子蒙特卡洛鲁棒性。
经统一 Explore 通道执行(矩阵 55 行):fn 只拿深拷贝沙盒,主干永不外泄写引用;
_run_sandbox 内部再做子沙盒扰动。
"""
from server.aps_domain.explore_boundary import run_explore
return run_explore(world, lambda sandbox: _sensitivity_impl(
sandbox, strategy=strategy,
))
def _sensitivity_impl(world: World, *, strategy: str) -> dict[str, Any]:
"""Tornado/蒙特卡洛核心实现(在统一通道沙盒内运行)。"""
sp = get_schedule_params(world)
base_horizon = int(sp.get("planningHorizonDays") or 14)
base_vip = float((sp.get("customerLevelWeights") or {}).get("VIP") or 3.0)
base_buffer = float(sp.get("deliveryBufferRatio") or 0.95)
base_freeze = float(sp.get("freezeWindowHours") or 24)
start = fmt_date(add_minutes(today0(), 24 * 60))
baseline = _run_sandbox(
world, strategy=strategy, horizon=base_horizon, start=start,
vip_weight=base_vip, delivery_buffer=base_buffer, freeze_hours=base_freeze,
efficiency_scale=1.0,
)
# 每因子:低/高 两档(相对基线)
factors: list[dict[str, Any]] = [
{
"id": "planningHorizonDays", "label": "展望期(天)",
"baseline": base_horizon,
"low": {"label": f"{max(3, base_horizon // 2)} 天", "kwargs": {"horizon": max(3, base_horizon // 2)}},
"high": {"label": f"{min(60, base_horizon * 2)} 天", "kwargs": {"horizon": min(60, base_horizon * 2)}},
},
{
"id": "vipWeight", "label": "VIP 等级权重",
"baseline": base_vip,
"low": {"label": "VIP=1", "kwargs": {"vip_weight": 1.0}},
"high": {"label": "VIP=10", "kwargs": {"vip_weight": 10.0}},
},
{
"id": "deliveryBufferRatio", "label": "交期缓冲比",
"baseline": base_buffer,
"low": {"label": "缓冲 0.85", "kwargs": {"delivery_buffer": 0.85}},
"high": {"label": "缓冲 1.00", "kwargs": {"delivery_buffer": 1.0}},
},
{
"id": "freezeWindowHours", "label": "冻结窗口(时)",
"baseline": base_freeze,
"low": {"label": "冻结 0h", "kwargs": {"freeze_hours": 0.0}},
"high": {"label": "冻结 48h", "kwargs": {"freeze_hours": 48.0}},
},
{
"id": "lineEfficiency", "label": "产线效率系数",
"baseline": 1.0,
"low": {"label": "效率×0.8", "kwargs": {"efficiency_scale": 0.8}},
"high": {"label": "效率×1.2", "kwargs": {"efficiency_scale": 1.2}},
},
]
rows: list[dict[str, Any]] = []
for fac in factors:
common = {
"strategy": strategy, "horizon": base_horizon, "start": start,
"vip_weight": base_vip, "delivery_buffer": base_buffer,
"freeze_hours": base_freeze, "efficiency_scale": 1.0,
}
low_kw = {**common, **fac["low"]["kwargs"]}
high_kw = {**common, **fac["high"]["kwargs"]}
# kwargs 用 horizon 键
def _call(kw: dict) -> dict[str, float]:
return _run_sandbox(
world,
strategy=kw["strategy"],
horizon=int(kw["horizon"]),
start=kw["start"],
vip_weight=kw.get("vip_weight"),
delivery_buffer=kw.get("delivery_buffer"),
freeze_hours=kw.get("freeze_hours"),
efficiency_scale=kw.get("efficiency_scale"),
)
low_kpi = _call(low_kw)
high_kpi = _call(high_kw)
d_low = round(low_kpi["tardiness"] - baseline["tardiness"], 2)
d_high = round(high_kpi["tardiness"] - baseline["tardiness"], 2)
rows.append({
"factorId": fac["id"],
"label": fac["label"],
"baselineValue": fac["baseline"],
"lowLabel": fac["low"]["label"],
"highLabel": fac["high"]["label"],
"low": {
"tardiness": low_kpi["tardiness"],
"conflicts": low_kpi["conflicts"],
"utilization": low_kpi["utilization"],
"deltaTardiness": d_low,
"deltaConflicts": round(low_kpi["conflicts"] - baseline["conflicts"], 1),
},
"high": {
"tardiness": high_kpi["tardiness"],
"conflicts": high_kpi["conflicts"],
"utilization": high_kpi["utilization"],
"deltaTardiness": d_high,
"deltaConflicts": round(high_kpi["conflicts"] - baseline["conflicts"], 1),
},
"swing": round(abs(d_low) + abs(d_high), 2),
"impactMetric": "tardiness",
})
rows.sort(key=lambda r: r["swing"], reverse=True)
monte_carlo = run_monte_carlo(
world,
strategy=strategy,
engine_type="RULE",
baseline_kpi=baseline,
planning_horizon_days=base_horizon,
start_date=start,
delivery_buffer_ratio=base_buffer,
freeze_window_hours=base_freeze,
constraints={
"materialKit": False, "equipment": True, "personnel": True, "changeover": True,
"capacity": True, "dueDate": True, "tooling": True, "freeze": True,
},
reset_schedule_products=True,
)
md_lines = [
"# 敏感性分析(Tornado)",
"",
f"- 策略基线:`{strategy}`",
f"- 基线 KPI:延期 **{baseline['tardiness']}** h · 冲突 **{int(baseline['conflicts'])}** · "
f"利用率 **{round(baseline['utilization'] * 100, 1)}%** · 换型 **{baseline['changeoverMin']}** 分",
"- 说明:沙盒 one-at-a-time,不写主干;超时秒数对 RULE 无意义,未纳入。",
"",
"| 因子 | 低档 Δ延期 | 高档 Δ延期 | 摆幅 |",
"| --- | ---: | ---: | ---: |",
]
for r in rows:
md_lines.append(
f"| {r['label']}({r['lowLabel']} / {r['highLabel']}) | "
f"{r['low']['deltaTardiness']:+} | {r['high']['deltaTardiness']:+} | {r['swing']} |"
)
md_lines.append("")
md_lines.append("摆幅 = |低档Δ延期| + |高档Δ延期|;越大表示该参数对延期越敏感。")
md_lines.extend([
"",
"## 固定种子蒙特卡洛鲁棒性",
"",
f"- 种子:`{monte_carlo['seed']}` · 样本:**{monte_carlo['trials']}** 次",
f"- 鲁棒性:**{round(monte_carlo['robustness'] * 100, 1)}%**",
f"- 延期分布:P50 **{monte_carlo['distribution']['tardinessP50']}h** · "
f"P90 **{monte_carlo['distribution']['tardinessP90']}h**",
])
return {
"strategy": strategy,
"baseline": baseline,
"rows": rows,
"monteCarlo": monte_carlo,
"markdown": "\n".join(md_lines),
"hint": "敏感性只跑沙盒。若要固化参数,请到设置 → 排产参数 改权重/展望期并确认(P2)。",
}
def sensitivity_as_block(report: dict[str, Any]) -> UIBlock:
"""产出 report UI 块(可预览/下载)。"""
return UIBlock(
blockId=f"sensitivity-{uuid.uuid4().hex[:8]}",
type="report",
props={
"reportId": uuid.uuid4().hex[:10],
"title": f"敏感性分析 Tornado({report.get('strategy')})",
"markdown": report.get("markdown") or "",
"reportType": "sensitivity-tornado",
"baseline": report.get("baseline"),
"rows": report.get("rows"),
"monteCarlo": report.get("monteCarlo"),
},
)

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,49 +0,0 @@
"""将幻灯片与配音逐段合成为 MP4,再拼接为完整视频。"""
import subprocess
import sys
from pathlib import Path
import imageio_ffmpeg
FFMPEG = imageio_ffmpeg.get_ffmpeg_exe()
WS = Path(__file__).resolve().parent
REPO_ROOT = WS.parent
PARTS = WS / "parts"
PARTS.mkdir(exist_ok=True)
N = 12
part_files = []
for i in range(1, N + 1):
slide = WS / "slides" / f"slide{i:02d}.png"
audio = WS / "audio" / f"seg{i:02d}.mp3"
part = PARTS / f"part{i:02d}.mp4"
cmd = [
FFMPEG, "-y",
"-loop", "1", "-framerate", "30", "-i", str(slide),
"-i", str(audio),
"-c:v", "libx264", "-preset", "medium", "-tune", "stillimage",
"-c:a", "aac", "-b:a", "192k",
"-pix_fmt", "yuv420p",
"-shortest", "-movflags", "+faststart",
str(part),
]
r = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
if r.returncode != 0 or not part.exists():
print(f"part{i:02d} 合成失败:\n{r.stderr[-800:]}")
sys.exit(1)
part_files.append(part)
print(f"part{i:02d}.mp4 ✓ ({part.stat().st_size // 1024} KB)")
lst = WS / "concat.txt"
lst.write_text("".join(f"file 'parts/{p.name}'\n" for p in part_files), encoding="utf-8")
final = REPO_ROOT / "APS智能体演示视频.mp4"
r = subprocess.run(
[FFMPEG, "-y", "-f", "concat", "-safe", "0", "-i", str(lst),
"-c", "copy", "-movflags", "+faststart", str(final)],
capture_output=True, text=True, timeout=600,
)
if r.returncode != 0 or not final.exists():
print("拼接失败:\n", r.stderr[-800:])
sys.exit(1)
print(f"\n最终视频: {final} ({final.stat().st_size / 1024 / 1024:.1f} MB)")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

View File

@ -1,12 +0,0 @@
file 'parts/part01.mp4'
file 'parts/part02.mp4'
file 'parts/part03.mp4'
file 'parts/part04.mp4'
file 'parts/part05.mp4'
file 'parts/part06.mp4'
file 'parts/part07.mp4'
file 'parts/part08.mp4'
file 'parts/part09.mp4'
file 'parts/part10.mp4'
file 'parts/part11.mp4'
file 'parts/part12.mp4'

View File

@ -1,36 +0,0 @@
"""从 narration.md 解析 SEG 分段,逐段调用 TTS 生成 MP3。"""
import os
import re
import subprocess
import sys
from pathlib import Path
WS = Path(__file__).resolve().parent
plugin_dir = (os.environ.get("APS_AUDIO_GENERATION_PLUGIN") or "").strip()
voice_id = (os.environ.get("APS_TTS_VOICE_ID") or "").strip()
if not plugin_dir or not voice_id:
raise SystemExit("请配置 APS_AUDIO_GENERATION_PLUGIN 和 APS_TTS_VOICE_ID 后再生成配音")
PLUGIN = Path(plugin_dir).expanduser().resolve()
VOICE = voice_id
text = (WS / "narration.md").read_text(encoding="utf-8")
segments = re.findall(r"SEG (\d+)([^)]*)\s*\n(.*?)(?=\n\nSEG |\Z)", text, re.S)
print(f"共解析 {len(segments)} 段")
for num, body in segments:
out = WS / "audio" / f"seg{num}.mp3"
if out.exists() and out.stat().st_size > 10_000:
print(f"seg{num} 已存在,跳过")
continue
body = " ".join(body.split())
result = subprocess.run(
[sys.executable, str(PLUGIN / "scripts" / "audio_generation_tool.py"), "speech",
"--text", body, "--voice-id", VOICE, "--output", str(out)],
cwd=PLUGIN, capture_output=True, text=True, timeout=600,
)
ok = out.exists() and out.stat().st_size > 10_000
print(f"seg{num}: {'OK' if ok else 'FAIL'} ({len(body)} 字)")
if not ok:
print(result.stdout[-500:], result.stderr[-500:])
sys.exit(1)
print("全部配音生成完成")

View File

@ -1,104 +0,0 @@
"""绘制演示视频用 1080p 幻灯片(深色科技风 + 品牌橙)。"""
import os
from PIL import Image, ImageDraw, ImageFont
from pathlib import Path
WS = Path(__file__).resolve().parent
W, H = 1920, 1080
BG = (13, 25, 42) # 深藏青
BG2 = (21, 37, 60) # 卡片底色
ORANGE = (232, 107, 32) # 品牌橙(与应用主题一致)
WHITE = (240, 244, 248)
GREY = (150, 165, 185)
FONT = os.environ.get("APS_VIDEO_FONT_REGULAR") or "msyh.ttc"
FONT_B = os.environ.get("APS_VIDEO_FONT_BOLD") or "msyhbd.ttc"
def font(size, bold=False):
return ImageFont.truetype(FONT_B if bold else FONT, size)
SLIDES = [
dict(kind="cover", title="从“人排产”到“智能体排产”",
sub="工业智核 APS · 计划排产智能体", note="产品汇报演示"),
dict(kicker="01 · 为什么做", title="排产:制造业数字化最后一块硬骨头",
bullets=["约束复杂 —— 物料齐套、设备产能、模具寿命、班组技能、换型耗时,牵一发动全身",
"变化频繁 —— 紧急插单、设备故障、物料延期,计划永远赶不上变化",
"经验依赖 —— 老师傅的判断无法沉淀、无法复制、无法传承",
"大语言模型的成熟,给出了全新解法"]),
dict(kicker="02 · 智能体闭环", title="听得懂 · 算得准 · 管得住",
bullets=["感知 —— 自然语言下达指令:「试排一版交期优先」",
"决策 —— 意图翻译成命令,驱动运筹学引擎真实求解",
"执行 —— 甘特 / 负荷 / 交期三视图实时呈现,左说右动",
"留痕 —— 每次操作进入哈希链式审计台账,可校验可回放"]),
dict(kicker="03 · 数据准备", title="把工厂“搬”进系统,只需一次导入",
bullets=["订单、物料、BOM、工艺路线、设备台账 —— 普通 Excel 即可",
"自动识别表角色、表头映射、数据校验",
"传统 APS 最耗时的数据初始化,在这里一次完成"]),
dict(kicker="04 · 一句话排产", title="「试排一版交期优先」",
bullets=["几秒钟产出排产版本:订单 × 设备 × 工序 × 时间一目了然",
"甘特图 / 设备负荷 / 交期看板三视图联动",
"数字全部来自引擎确定性计算 —— 大模型不得编造任何数字"]),
dict(kicker="05 · 多策略对比", title="机器穷举,人来拍板",
bullets=["交期优先 / 产能均衡 / 换型最小化 —— 沙盒并行试排",
"准时率、换型次数、设备利用率逐项对照,最优项高亮",
"一键采用,右侧沙盘即刻刷新,正式数据零风险"]),
dict(kicker="06 · 插单与动态调度", title="L1 → L4 分级动态调度",
bullets=["紧急插单:先局部修复、评估影响面,而非硬塞引发连锁延期",
"设备故障:秒级池内换机 → 短窗重排 → 日重排 → 全局重排",
"每级重排附带影响评估与确认卡 —— 拍板权永远在人"]),
dict(kicker="07 · 柔性排产", title="能力池 + 虚拟产线(差异化能力)",
bullets=["打破“设备固定属于产线”假设,按订单动态组线、用完释放",
"正排保开工 / 倒排保交期 / 瓶颈锚定保利用率",
"设备停机即刻重算瓶颈产能,负载预警自动色标"]),
dict(kicker="08 · 图纸智能解析", title="让 CAD 图纸自己“开口说话”",
bullets=["DXF 图纸导入:自动识别图号与版本,逐图元解析",
"提取物料 / BOM 引用 / 工艺信息为结构化候选清单",
"图纸是证据不是命令 —— AI 负责提取,人负责批准"]),
dict(kicker="09 · 门禁与审计", title="智能体的每一步“想动”,都要人“放行”",
bullets=["P0–P3 四级门禁:只读自由 / 试排轻提示 / 关键写确认 / 外部二次确认",
"违反硬约束的计划,任何人都无法发布",
"哈希链审计:谁决定的、依据是什么、当时看到了什么,随时可查"]),
dict(kicker="10 · 沉淀与报告", title="把经验沉淀为组织资产",
bullets=["检查点时间线:每个决策节点自动存档,随时回滚",
"KPI 仪表盘:利用率 / 准时率 / 在制 / 延误一屏汇总",
"一键生成 Word 排产报告,数字来自冻结快照,不经 AI 改写"]),
dict(kind="cover", title="让排产听得懂人话,让决策算得清利害",
sub="工业智核 APS · 计划排产智能体", note="汇报完毕 · 谢谢大家"),
]
def draw_cover(img, d, s):
d.rectangle([0, H - 18, W, H], fill=ORANGE)
d.rectangle([0, 0, W, 14], fill=ORANGE)
tw = d.textlength(s["title"], font=font(72, True))
d.text(((W - tw) / 2, H / 2 - 130), s["title"], font=font(72, True), fill=WHITE)
sw = d.textlength(s["sub"], font=font(40))
d.text(((W - sw) / 2, H / 2 + 10), s["sub"], font=font(40), fill=ORANGE)
nw = d.textlength(s["note"], font=font(30))
d.text(((W - nw) / 2, H / 2 + 110), s["note"], font=font(30), fill=GREY)
def draw_content(img, d, s, idx):
d.rectangle([0, 0, W, 14], fill=ORANGE)
d.rectangle([96, 120, 106, 260], fill=ORANGE)
d.text((136, 118), s["kicker"], font=font(34, True), fill=ORANGE)
d.text((136, 172), s["title"], font=font(56, True), fill=WHITE)
y = 340
for b in s["bullets"]:
d.rounded_rectangle([96, y - 18, W - 96, y + 78], radius=16, fill=BG2)
d.ellipse([132, y + 18, 156, y + 42], fill=ORANGE)
d.text((190, y), b, font=font(34), fill=WHITE)
y += 128
footer = "工业智核 APS · 计划排产智能体"
d.text((96, H - 72), footer, font=font(24), fill=GREY)
num = f"{idx:02d} / {len(SLIDES):02d}"
d.text((W - 96 - d.textlength(num, font=font(24)), H - 72), num, font=font(24), fill=GREY)
for i, s in enumerate(SLIDES, 1):
img = Image.new("RGB", (W, H), BG)
d = ImageDraw.Draw(img)
if s.get("kind") == "cover":
draw_cover(img, d, s)
else:
draw_content(img, d, s, i)
img.save(WS / "slides" / f"slide{i:02d}.png")
print(f"slide{i:02d}.png ✓")
print("全部幻灯片绘制完成")

View File

@ -1,37 +0,0 @@
# 视频解说词分段(配合幻灯片,总时长约 8 分钟)
SEG 01(封面)
各位领导,大家好。今天向大家汇报的,是工业智核 APS 计划排产智能体。它不是对传统排产软件的界面改良,而是排产工作方式的一次范式升级:让机器理解人的意图,让算法完成繁重的计算,让人专注于判断与决策。
SEG 02(为什么做)
排产,是制造业数字化最后一块硬骨头。约束复杂:物料齐套、设备产能、模具寿命、班组技能、换型耗时,牵一发而动全身;变化频繁:紧急插单、设备故障、物料延期,计划永远赶不上变化;决策又高度依赖老师傅的个人经验,无法沉淀、无法复制、更无法传承。而大语言模型的成熟,给了我们一条全新的路。
SEG 03(智能体闭环)
这套系统,是用自然语言驱动、用可视化确认、用门禁审计约束的计划排产智能体,具备感知、决策、执行、留痕的完整闭环。计划员用母语直接下达指令:试排一版交期优先;系统理解意图,驱动运筹学引擎真实求解;结果以甘特图、设备负荷、交期看板三视图实时呈现;每一次操作,全部留痕可审计。
SEG 04(数据准备)
一切智能的前提是数据。订单、物料、BOM、工艺路线、设备台账,就是最普通的 Excel 表格,一键导入。系统自动识别每张表的角色,完成表头映射与校验。传统排产软件实施中最耗时的数据初始化,在这里一次完成。
SEG 05(一句话排产)
数据就绪,我们只对系统说一句话:试排一版交期优先。几秒钟,一个排产版本呈现眼前:每个订单在哪台设备、什么时间、哪道工序,一目了然;哪台设备超载、哪张订单有延期风险,清清楚楚。特别强调:这些数字全部来自运筹学引擎的确定性计算,大模型只负责理解意图,制度上不允许它编造任何一个数字。
SEG 06(多策略对比)
排产没有唯一解,只有适合当下经营目标的解。一句"对比几种策略",系统在沙盒中把交期优先、产能均衡、换型最小化等策略并行试排,准时率、换型次数、设备利用率逐项对照,最优项高亮。看中哪个,一键采用。过去计划员凭经验只能想一种排法,现在是机器穷举、人来拍板。
SEG 07(插单与动态调度)
计划永远赶不上变化。客户急单插进来,系统先做局部修复、评估影响面,而不是硬塞进去引发连锁延期;设备故障,秒级给出池内换机建议。影响小,局部消化;影响大,逐级升级为窗口重排、日重排乃至全局重排。这就是 L1 到 L4 分级动态调度,每一步重排都带着影响评估和确认卡,拍板权永远在人。
SEG 08(柔性排产)
多品种、小批量的工厂,设备未必永远属于某条产线。系统建立工序能力池与虚拟产线机制:按订单需求动态组合设备,预占资源、用完释放,连设备移动耗时、模具换型时间都精确计算。正排保开工、倒排保交期、瓶颈锚定保利用率,三种模式自由切换。设备一停机,瓶颈产能即刻重算,负载预警自动色标。这是我们与市面产品最大的不同。
SEG 09(图纸解析)
排产的上游是技术资料。一张 CAD 工程图纸导入系统,自动识别图号和版本,九千多个图元逐一解析,把图纸里的物料、BOM 引用、工艺信息提取成结构化的候选清单。请注意"候选"两个字:图纸是证据,不是命令,这些信息必须经过人工确认才会写入主数据。AI 负责提取,人负责批准。
SEG 10(门禁与审计)
方案满意,能不能一键生效?能,但要过一道门。系统实行四级门禁:只读查询自由进行,试排对比轻量提示,发布、回滚等关键动作必须经确认卡人工点头,涉及外部系统的动作二次确认。每一次操作记入哈希链式审计台账:谁决定的、依据是什么、系统当时看到了什么,随时可查、不可篡改。智能体的每一步"想动",都要经过人的"放行"。
SEG 11(沉淀与报告)
每个决策节点自动存档,随时回滚到任何一个"如果当初";利用率、准时率、在制、延误,一屏汇总;一键生成排产日报和正式的 Word 排产报告,数字直接来自冻结快照,不经过任何 AI 改写。老师傅的经验,从此沉淀为组织的系统能力,越用越聪明。
SEG 12(收尾)
从一份 Excel 开始,到一份可下发的生产计划结束,这套系统走完了完整闭环。让排产听得懂人话,让决策算得清利害,让经验沉淀为资产。它对标国际主流排产产品完成主体能力覆盖,行业适配不靠定制开发,换一套数据即可运转。这,就是工业智核 APS 智能体交出的答卷。汇报完毕,谢谢大家。

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB