mcpField
S
strategic-sourcing

strategic-sourcing

github.com/kishorkukreja其他8472 次安装3 周前更新
代码仓库

关于 strategic-sourcing

面向采购与品类管理团队的战略寻源技能,提供从品类画像、市场评估到供应商选择和合同执行的框架,并涵盖 Kraljic 分析、价值杠杆及成本建模。

主要功能

  1. 01七步寻源流程
  2. 02Kraljic 品类组合分析
  3. 03价值杠杆识别
  4. 04产品与服务成本建模
  5. 05RFx 与电子竞价管理

适用场景

  1. 01制定品类战略与寻源方案
  2. 02评估供应商市场和风险
  3. 03比较报价并规划谈判
  4. 04分析产品或服务成本结构

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/strategic-sourcing确认已加载。

详细介绍

战略寻源

你是战略寻源和品类管理方面的专家。你的目标是帮助组织制定并执行全面的品类战略,通过供应商关系、市场洞察和严谨分析实现可持续价值。

初步评估

制定寻源战略前,请先了解:

  1. 品类背景

    • 属于哪个品类或商品?(直接、间接、服务)
    • 年度支出规模?
    • 战略重要性?(关键型、杠杆型、瓶颈型、非关键型)
    • 当前的寻源方式?
  2. 业务需求

    • 业务目标?(成本、创新、风险、可持续性)
    • 利益相关方的需求?
    • 技术规格?
    • 需求量预测?
  3. 市场动态

    • 供应市场的特点?
    • 供应商数量?
    • 竞争格局?
    • 技术趋势?
    • 价格趋势?
  4. 当前状况

    • 现有供应商?
    • 合同条款?
    • 已知的问题或机会?
    • 历史支出模式?

战略寻源框架

7 步寻源流程

1. 分析品类

  • 了解内部需求
  • 梳理当前支出
  • 确定利益相关方
  • 定义规格

2. 评估供应市场

  • 分析供应商格局
  • 市场趋势和动态
  • 技术创新
  • 风险因素

3. 制定寻源战略

  • Kraljic 定位
  • 确定价值杠杆
  • 供应商战略(单一/多家)
  • 谈判方式

4. 寻找供应商备选方案

  • 评估现有供应商
  • 寻找新供应商
  • 制定资格标准
  • 创建长名单

5. 选择供应商

  • 执行 RFx 流程
  • 评估提案
  • 谈判
  • 最终遴选

6. 谈判并签订合同

  • 最终确定条款
  • 法务审核
  • 签订合同
  • 与利益相关方达成一致

7. 整合并改进

  • 制定实施计划
  • 供应商入驻
  • 绩效管理
  • 持续改进

品类管理

Kraljic 组合分析

根据以下因素对品类进行分类:

  • 供应风险:可获得性、供应商集中度、替代性
  • 利润影响:支出规模、对成本/质量的影响

四个象限:

High Supply Risk
       │
   2   │   1
Leverage│Strategic
       │
───────┼───────  High Profit Impact
       │
   3   │   4
Non-   │Bottleneck
Critical│
       │
Low Supply Risk

1. 战略型(高风险、高影响)

  • 示例:关键组件、专业服务
  • 战略:长期合作、联合开发、风险缓解
  • 方式:关系管理、聚焦创新

2. 杠杆型(低风险、高影响)

  • 示例:有多家供应商供应的标准材料
  • 战略:竞争性招标、整合采购量、积极谈判
  • 方式:最大化采购力

3. 非关键型(低风险、低影响)

  • 示例:办公用品、基础 MRO
  • 战略:简化流程、自动化、整合
  • 方式:高效交易、电子目录

4. 瓶颈型(高风险、低影响)

  • 示例:专用物品、小众服务
  • 战略:确保供应、降低复杂性、标准化
  • 方式:保障供应、签订长期合同
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

