mcpField
E
electronics-supply-chain

electronics-supply-chain

github.com/kishorkukrejaその他8483 回インストール3 週間前に更新
リポジトリ

electronics-supply-chain について

電子機器製造と半導体運用向けのサプライチェーン管理スキルです。部品調達・割り当て・リードタイム、SMT組立、余剰在庫、新製品導入の分析枠組みに加え、供給リスクとレポート作成の指針を扱います。

主な機能

  1. 01製造モデルとサプライチェーン構造の把握
  2. 02部品調達、割り当て、リードタイムの管理
  3. 03SMTラインバランスの計画
  4. 04余剰在庫とライフサイクルリスクの特定
  5. 05供給不足や中断への対応策の評価
  6. 06サプライチェーンのリスク・実績レポート作成

活用シーン

  1. 01重要部品の不足と割り当て状況の分析
  2. 02調達、代替供給元、安全在庫の計画
  3. 03過剰・製造終了部品の在庫評価
  4. 04新製品導入と供給リスクの追跡

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kishorkukreja/awesome-supply-chain --skill electronics-supply-chain

インストール後、Claude Code で/electronics-supply-chainを入力して読み込まれたか確認します。

詳細

電子機器のサプライチェーン

電子機器の製造サプライチェーン管理と半導体事業のエキスパートです。複雑なグローバルサプライネットワークの最適化、コンポーネントの調達と割り当ての管理、効率的な組み立て作業の実施、電子機器製造特有の課題への対応を支援します。

初期評価

電子機器のサプライチェーンを最適化する前に、次の点を把握してください。

  1. 製造モデル

    • OEM、ODM、EMS、または社内製造ですか?
    • 製品の種類は何ですか?(家電、産業機器、自動車、医療機器)
    • 生産量はどの程度ですか?(大量生産、中量生産、試作)
    • 製造方式は何ですか?(見込み生産、受注生産、受注構成生産)
    • バリューチェーンのどの部分に位置しますか?(コンポーネント、モジュール、完成品)
  2. コンポーネントのプロファイル

    • 半導体への依存度はどの程度ですか?(IC、プロセッサ、メモリ、アナログ)
    • 受動部品の使用量はどの程度ですか?(抵抗器、コンデンサ、コネクタ)
    • リードタイムの長いコンポーネントはありますか?(FPGA、カスタム ASIC、ディスプレイ)
    • 単一調達品ですか、それとも複数調達品ですか?
    • 割り当て状況はどうなっていますか?(自由市場、割り当て対象、重要割り当て対象)
  3. サプライチェーンの構造

    • 地理的な展開状況はどうなっていますか?(アジア中心、多角化、ニアショア)
    • サプライヤーと CM は各ティアに何社ありますか?
    • 直接調達と販売代理店経由の調達のどちらですか?
    • 委託在庫モデルとターンキー方式のどちらですか?
    • VMI(ベンダー管理在庫)プログラムを利用していますか?
  4. 現在の課題

    • コンポーネントの入手可能性や割り当てに関する問題はありますか?
    • リードタイムの変動はありますか?
    • 過剰・陳腐化(E&O)在庫はありますか?
    • 製品ライフサイクル管理に課題はありますか?
    • コスト削減目標はありますか?

電子機器サプライチェーンのフレームワーク

バリューチェーンの構造

電子機器製造エコシステム:

Raw Materials (Silicon, Metals, Plastics)
  ↓
Component Manufacturers (Semiconductors, Passives, Connectors)
  ↓
Distributors / Brokers
  ↓
EMS/ODM (Contract Manufacturers)
  ↓
OEM (Brand Owners)
  ↓
Distribution / Retail
  ↓
End Customers

ティア別の主要企業:

  • コンポーネントメーカー:Intel、Samsung、TSMC、TI、Analog Devices、Infineon
  • 販売代理店:Arrow、Avnet、Digi-Key、Mouser、Future Electronics
  • EMS/ODM:Foxconn、Flex、Jabil、Pegatron、Wistron、Quanta
  • OEM:Apple、Dell、HP、Cisco、Huawei、Lenovo

コンポーネントの調達と割り当て管理

割り当て戦略
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

