Agent skill
warehouse-slotting-optimizer
Warehouse slotting and layout optimization skill for pick path minimization and space utilization.
Install this agent skill to your Project
npx add-skill https://github.com/a5c-ai/babysitter/tree/main/library/specializations/domains/science/industrial-engineering/skills/warehouse-slotting-optimizer
Metadata
Additional technical details for this skill
- author
- babysitter-sdk
- version
- 1.0.0
- category
- supply-chain
- backlog id
- SK-IE-026
SKILL.md
warehouse-slotting-optimizer
You are warehouse-slotting-optimizer - a specialized skill for optimizing warehouse slotting and layout to minimize pick paths and maximize space utilization.
Overview
This skill enables AI-powered warehouse optimization including:
- Product velocity analysis (ABC by picks)
- Cube movement analysis
- Pick path optimization
- Zone design and assignment
- Forward pick area sizing
- Slot assignment algorithms
- Golden zone optimization
- Slotting performance metrics
Capabilities
1. Velocity Analysis
import pandas as pd
import numpy as np
def velocity_analysis(order_data: pd.DataFrame):
"""
Analyze SKU velocity by pick frequency
"""
# Aggregate picks by SKU
sku_picks = order_data.groupby('sku').agg({
'quantity': 'sum',
'order_id': 'count'
}).rename(columns={'order_id': 'pick_count'})
# Sort by picks descending
sku_picks = sku_picks.sort_values('pick_count', ascending=False)
# Calculate cumulative percentages
total_picks = sku_picks['pick_count'].sum()
sku_picks['cum_picks'] = sku_picks['pick_count'].cumsum()
sku_picks['cum_pct'] = sku_picks['cum_picks'] / total_picks * 100
# Assign velocity class
def assign_velocity(pct):
if pct <= 80:
return 'Fast' # A items - top 80% of picks
elif pct <= 95:
return 'Medium' # B items
else:
return 'Slow' # C items
sku_picks['velocity_class'] = sku_picks['cum_pct'].apply(assign_velocity)
return {
"sku_velocity": sku_picks,
"summary": {
"total_skus": len(sku_picks),
"fast_movers": len(sku_picks[sku_picks['velocity_class'] == 'Fast']),
"medium_movers": len(sku_picks[sku_picks['velocity_class'] == 'Medium']),
"slow_movers": len(sku_picks[sku_picks['velocity_class'] == 'Slow'])
}
}
2. Golden Zone Optimization
def optimize_golden_zone(skus: pd.DataFrame, warehouse_config: dict):
"""
Optimize placement in golden zone (ergonomic prime picking zone)
Golden zone: waist to shoulder height, immediate reach
"""
golden_zone = warehouse_config.get('golden_zone', {
'height_min': 24, # inches from floor
'height_max': 54,
'reach_max': 24 # inches from aisle
})
# Calculate golden zone capacity
rack_config = warehouse_config.get('rack', {
'bays': 100,
'levels': 5,
'positions_per_bay': 3
})
# Levels in golden zone (typically levels 2-3 of 5)
golden_levels = [2, 3] # Assuming 5 levels
golden_positions = (rack_config['bays'] *
len(golden_levels) *
rack_config['positions_per_bay'])
# Sort SKUs by pick frequency
fast_skus = skus[skus['velocity_class'] == 'Fast'].copy()
fast_skus = fast_skus.sort_values('pick_count', ascending=False)
# Assign to golden zone
assignments = []
position_count = 0
for idx, row in fast_skus.iterrows():
if position_count < golden_positions:
assignments.append({
'sku': idx,
'zone': 'golden',
'level': golden_levels[position_count % len(golden_levels)],
'priority': position_count + 1
})
position_count += 1
else:
assignments.append({
'sku': idx,
'zone': 'standard',
'level': None,
'priority': position_count + 1
})
return {
"golden_zone_capacity": golden_positions,
"skus_in_golden": position_count,
"assignments": assignments,
"golden_zone_pick_coverage": fast_skus.head(golden_positions)['pick_count'].sum() /
skus['pick_count'].sum() * 100
}
3. Pick Path Optimization
def optimize_pick_path(picks: list, warehouse_layout: dict):
"""
Optimize pick path through warehouse
Uses traveling salesman heuristic
"""
from scipy.spatial.distance import cdist
import itertools
# Get location coordinates for picks
locations = []
for pick in picks:
loc = warehouse_layout['locations'].get(pick['location'])
if loc:
locations.append((pick['location'], loc['x'], loc['y']))
# Calculate distance matrix
coords = np.array([(l[1], l[2]) for l in locations])
dist_matrix = cdist(coords, coords)
# Nearest neighbor heuristic
n = len(locations)
visited = [False] * n
path = [0] # Start at first location
visited[0] = True
for _ in range(n - 1):
current = path[-1]
nearest = None
nearest_dist = float('inf')
for j in range(n):
if not visited[j] and dist_matrix[current][j] < nearest_dist:
nearest = j
nearest_dist = dist_matrix[current][j]
if nearest is not None:
path.append(nearest)
visited[nearest] = True
# Calculate total distance
total_distance = sum(dist_matrix[path[i]][path[i+1]]
for i in range(len(path)-1))
# Return optimized sequence
optimized_picks = [picks[i] for i in path]
return {
"optimized_sequence": optimized_picks,
"total_distance": total_distance,
"locations_count": n,
"estimated_time_minutes": total_distance / warehouse_layout.get('walk_speed', 100) * 60
}
4. Forward Pick Area Sizing
def size_forward_pick_area(sku_data: pd.DataFrame, replenishment_cost: float,
space_cost_per_unit: float):
"""
Determine optimal forward pick area size
Balance replenishment cost vs. space cost
"""
# Sort by velocity
sku_data = sku_data.sort_values('picks_per_day', ascending=False)
results = []
cumulative_picks = 0
total_picks = sku_data['picks_per_day'].sum()
for i, (idx, row) in enumerate(sku_data.iterrows()):
cumulative_picks += row['picks_per_day']
pick_coverage = cumulative_picks / total_picks
# Estimate costs
forward_skus = i + 1
space_cost = forward_skus * row.get('cube', 1) * space_cost_per_unit
replen_trips = sku_data.head(forward_skus)['picks_per_day'].sum() / \
sku_data.head(forward_skus)['case_qty'].mean()
replen_cost = replen_trips * replenishment_cost
total_cost = space_cost + replen_cost
results.append({
'forward_skus': forward_skus,
'pick_coverage': pick_coverage,
'space_cost': space_cost,
'replen_cost': replen_cost,
'total_cost': total_cost
})
if pick_coverage >= 0.95:
break
# Find optimal
optimal = min(results, key=lambda x: x['total_cost'])
return {
"analysis": results,
"optimal_forward_skus": optimal['forward_skus'],
"pick_coverage": optimal['pick_coverage'],
"total_cost": optimal['total_cost']
}
5. Slotting Assignment Algorithm
def slot_assignment(skus: pd.DataFrame, locations: pd.DataFrame,
constraints: dict = None):
"""
Assign SKUs to warehouse locations
Considers:
- Velocity (fast movers to best locations)
- Cube (size compatibility)
- Weight (heavy items at floor level)
- Family grouping (related items together)
"""
constraints = constraints or {}
# Score each location
def score_location(loc):
score = 0
# Distance from shipping (lower is better)
score -= loc.get('distance_to_ship', 0) * 0.01
# Ergonomic zone bonus
if 24 <= loc.get('height', 0) <= 54:
score += 10
# Ground level for heavy
if loc.get('level', 0) == 1:
score += 5
return score
locations['score'] = locations.apply(score_location, axis=1)
locations = locations.sort_values('score', ascending=False)
# Sort SKUs by assignment priority
skus['priority'] = skus['picks_per_day'] * 100 - skus.get('cube', 1)
skus = skus.sort_values('priority', ascending=False)
assignments = []
used_locations = set()
for sku_idx, sku in skus.iterrows():
for loc_idx, loc in locations.iterrows():
if loc_idx in used_locations:
continue
# Check constraints
if sku.get('cube', 1) > loc.get('capacity', float('inf')):
continue
if sku.get('weight', 0) > loc.get('weight_limit', float('inf')):
continue
# Assign
assignments.append({
'sku': sku_idx,
'location': loc_idx,
'picks_per_day': sku['picks_per_day'],
'location_score': loc['score']
})
used_locations.add(loc_idx)
break
return {
"assignments": assignments,
"assigned_count": len(assignments),
"unassigned_skus": len(skus) - len(assignments)
}
6. Slotting Performance Metrics
def calculate_slotting_metrics(current_slotting: pd.DataFrame,
order_history: pd.DataFrame,
warehouse_config: dict):
"""
Calculate slotting performance metrics
"""
metrics = {}
# Pick density (picks per foot traveled)
total_picks = len(order_history)
# Estimate travel based on current slotting
travel_estimate = estimate_total_travel(current_slotting, order_history, warehouse_config)
metrics['pick_density'] = total_picks / travel_estimate if travel_estimate > 0 else 0
# Golden zone utilization
golden_picks = order_history.merge(current_slotting, on='sku')
golden_picks = golden_picks[golden_picks['zone'] == 'golden']
metrics['golden_zone_pick_pct'] = len(golden_picks) / total_picks * 100
# Slot utilization
total_slots = len(current_slotting)
active_slots = current_slotting[current_slotting['picks_per_day'] > 0]
metrics['slot_utilization'] = len(active_slots) / total_slots * 100
# Velocity alignment score (are fast movers in best spots?)
current_slotting = current_slotting.sort_values('picks_per_day', ascending=False)
current_slotting['ideal_rank'] = range(1, len(current_slotting) + 1)
current_slotting['actual_rank'] = current_slotting['location_score'].rank(ascending=False)
correlation = current_slotting['ideal_rank'].corr(current_slotting['actual_rank'])
metrics['velocity_alignment'] = correlation
return metrics
def estimate_total_travel(slotting, orders, config):
# Simplified travel estimation
avg_picks_per_order = len(orders) / orders['order_id'].nunique()
avg_travel_per_pick = config.get('avg_aisle_length', 100) / 2
return len(orders) * avg_travel_per_pick
Process Integration
This skill integrates with the following processes:
warehouse-layout-slotting-optimization.jsinventory-optimization-analysis.js
Output Format
{
"velocity_analysis": {
"fast_movers": 150,
"medium_movers": 450,
"slow_movers": 2400
},
"golden_zone": {
"capacity": 300,
"pick_coverage": 72.5
},
"slotting_metrics": {
"pick_density": 2.3,
"velocity_alignment": 0.85
},
"recommendations": [
"Move top 50 SKUs to golden zone",
"Consider forward pick area for 200 SKUs"
]
}
Best Practices
- Use actual pick data - Not just sales or forecast
- Regular re-slotting - Velocity changes over time
- Consider ergonomics - Not just efficiency
- Family grouping - Items ordered together
- Measure before/after - Validate improvements
- Involve pickers - They know the issues
Constraints
- Requires historical pick data
- Physical constraints limit optimization
- Re-slotting has transition costs
- Balance optimization with operational flexibility
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
gsd-tools
Central utility skill for GSD operations. Provides config parsing, slug generation, timestamps, path operations, and orchestrates calls to other specialized skills. Acts as the unified entry point that the original gsd-tools.cjs provided via its lib/ modules (commands, config, core, init).
model-profile-resolution
Resolve model profile (quality/balanced/budget) at orchestration start and map agents to specific models. Enables cost/quality tradeoffs by selecting appropriate AI models for each agent role.
verification-suite
Plan structure validation, phase completeness checks, reference integrity verification, and artifact existence confirmation. Provides the structured verification layer ensuring GSD artifacts are well-formed and complete.
state-management
STATE.md reading, writing, and field-level updates. Provides cross-session state persistence via .planning/STATE.md with structured fields for current task, completed phases, blockers, decisions, and quick tasks.
git-integration
Git commit patterns, formats, and conventions for GSD methodology. Provides atomic commits per task, structured commit messages, planning file commits, branch management, and milestone tag operations.
frontmatter-parsing
YAML frontmatter parsing and manipulation for .planning/ documents. Provides read, write, update, query, and validation operations on frontmatter blocks in GSD markdown artifacts.
Didn't find tool you were looking for?