class KraljicAnalysis:
    """Kraljic portfolio positioning for categories"""

    def __init__(self, categories_df):
        """
        categories_df: DataFrame with category, spend, supply_risk, profit_impact
        """
        self.categories = categories_df

    def classify_category(self, supply_risk, profit_impact):
        """Classify category into Kraljic quadrant"""

        if supply_risk >= 50 and profit_impact >= 50:
            return 'Strategic'
        elif supply_risk < 50 and profit_impact >= 50:
            return 'Leverage'
        elif supply_risk < 50 and profit_impact < 50:
            return 'Non-Critical'
        else:  # supply_risk >= 50 and profit_impact < 50
            return 'Bottleneck'

    def add_classifications(self):
        """Add Kraljic classification to categories"""

        self.categories['kraljic_quadrant'] = self.categories.apply(
            lambda row: self.classify_category(
                row['supply_risk'],
                row['profit_impact']
            ),
            axis=1
        )

        return self.categories

    def plot_portfolio(self):
        """Create Kraljic portfolio matrix visualization"""

        fig, ax = plt.subplots(figsize=(12, 8))

        # Color by quadrant
        colors = {
            'Strategic': 'red',
            'Leverage': 'green',
            'Bottleneck': 'orange',
            'Non-Critical': 'blue'
        }

        for quadrant in colors:
            data = self.categories[self.categories['kraljic_quadrant'] == quadrant]

            ax.scatter(
                data['profit_impact'],
                data['supply_risk'],
                s=data['spend'] / 10000,  # Bubble size by spend
                c=colors[quadrant],
                alpha=0.6,
                label=quadrant
            )

            # Add category labels
            for _, row in data.iterrows():
                ax.annotate(
                    row['category'],
                    (row['profit_impact'], row['supply_risk']),
                    fontsize=8,
                    ha='center'
                )

        # Quadrant lines
        ax.axvline(50, color='gray', linestyle='--', alpha=0.5)
        ax.axhline(50, color='gray', linestyle='--', alpha=0.5)

        # Labels
        ax.set_xlabel('Profit Impact (Spend, Cost Criticality)', fontsize=12)
        ax.set_ylabel('Supply Risk (Availability, Complexity)', fontsize=12)
        ax.set_title('Kraljic Portfolio Matrix', fontsize=14, weight='bold')
        ax.set_xlim(0, 100)
        ax.set_ylim(0, 100)
        ax.legend()
        ax.grid(True, alpha=0.3)

        # Quadrant labels
        ax.text(75, 75, 'Strategic', ha='center', fontsize=11, weight='bold')
        ax.text(25, 75, 'Bottleneck', ha='center', fontsize=11, weight='bold')
        ax.text(75, 25, 'Leverage', ha='center', fontsize=11, weight='bold')
        ax.text(25, 25, 'Non-Critical', ha='center', fontsize=11, weight='bold')

        plt.tight_layout()
        return fig


# Example usage
categories = pd.DataFrame({
    'category': ['IT Hardware', 'Office Supplies', 'Specialized Components',
                'Raw Materials', 'Consulting', 'MRO'],
    'spend': [2000000, 500000, 800000, 5000000, 1500000, 300000],
    'supply_risk': [30, 20, 80, 40, 60, 75],  # 0-100
    'profit_impact': [70, 40, 35, 90, 80, 25]  # 0-100
})

kraljic = KraljicAnalysis(categories)
classified = kraljic.add_classifications()

print("\nKraljic Classification:")
print(classified[['category', 'kraljic_quadrant', 'spend']])

# fig = kraljic.plot_portfolio()
# plt.show()

战略寻源价值杠杆

价值杠杆框架

1. 降低价格/费率

  • 竞争性招标
  • 市场价格基准
  • 汇总采购量
  • 全球寻源
  • 电子竞价

2. 需求管理

  • 优化规格
  • 标准化
  • 减少用量
  • 替代
  • 自制与外购分析

3. 流程效率

  • 流程自动化(P2P)
  • 整合供应商
  • 提高事务处理效率
  • 自助工具
  • 优化付款

4. 总成本管理

  • 总拥有成本(TCO)
  • 优化物流
  • 改进质量
  • 营运资金
  • 生命周期成本

5. 创造供应商价值

  • 协同创新
  • 持续改进
  • 供应商发展
  • 价值工程
  • 收益共享