class ComponentAllocationManager:
    """
    Manage component allocation in constrained supply environment
    """

    def __init__(self, components_df):
        """
        Initialize allocation manager

        Parameters:
        - components_df: component data with lead times, allocation status
        """
        self.components = components_df
        self.allocation_tiers = {
            'strategic': 1,
            'preferred': 2,
            'standard': 3,
            'new': 4
        }

    def assess_allocation_risk(self, bom_df, production_plan):
        """
        Assess component allocation risk for production plan

        Parameters:
        - bom_df: Bill of Materials
        - production_plan: planned production volumes by period

        Returns:
        - risk assessment by component
        """

        risk_assessment = []

        for idx, component in bom_df.iterrows():
            part_number = component['part_number']
            qty_per_unit = component['quantity_per_unit']

            # Get component details
            comp_info = self.components[
                self.components['part_number'] == part_number
            ].iloc[0] if len(self.components[
                self.components['part_number'] == part_number
            ]) > 0 else None

            if comp_info is None:
                continue

            # Calculate requirements
            total_requirement = production_plan['units'].sum() * qty_per_unit

            # Allocation status
            allocation_status = comp_info.get('allocation_status', 'open')
            lead_time_weeks = comp_info.get('lead_time_weeks', 12)
            available_inventory = comp_info.get('available_inventory', 0)
            allocated_qty = comp_info.get('allocated_qty', 0)

            # Calculate risk score
            risk_score = self._calculate_risk_score(
                allocation_status,
                lead_time_weeks,
                total_requirement,
                available_inventory + allocated_qty
            )

            risk_assessment.append({
                'part_number': part_number,
                'description': comp_info.get('description', ''),
                'manufacturer': comp_info.get('manufacturer', ''),
                'total_requirement': total_requirement,
                'available_inventory': available_inventory,
                'allocated_qty': allocated_qty,
                'shortfall': max(0, total_requirement - available_inventory - allocated_qty),
                'allocation_status': allocation_status,
                'lead_time_weeks': lead_time_weeks,
                'risk_score': risk_score,
                'risk_category': self._categorize_risk(risk_score)
            })

        return pd.DataFrame(risk_assessment).sort_values('risk_score', ascending=False)

    def _calculate_risk_score(self, allocation_status, lead_time, requirement, supply):
        """Calculate component risk score (0-100)"""

        # Allocation multiplier
        allocation_multiplier = {
            'open': 1.0,
            'watch': 2.0,
            'allocated': 4.0,
            'critical': 8.0,
            'unobtainable': 10.0
        }.get(allocation_status, 1.0)

        # Lead time factor (longer = higher risk)
        lt_factor = min(lead_time / 52, 2.0)  # Cap at 2x

        # Supply coverage (weeks)
        coverage = (supply / requirement) if requirement > 0 else 999
        coverage_factor = max(0, 2 - coverage)  # Higher if coverage < 2x

        risk_score = (allocation_multiplier * 20 +
                     lt_factor * 20 +
                     coverage_factor * 30)

        return min(100, risk_score)

    def _categorize_risk(self, risk_score):
        """Categorize risk level"""
        if risk_score >= 70:
            return 'critical'
        elif risk_score >= 50:
            return 'high'
        elif risk_score >= 30:
            return 'medium'
        else:
            return 'low'

    def optimize_allocation_strategy(self, risk_assessment, supplier_relationships):
        """
        Generate allocation strategy recommendations

        Parameters:
        - risk_assessment: output from assess_allocation_risk
        - supplier_relationships: customer tier with suppliers

        Returns:
        - recommended actions by component
        """

        recommendations = []

        critical_parts = risk_assessment[risk_assessment['risk_category'] == 'critical']

        for idx, part in critical_parts.iterrows():
            actions = []

            # Determine customer tier
            customer_tier = supplier_relationships.get(
                part['manufacturer'], 'standard'
            )

            # Strategy based on risk and relationship
            if part['allocation_status'] == 'critical':
                actions.append('escalate_to_executive_level')
                actions.append('request_emergency_allocation')
                actions.append('explore_authorized_distributors')

            if part['lead_time_weeks'] > 26:
                actions.append('increase_forecast_horizon')
                actions.append('commit_to_longer_term_contract')

            if part['shortfall'] > 0:
                actions.append('identify_alternative_components')
                actions.append('engage_design_engineering_for_redesign')
                actions.append('search_broker_market')

            if customer_tier == 'new':
                actions.append('establish_strategic_relationship')
                actions.append('increase_volumes_to_gain_priority')

            recommendations.append({
                'part_number': part['part_number'],
                'manufacturer': part['manufacturer'],
                'risk_category': part['risk_category'],
                'customer_tier': customer_tier,
                'recommended_actions': actions,
                'priority': 'immediate' if part['risk_score'] > 80 else 'urgent'
            })

        return pd.DataFrame(recommendations)


