容量规划Skill capacity-planning

容量规划是用于分析团队容量,规划资源分配,并在项目间平衡工作负载的过程。它预测人员需求并优化团队利用率,同时保持可持续的步伐,防止团队疲劳,并能够向利益相关者做出准确的承诺。

项目管理 0 次安装 0 次浏览 更新于 3/3/2026

以下是对提供的英文内容的中文翻译,保持原有格式不变:


name: 容量规划 description: 分析团队容量,规划资源分配,并在项目间平衡工作负载。预测人员需求并优化团队利用率,同时保持可持续的步伐。

容量规划

概览

容量规划确保团队拥有足够的资源以可持续的步伐交付工作,防止疲劳,并能够向利益相关者做出准确的承诺。

何时使用

  • 年度或季度规划周期
  • 人员分配至项目
  • 调整团队规模
  • 规划假期和缺席
  • 预测资源需求
  • 平衡多个项目
  • 识别瓶颈

指南

1. 容量评估

# 团队容量计算和规划

class CapacityPlanner:
    # 每周标准工作小时数
    STANDARD_WEEK_HOURS = 40

    # 减少可用容量的活动
    OVERHEAD_HOURS = {
        'meetings': 5,           # 站立会,一对一会议,计划会议
        'training': 2,           # 学习新技术
        'administrative': 2,     # 电子邮件,审批
        'support': 2,            # 帮助队友
        'contingency': 2         # 中断,紧急情况
    }

    def __init__(self, team_size, sprint_duration_weeks=2):
        self.team_size = team_size
        self.sprint_duration_weeks = sprint_duration_weeks
        self.members = []

    def calculate_team_capacity(self):
        """计算可用容量小时数"""
        # 基础容量
        base_hours = self.team_size * self.STANDARD_WEEK_HOURS * self.sprint_duration_weeks

        # 减去开销
        overhead = sum(self.OVERHEAD_HOURS.values()) * self.team_size * self.sprint_duration_weeks

        # 减去缺席
        absence_hours = self.calculate_absences()

        # 可用容量
        available_capacity = base_hours - overhead - absence_hours

        return {
            'base_hours': base_hours,
            'overhead_hours': overhead,
            'absence_hours': absence_hours,
            'available_capacity': available_capacity,
            'utilization_target': '85%',  # 保留15%的缓冲
            'target_commitment': available_capacity * 0.85
        }

    def calculate_absences(self):
        """考虑假期、病假等"""
        absence_days = 0

        # 标准缺席
        vacation_days = 15  # 年度
        sick_days = 5       # 年度
        holidays = 10       # 年度

        # 转换为每个冲刺
        absence_days = (vacation_days + sick_days + holidays) / 52 * self.sprint_duration_weeks

        absence_hours = absence_days * 8 * self.team_size
        return absence_hours

    def allocate_to_projects(self, projects, team):
        """在多个项目间分配容量"""
        allocation = {}
        total_allocation = 0

        # 按优先级分配
        for project in sorted(projects, key=lambda p: p.priority):
            required_hours = project.effort_hours
            available = self.calculate_team_capacity()['available_capacity'] - total_allocation

            if available >= required_hours:
                allocation[project.id] = {
                    'project': project.name,
                    'allocated': required_hours,
                    'team_members': int(required_hours / (self.STANDARD_WEEK_HOURS * self.sprint_duration_weeks)),
                    'allocation_percent': (required_hours / available * 100)
                }
                total_allocation += required_hours
            else:
                allocation[project.id] = {
                    'project': project.name,
                    'allocated': available,
                    'status': 'Insufficient capacity',
                    'shortfall': required_hours - available,
                    'recommendation': 'Add resources or defer scope'
                }
                total_allocation = available

        return allocation

    def identify_bottlenecks(self, skills, projects):
        """找到技能限制"""
        bottlenecks = []

        for skill in skills:
            people_with_skill = sum(1 for p in self.members if skill in p.skills)
            projects_needing_skill = sum(1 for p in projects if skill in p.required_skills)

            utilization = (projects_needing_skill / people_with_skill * 100) if people_with_skill > 0 else 0

            if utilization > 100:
                bottlenecks.append({
                    'skill': skill,
                    'people_available': people_with_skill,
                    'projects_needing': projects_needing_skill,
                    'utilization': utilization,
                    'severity': 'Critical',
                    'actions': ['Cross-train team', 'Hire specialist', 'Adjust scope']
                })

        return bottlenecks

2. 容量规划模板

2025年第一季度容量计划:

团队:平台工程(12人)
期限:2025年1月1日至3月31日
计划时长:13周

---

## 团队组成

工程师:
  - 高级工程师:3(每人1.2全职等效)
  - 中级工程师:6(每人0.95全职等效)
  - 初级工程师:2(每人0.8全职等效)
  - DevOps:1(1.0全职等效)

总可用全职等效:11.1(考虑开销、缺席)
总可用小时数:11.1 * 40 * 13 = 5,772小时

---

## 计划缺席

假期:团队共8周(估计)
病假/个人事假:团队共2周
假日:1周(马丁·路德·金日,总统日)
总计:约480小时

---

## 容量分配

项目A:关键基础设施
  分配:60%(需要6,600小时)
  团队:3名高级,3名中级工程师
  全职等效:6.6
  状态:已承诺