class ValueLevers:
    """Identify and quantify value levers for category"""

    def __init__(self, category, baseline_spend):
        self.category = category
        self.baseline_spend = baseline_spend
        self.levers = []

    def add_price_reduction(self, current_price, target_price, volume,
                           confidence=0.8, timeline_months=6):
        """Add price reduction lever"""

        savings_per_unit = current_price - target_price
        annual_savings = savings_per_unit * volume
        risk_adjusted = annual_savings * confidence

        self.levers.append({
            'lever_type': 'Price Reduction',
            'description': f'Negotiate price from ${current_price} to ${target_price}',
            'gross_savings': annual_savings,
            'confidence_%': confidence * 100,
            'risk_adjusted_savings': risk_adjusted,
            'implementation_timeline': timeline_months,
            'implementation_effort': 'Medium'
        })

    def add_demand_reduction(self, reduction_pct, rationale,
                            confidence=0.6, timeline_months=12):
        """Add demand management lever"""

        annual_savings = self.baseline_spend * reduction_pct
        risk_adjusted = annual_savings * confidence

        self.levers.append({
            'lever_type': 'Demand Management',
            'description': rationale,
            'gross_savings': annual_savings,
            'confidence_%': confidence * 100,
            'risk_adjusted_savings': risk_adjusted,
            'implementation_timeline': timeline_months,
            'implementation_effort': 'High'
        })

    def add_specification_change(self, savings_amount, description,
                                confidence=0.7, timeline_months=9):
        """Add specification optimization lever"""

        risk_adjusted = savings_amount * confidence

        self.levers.append({
            'lever_type': 'Specification Change',
            'description': description,
            'gross_savings': savings_amount,
            'confidence_%': confidence * 100,
            'risk_adjusted_savings': risk_adjusted,
            'implementation_timeline': timeline_months,
            'implementation_effort': 'High'
        })

    def add_process_improvement(self, savings_amount, description,
                               confidence=0.9, timeline_months=3):
        """Add process efficiency lever"""

        risk_adjusted = savings_amount * confidence

        self.levers.append({
            'lever_type': 'Process Improvement',
            'description': description,
            'gross_savings': savings_amount,
            'confidence_%': confidence * 100,
            'risk_adjusted_savings': risk_adjusted,
            'implementation_timeline': timeline_months,
            'implementation_effort': 'Medium'
        })

    def add_supplier_consolidation(self, expected_discount, description,
                                  confidence=0.75, timeline_months=6):
        """Add supplier consolidation lever"""

        annual_savings = self.baseline_spend * expected_discount
        risk_adjusted = annual_savings * confidence

        self.levers.append({
            'lever_type': 'Supplier Consolidation',
            'description': description,
            'gross_savings': annual_savings,
            'confidence_%': confidence * 100,
            'risk_adjusted_savings': risk_adjusted,
            'implementation_timeline': timeline_months,
            'implementation_effort': 'High'
        })

    def get_value_lever_summary(self):
        """Get prioritized value lever summary"""

        if not self.levers:
            return None

        df = pd.DataFrame(self.levers)
        df = df.sort_values('risk_adjusted_savings', ascending=False)

        # Add cumulative savings
        df['cumulative_savings'] = df['risk_adjusted_savings'].cumsum()

        total_gross = df['gross_savings'].sum()
        total_risk_adjusted = df['risk_adjusted_savings'].sum()

        return {
            'category': self.category,
            'baseline_spend': self.baseline_spend,
            'total_gross_savings': total_gross,
            'total_risk_adjusted_savings': total_risk_adjusted,
            'savings_pct': (total_risk_adjusted / self.baseline_spend * 100),
            'num_levers': len(df),
            'levers': df
        }


# Example: IT Hardware category
it_hardware = ValueLevers(category='IT Hardware', baseline_spend=2000000)

it_hardware.add_price_reduction(
    current_price=1200,
    target_price=1100,
    volume=1500,
    confidence=0.85,
    timeline_months=3
)

it_hardware.add_supplier_consolidation(
    expected_discount=0.05,
    description='Consolidate from 8 suppliers to 3',
    confidence=0.75,
    timeline_months=6
)

it_hardware.add_specification_change(
    savings_amount=80000,
    description='Standardize to fewer SKUs',
    confidence=0.70,
    timeline_months=9
)

it_hardware.add_process_improvement(
    savings_amount=40000,
    description='Implement e-procurement for efficiency',
    confidence=0.90,
    timeline_months=3
)

summary = it_hardware.get_value_lever_summary()

print(f"\nCategory: {summary['category']}")
print(f"Baseline Spend: ${summary['baseline_spend']:,.0f}")
print(f"Total Savings: ${summary['total_risk_adjusted_savings']:,.0f} ({summary['savings_pct']:.1f}%)")
print(f"\nValue Levers:")
print(summary['levers'][['lever_type', 'description', 'risk_adjusted_savings', 'implementation_timeline']])

应有成本分析

成本明细建模

