第20章 制造与供应链MCP应用

36 阅读8分钟

第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章将讲述行业对标与最佳实践