项目B:功能开发
  分配:30%(需要3,300小时)
  团队:2名中级,2名初级工程师
  全职等效:3.3
  状态:已承诺

基础设施和维护:
  分配:10%(1,100小时)
  团队:DevOps,1名高级工程师
  全职等效:1.1
  状态:运营容量

总计:100%分配,0%缓冲

---

## 风险评估

风险:
  1. 零缓冲容量(100%分配)
    影响:任何缺席/问题都会造成危机
    缓解措施:交叉培训,自动化

  2. 初级工程师上手时间
    影响:中级工程师被拉去辅导
    缓解措施:每周分配1小时辅导时间

  3. 基础设施瓶颈(1名DevOps)
    影响:扩展限制
    缓解措施:2月1日前增加1名DevOps

---

## 建议

1. 将容量规划从100%降低到85%
2. 增加1名DevOps工程师
3. 对2名工程师进行关键系统交叉培训
4. 策略性安排假期(不在第二阶段期间)
5. 为紧急情况建立15%的缓冲

3. 资源平衡

// 在团队成员间平衡工作负载

class ResourceLeveling {
  levelWorkload(team, tasks) {
    const workloadByPerson = {};

    // 初始化团队成员工作负载
    team.forEach(person => {
      workloadByPerson[person.id] = {
        name: person.name,
        skills: person.skills,
        capacity: person.capacity_hours,
        assigned: [],
        utilization: 0
      };
    });

    // 分配任务以平衡工作负载
    const sortedTasks = tasks.sort((a, b) => b.effort - a.effort); // 最大的先分配

    sortedTasks.forEach(task => {
      const suitable = team.filter(p =>
        this.hasSufficientSkills(p.skills, task.required_skills) &&
        this.hasCapacity(workloadByPerson[p.id].utilization, p.capacity_hours)
      );

      if (suitable.length > 0) {
        const leastUtilized = suitable.reduce((a, b) =>
          workloadByPerson[a.id].utilization < workloadByPerson[b.id].utilization ? a : b
        );

        workloadByPerson[leastUtilized.id].assigned.push(task);
        workloadByPerson[leastUtilized.id].utilization += task.effort;
      }
    });

    return {
      assignments: workloadByPerson,
      balanceMetrics: this.calculateBalance(workloadByPerson),
      unassignedTasks: tasks.filter(t => !Object.values(workloadByPerson).some(p => p.assigned.includes(t)))
    };
  }

  calculateBalance(workloadByPerson) {
    const utilizations = Object.values(workloadByPerson).map(p => p.utilization);
    const average = utilizations.reduce((a, b) => a + b) / utilizations.length;
    const variance = Math.sqrt(
      utilizations.reduce((sum, u) => sum + Math.pow(u - average, 2)) / utilizations.length
    );

    return {
      average_utilization: average.toFixed(1),
      std_deviation: variance.toFixed(1),
      balance_score: this.calculateBalanceScore(variance),
      recommendations: this.getBalancingRecommendations(variance)
    };
  }

  calculateBalanceScore(variance) {
    if (variance < 5) return 'Excellent';
    if (variance < 10) return 'Good';
    if (variance < 15) return 'Fair';
    return 'Poor - needs rebalancing';
  }
}

4. 容量预测

12个月容量预测:

团队增长计划:
  2025年第一季度:12人(当前)
  2025年第二季度:13人(招聘1名DevOps)
  2025年第三季度:15人(招聘2名工程师)
  2025年第四季度:15人(稳定)

每月容量(全职等效):

2025年1月:10.8全职等效(低于正常 - 上手期)
2025年2月:11.1全职等效(正常)
2025年3月:11.0全职等效(1人休假)

第二季度平均:12.5全职等效(新员工贡献)
第三季度平均:14.2全职等效(2名新员工)
第四季度平均:15.0全职等效(全部满负荷)

---

项目承诺与可用容量对比:

第一季度:承诺11.0全职等效,可用11.1全职等效(安全)
第二季度:承诺12.0全职等效,可用12.5全职等效(缓冲4%)
第三季度:承诺13.0全职等效,可用14.2全职等效(缓冲9%)
第四季度:承诺14.0全职等效,可用15.0全职等效(缓冲7%)

---

风险预警:
  - 第一季度紧张(98%利用)
  - 技能缺口:第二季度后端专长
  - 人员流失风险:计划第三季度1人离职

最佳实践

✅ 做

  • 以85%的利用率规划容量(保留15%的缓冲)
  • 考虑会议、培训和开销
  • 包括已知缺席(假期、节日)
  • 提前识别技能瓶颈
  • 公平地在团队间平衡工作负载
  • 每月审查容量
  • 根据实际速度调整计划
  • 对关键技能进行交叉培训
  • 向利益相关者传达现实的承诺
  • 为紧急情况建立缓冲

❌ 不做

  • 不以100%的利用率规划
  • 忽略会议和开销
  • 在未检查技能的情况下分配工作
  • 创造连续的惊喜导致超负荷
  • 忘记学习/培训时间
  • 将容量规划留到最后一分钟
  • 持续超承诺团队
  • 烧毁关键人员
  • 忽略团队对工作负载的反馈
  • 不考虑缺席进行规划

容量规划提示

  • 使用过去冲刺的速度数据
  • 跟踪实际与计划的利用率
  • 在站立会中每周审查容量
  • 为紧急情况保持15%的缓冲
  • 对关键职能进行交叉培训