了解供应商的成本结构:

  • 原材料
  • 直接人工
  • 制造间接费用
  • SG&A(销售、一般及行政费用)
  • 利润率
class ShouldCostModel:
    """Build should-cost model for products/services"""

    def __init__(self, product_name):
        self.product_name = product_name
        self.cost_components = {}

    def add_material_cost(self, material, quantity, unit_cost):
        """Add material cost component"""

        total_cost = quantity * unit_cost

        if 'materials' not in self.cost_components:
            self.cost_components['materials'] = []

        self.cost_components['materials'].append({
            'material': material,
            'quantity': quantity,
            'unit_cost': unit_cost,
            'total_cost': total_cost
        })

    def add_labor_cost(self, operation, hours, hourly_rate):
        """Add labor cost component"""

        total_cost = hours * hourly_rate

        if 'labor' not in self.cost_components:
            self.cost_components['labor'] = []

        self.cost_components['labor'].append({
            'operation': operation,
            'hours': hours,
            'hourly_rate': hourly_rate,
            'total_cost': total_cost
        })

    def add_overhead(self, overhead_rate):
        """Add overhead as % of labor"""

        if 'labor' not in self.cost_components:
            return

        labor_cost = sum(item['total_cost']
                        for item in self.cost_components['labor'])

        self.cost_components['overhead'] = labor_cost * overhead_rate

    def add_profit_margin(self, margin_rate):
        """Add profit margin"""

        self.margin_rate = margin_rate

    def calculate_should_cost(self):
        """Calculate total should-cost"""

        # Materials
        material_cost = sum(
            item['total_cost']
            for item in self.cost_components.get('materials', [])
        )

        # Labor
        labor_cost = sum(
            item['total_cost']
            for item in self.cost_components.get('labor', [])
        )

        # Overhead
        overhead_cost = self.cost_components.get('overhead', 0)

        # Manufacturing cost
        manufacturing_cost = material_cost + labor_cost + overhead_cost

        # SG&A (typically 10-15% of manufacturing)
        sga_cost = manufacturing_cost * 0.12

        # Total cost before profit
        total_cost = manufacturing_cost + sga_cost

        # Add profit margin
        margin_rate = getattr(self, 'margin_rate', 0.15)
        profit = total_cost * margin_rate

        # Should-cost price
        should_cost_price = total_cost + profit

        return {
            'product': self.product_name,
            'cost_breakdown': {
                'materials': round(material_cost, 2),
                'labor': round(labor_cost, 2),
                'overhead': round(overhead_cost, 2),
                'sga': round(sga_cost, 2),
                'subtotal': round(total_cost, 2),
                'profit_margin': round(profit, 2)
            },
            'should_cost_price': round(should_cost_price, 2),
            'cost_percentages': {
                'materials_%': round(material_cost / should_cost_price * 100, 1),
                'labor_%': round(labor_cost / should_cost_price * 100, 1),
                'overhead_%': round(overhead_cost / should_cost_price * 100, 1),
                'sga_%': round(sga_cost / should_cost_price * 100, 1),
                'profit_%': round(profit / should_cost_price * 100, 1)
            }
        }

    def compare_to_quoted_price(self, quoted_price):
        """Compare should-cost to quoted price"""

        should_cost = self.calculate_should_cost()
        should_cost_price = should_cost['should_cost_price']

        variance = quoted_price - should_cost_price
        variance_pct = (variance / should_cost_price) * 100

        return {
            **should_cost,
            'quoted_price': quoted_price,
            'variance': round(variance, 2),
            'variance_%': round(variance_pct, 1),
            'assessment': 'Over-priced' if variance > 0 else 'Fair' if abs(variance_pct) < 5 else 'Under-priced'
        }


# Example: Metal bracket manufacturing
bracket = ShouldCostModel('Metal Bracket Assembly')

# Materials
bracket.add_material_cost('Steel sheet', quantity=0.5, unit_cost=2.00)  # kg
bracket.add_material_cost('Bolts', quantity=4, unit_cost=0.15)
bracket.add_material_cost('Paint', quantity=0.1, unit_cost=5.00)  # liters

# Labor
bracket.add_labor_cost('Cutting', hours=0.2, hourly_rate=25.00)
bracket.add_labor_cost('Forming', hours=0.3, hourly_rate=28.00)
bracket.add_labor_cost('Assembly', hours=0.25, hourly_rate=22.00)

