第20章 制造与供应链MCP应用
前言
全球化竞争对制造企业提出严峻考验。本章展示如何通过MCP将Claude集成到供应链系统中,实现需求预测、库存优化、采购决策和生产计划的智能自动化,帮助企业降低成本、提升效率。
20.1 案例1:智能供应链管理系统
20.1.1 应用场景
graph TB
A["供应链数据"] --> B["ERP系统"]
A --> C["库存管理"]
A --> D["预测模型"]
A --> E["供应商信息"]
F["Claude供应链助手"] --> F1["需求预测"]
F --> F2["库存优化"]
F --> F3["采购建议"]
F --> F4["供应商评估"]
B --> F
C --> F
D --> F
E --> F
F --> G["采购决策优化"]
F --> H["成本降低"]
F --> I["风险管理"]
20.1.2 供应链核心实现
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
import statistics
class SupplierRating(Enum):
"""供应商评级"""
EXCELLENT = "excellent"
GOOD = "good"
ACCEPTABLE = "acceptable"
POOR = "poor"
class ProcurementStatus(Enum):
"""采购状态"""
PENDING = "pending"
APPROVED = "approved"
ORDERED = "ordered"
SHIPPED = "shipped"
RECEIVED = "received"
@dataclass
class Product:
"""产品"""
product_id: str
name: str
category: str
unit_cost: float
lead_time_days: int
safety_stock: int
@dataclass
class Supplier:
"""供应商"""
supplier_id: str
name: str
location: str
products: List[str] = field(default_factory=list)
lead_time_days: int = 7
reliability_score: float = 0.95 # 0-1
cost_index: float = 1.0 # 相对成本
available_capacity: int = 10000
@dataclass
class InventoryItem:
"""库存项目"""
item_id: str
product_id: str
quantity: int
reorder_point: int
max_quantity: int
last_restocked: datetime
warehouse_location: str
@dataclass
class Forecast:
"""需求预测"""
forecast_id: str
product_id: str
period: str # "weekly", "monthly"
predicted_demand: int
confidence: float
base_date: datetime
class SupplyChainOptimizer:
"""供应链优化器"""
def __init__(self):
self.products: Dict[str, Product] = {}
self.suppliers: Dict[str, Supplier] = {}
self.inventory: Dict[str, InventoryItem] = {}
self.forecasts: Dict[str, Forecast] = {}
self.historical_demand: Dict[str, List[int]] = {}
async def forecast_demand(self, product_id: str,
periods: int = 12) -> Dict:
"""
需求预测
Args:
product_id: 产品ID
periods: 预测周期数
Returns:
需求预测
"""
product = self.products.get(product_id)
if not product:
return {"error": "Product not found"}
# 获取历史数据
historical = self.historical_demand.get(product_id, [100] * 12)
# 简单的移动平均预测
if len(historical) >= 3:
trend = statistics.mean(historical[-3:])
variance = statistics.stdev(historical[-3:]) if len(historical[-3:]) > 1 else 0
else:
trend = statistics.mean(historical)
variance = 0
# 生成预测
forecasts = []
for i in range(periods):
# 考虑季节性因素(简化版)
seasonal_factor = 1.0 + 0.1 * ((i % 4) - 2) / 2
predicted = int(trend * seasonal_factor)
forecasts.append({
"period": i + 1,
"predicted_demand": predicted,
"confidence": max(0.6, 1 - variance / max(trend, 1) * 0.1)
})
return {
"product_id": product_id,
"product_name": product.name,
"forecast_period_months": periods,
"forecasts": forecasts,
"average_monthly_demand": statistics.mean(historical),
"trend": "increasing" if forecasts[-1]["predicted_demand"] > historical[-1] else "decreasing",
"recommendation": "根据预测情况提前采购"
}
async def optimize_inventory(self, product_id: str) -> Dict:
"""
库存优化
Args:
product_id: 产品ID
Returns:
库存优化建议
"""
product = self.products.get(product_id)
if not product:
return {"error": "Product not found"}
# 查找库存
inventory_items = [inv for inv in self.inventory.values()
if inv.product_id == product_id]
if not inventory_items:
return {"error": "No inventory found for product"}
total_quantity = sum(item.quantity for item in inventory_items)
# 获取预测
forecast = next((f for f in self.forecasts.values()
if f.product_id == product_id), None)
monthly_demand = forecast.predicted_demand if forecast else 100
# 计算安全库存(简化版)
lead_time = product.lead_time_days / 30
monthly_variance = monthly_demand * 0.2
safety_stock = int(2.33 * monthly_variance * (lead_time ** 0.5))
# 计算经济订单量(EOQ)
holding_cost_per_unit = product.unit_cost * 0.25
ordering_cost = 100
eoq = int((2 * monthly_demand * 12 * ordering_cost / holding_cost_per_unit) ** 0.5)
# 库存状态
status = "optimal"
if total_quantity < safety_stock:
status = "critical"
elif total_quantity < monthly_demand:
status = "warning"
elif total_quantity > monthly_demand * 6:
status = "overstocked"
return {
"product_id": product_id,
"product_name": product.name,
"current_inventory": total_quantity,
"inventory_analysis": {
"monthly_demand": monthly_demand,
"safety_stock": safety_stock,
"economic_order_quantity": eoq,
"inventory_status": status,
"holding_cost_monthly": total_quantity * holding_cost_per_unit / 12
},
"recommendations": [
f"安全库存应保持在{safety_stock}个单位",
f"经济订单量为{eoq}个单位",
"建议根据季节性调整采购计划"
] if status in ["critical", "warning"] else [
"库存水平适中",
f"可考虑优化为{int(eoq * 1.2)}个单位降低成本"
]
}
async def recommend_suppliers(self, product_id: str,
required_quantity: int) -> Dict:
"""
推荐供应商
Args:
product_id: 产品ID
required_quantity: 需求数量
Returns:
供应商推荐
"""
product = self.products.get(product_id)
if not product:
return {"error": "Product not found"}
# 查找提供该产品的供应商
eligible_suppliers = [
sup for sup in self.suppliers.values()
if product_id in sup.products and sup.available_capacity >= required_quantity
]
if not eligible_suppliers:
return {"error": "No suitable suppliers found"}
# 评分供应商
supplier_scores = []
for supplier in eligible_suppliers:
# 综合评分(可靠性40% + 成本30% + 交期20% + 产能10%)
score = (
supplier.reliability_score * 0.4 +
(2 - supplier.cost_index) * 0.3 +
(1 - supplier.lead_time_days / 30) * 0.2 +
(supplier.available_capacity / (required_quantity * 2)) * 0.1
)
supplier_scores.append({
"supplier_id": supplier.supplier_id,
"name": supplier.name,
"location": supplier.location,
"score": score,
"reliability": supplier.reliability_score,
"lead_time_days": supplier.lead_time_days,
"cost_per_unit": product.unit_cost * supplier.cost_index,
"total_cost": product.unit_cost * supplier.cost_index * required_quantity,
"available_capacity": supplier.available_capacity
})
supplier_scores.sort(key=lambda x: x["score"], reverse=True)
return {
"product_id": product_id,
"required_quantity": required_quantity,
"recommended_suppliers": supplier_scores[:3],
"best_supplier": supplier_scores[0] if supplier_scores else None,
"procurement_strategy": "可考虑分单采购以降低风险"
}
async def analyze_procurement(self, product_id: str,
quantity: int,
supplier_id: str) -> Dict:
"""
采购分析
Args:
product_id: 产品ID
quantity: 数量
supplier_id: 供应商ID
Returns:
采购分析结果
"""
product = self.products.get(product_id)
supplier = self.suppliers.get(supplier_id)
if not product or not supplier:
return {"error": "Product or supplier not found"}
unit_cost = product.unit_cost * supplier.cost_index
total_cost = unit_cost * quantity
# 交货时间
delivery_date = datetime.now() + timedelta(days=supplier.lead_time_days)
# 风险评估
risks = []
if supplier.reliability_score < 0.9:
risks.append("供应商可靠性一般,建议备货")
if supplier.lead_time_days > 14:
risks.append("交期较长,需提前规划")
if supplier.available_capacity < quantity * 1.5:
risks.append("供应商产能紧张,可能存在风险")
return {
"procurement_plan": {
"product_id": product_id,
"product_name": product.name,
"quantity": quantity,
"supplier_id": supplier_id,
"supplier_name": supplier.name,
"unit_cost": unit_cost,
"total_cost": total_cost,
"estimated_delivery": delivery_date.isoformat()
},
"supplier_assessment": {
"reliability_score": supplier.reliability_score,
"lead_time_days": supplier.lead_time_days,
"cost_competitiveness": "competitive" if supplier.cost_index < 1.1 else "fair"
},
"risk_assessment": {
"risk_level": "high" if len(risks) > 2 else "medium" if risks else "low",
"identified_risks": risks,
"mitigation_strategies": [
"确认交期承诺",
"建立备选供应商",
"定期沟通进展"
]
}
}
class SupplyChainMCPServer:
"""供应链MCP服务器"""
def __init__(self, optimizer: SupplyChainOptimizer):
self.optimizer = optimizer
def get_tools(self) -> List[Dict]:
"""定义工具"""
return [
{
"name": "forecast_demand",
"description": "需求预测",
"inputSchema": {
"type": "object",
"properties": {
"product_id": {"type": "string"},
"periods": {"type": "integer"}
},
"required": ["product_id"]
}
},
{
"name": "optimize_inventory",
"description": "库存优化",
"inputSchema": {
"type": "object",
"properties": {
"product_id": {"type": "string"}
},
"required": ["product_id"]
}
},
{
"name": "recommend_suppliers",
"description": "推荐供应商",
"inputSchema": {
"type": "object",
"properties": {
"product_id": {"type": "string"},
"quantity": {"type": "integer"}
},
"required": ["product_id", "quantity"]
}
},
{
"name": "analyze_procurement",
"description": "采购分析",
"inputSchema": {
"type": "object",
"properties": {
"product_id": {"type": "string"},
"quantity": {"type": "integer"},
"supplier_id": {"type": "string"}
},
"required": ["product_id", "quantity", "supplier_id"]
}
}
]
async def call_tool(self, tool_name: str, arguments: Dict) -> str:
"""调用工具"""
import json
try:
if tool_name == "forecast_demand":
result = await self.optimizer.forecast_demand(
arguments["product_id"],
arguments.get("periods", 12)
)
elif tool_name == "optimize_inventory":
result = await self.optimizer.optimize_inventory(
arguments["product_id"]
)
elif tool_name == "recommend_suppliers":
result = await self.optimizer.recommend_suppliers(
arguments["product_id"],
arguments["quantity"]
)
elif tool_name == "analyze_procurement":
result = await self.optimizer.analyze_procurement(
arguments["product_id"],
arguments["quantity"],
arguments["supplier_id"]
)
else:
return json.dumps({"error": f"Unknown tool: {tool_name}"})
return json.dumps(result, ensure_ascii=False, indent=2)
except Exception as e:
return json.dumps({"error": str(e)})
20.2 案例2:生产计划与质量控制系统
20.2.1 生产调度与质量管理
@dataclass
class ProductionOrder:
"""生产订单"""
order_id: str
product_id: str
quantity: int
due_date: datetime
priority: str # "low", "normal", "high", "urgent"
status: str = "pending"
@dataclass
class QualityRecord:
"""质量记录"""
record_id: str
order_id: str
inspection_date: datetime
defect_count: int
defect_rate: float
issues: List[str] = field(default_factory=list)
class ProductionScheduler:
"""生产调度器"""
def __init__(self):
self.orders: Dict[str, ProductionOrder] = {}
self.quality_records: Dict[str, QualityRecord] = {}
self.equipment_capacity: Dict[str, float] = {} # 设备ID -> 产能
self.equipment_utilization: Dict[str, float] = {} # 设备使用率
async def plan_production(self, orders: List[Dict]) -> Dict:
"""
规划生产
Args:
orders: 订单列表
Returns:
生产计划
"""
# 按优先级排序
priority_map = {"urgent": 0, "high": 1, "normal": 2, "low": 3}
sorted_orders = sorted(
orders,
key=lambda x: (priority_map.get(x.get("priority", "normal"), 2),
x.get("due_date", datetime.now()))
)
# 分配产能
schedule = []
for order in sorted_orders:
# 计算生产时间
batch_size = order.get("quantity", 100)
production_time = batch_size / 50 # 简化:每小时生产50个
schedule.append({
"order_id": order.get("order_id"),
"product_id": order.get("product_id"),
"quantity": batch_size,
"priority": order.get("priority", "normal"),
"estimated_production_hours": production_time,
"due_date": order.get("due_date"),
"status": "scheduled"
})
return {
"total_orders": len(schedule),
"production_schedule": schedule,
"total_production_hours": sum(s["estimated_production_hours"] for s in schedule),
"bottleneck_warning": "设备产能可能不足" if sum(s["estimated_production_hours"] for s in schedule) > 200 else "无"
}
async def analyze_quality(self, order_id: str) -> Dict:
"""
分析质量
Args:
order_id: 订单ID
Returns:
质量分析结果
"""
# 查找该订单的质量记录
records = [r for r in self.quality_records.values()
if r.order_id == order_id]
if not records:
return {"error": "No quality records found"}
avg_defect_rate = statistics.mean([r.defect_rate for r in records])
total_defects = sum([r.defect_count for r in records])
# 识别常见问题
all_issues = []
for r in records:
all_issues.extend(r.issues)
issue_counts = {}
for issue in all_issues:
issue_counts[issue] = issue_counts.get(issue, 0) + 1
top_issues = sorted(issue_counts.items(), key=lambda x: x[1], reverse=True)[:3]
return {
"order_id": order_id,
"quality_analysis": {
"total_defects": total_defects,
"average_defect_rate": f"{avg_defect_rate*100:.2f}%",
"quality_grade": "A" if avg_defect_rate < 0.02 else "B" if avg_defect_rate < 0.05 else "C",
"top_issues": [issue for issue, count in top_issues],
"inspection_count": len(records)
},
"improvement_recommendations": [
f"重点关注{top_issues[0][0]}" if top_issues else "无重大问题",
"建议增加工序检查" if avg_defect_rate > 0.05 else "质量稳定",
"定期设备维护可降低缺陷" if avg_defect_rate > 0.02 else "继续保持"
]
}
async def optimize_equipment_utilization(self) -> Dict:
"""
优化设备利用率
Returns:
利用率优化建议
"""
utilizations = list(self.equipment_utilization.values())
if not utilizations:
return {"error": "No equipment data available"}
avg_utilization = statistics.mean(utilizations)
# 识别低效设备
low_utilization = [
(eq_id, util) for eq_id, util in self.equipment_utilization.items()
if util < 0.6
]
high_utilization = [
(eq_id, util) for eq_id, util in self.equipment_utilization.items()
if util > 0.85
]
return {
"overall_utilization": f"{avg_utilization*100:.1f}%",
"equipment_status": {
"total_equipment": len(self.equipment_utilization),
"high_utilization_count": len(high_utilization),
"low_utilization_count": len(low_utilization)
},
"optimization_recommendations": [
f"平衡产能分配,目标{avg_utilization*100:.0f}%以上",
f"提高{len(low_utilization)}台低效设备利用率" if low_utilization else "设备利用率均衡",
"考虑重新安排工序流程" if len(high_utilization) > len(low_utilization) else "产能分配适当"
]
}
class ProductionMCPServer:
"""生产MCP服务器"""
def __init__(self, scheduler: ProductionScheduler):
self.scheduler = scheduler
def get_tools(self) -> List[Dict]:
"""定义工具"""
return [
{
"name": "plan_production",
"description": "规划生产",
"inputSchema": {
"type": "object",
"properties": {
"orders": {
"type": "array",
"items": {"type": "object"}
}
},
"required": ["orders"]
}
},
{
"name": "analyze_quality",
"description": "分析质量",
"inputSchema": {
"type": "object",
"properties": {
"order_id": {"type": "string"}
},
"required": ["order_id"]
}
},
{
"name": "optimize_equipment",
"description": "优化设备利用率",
"inputSchema": {
"type": "object",
"properties": {}
}
}
]
async def call_tool(self, tool_name: str, arguments: Dict) -> str:
"""调用工具"""
import json
try:
if tool_name == "plan_production":
result = await self.scheduler.plan_production(
arguments["orders"]
)
elif tool_name == "analyze_quality":
result = await self.scheduler.analyze_quality(
arguments["order_id"]
)
elif tool_name == "optimize_equipment":
result = await self.scheduler.optimize_equipment_utilization()
else:
return json.dumps({"error": f"Unknown tool: {tool_name}"})
return json.dumps(result, ensure_ascii=False, indent=2)
except Exception as e:
return json.dumps({"error": str(e)})
本章总结
| 关键点 | 说明 |
|---|---|
| 需求预测 | 移动平均、季节性分析 |
| 库存优化 | 安全库存、经济订单量计算 |
| 供应商评估 | 多维度评分和推荐 |
| 采购决策 | 成本、风险、时间综合分析 |
| 生产排程 | 优先级调度、产能分配 |
| 质量分析 | 缺陷追踪、问题识别 |
| 产能优化 | 设备利用率分析 |
常见问题
Q1: 如何实现准确的需求预测? A: 历史数据分析、季节性模型、机器学习算法、定期调整。
Q2: 库存成本如何计算? A: 持有成本 + 订购成本 + 缺货成本 + 进货成本。
Q3: 如何选择最优供应商? A: 多维度评分模型:可靠性、成本、交期、产能。
Q4: 如何处理生产瓶颈? A: 产能分析、工序优化、外包或增加设备。
Q5: 质量问题如何快速定位? A: 数据分析、过程控制、根本原因分析、持续改进。
下一章预告:第21章将讲述行业对标与最佳实践!