# Example usage
components_data = pd.DataFrame({
    'part_number': ['IC_001', 'IC_002', 'CAP_001', 'RES_001'],
    'description': ['MCU STM32', 'Power IC', 'MLCC 10uF', 'Resistor 10K'],
    'manufacturer': ['STMicro', 'TI', 'Murata', 'Yageo'],
    'allocation_status': ['allocated', 'critical', 'open', 'open'],
    'lead_time_weeks': [32, 52, 8, 4],
    'available_inventory': [5000, 0, 100000, 500000],
    'allocated_qty': [10000, 5000, 0, 0]
})

bom = pd.DataFrame({
    'part_number': ['IC_001', 'IC_002', 'CAP_001', 'RES_001'],
    'quantity_per_unit': [1, 1, 12, 45]
})

production_plan = pd.DataFrame({
    'month': ['2025-02', '2025-03', '2025-04'],
    'units': [10000, 12000, 15000]
})

manager = ComponentAllocationManager(components_data)
risk_assessment = manager.assess_allocation_risk(bom, production_plan)

print("Component Risk Assessment:")
print(risk_assessment[['part_number', 'allocation_status', 'shortfall',
                       'risk_score', 'risk_category']])

PCB 組み立ての最適化

SMT ラインのラインバランシング
class SMTLineOptimizer:
    """
    Optimize Surface Mount Technology (SMT) line operations
    """

    def __init__(self, line_config):
        """
        Initialize SMT line optimizer

        Parameters:
        - line_config: SMT line configuration (machines, feeders, speed)
        """
        self.line_config = line_config

    def calculate_line_capacity(self, board_config):
        """
        Calculate SMT line capacity for given board

        Parameters:
        - board_config: PCB specifications and component placement

        Returns:
        - theoretical capacity (boards/hour)
        """

        # Component placement time
        num_components = board_config['component_count']
        avg_placement_time_sec = board_config.get('avg_placement_time', 0.3)

        # Machine parameters
        num_placement_heads = self.line_config.get('placement_heads', 8)
        machine_efficiency = self.line_config.get('efficiency', 0.85)

        # Calculate placement time per board
        placement_time = (num_components * avg_placement_time_sec) / num_placement_heads

        # Add process times
        screen_print_time = 15  # seconds
        reflow_time = 180  # seconds
        inspection_time = 30  # seconds
        board_handling_time = 10  # seconds

        total_cycle_time = (placement_time + screen_print_time +
                           reflow_time + inspection_time + board_handling_time)

        # Apply efficiency factor
        effective_cycle_time = total_cycle_time / machine_efficiency

        # Capacity (boards per hour)
        capacity_per_hour = 3600 / effective_cycle_time

        return {
            'capacity_boards_per_hour': capacity_per_hour,
            'cycle_time_seconds': effective_cycle_time,
            'placement_time': placement_time,
            'bottleneck': self._identify_bottleneck(
                placement_time, screen_print_time, reflow_time
            )
        }

    def _identify_bottleneck(self, placement_time, print_time, reflow_time):
        """Identify process bottleneck"""
        times = {
            'placement': placement_time,
            'screen_print': print_time,
            'reflow': reflow_time
        }
        return max(times, key=times.get)

    def optimize_feeder_setup(self, bom_df, feeder_slots=120):
        """
        Optimize feeder setup for component loading

        Parameters:
        - bom_df: Bill of Materials with component usage
        - feeder_slots: available feeder slots on machine

        Returns:
        - feeder assignment plan
        """

        # Sort components by usage frequency
        bom_sorted = bom_df.sort_values('quantity_per_board', ascending=False)

        # Assign to feeders (most used components get priority positions)
        feeder_assignments = []

        for idx, component in bom_sorted.iterrows():
            if idx < feeder_slots:
                # Optimal position: center positions for high-usage parts
                if idx < 20:
                    position = 60 + (idx - 10)  # Center positions
                else:
                    position = idx

                feeder_assignments.append({
                    'part_number': component['part_number'],
                    'feeder_position': position,
                    'quantity_per_board': component['quantity_per_board'],
                    'priority': 'high' if idx < 20 else 'medium'
                })
            else:
                # Bulk feeders or manual loading required
                feeder_assignments.append({
                    'part_number': component['part_number'],
                    'feeder_position': None,
                    'quantity_per_board': component['quantity_per_board'],
                    'priority': 'low',
                    'loading_method': 'manual_or_bulk'
                })

        return pd.DataFrame(feeder_assignments)

    def calculate_changeover_time(self, current_bom, next_bom, feeder_change_time=60):
        """
        Calculate line changeover time between products

        Parameters:
        - current_bom: current product BOM
        - next_bom: next product BOM
        - feeder_change_time: seconds per feeder change

        Returns:
        - estimated changeover time
        """

        # Components unique to each product
        current_parts = set(current_bom['part_number'])
        next_parts = set(next_bom['part_number'])

        # Components to remove and add
        parts_to_remove = current_parts - next_parts
        parts_to_add = next_parts - current_parts

        total_changes = len(parts_to_remove) + len(parts_to_add)

        # Changeover time
        feeder_changeover = total_changes * feeder_change_time
        program_change = 300  # 5 minutes for program change
        first_article_inspection = 600  # 10 minutes

        total_changeover = feeder_changeover + program_change + first_article_inspection

        return {
            'total_changeover_minutes': total_changeover / 60,
            'feeder_changes': total_changes,
            'parts_to_remove': len(parts_to_remove),
            'parts_to_add': len(parts_to_add),
            'common_parts': len(current_parts & next_parts)
        }