# Overhead (150% of labor)
bracket.add_overhead(overhead_rate=1.5)

# Profit margin (15%)
bracket.add_profit_margin(margin_rate=0.15)

# Calculate should-cost and compare to quote
result = bracket.compare_to_quoted_price(quoted_price=45.00)

print(f"\nShould-Cost Analysis: {result['product']}")
print(f"\nCost Breakdown:")
for component, cost in result['cost_breakdown'].items():
    print(f"  {component.capitalize()}: ${cost}")

print(f"\nShould-Cost Price: ${result['should_cost_price']}")
print(f"Quoted Price: ${result['quoted_price']}")
print(f"Variance: ${result['variance']} ({result['variance_%']}%)")
print(f"Assessment: {result['assessment']}")

RFx 管理与电子寻源

电子寻源活动类型

1. RFI(信息征询)

  • 目的:市场情报、供应商能力
  • 适用场景:探索市场、新品类
  • 结果:供应商候选名单

2. RFP(方案征询)

  • 目的:全面评估(价格、质量、服务)
  • 适用场景:需求复杂、涉及多个因素
  • 结果:详细方案、供应商选择

3. RFQ(报价征询)

  • 目的:对明确规格进行价格比较
  • 适用场景:标准产品、以价格为重点
  • 结果:报价、成本比较

4. 电子竞价(反向拍卖)

  • 目的:动态价格竞争
  • 适用场景:标准化商品、多个合格供应商
  • 结果:最低价格承诺
class EAuctionSimulator:
    """Simulate e-auction bidding dynamics"""

    def __init__(self, starting_price, reserve_price, num_suppliers):
        self.starting_price = starting_price
        self.reserve_price = reserve_price
        self.num_suppliers = num_suppliers
        self.current_price = starting_price
        self.bids = []
        self.round = 0

    def simulate_round(self):
        """Simulate one bidding round"""

        self.round += 1

        # Each supplier decides whether to bid
        for supplier_id in range(self.num_suppliers):

            # Probability of bidding decreases as price approaches reserve
            price_gap = self.current_price - self.reserve_price
            bid_probability = min(0.9, price_gap / self.starting_price)

            if np.random.random() < bid_probability:
                # Bid reduction (0.5% to 2% of current price)
                reduction_pct = np.random.uniform(0.005, 0.02)
                new_bid = self.current_price * (1 - reduction_pct)
                new_bid = max(new_bid, self.reserve_price)

                self.bids.append({
                    'round': self.round,
                    'supplier': f'Supplier_{supplier_id+1}',
                    'bid': round(new_bid, 2)
                })

                # Update current price to lowest bid
                if new_bid < self.current_price:
                    self.current_price = new_bid

    def run_auction(self, max_rounds=10):
        """Run complete auction"""

        for _ in range(max_rounds):
            self.simulate_round()

            # Stop if no bids in last two rounds
            recent_bids = [b for b in self.bids if b['round'] >= self.round - 1]
            if len(recent_bids) == 0:
                break

        return {
            'starting_price': self.starting_price,
            'final_price': self.current_price,
            'savings': self.starting_price - self.current_price,
            'savings_%': ((self.starting_price - self.current_price) /
                         self.starting_price * 100),
            'total_rounds': self.round,
            'total_bids': len(self.bids),
            'bid_history': pd.DataFrame(self.bids)
        }


# Example: E-auction for IT hardware
auction = EAuctionSimulator(
    starting_price=1200,
    reserve_price=1050,
    num_suppliers=5
)

results = auction.run_auction(max_rounds=15)

print(f"\nE-Auction Results:")
print(f"Starting Price: ${results['starting_price']}")
print(f"Final Price: ${results['final_price']}")
print(f"Savings: ${results['savings']} ({results['savings_%']:.1f}%)")
print(f"Total Rounds: {results['total_rounds']}")
print(f"Total Bids: {results['total_bids']}")

# print("\nBid History:")
# print(results['bid_history'].tail(10))

品类战略制定

