技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
engineering-tradeoffs【数据与研究】Evaluates competing engineering options using weighted decision matrices, reversibility analysis, and multi-criteria tradeoff frameworks to make defensible technical decisions under constraints.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: engineering-tradeoffs description: Evaluates competing engineering options using weighted decision matrices, reversibility analysis, and multi-criteria tradeoff frameworks to make defensible technical decisions under constraints. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: coding triggers: engineering tradeoffs, decision making under constraints, build vs buy, speed vs quality, technology selection, weighted decision matrix, tradeoff analysis, two-way door decisions speed vs quality archetypes:
Senior engineer facilitating structured tradeoff decisions when requirements conflict and no option is perfect. This skill makes the model act as a disciplined decision analyst — surfacing hidden assumptions, quantifying competing priorities, and producing recommendations with explicit reasoning that stakeholders can challenge or endorse.
Use this skill when:
Avoid this skill for:
architecture-decision-records to document decisions that have already been madedesign-pattern-selection when you know the pattern and need implementation guidanceWrite out the tension in this exact form:
"We want [goal] but achieving it requires [option A's cost/benefit] while [option B's cost/benefit]."
Do not skip this step. Vague conflicts produce vague decisions. Examples:
Checkpoint: Can a stakeholder read this statement and understand exactly what is being debated? If not, rewrite it.
Not all requirements carry equal weight. Categorize every requirement into one of three tiers:
| Tier | Description | Examples |
|---|---|---|
| Non-negotiable | Must be satisfied; deal-breaker if not met | Regulatory compliance (GDPR, PCI-DSS), security baseline, hard SLA commitments |
| Strong Preference | Highly desirable; strong penalty if unmet | Team's existing expertise, time-to-market < 3 months, sub-100ms latency target |
| Nice-to-have | Desirable but acceptable to defer or compromise on | Preferred language, nice API ergonomics, future scalability beyond current needs |
For each requirement, assign a weight from 1.0 (nice-to-have) to 3.0 (non-negotiable). This feeds directly into the decision matrix.
Checkpoint: Verify that at least one requirement is classified as Non-negotiable. If not, revisit with stakeholders.
Apply Bezos's two-way door framework to determine analysis depth and urgency:
Two-Way Door (Reversible) One-Way Door (Irreversible)
┌─────────────────────┐ ┌──────────────────────────┐
│ • Can undo later │ │ • Difficult or costly to │
│ • Low permanence │ │ reverse │
│ • Fast decisions OK │ │ • Requires deep analysis │
│ • Act fast, iterate │ │ • Build consensus first │
│ • Example: UI theme │ │ • Example: choosing DB │
│ change, API route │ │ engine, data migration │
└─────────────────────┘ └──────────────────────────┘
Checkpoint: Have you explicitly labeled the decision type? This determines how much effort is appropriate for analysis.
Before looking at any specific option, write down what success looks like. This prevents anchoring bias — the tendency to evaluate options against a preconceived favorite.
Success criteria should cover all three dimensions from the evaluation framework:
Technical: Correctness, Performance, Reliability, Scalability, Security Organizational: Team skill fit, Time to value, Operational burden, Vendor lock-in risk Strategic: Reversibility, Strategic alignment, Competitive differentiation
Write 3–7 success criteria. Each will become a column in your decision matrix.
Checkpoint: Would two independent engineers agree on these criteria? If not, the criteria need more objectivity.
Never present a binary choice (Option A vs. Option B). Binary framing is a cognitive bias that hides superior alternatives. Generate three archetypes:
| Archetype | Description | Purpose |
|---|---|---|
| Minimal Change | Incremental improvement over current state | Baseline — shows what the easiest path looks like |
| Bold Solution | Maximum benefit, maximum cost/risk | Shows the ideal outcome if constraints didn't matter |
| Middle Path | Balanced compromise with creative elements | Often the actual chosen solution; reveals tradeoffs clearly |
For each option, briefly note:
Checkpoint: Do all three options address every Non-negotiable requirement? If one fails a non-negotiable, eliminate it and generate another.
Score each option against each criterion on a scale of 1–5 (1 = poor fit, 5 = excellent fit). Multiply by the criterion weight from Step 2. Sum weighted scores to rank options.
See the Decision Matrix Pattern in the Reference Guide below for the implementation.
Checkpoint: Do the ranked results feel right? If the top choice contradicts your team's intuition, revisit your weights — you may have misaligned priorities.
Present the recommendation with this structure:
For one-way door decisions, write an Architecture Decision Record (architecture-decision-records skill). For two-way door decisions, a brief comment or PR description suffices.
Checkpoint: If you can't articulate the tradeoff clearly in one sentence, the decision isn't ready to communicate.
Classify every technical decision along two axes — Immutability (how hard is it to change?) × Configurability (can it be tuned without code changes?):
IMMUTABLE CONFIGURABLE
┌──────────────┬──────────────────┐
│ MODULAR │ EMERGENT │
Immutability → │ │ │
│ Architecture│ Infrastructure │
│ choices: │ configuration: │
│ - Service │ - Feature flags │
│ boundaries│ - Env variables │
│ - API │ - Database │
│ contracts │ connection │
├──────────────┼──────────────────┤
│ ADAPTABLE │ FLEXIBLE │
│ │ │
│ Code-level: │ Creative work: │
│ - Plugin │ - Algorithm │
│ interfaces│ parameter │
│ - Strategy │ tuning │
│ pattern │ - ML model │
│ │ selection │
└──────────────┴──────────────────┘
OREO helps structure the analysis before scoring:
While CAP is often discussed in distributed systems context, it generalizes to any software architecture decision where you balance competing non-functional requirements:
| Dimension | What it means | Example tradeoff |
|---|---|---|
| Consistency | All consumers see the same data at the same time | Strong consistency slows writes (CAP: CP systems) |
| Availability | Every request gets a response, even if stale | Eventual consistency risks reading stale data |
| Partition Tolerance | System works despite network/component failures | Requires handling partial failures gracefully |
In practice, choose which two of C/A/P matter most for your use case. There is no free lunch — every choice sacrifices one dimension.
This Python function implements the core scoring engine for tradeoff analysis:
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class Criterion:
"""A single evaluation criterion with its weight."""
name: str
weight: float # Must sum to 1.0 across all criteria
description: str = ""
def __post_init__(self):
if not 0 < self.weight <= 1.0:
raise ValueError(f"Weight must be between 0 and 1, got {self.weight}")
@dataclass
class Option:
"""A candidate option to evaluate."""
name: str
description: str
scores: dict[str, int] = field(default_factory=dict) # criterion_name -> 1-5 score
def weighted_score(self, criteria: list[Criterion]) -> float:
"""Calculate total weighted score across all criteria."""
return sum(
self.scores.get(criterion.name, 0) * criterion.weight
for criterion in criteria
)
def __repr__(self) -> str:
return f"Option({self.name}: {self.description})"
@dataclass
class TradeoffResult:
"""Structured result from tradeoff evaluation."""
chosen: Option
all_ranked: list[Option]
criteria: list[Criterion]
analysis_summary: str
acknowledged_tradeoffs: list[str] = field(default_factory=list)
def summary(self) -> str:
lines = [f"## Tradeoff Analysis Result\n", f"**Chosen:** {self.chosen.name}\n"]
lines.append(f"**Weighted Score:** {self.chosen.weighted_score(self.criteria):.2f}/5.00\n")
lines.append("\n### Ranking\n")
for i, opt in enumerate(self.all_ranked, 1):
score = opt.weighted_score(self.criteria)
marker = " ← CHOSEN" if opt is self.chosen else ""
lines.append(f"{i}. **{opt.name}** — {score:.2f}/5.00{marker}")
if self.acknowledged_tradeoffs:
lines.append("\n### Acknowledged Tradeoffs\n")
for tradeoff in self.acknowledged_tradeoffs:
lines.append(f"- {tradeoff}")
return "".join(lines)
def evaluate_tradeoffs(
options: list[Option],
criteria: list[Criterion],
decision_type: str = "two-way", # or "one-way"
) -> TradeoffResult:
"""Evaluate competing options using weighted multi-criteria analysis.
Args:
options: Candidate options with scores per criterion (1-5 scale)
criteria: Named criteria with weights summing to 1.0
decision_type: Reversibility classification for urgency context
Returns:
Structured result with ranking, chosen option, and analysis summary
Raises:
ValueError: If criteria weights do not sum to 1.0 or scores are out of range
"""
# Validate weights sum to 1.0
total_weight = sum(c.weight for c in criteria)
if abs(total_weight - 1.0) > 0.001:
raise ValueError(f"Criterion weights must sum to 1.0, got {total_weight:.4f}")
# Validate scores are in range
criterion_names = {c.name for c in criteria}
for opt in options:
for name, score in opt.scores.items():
if name not in criterion_names:
raise ValueError(f"Unknown criterion '{name}' in option '{opt.name}'")
if not (1 <= score <= 5):
raise ValueError(f"Score for {opt.name}.{name} = {score}, must be 1-5")
# Score and rank options
scored = sorted(options, key=lambda o: o.weighted_score(criteria), reverse=True)
# Build analysis summary
chosen = scored[0]
runner_up = scored[1] if len(scored) > 1 else None
gap = chosen.weighted_score(criteria) - (runner_up.weighted_score(criteria) if runner_up else 0)
decision_label = "fast-tracked" if decision_type == "two-way" else "thoroughly analyzed"
summary = (
f"Option '{chosen.name}' selected ({decision_label}) with score "
f"{chosen.weighted_score(criteria):.2f}. "
f"Margin over runner-up '{runner_up.name if runner_up else 'N/A'}': {gap:.2f} points."
)
# Identify key tradeoffs: where runner-up beats chosen
tradeoffs = []
for c in criteria:
if runner_up and runner_up.scores.get(c.name, 0) > chosen.scores.get(c.name, 0):
direction = "better" if decision_type == "two-way" else "worse"
tradeoffs.append(
f"We choose '{chosen.name}' over '{runner_up.name}' accepting that "
f"it scores lower on '{c.name}' (weight: {c.weight:.1f})"
)
return TradeoffResult(
chosen=chosen,
all_ranked=scored,
criteria=criteria,
analysis_summary=summary,
acknowledged_tradeoffs=tradeoffs,
)
# Example usage: Choosing between PostgreSQL and MongoDB for a user data store
if __name__ == "__main__":
criteria = [
Criterion("Data Integrity", weight=0.30, description="Required by financial compliance"),
Criterion("Development Velocity", weight=0.25, description="Team needs to ship in < 6 weeks"),
Criterion("Flexibility / Schema Evolution", weight=0.20),
Criterion("Operational Complexity", weight=0.15),
Criterion("Ecosystem Tooling", weight=0.10),
]
options = [
Option(
name="PostgreSQL",
description="Relational DB with ACID guarantees, rigid schema",
scores={"Data Integrity": 5, "Development Velocity": 3, "Flexibility": 2, "Operational Complexity": 3, "Ecosystem Tooling": 5},
),
Option(
name="MongoDB",
description="Document DB with flexible schema, eventual consistency",
scores={"Data Integrity": 3, "Development Velocity": 4, "Flexibility": 5, "Operational Complexity": 4, "Ecosystem Tooling": 4},
),
]
# Note: "Flexibility" maps to "Flexibility / Schema Evolution" criterion
# In production, ensure option score keys match criterion names exactly
result = evaluate_tradeoffs(options, criteria, decision_type="one-way")
print(result.summary())
When producing tradeoff analysis for stakeholders, use this structured format. This is the output that feeds into an Architecture Decision Record.
Decision Matrix: [Decision Topic]
┌─────────────────────┬───────────┬───────────┬───────────┐
│ Criterion │ Weight │ Option A │ Option B │ Option C │
├─────────────────────┼───────────┼───────────┼───────────┤
│ Data Integrity │ 0.30 │ 5 │ 3 │ 4 │
│ → Weighted Score │ │ 1.50 │ 0.90 │ 1.20 │
├─────────────────────┼───────────┼───────────┼───────────┤
│ Dev Velocity │ 0.25 │ 3 │ 4 │ 3 │
│ → Weighted Score │ │ 0.75 │ 1.00 │ 0.75 │
├─────────────────────┼───────────┼───────────┼───────────┤
│ [Additional] │ ... │ · │ · │ · │
├─────────────────────┼───────────┼───────────┼───────────┤
│ TOTAL │ 1.00 │ 3.XX │ X.XX │ X.XX │
│ RANKING │ │ #1 │ #2 │ #3 │
└─────────────────────┴───────────┴───────────┴───────────┘
Decision Type: [Two-way door / One-way door]
Recommended Option: [Option A/B/C]
Review Date: [Date to revisit if assumptions prove wrong]
These examples demonstrate how leading companies navigated similar tradeoffs:
Conflict: Performance under load vs. operational complexity
Conflict: Fast iteration vs. long-term performance scalability
Conflict: Data integrity vs. rapid schema evolution during product discovery
Conflict: Technical elegance (Elixir/BEAM) vs. organizational hiring reality
Conflict: Build cost vs. vendor lock-in risk + competitive differentiation
Apply these rules of thumb when the analysis feels stuck or overwhelming:
When applying this skill to a tradeoff decision, produce:
For one-way door decisions, also produce an Architecture Decision Record following the architecture-decision-records skill template.
| Skill | Purpose |
|---|---|
architecture-decision-records | Document the decision after it's made — this skill analyzes, ADRs record |
design-pattern-selection | Picks specific implementation patterns — use after tradeoff analysis narrows direction |
engineering-principles | Foundational principles that inform criteria weights and constraint definitions |
technical-debt-management | When the tradeoff accepts debt, track it here with repayment plans |
Authoritative sources for engineering tradeoff frameworks and decision-making methodologies.