# Example
line_config = {
    'placement_heads': 8,
    'efficiency': 0.85,
    'feeder_slots': 120
}

board_config = {
    'component_count': 450,
    'avg_placement_time': 0.3,
    'board_size': '300x200mm'
}

optimizer = SMTLineOptimizer(line_config)
capacity = optimizer.calculate_line_capacity(board_config)

print(f"Line Capacity: {capacity['capacity_boards_per_hour']:.1f} boards/hour")
print(f"Cycle Time: {capacity['cycle_time_seconds']:.1f} seconds")
print(f"Bottleneck: {capacity['bottleneck']}")

リードタイム管理

動的なリードタイム計画
class LeadTimeManager:
    """
    Manage component lead times and procurement planning
    """

    def __init__(self, components_df):
        self.components = components_df

    def calculate_procurement_dates(self, production_schedule, bom_df):
        """
        Calculate when to order components based on lead times

        Parameters:
        - production_schedule: planned production dates
        - bom_df: Bill of Materials with quantities

        Returns:
        - component order schedule
        """

        procurement_schedule = []

        for idx, production in production_schedule.iterrows():
            production_date = production['production_date']
            product_id = production['product_id']
            quantity = production['quantity']

            # Get BOM for this product
            product_bom = bom_df[bom_df['product_id'] == product_id]

            for _, component in product_bom.iterrows():
                part_number = component['part_number']
                qty_per_unit = component['quantity_per_unit']
                total_needed = quantity * qty_per_unit

                # Get component lead time
                comp_info = self.components[
                    self.components['part_number'] == part_number
                ].iloc[0]

                lead_time_weeks = comp_info['lead_time_weeks']
                safety_buffer_weeks = comp_info.get('safety_buffer_weeks', 2)

                # Calculate order date
                total_lead_time = timedelta(weeks=lead_time_weeks + safety_buffer_weeks)
                order_date = production_date - total_lead_time

                procurement_schedule.append({
                    'part_number': part_number,
                    'manufacturer': comp_info['manufacturer'],
                    'order_date': order_date,
                    'need_by_date': production_date,
                    'quantity': total_needed,
                    'lead_time_weeks': lead_time_weeks,
                    'production_order': product_id,
                    'days_until_order': (order_date - datetime.now()).days
                })

        return pd.DataFrame(procurement_schedule).sort_values('order_date')

    def simulate_lead_time_variability(self, component, order_quantity,
                                      num_simulations=1000):
        """
        Monte Carlo simulation of lead time variability

        Parameters:
        - component: component details with lead time distribution
        - order_quantity: quantity to order
        - num_simulations: number of Monte Carlo runs

        Returns:
        - lead time distribution and risk metrics
        """

        # Lead time distribution parameters
        lt_mean = component['lead_time_weeks']
        lt_std = component.get('lead_time_std', lt_mean * 0.2)

        # Simulate lead times
        simulated_lts = np.random.normal(lt_mean, lt_std, num_simulations)
        simulated_lts = np.maximum(simulated_lts, lt_mean * 0.5)  # Floor

        # Calculate percentiles
        p50 = np.percentile(simulated_lts, 50)
        p80 = np.percentile(simulated_lts, 80)
        p95 = np.percentile(simulated_lts, 95)

        return {
            'mean_lt_weeks': lt_mean,
            'p50_lt_weeks': p50,
            'p80_lt_weeks': p80,
            'p95_lt_weeks': p95,
            'recommended_buffer_weeks': p95 - lt_mean,
            'variability_coefficient': lt_std / lt_mean
        }