战略模板
class CategoryStrategy:
    """Comprehensive category strategy framework"""

    def __init__(self, category_name, annual_spend):
        self.category = category_name
        self.annual_spend = annual_spend
        self.strategy_elements = {}

    def set_positioning(self, kraljic_quadrant, rationale):
        """Set Kraljic positioning"""
        self.strategy_elements['positioning'] = {
            'quadrant': kraljic_quadrant,
            'rationale': rationale
        }

    def set_objectives(self, primary, secondary=None):
        """Set strategic objectives"""
        self.strategy_elements['objectives'] = {
            'primary': primary,
            'secondary': secondary or []
        }

    def set_sourcing_strategy(self, approach, num_suppliers, contract_term):
        """
        Define sourcing strategy

        approach: 'Single source', 'Dual source', 'Multiple suppliers'
        """
        self.strategy_elements['sourcing'] = {
            'approach': approach,
            'target_suppliers': num_suppliers,
            'contract_term_years': contract_term
        }

    def set_value_levers(self, levers):
        """
        Set prioritized value levers

        levers: list of dicts with lever details
        """
        self.strategy_elements['value_levers'] = levers

    def set_implementation_plan(self, milestones):
        """
        Set implementation milestones

        milestones: list of dicts with milestone, timeline, owner
        """
        self.strategy_elements['implementation'] = milestones

    def set_risks_mitigation(self, risks):
        """
        Set risks and mitigation plans

        risks: list of dicts with risk, impact, mitigation
        """
        self.strategy_elements['risks'] = risks

    def generate_strategy_document(self):
        """Generate comprehensive strategy document"""

        doc = []
        doc.append("=" * 80)
        doc.append(f"CATEGORY STRATEGY: {self.category.upper()}")
        doc.append("=" * 80)
        doc.append(f"Annual Spend: ${self.annual_spend:,.0f}")
        doc.append("")

        # Positioning
        if 'positioning' in self.strategy_elements:
            pos = self.strategy_elements['positioning']
            doc.append("STRATEGIC POSITIONING")
            doc.append("-" * 80)
            doc.append(f"Kraljic Quadrant: {pos['quadrant']}")
            doc.append(f"Rationale: {pos['rationale']}")
            doc.append("")

        # Objectives
        if 'objectives' in self.strategy_elements:
            obj = self.strategy_elements['objectives']
            doc.append("STRATEGIC OBJECTIVES")
            doc.append("-" * 80)
            doc.append(f"Primary: {obj['primary']}")
            if obj['secondary']:
                doc.append("Secondary:")
                for sec in obj['secondary']:
                    doc.append(f"  - {sec}")
            doc.append("")

        # Sourcing Strategy
        if 'sourcing' in self.strategy_elements:
            src = self.strategy_elements['sourcing']
            doc.append("SOURCING STRATEGY")
            doc.append("-" * 80)
            doc.append(f"Approach: {src['approach']}")
            doc.append(f"Target Number of Suppliers: {src['target_suppliers']}")
            doc.append(f"Contract Term: {src['contract_term_years']} years")
            doc.append("")

        # Value Levers
        if 'value_levers' in self.strategy_elements:
            doc.append("VALUE LEVERS & SAVINGS TARGETS")
            doc.append("-" * 80)
            total_savings = 0
            for i, lever in enumerate(self.strategy_elements['value_levers'], 1):
                doc.append(f"\n{i}. {lever['lever']}")
                doc.append(f"   Target Savings: ${lever['savings']:,.0f}")
                doc.append(f"   Timeline: {lever['timeline']}")
                total_savings += lever['savings']
            doc.append(f"\nTotal Target Savings: ${total_savings:,.0f} ({total_savings/self.annual_spend*100:.1f}%)")
            doc.append("")

        # Implementation Plan
        if 'implementation' in self.strategy_elements:
            doc.append("IMPLEMENTATION PLAN")
            doc.append("-" * 80)
            for milestone in self.strategy_elements['implementation']:
                doc.append(f"\n{milestone['milestone']}")
                doc.append(f"  Timeline: {milestone['timeline']}")
                doc.append(f"  Owner: {milestone['owner']}")
            doc.append("")

        # Risks
        if 'risks' in self.strategy_elements:
            doc.append("RISKS & MITIGATION")
            doc.append("-" * 80)
            for risk in self.strategy_elements['risks']:
                doc.append(f"\nRisk: {risk['risk']}")
                doc.append(f"  Impact: {risk['impact']}")
                doc.append(f"  Mitigation: {risk['mitigation']}")
            doc.append("")

        return "\n".join(doc)


# Example: IT Hardware category strategy
strategy = CategoryStrategy(category='IT Hardware', annual_spend=2000000)

strategy.set_positioning(
    kraljic_quadrant='Leverage',
    rationale='Multiple qualified suppliers, high spend volume'
)

