Palantir 供应链缺料自动调拨:端到端配置全览
把「工厂 IoT 告警自动分派」整条链路迁移到供应链缺料调拨(Shortage → Reallocation)场景,结构和字段一一对应,方便对照两套生产配置。
重要说明:Palantir 官方并没有把 Automate 规则公开成”手写 JSON 配置文件”;UI 里是 Condition → Effects,AIP Logic 里是 Blocks(Conditionals / Loop)。下文 JSON 均为教学骨架,用于表达平台内部概念的结构,帮助理解各字段语义。
前置阅读:
场景设定
- 业务诉求:工厂/产线物料库存跌破安全水位 → 系统自动建
MaterialShortage对象 → 按缺口量、物料关键等级、周边仓库/工厂的在库与在途情况 → 计算出「从哪调、调多少、优先级」→ 自动生成调拨单(TransferOrder)→ 严重缺料让 AIP Agent 辅助决策,但扣减库存、改生产计划等高风险操作需人确认。
一、Ontology 层:业务”名词”
以下 Object Type 均建模在 Foundry Ontology 中:
Object Type:MaterialShortage(缺料事件)
| 属性 | 类型 | 说明 |
|---|---|---|
| shortageId | string | 缺料事件唯一标识 |
| materialId | string | 关联物料 |
| plantId | string | 需求方工厂 |
| lineId | string | 产线(可选) |
| shortageQty | number | 缺口数量 |
| severity | enum | LOW / MEDIUM / HIGH / CRITICAL |
| status | enum | DETECTED / ALLOCATED / CONFIRMED / CLOSED |
| detectedAt | datetime | 检测时间 |
Links:
resolvedBy→ TransferOrder(调拨单,分配后建立)
Object Type:Material(物料)
| 属性 | 类型 | |
|---|---|---|
| materialId | string | |
| name | string | |
| criticality | enum | A / B / C |
| safetyStock | number | 安全库存水位 |
Object Type:Plant / Warehouse(工厂 / 仓库)
| 属性 | 类型 |
|---|---|
| id | string |
| region | string |
| name | string |
Object Type:Inventory(库存,含在库/在途)
| 属性 | 类型 | |
|---|---|---|
| materialId | string | |
| locationId | string | |
| onHandQty | number | 在库数量 |
| inTransitQty | number | 在途数量 |
Object Type:TransferOrder(调拨单)
| 属性 | 类型 | |
|---|---|---|
| orderId | string | |
| fromLocation | string | |
| toLocation | string | |
| qty | number | |
| status | enum | DRAFT / CONFIRMED / SHIPPED / CLOSED |
| eta | string | 预计到货时间 |
Links:
fulfills→ MaterialShortage(一对多,一张调拨单可覆盖多个缺料事件)
关键点
Action 操作的都是这些语义对象,不直接碰 ERP 库存表。LLM/Agent 看到的是”缺料事件、物料、仓库、调拨单”,不接触原始 ERP 数据。
二、Action Type:allocate-shortage(缺料调拨分配)
为缺料事件计算调出方与数量,生成调拨单 TransferOrder。
{
"apiName": "allocate-shortage",
"displayName": "Allocate Shortage via Transfer",
"description": "为缺料事件计算调出方与数量,生成调拨单 TransferOrder",
"parameters": {
"shortage": {
"type": "objectType:MaterialShortage",
"required": true,
"description": "待处理的缺料事件"
},
"sourceLocation": {
"type": "objectType:Warehouse",
"required": true,
"description": "调出仓库/工厂"
},
"transferQty": {
"type": "number",
"required": true,
"description": "调拨数量,不能超过缺口与可调出量"
},
"overrideEta": {
"type": "string",
"required": false,
"description": "人工覆盖的预计到货时间"
}
},
"backingLogic": {
"type": "function",
"functionRid": "ri.function.main.allocate-shortage-fn",
"outputs": {
"transferQty": "number",
"eta": "string",
"feasible": "boolean",
"reason": "string"
}
},
"submissionCriteria": [
{
"condition": "shortage.status == 'DETECTED'",
"message": "只能处理处于 DETECTED 状态的缺料事件"
},
{
"condition": "transferQty > 0 && transferQty <= shortage.shortageQty",
"message": "调拨量必须为正且不超过缺口量"
},
{
"condition": "sourceLocation.inventoryFor(shortage.materialId).onHandQty >= transferQty",
"message": "调出方可用库存不足"
}
],
"permissions": {
"defaultRole": "DENY",
"roleGrants": [
{ "roleId": "supply-planner", "operations": ["EXECUTE"] },
{ "roleId": "plant-manager", "operations": ["VIEW"] }
],
"requireMarkingAccess": true
},
"edits": [
{
"modifyObject": "shortage",
"set": {
"status": "ALLOCATED",
"severity": "$output.severity",
"allocationReason": "$output.reason"
}
},
{
"createObject": "TransferOrder",
"set": {
"fromLocation": "$parameter.sourceLocation",
"toLocation": "$parameter.shortage.plantId",
"materialId": "$parameter.shortage.materialId",
"qty": "$output.transferQty",
"eta": "$output.eta",
"status": "DRAFT"
},
"link": { "fulfills": "$parameter.shortage" }
}
],
"sideEffects": {
"notifications": [
{
"to": "linked:TransferOrder.toLocation.hasPlanners.Person",
"title": "新调拨单已生成: ${shortage.shortageId}",
"body": "从 ${sourceLocation.name} 调拨 ${transferQty} 至 ${shortage.plantId}"
}
],
"webhooks": [
{
"name": "sync-erp-draft",
"url": "https://erp.internal/api/transfer-orders/draft",
"method": "POST",
"body": {
"shortageId": "${shortage.shortageId}",
"from": "${sourceLocation.id}",
"to": "${shortage.plantId}",
"qty": "${transferQty}"
}
}
]
},
"idempotencyBehavior": {
"strategy": "UPSERT",
"dedupKeys": ["shortage.shortageId"]
},
"auditConfig": {
"recordExecutions": true,
"includeInputParameters": true,
"provenanceSource": "ACTION"
}
}
关键字段要点
| 字段 | 说明 |
|---|---|
backingLogic |
函数只算决策(transferQty、eta、feasible、reason),不做写操作 |
submissionCriteria[2] |
库存校验写在 Action 里,人 / Automate / Agent 任何调用方都过同一道门 |
edits[1] 的 createObject |
同时创建 TransferOrder 并建立 Link fulfills → shortage |
sideEffects.webhooks[0] |
通知 ERP 生成草稿单(不是正式提交) |
idempotency.dedupKeys |
同一 shortageId 重复提交视为幂等更新 |
三、Automate 多分支编排:缺料调拨路由
{
"apiName": "shortage-reallocation-orchestrator",
"displayName": "缺料自动调拨编排",
"description": "按缺口/关键等级决定调拨策略分支",
"trigger": {
"type": "objectChange",
"objectTypeApiName": "MaterialShortage",
"eventTypes": ["CREATE"],
"filter": {
"type": "and",
"conditions": [
{ "property": "status", "operator": "EQUALS", "value": "DETECTED" },
{ "property": "shortageQty", "operator": "GREATER_THAN", "value": 0 }
]
}
},
"effects": [
{
"type": "logic",
"logicRid": "ri.logic.main.shortage-router",
"input": { "shortage": "$trigger.object" },
"outputVar": "route"
},
{
"type": "action",
"if": "route.decision == 'AUTO_TRANSFER'",
"actionApiName": "allocate-shortage",
"input": {
"shortage": "$trigger.object",
"sourceLocation": "$route.sourceLocation",
"transferQty": "$route.transferQty"
},
"retry": { "maxAttempts": 3, "backoff": "EXPONENTIAL" },
"fallback": {
"type": "action",
"actionApiName": "escalate-shortage",
"input": { "shortage": "$trigger.object", "reason": "自动调拨失败" }
}
},
{
"type": "action",
"if": "route.decision == 'EXPEDITE_PO'",
"actionApiName": "create-expedite-order",
"input": {
"shortage": "$trigger.object",
"qty": "$route.transferQty"
}
},
{
"type": "action",
"if": "route.decision == 'HUMAN_REVIEW'",
"actionApiName": "create-allocation-task",
"input": {
"shortage": "$trigger.object",
"candidates": "$route.candidateSources"
}
},
{
"type": "notification",
"if": "route.decision == 'SUPPRESS'",
"to": ["user:supply-noise-owner"],
"title": "抑制的缺料事件 ${trigger.object.shortageId}"
}
],
"executionConfig": {
"effectOrder": "SEQUENTIAL",
"mode": "PER_OBJECT"
}
}
AIP Logic shortage-router 分支逻辑(Conditionals Block)
Input: shortage
Function: routeShortage(shortage)
├─ Branch 1: shortage.severity == CRITICAL && candidateSources.exists()
│ → decision = AUTO_TRANSFER
│ → sourceLocation = 最近且有库存的仓库
│ → transferQty = min(shortageQty, onHandQty)
│
├─ Branch 2: shortage.material.criticality == 'A' && shortage.severity >= HIGH
│ → decision = EXPEDITE_PO (无可用库存,紧急加单)
│
├─ Branch 3: candidateSources.exists() && shortage.severity <= MEDIUM
│ → decision = AUTO_TRANSFER (低风险自动调拨)
│
├─ Branch 4: 多个候选源冲突 / 跨 region
│ → decision = HUMAN_REVIEW (需采购/生产共同拍板)
│ → candidates = candidateSources
│
└─ Else:
→ decision = SUPPRESS (噪声/已覆盖)
注:上方
if/outputVar是概念层表达;真实 Palantir 中分支由 AIP Logic Conditionals 实现,或拆成多个对象集条件的 Automation(做法 A)。
四、配套 Action ①:confirm-transfer(人工确认调拨,高风险)
调拨单生成后,扣减库存、改生产计划等动作需要人工二次确认。
{
"apiName": "confirm-transfer",
"displayName": "Confirm Transfer Order",
"description": "确认调拨单,触发 ERP 正式扣减与生产计划调整",
"parameters": {
"transferOrder": {
"type": "objectType:TransferOrder",
"required": true
}
},
"submissionCriteria": [
{
"condition": "transferOrder.status == 'DRAFT'",
"message": "只能确认草稿状态的调拨单"
}
],
"edits": [
{
"modifyObject": "transferOrder",
"set": { "status": "CONFIRMED" }
},
{
"modifyObject": "shortage",
"set": { "status": "CONFIRMED" }
}
],
"sideEffects": {
"webhooks": [
{
"name": "commit-erp",
"url": "https://erp.internal/api/transfer-orders/confirm",
"method": "POST"
}
]
},
"governance": {
"requireHumanApprovalIf": "shortage.severity == 'CRITICAL' || transferOrder.qty > 1000",
"autoApproveIf": "shortage.severity <= 'MEDIUM' && transferOrder.qty <= 1000"
}
}
与 allocate-shortage 的分工
| 环节 | Action | 是否需人确认 |
|---|---|---|
| 生成调拨草稿 | allocate-shortage |
否(低风险自动) |
| 确认并提交 ERP | confirm-transfer |
是(高风险必审) |
| 升级/紧急加单 | escalate-shortage |
否(仅状态变更) |
五、配套 Action ②:escalate-shortage(升级,Automate 的 Fallback 调用)
当 allocate-shortage 自动调拨失败时,Automate 的 fallback 会调用此 Action。
{
"apiName": "escalate-shortage",
"displayName": "Escalate Shortage",
"description": "将缺料事件升级到应急队列,通知供应链指挥中心",
"parameters": {
"shortage": {
"type": "objectType:MaterialShortage",
"required": true
},
"reason": {
"type": "string",
"required": false
}
},
"edits": [
{
"modifyObject": "shortage",
"set": { "status": "ESCALATED" }
}
],
"sideEffects": {
"notifications": [
{
"to": ["group:supply-chain-command"],
"title": "缺料升级: ${shortage.shortageId}"
}
]
}
}
六、AIP Agent Tool 治理层
{
"tools": [
{
"type": "ontologicalAction",
"actionApiName": "allocate-shortage",
"displayName": "生成调拨方案",
"governance": {
"autoApproveConditions": [
{
"condition": "shortage.severity <= 'MEDIUM' && transferQty <= 500",
"reason": "小量调拨自动执行"
}
],
"humanInTheLoopConditions": [
{
"condition": "shortage.severity == 'CRITICAL' || transferQty > 500",
"reason": "大额/关键物料需人工确认"
}
]
},
"inputBinding": {
"shortage": {
"source": "conversationEntity",
"entityType": "MaterialShortage"
},
"sourceLocation": {
"source": "functionCall",
"functionRid": "ri.function.main.find-best-source"
},
"transferQty": {
"source": "functionCall",
"functionRid": "ri.function.main.calc-transfer-qty"
}
}
},
{
"type": "ontologicalAction",
"actionApiName": "confirm-transfer",
"displayName": "确认调拨单",
"governance": {
"humanInTheLoopConditions": [
{
"condition": "always",
"reason": "扣减库存/改生产计划必须人审"
}
]
}
}
]
}
inputBinding 来源类型映射
| 参数 | source | 说明 |
|---|---|---|
shortage |
conversationEntity |
从对话上下文提取的 Ontology 实体 |
sourceLocation |
functionCall |
调用 find-best-source 函数算出最优调出方 |
transferQty |
functionCall |
调用 calc-transfer-qty 算调拨数量 |
七、端到端时序
库存跌破安全水位
│
▼
Foundry 监听到新 MaterialShortage 对象(status=DETECTED)
│
▼
Automate: objectsAddedToSet(MaterialShortage.status=DETECTED)
│
▼
AIP Logic: shortage-router 多分支
├─ CRITICAL + 有库存 → AUTO_TRANSFER
├─ A 类料且无库存 → EXPEDITE_PO
├─ 多候选/跨 region → HUMAN_REVIEW
└─ 噪声/已覆盖 → SUPPRESS
│
▼
allocate-shortage Action(Function-backed)
├─ backingLogic 函数算 transferQty / eta / feasible
├─ submissionCriteria 拦截(仅 DETECTED、库存充足)
├─ edits 事务写回 Ontology(shortage.status=ALLOCATED + 创建 TransferOrder DRAFT)
├─ sideEffects:站内通知 + ERP 草稿 Webhook
└─ 高风险 → confirm-transfer 需人工确认
│
▼
(若 allocate-shortage 失败)
→ Automate Effect fallback → escalate-shortage → 通知供应链指挥中心
│
▼
全链路 Action Execution + Lineage 审计
八、供应链场景 vs 告警分派:关键差异
| 维度 | 告警分派(IoT) | 缺料调拨(供应链) |
|---|---|---|
| 核心约束 | 温度阈值、处理组匹配 | 库存可用性、调拨量 ≤ 缺口 |
| 写操作对象 | Alert.priority、Alert.status、Link | TransferOrder 创建、Shortage.status |
| 副作用链路 | 通知/IM | 草稿 → 确认 → ERP 正式扣减(两阶段) |
| 高风险点 | 改设备状态 | 扣减库存、改生产计划 |
| 回退策略 | 转未分派队列 | 调拨失败 → 紧急加单(EXPEDITE_PO)或升级(ESCALATE) |
| 审批阈值 | severity = CRITICAL | severity = CRITICAL 或 qty > 1000 |
| AIP Agent 输入绑定 | group 来自 LLM 推理 | sourceLocation / transferQty 来自 Function 计算 |
九、下一步可展开方向
如需继续深入,可选择以下任一主题:
- Function-backed 算法实现:把
allocate-shortage-fn的”找最优调出方”逻辑写成可运行的 TypeScript/Python 伪代码 - AIP Logic Conditionals 变量设计:完整绘制
shortage-router的变量/路径图,含循环遍历候选仓库的逻辑 - 跨工厂冲突解决:两个工厂同时抢同一仓库库存时的锁机制与优先级仲裁
阅读 —
·
全站 —