# Example
components_data = pd.DataFrame({
    'part_number': ['IC_001', 'IC_002'],
    'manufacturer': ['STMicro', 'TI'],
    'lead_time_weeks': [32, 52],
    'lead_time_std': [6, 12],
    'safety_buffer_weeks': [4, 8]
})

production_schedule = pd.DataFrame({
    'production_date': pd.to_datetime(['2025-06-01', '2025-07-01']),
    'product_id': ['PROD_A', 'PROD_A'],
    'quantity': [5000, 6000]
})

bom = pd.DataFrame({
    'product_id': ['PROD_A', 'PROD_A'],
    'part_number': ['IC_001', 'IC_002'],
    'quantity_per_unit': [1, 2]
})

lt_manager = LeadTimeManager(components_data)
procurement = lt_manager.calculate_procurement_dates(production_schedule, bom)

print("Procurement Schedule:")
print(procurement[['part_number', 'order_date', 'need_by_date',
                   'quantity', 'days_until_order']])

過剰・陳腐化(E&O)管理

class EOInventoryManager:
    """
    Manage excess and obsolete inventory in electronics
    """

    def __init__(self, inventory_df, bom_df, forecast_df):
        self.inventory = inventory_df
        self.bom = bom_df
        self.forecast = forecast_df

    def identify_excess_obsolete(self, time_horizon_months=12):
        """
        Identify excess and obsolete inventory

        Parameters:
        - time_horizon_months: planning horizon for demand

        Returns:
        - E&O classification by component
        """

        eo_analysis = []

        for idx, inv in self.inventory.iterrows():
            part_number = inv['part_number']
            on_hand_qty = inv['on_hand_quantity']
            unit_cost = inv['unit_cost']

            # Calculate future demand
            future_demand = self._calculate_future_demand(
                part_number, time_horizon_months
            )

            # Calculate excess
            excess_qty = max(0, on_hand_qty - future_demand)
            excess_value = excess_qty * unit_cost

            # Determine obsolescence risk
            lifecycle_status = inv.get('lifecycle_status', 'active')
            last_usage_date = inv.get('last_usage_date', datetime.now())
            months_since_use = (datetime.now() - last_usage_date).days / 30

            # Classification
            if lifecycle_status == 'discontinued' or months_since_use > 24:
                classification = 'obsolete'
            elif excess_qty > future_demand * 0.5 or months_since_use > 12:
                classification = 'excess'
            elif excess_qty > future_demand * 0.2:
                classification = 'watch'
            else:
                classification = 'normal'

            eo_analysis.append({
                'part_number': part_number,
                'on_hand_qty': on_hand_qty,
                'future_demand_12m': future_demand,
                'excess_qty': excess_qty,
                'excess_value': excess_value,
                'unit_cost': unit_cost,
                'lifecycle_status': lifecycle_status,
                'months_since_use': months_since_use,
                'classification': classification,
                'recommended_action': self._recommend_action(
                    classification, excess_qty, excess_value
                )
            })

        return pd.DataFrame(eo_analysis)

    def _calculate_future_demand(self, part_number, months):
        """Calculate future demand for component"""

        # Get products using this part
        products_using = self.bom[self.bom['part_number'] == part_number]

        total_demand = 0
        for _, product in products_using.iterrows():
            product_id = product['product_id']
            qty_per_unit = product['quantity_per_unit']

            # Get forecast for product
            product_forecast = self.forecast[
                self.forecast['product_id'] == product_id
            ]['forecast_units'].sum() if len(
                self.forecast[self.forecast['product_id'] == product_id]
            ) > 0 else 0

            total_demand += product_forecast * qty_per_unit

        return total_demand

    def _recommend_action(self, classification, excess_qty, excess_value):
        """Recommend disposition action"""

        if classification == 'obsolete':
            if excess_value > 50000:
                return 'scrap_with_recovery_value_analysis'
            else:
                return 'scrap_dispose'
        elif classification == 'excess':
            if excess_value > 100000:
                return 'sell_to_brokers_or_redistribute'
            elif excess_value > 10000:
                return 'return_to_supplier_negotiation'
            else:
                return 'consume_in_production_if_possible'
        elif classification == 'watch':
            return 'monitor_and_reduce_future_buys'
        else:
            return 'no_action_required'

    def calculate_eo_provision(self, eo_analysis):
        """
        Calculate accounting provision for E&O inventory

        Returns:
        - provision amount by category
        """

        provision_rates = {
            'normal': 0.0,
            'watch': 0.25,
            'excess': 0.50,
            'obsolete': 1.0
        }

        eo_analysis['provision_rate'] = eo_analysis['classification'].map(provision_rates)
        eo_analysis['provision_amount'] = (
            eo_analysis['excess_value'] * eo_analysis['provision_rate']
        )

        total_provision = eo_analysis['provision_amount'].sum()

        summary = eo_analysis.groupby('classification').agg({
            'excess_qty': 'sum',
            'excess_value': 'sum',
            'provision_amount': 'sum'
        })

        return {
            'total_provision': total_provision,
            'summary_by_classification': summary
        }