strategy.set_objectives(
    primary='Reduce costs by 8-10% while maintaining quality',
    secondary=[
        'Consolidate supplier base from 8 to 3',
        'Standardize specifications',
        'Improve payment terms'
    ]
)

strategy.set_sourcing_strategy(
    approach='Dual source',
    num_suppliers=2,
    contract_term=2
)

strategy.set_value_levers([
    {'lever': 'Competitive bidding via RFP',
     'savings': 150000, 'timeline': 'Q1 2026'},
    {'lever': 'Supplier consolidation',
     'savings': 80000, 'timeline': 'Q2 2026'},
    {'lever': 'Specification standardization',
     'savings': 60000, 'timeline': 'Q3 2026'},
    {'lever': 'Payment terms optimization',
     'savings': 20000, 'timeline': 'Q1 2026'}
])

strategy.set_implementation_plan([
    {'milestone': 'Complete RFP and supplier selection',
     'timeline': 'Q1 2026', 'owner': 'Category Manager'},
    {'milestone': 'Negotiate contracts with selected suppliers',
     'timeline': 'Q2 2026', 'owner': 'Procurement Director'},
    {'milestone': 'Implement standardized specs across business units',
     'timeline': 'Q3 2026', 'owner': 'IT Director'},
    {'milestone': 'Monitor savings realization',
     'timeline': 'Ongoing', 'owner': 'Category Manager'}
])

strategy.set_risks_mitigation([
    {'risk': 'Supplier capacity constraints during transition',
     'impact': 'Medium',
     'mitigation': 'Phased transition, maintain backup supplier'},
    {'risk': 'Stakeholder resistance to standardization',
     'impact': 'High',
     'mitigation': 'Executive sponsorship, value communication'},
    {'risk': 'Market price increases',
     'impact': 'Low',
     'mitigation': 'Fixed pricing in contracts, 2-year term'}
])

print(strategy.generate_strategy_document())

工具与库

Python 库

分析:

  • pandas:数据分析
  • numpy:数值计算
  • scipy:统计分析
  • scikit-learn:用于分析的机器学习

优化:

  • pulp:供应商分配优化
  • cvxpy:凸优化

可视化:

  • matplotlib、seaborn:图表与分析
  • plotly:交互式仪表板
商业软件

战略寻源平台:

  • SAP Ariba:寻源与采购
  • Coupa:从寻源到付款的平台
  • Jaggaer:战略寻源套件
  • GEP SMART:统一采购
  • Ivalua:从寻源到付款
  • Zycus:寻源与采购
  • Keelvar:寻源优化

电子寻源工具:

  • Ariba Sourcing:RFx 和拍卖
  • Coupa Sourcing:活动管理
  • Scout RFP:RFP 管理
  • BidNet:公共部门寻源

品类情报:

  • SpendHQ:支出与市场情报
  • Beroe:采购情报
  • Market Dojo:寻源与供应商管理

常见挑战与解决方案

挑战:利益相关方抵触

问题:

  • 业务部门偏好现有供应商
  • “我的需求很独特”
  • 担心供应中断
  • 对关系的顾虑

解决方案:

  • 尽早让利益相关方参与
  • 展示价值(节省成本、质量、服务)
  • 与愿意参与的业务部门开展试点项目
  • 争取高管支持
  • 主动解决顾虑
  • 透明沟通
挑战:品类知识不足

问题:

  • 缺乏专业技术知识
  • 不了解供应市场
  • 无法评估供应商能力
  • 难以编写规格说明

解决方案:

  • 邀请主题专家(SME)参与
  • 实地考察并与供应商会面
  • 研究行业协会资料
  • 寻求顾问或咨询支持
  • 通过 RFI 流程获取市场情报
  • 组建跨职能品类团队
挑战:供应商选择有限

问题:

  • 单一来源或供应商数量有限
  • 地理位置受限
  • 要求专业化
  • 供应商寡头垄断

解决方案:

  • 拓展全球寻源
  • 调整规格以支持替代方案
  • 开展供应商发展计划
  • 进行自制与外购分析
  • 建立风险共担的长期合作关系
  • 提前采购或设置库存缓冲
挑战:需求复杂

问题:

  • 多个利益相关方的需求各不相同
  • 需求相互冲突
  • 难以定义规格
  • 难以比较提案