# Example would require full inventory, BOM, and forecast data

製品ライフサイクル管理

新製品導入(NPI)の計画
class NPIManager:
    """
    Manage New Product Introduction process for electronics
    """

    def __init__(self):
        self.npi_phases = [
            'concept',
            'design',
            'prototype',
            'pilot',
            'ramp',
            'mass_production'
        ]

    def create_npi_timeline(self, product_spec, target_launch_date):
        """
        Create NPI timeline with key milestones

        Parameters:
        - product_spec: product specifications
        - target_launch_date: desired production start

        Returns:
        - detailed timeline with activities
        """

        # Standard phase durations (weeks)
        phase_durations = {
            'concept': 4,
            'design': 12,
            'prototype': 8,
            'pilot': 6,
            'ramp': 8,
            'mass_production': 0  # ongoing
        }

        # Adjust for product complexity
        complexity_factor = product_spec.get('complexity_factor', 1.0)

        timeline = []
        current_date = target_launch_date

        # Work backwards from launch
        for phase in reversed(self.npi_phases[:-1]):
            duration_weeks = phase_durations[phase] * complexity_factor
            phase_start = current_date - timedelta(weeks=duration_weeks)

            timeline.append({
                'phase': phase,
                'start_date': phase_start,
                'end_date': current_date,
                'duration_weeks': duration_weeks,
                'key_activities': self._get_phase_activities(phase),
                'deliverables': self._get_phase_deliverables(phase)
            })

            current_date = phase_start

        # Reverse to chronological order
        timeline.reverse()

        return pd.DataFrame(timeline)

    def _get_phase_activities(self, phase):
        """Get key activities for NPI phase"""

        activities = {
            'concept': ['Market research', 'Feature definition', 'Cost target'],
            'design': ['Schematic design', 'PCB layout', 'Component selection',
                      'DFM review'],
            'prototype': ['Prototype build', 'Functional testing', 'Design validation'],
            'pilot': ['Pilot run 100-500 units', 'Process validation',
                     'Supplier qualification'],
            'ramp': ['Ramp to volume', 'Yield optimization', 'Cost reduction']
        }

        return activities.get(phase, [])

    def _get_phase_deliverables(self, phase):
        """Get deliverables for NPI phase"""

        deliverables = {
            'concept': ['Product requirements document', 'Cost model'],
            'design': ['Final schematic', 'Gerber files', 'BOM', 'AVL'],
            'prototype': ['Working prototypes', 'Test reports', 'Design changes'],
            'pilot': ['Pilot build report', 'Qualified suppliers', 'Manufacturing docs'],
            'ramp': ['Volume production', 'Quality metrics', 'Cost targets met']
        }

        return deliverables.get(phase, [])

    def assess_component_risk_npi(self, bom_df, components_df):
        """
        Assess component risks for NPI

        Focus on:
        - Long lead time parts
        - Sole source components
        - Lifecycle risks
        - Allocation risks
        """

        risks = []

        for idx, component in bom_df.iterrows():
            part_number = component['part_number']

            # Get component details
            comp_info = components_df[
                components_df['part_number'] == part_number
            ].iloc[0]

            # Risk factors
            risk_factors = []
            risk_score = 0

            # Lead time risk
            if comp_info['lead_time_weeks'] > 26:
                risk_factors.append('long_lead_time_>6months')
                risk_score += 30

            # Sole source risk
            if comp_info.get('alternate_sources', 0) == 0:
                risk_factors.append('sole_source')
                risk_score += 25

            # Lifecycle risk
            if comp_info.get('lifecycle_status') == 'nrnd':
                risk_factors.append('not_recommended_for_new_design')
                risk_score += 40

            # Allocation risk
            if comp_info.get('allocation_status') in ['allocated', 'critical']:
                risk_factors.append('allocated_part')
                risk_score += 35

            risks.append({
                'part_number': part_number,
                'manufacturer': comp_info['manufacturer'],
                'risk_score': risk_score,
                'risk_factors': risk_factors,
                'mitigation_required': risk_score > 50
            })

        return pd.DataFrame(risks).sort_values('risk_score', ascending=False)

ツールとライブラリ

Python ライブラリ

サプライチェーンの最適化:

  • pulp:割り当て最適化のための線形計画法
  • pyomo:高度な最適化モデリング
  • networkx:サプライネットワーク分析

データ分析:

  • pandas:データ操作と BOM 管理
  • numpy:数値計算
  • scipy:統計分析

可視化:

  • matplotlib、seaborn:チャートとグラフ
  • plotly:インタラクティブなダッシュボード
  • networkx + matplotlib:サプライネットワークの可視化
商用ソフトウェア

ERP/MRP システム:

  • SAP S/4HANA:エンタープライズリソースプランニング
  • Oracle ERP Cloud:製造業向けクラウド ERP
  • Microsoft Dynamics 365:サプライチェーン管理
  • IFS Applications:製造とサプライチェーン

コンポーネント管理:

  • Arena PLM:製品ライフサイクル管理
  • SiliconExpert:コンポーネントのライフサイクルとコンプライアンス
  • Z2Data:サプライチェーンインテリジェンス
  • Supplyframe:コンポーネントの調達とインテリジェンス

受託製造:

  • Aligni:電子機器の在庫と BOM の管理
  • PLM システム:PTC Windchill、Siemens Teamcenter、Dassault ENOVIA

サプライヤーとの連携:

  • E2open:複数ティアにわたるサプライチェーンの可視化
  • Kinaxis RapidResponse:サプライチェーン計画
  • Blue Yonder:サプライチェーンスイート

よくある課題と解決策

課題:部品の割り当てと不足

問題:

  • 重要部品(半導体、ディスプレイ、コネクター)が割り当て制
  • 必要数量を確保できない
  • リードタイムが長い(26〜52週間)
  • スポット市場価格が通常の5〜10倍

解決策:

  • 需要の集約:予測を集約して数量を増やします
  • 戦略的な関係構築:サプライヤーから優先顧客として認められるようにします
  • 長期契約:複数年契約で生産能力を確保します
  • 入手しやすさを考慮した設計:設計段階で入手しやすい部品を使用します
  • 正規代理店:正規代理店との関係を構築します
  • 代替調達:設計段階で第二供給元を認定します
  • バッファ在庫:リードタイムの長い部品を戦略的に備蓄します
  • 割り当て状況の追跡:割り当て状況をリアルタイムで監視します
課題:製品の急速な陳腐化

問題:

  • 部品のライフサイクルが製品のライフサイクルより短い
  • 最終購入の判断が難しい
  • 生産終了(EOL)部品の管理
  • 再設計コストが高い

解決策:

  • ライフサイクルの監視:部品のライフサイクル状況を継続的に追跡します
  • 予防的な陳腐化管理:3〜5年先を見越します
  • 最終購入数量の算出:残存需要を正確にモデル化します
  • 長寿命を考慮した設計:ライフサイクルの長い部品を選定します
  • 部品の標準化:固有部品の種類を減らします
  • エミュレーション/ドロップイン置換:互換性のある代替品を特定します
  • エスクロー在庫:長期にわたる保守需要に備えて戦略的な在庫を確保します
課題:複数のEMSプロバイダーの管理

問題:

  • 世界各地の3〜5社の受託製造業者との調整
  • 品質とプロセスにばらつきがある
  • 知的財産の保護に関する懸念
  • 生産量の移行が難しい

解決策:

  • プロセスの標準化:共通の品質基準を導入します
  • ゴールデンユニット方式:一貫性を保つための基準となる製造品を用意します
  • 定期監査:製造拠点を四半期ごとに監査します
  • 複数拠点への設備配置:柔軟性を確保するため、複数拠点に設備を維持します
  • 知的財産の管理:NDA、BOMへのアクセス制限、設計の分割を行います
  • 透明性の高いコスト管理:オープンブック方式の価格モデルを採用します
  • 生産量の分散:各社の能力に基づいて戦略的に割り当てます
課題:偽造部品のリスク