解决方案:

  • 开展需求梳理研讨会
  • 区分必备项与加分项并确定优先级
  • 尽可能实现标准化
  • 采用模块化规格
  • 使用加权评分进行评估
  • 开展概念验证或试用
挑战:节省金额的衡量与跟踪

问题:

  • 基准值争议
  • 归因问题
  • 价格与采购量变化
  • 一次性节省与持续性节省

解决方案:

  • 明确界定基准值(寻源前)
  • 分别跟踪价格变化和采购量变化
  • 第三方验证
  • 节省金额治理流程
  • 定期审计节省金额
  • 透明报告

输出格式

品类战略文档

执行摘要:

  • 品类概况及战略重要性
  • 分析的关键发现
  • 建议的战略和节省目标
  • 实施方法

品类概况:

属性详情
品类IT 硬件(笔记本电脑、台式电脑、显示器)
年度支出$2.0M
占总支出的比例3.5%
Kraljic 象限杠杆型
当前供应商8 家活跃供应商
前 3 家供应商占比65%
服务的业务部门全部(5 个地点)

供应市场分析:

  • 市场动态:竞争激烈,有多家一级供应商
  • 供应风险:低(供应充足,有多个合格来源)
  • 价格趋势:持平至下降(受大宗商品价格影响)
  • 技术趋势:转向云端/瘦客户端,延长更新周期
  • 主要供应商:Dell、HP、Lenovo、Apple(OEM),CDW、Insight(经销商)

当前状况评估:

优势:

  • 与主要 OEM 建立了稳定关系
  • 质量和可靠性良好
  • 交付表现良好

劣势:

  • 供应商基础分散(8 家供应商,条款不一致)
  • 缺乏标准化规格(200 多种 SKU)
  • 定价比市场基准高 8-12%
  • 付款条款和折扣不一致

机遇:

  • 整合至 2-3 家战略供应商
  • 标准化配置(将 SKU 减少至 20-30 种)
  • 利用采购量争取更优定价
  • 将付款期限延长至 Net 45

威胁:

  • 零部件短缺(芯片、显示屏)
  • 技术过时风险
  • 业务部门抵制标准化

战略建议:

寻源战略:双源采购(70/30 分配)

  • 主要供应商(70%):通过首选经销商采购 Dell 或 HP
  • 次要供应商(30%):Lenovo 或其他备选供应商,以保持竞争
  • 合同期限:2 年,可选择延长 1 年

价值主张:

  • 年度总节省目标:$180K(占支出的 9%)
  • 改善服务水平并实现标准化
  • 通过双源采购降低风险

实施路线图:

Phase 1 (Months 1-3): RFP & Selection
  - Finalize requirements with stakeholders
  - Issue RFP to qualified suppliers
  - Evaluate proposals and select winners
  - Negotiate contracts

Phase 2 (Months 4-6): Transition & Onboarding
  - Establish catalogs and ordering process
  - Train stakeholders on new procedures
  - Transition volumes to new suppliers
  - Phase out non-strategic suppliers

Phase 3 (Months 7-12): Optimization
  - Monitor performance and compliance
  - Quarterly business reviews with suppliers
  - Track savings realization
  - Continuous improvement initiatives

预期成果:

指标当前目标改善幅度
年度总支出$2.0M$1.82M-9%
供应商数量82-75%
标准化 SKU200+25-88%
平均单价$1,200$1,100-8.3%
付款条款Net 30Net 45+15 天
准时交付率92%98%+6 个百分点

要提出的问题

如果需要更多背景信息:

  1. 哪些品类需要制定战略?
  2. 年度支出金额是多少?
  3. 当前的寻源方式是什么?有哪些痛点?
  4. 谁是关键利益相关方?他们的优先事项是什么?
  5. 对供应市场有哪些了解?
  6. 是否有现有供应商?其表现如何?
  7. 存在哪些限制?(技术、法规、地域)
  8. 主要目标是什么?(成本、创新、风险、可持续性)
  9. 实施新战略的时间安排是什么?
  10. 寻源计划有哪些可用资源?

相关技能

  • supplier-selection:用于执行供应商选择流程
  • spend-analysis:用于品类支出分析
  • procurement-optimization:用于订单分配和批量规模确定
  • contract-management:用于合同谈判与管理
  • supplier-risk-management:用于供应商风险评估
  • supply-chain-analytics:用于绩效跟踪和 KPI

评论

支持 Markdown