問題:

  • サプライチェーンに偽造ICが混入する(特にグレーマーケット)
  • 品質と信頼性に問題がある
  • ブランドと安全性にリスクがある
  • 検出が難しい

解決策:

  • 正規の調達先のみを利用:正規代理店から購入します
  • サプライヤーの認定:調達先を厳格に審査します
  • 試験プロトコル:受け入れ検査とX線分析を実施します
  • トレーサビリティ:完全な管理履歴の文書を保持します
  • 偽造防止技術:認証チップ/ラベルを使用します
  • サプライヤー監査:サプライヤー施設を定期的に検査します
  • 市場の監視:グレーマーケットの動向を追跡します
課題:グローバルサプライチェーンの混乱

問題:

  • 地政学的リスク(中国と台湾の緊張)
  • 自然災害(地震、津波)
  • パンデミックの影響
  • 港湾の混雑と物流の遅延

解決策:

  • 地理的な分散:複数の地域で製造します
  • ニアショアリング:一部の生産を需要地に近い場所へ移します
  • 安全在庫戦略:重要部品の在庫を増やします
  • 複数供給元からの調達:複数のサプライヤーと地域を確保します
  • サプライチェーンの可視化:リアルタイム追跡ツールを活用します
  • シナリオ計画:混乱のシナリオをモデル化します
  • 航空貨物の輸送能力:緊急時に備えて輸送能力を確保します

出力形式

電子機器サプライチェーンレポート

エグゼクティブサマリー:

  • 製品ポートフォリオの概要
  • 重要部品の状況
  • サプライチェーンのリスクレベル
  • 主な取り組みと投資

部品リスクダッシュボード:

部品番号メーカー割り当て状況リードタイム在庫不足数リスクレベル
IC_STM32F4STMicro割り当て済み32週間10,00015,000重大
PMIC_TPS65TI重大52週間025,000重大
LCD_7inchBOE要注意16週間8,0000中
MLCC_10uFMurata制限なし8週間50,0000低

サプライチェーンのパフォーマンス:

指標現在値目標状況
納期遵守率87%95%⚠ 黄色
部品PPM120<100⚠ 黄色
E&O在庫$2.8M<$2M⚠ 黄色
在庫回転率6.28.0⚠ 黄色
割り当て対象部品45<20⚠ 黄色

NPIの状況:

製品フェーズ開始日発売日状況重大なリスク
PROD_A試作2025-01-152025-04-01順調ICの割り当て
PROD_B設計2025-02-012025-08-01遅延ディスプレイのEOL
PROD_C量産立ち上げ2024-12-012025-03-01順調なし

E&O在庫:

分類部品数数量金額評価引当金
廃番23445,000$890K$890K
過剰456128,000$1.8M$900K
要注意678234,000$2.1M$525K
合計1,368407,000$4.79M$2.32M

アクション項目:

  1. STM32の割り当て問題を経営層にエスカレーションする - サプライチェーン担当VPと連携する
  2. EOLディスプレイの最終購入を完了する - $1.2Mの購入を承認する
  3. 代替PMICサプライヤーを認定する - 2025年第2四半期までに完了する
  4. 部品ライフサイクル監視ツールを導入する - SiliconExpertを評価する
  5. E&O在庫を<$2Mまで削減する - ブローカーによる販売と返品プログラムを実施する

質問事項

さらに詳しい情報が必要な場合:

  1. どのような種類の電子機器製品ですか?(民生用、産業用、自動車用、医療用)
  2. 製造モデルは何ですか?(内製、EMS/ODM、ハイブリッド)
  3. 問題を引き起こしている重要部品は何ですか?
  4. 現在の割り当て状況はどうなっていますか?
  5. リードタイムの長い部品のリードタイムはどのくらいですか?
  6. 現在のE&O在庫はどのくらいですか?
  7. 製品ライフサイクルの段階はどこですか?(NPI、成熟期、ライフサイクル終了)
  8. 製造拠点は地理的にどこにありますか?

関連スキル

  • production-scheduling:製造スケジューリング向け
  • capacity-planning:生産能力管理向け
  • inventory-optimization:部品在庫方針向け
  • supplier-selection:EMSおよび部品サプライヤーの選定向け
  • supplier-risk-management:供給継続性の確保向け
  • quality-management:製造品質およびPPM追跡向け
  • demand-forecasting:部品需要計画向け
  • procurement-optimization:部品購買の最適化向け
  • network-design:グローバルサプライネットワークの最適化向け
  • risk-mitigation:サプライチェーンリスク管理向け

コメント