# System Design 3 Layer

> 进行系统设计时使用，本技能提供系统化的设计方法论，通过三层认知架构（直觉-工程-形式化）确保设计方案从概念到实现的严谨性。适用于后端架构、前端交互、分布式系统、嵌入式系统等复杂软件设计场景。

- Skill: `yamsfeer/system-design-3-layer` (Agent Skill)
- Install (CLI): `npx skillmds@latest add yamsfeer/system-design-3-layer`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yamsfeer/system-design-3-layer/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: yamsfeer (https://skillmd.com/u/yamsfeer)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/yamsfeer/system-design-3-layer

---


# System Design Skill: Tri-Layer Architectural Reasoning

# 系统设计技能：三层认知架构推理法

## 1. Skill Overview 技能概述

本技能提供系统化的设计方法论，通过三层认知架构（直觉-工程-形式化）确保设计方案从概念到实现的严谨性。适用于后端架构、前端交互、分布式系统、嵌入式系统等复杂软件设计场景。

**核心原则**:

- **Layer 1 (直觉层)**: 快速启动，建立认知锚点
- **Layer 2 (工程层)**: 约束驱动，验证设计必要性
- **Layer 3 (形式化层)**: 数学保证，消除不确定性

---

## 2. Layer 1: Experiential Intuition 经验直觉层

**定义**: 基于模式识别、类比和启发式的快速设计方法
**适用场景**: 概念探索、技术选型初期、陌生领域快速建模
**风险提示**: 可能产生偏见，必须在 Layer 2 验证

### 2.1 Comparative Study 对比迁移法

**触发条件**: 面对不熟悉的问题域，需要快速建立认知模型

**执行步骤**:

1. 识别当前问题与已知系统的相似性维度（架构、约束、数据流）
2. 列举 3 个相似系统的解决方案
3. 对比差异点（规模、并发量、一致性要求）
4. 迁移适配（不要复制，要改造）

**输出模板**:

```markdown
### 对比迁移分析

- **参照系统**: [System A], [System B], [System C]
- **相似性**: [维度1], [维度2]
- **关键差异**: [差异1: 约束不同], [差异2: 规模不同]
- **可迁移模式**: [Pattern X - 需改造Y]
- **不可迁移点**: [因差异Z而放弃]
```

**示例**:

> 设计一个实时协作白板：
>
> - 参照：Google Docs (OT), Figma (CRDT), Git (版本控制)
> - 相似：多人并发编辑
> - 差异：白板是二维几何数据（非线性文本），需保留笔压时序
> - 迁移：采用 CRDT 而非 OT（更适合几何对象的冲突解决）

### 2.2 Pattern Matching 模式匹配法

**触发条件**: 识别到熟悉的设计场景（高并发、数据一致性、容错等）

**执行步骤**:

1. 识别核心场景关键词（如"秒杀"、"聊天室"、"主从同步"）
2. 调用对应经典模式目录
3. 检查模式的前提条件是否满足
4. 应用模式并记录假设

**经典模式目录**:

- **并发控制**: 乐观锁、悲观锁、CAS、Actor 模型
- **数据一致性**: 最终一致、强一致、BASE、CAP 权衡
- **容错**: 熔断、限流、舱壁、重试退避
- **前端状态**: Redux（单一状态树）、Zustand（原子化）、TanStack Query（服务器状态缓存）

**输出模板**:

```markdown
### 模式匹配

- **场景识别**: [Scenario: 高并发写]
- **匹配模式**: [Pattern: 写缓冲 + 异步刷盘]
- **前提条件检查**:
  - [x] 允许短暂不一致
  - [ ] 需要立即持久化（不满足，需调整）
- **调整措施**: [改为：同步写 WAL + 异步刷数据页]
```

### 2.3 Heuristic Evaluation 启发式评估

**触发条件**: 需要快速检查设计明显的反模式或坏味道

**检查清单**:

- [ ] **单一职责**: 一个模块是否只处理一种变化原因？
- [ ] **开闭原则**: 新增功能是否需要修改旧代码？
- [ ] **最小 surprised**: API 行为是否符合直觉命名？
- [ ] **正交性**: 移除组件 A 是否会导致组件 B 意外失效？
- [ ] **前端特有**: 是否处理了 Loading/Error/Success 三态？

**输出**: 风险标记列表（高/中/低）

---

## 3. Layer 2: Engineering Heuristics 工程思维层

**定义**: 通过约束分析、反事实推理和架构分层，确保设计的必要性和可行性
**适用场景**: 详细设计、架构评审、技术方案选型
**目标**: 证明设计是"被逼出来的"，而非"拍脑袋想出来的"

### 3.1 Necessity-Driven Reasoning 反证式推理

**触发条件**: 需要验证某个组件/机制是否必须存在，或证明某设计的唯一性

**执行步骤（四步法）**:

1. **Assume the Negative**: 假设目标机制不存在，使用朴素方案（MVS - Minimal Viable Solution）
2. **Apply Constraints**: 依次施加系统约束（性能、安全、一致性、资源限制）
3. **Derive Contradiction**: 推导约束违反导致的连锁故障（具体、可观测的失效）
4. **Prove Necessity**: 证明该机制是满足约束的**最小充分集**（不可再减）

**输出模板**:

```markdown
### 反证式推理: [机制名称]

**Step 1 - 否定假设**: 假设没有 [消息队列]，只用 [管道]
**Step 2 - 施加约束**:

- C1: 异步通信（发送方不等接收方）
- C2: 内存有界（内核资源安全）
  **Step 3 - 矛盾推导**:
- 无队列 + C1 → 发送方阻塞等待 → 失去异步语义（违反C1）
- 无队列 + C2 → 数据积压 → OOM（违反C2）
- 应用层自己实现队列 → 重复造轮子、字节序问题、竞态条件
  **Step 4 - 必然性结论**:
- [消息队列] 是 [异步通信 ∧ 资源安全] 的必然交集
- 最小结构必须包含: [有界缓冲] + [消息边界维护] + [同步原语]
- 去掉任一部分 → 特定场景失效
```

**示例（后端）**:

> **问题**: 为什么需要 WAL（预写日志）？
>
> - 否定：直接写入数据文件
> - 约束：崩溃后原子性（要么全写要么全不）
> - 矛盾：数据文件半写状态无法回滚
> - 必然：必须先写顺序日志（WAL），再异步刷盘，崩溃后重放日志

**示例（前端）**:

> **问题**: 为什么需要虚拟列表（Virtual List）？
>
> - 否定：直接渲染 10万条 DOM
> - 约束：浏览器渲染 16ms/帧（60fps），DOM 节点内存限制
> - 矛盾：布局计算超时 → 卡顿；内存溢出 → 崩溃
> - 必然：只渲染视口内节点 + 占位符高度计算

### 3.2 First Principles 第一性原理

**触发条件**: 现有方案都不满意，需要从零创新；或理解某设计的物理极限

**执行步骤**:

1. **剥离**: 去除所有现有实现（"不用 Redis/不用 React"）
2. **识别物理约束**: 列出不可妥协的硬性限制（光速、内存墙、CAP 定理、浏览器单线程）
3. **数学建模**: 用公式描述约束（如：延迟 = 网络RTT + 处理时间 + 排队延迟）
4. **自下而上重建**: 从约束推导最小必要结构

**输出模板**:

```markdown
### 第一性原理分析

**剥离现有方案**: [抛开 Kafka/React/微服务]
**物理约束识别**:

- P1: [网络分区必然发生]
- P2: [磁盘顺序写速度 > 随机写两个数量级]
- P3: [浏览器主线程是单线程]
  **数学关系**:
- Throughput ≤ min(Bandwidth, 1/Latency)
  **重建设计**:
- 由 P2 得：必须将随机写转为顺序追加（Log-Structured Merge）
- 由 P1 得：必须接受最终一致性，设计冲突解决策略
- 最终结构: [LSM-Tree + Vector Clock]
```

**对比反证法**:

- 反证法：**验证**现有设计的必要性（"为什么不能去掉X"）
- 第一性原理：**生成**新设计（"如果重新发明，物理极限允许什么"）

### 3.3 Layered Abstraction 抽象分层

**触发条件**: 系统复杂度爆炸，需要分离关注点；或设计跨层接口

**执行步骤**:

1. **识别复杂度类型**: 业务逻辑/数据存储/网络通信/呈现渲染
2. **定义层间契约**: 上层向下层请求什么？下层承诺什么不变量？
3. **验证解耦**: 能否替换某层实现而不影响其他层？
4. **检查依赖方向**: 确保依赖单向（高层→低层），无循环依赖

**输出模板**:

```markdown
### 分层架构: [系统名称]

| 层级      | 职责     | 契约（对外承诺） | 替换成本 |
| --------- | -------- | ---------------- | -------- |
| L3 API层  | 协议转换 | 请求有效性验证   | 低       |
| L2 业务层 | 用例编排 | 事务边界/一致性  | 中       |
| L1 存储层 | 持久化   | ACID/查询能力    | 高       |

**关键约束传播**:

- 上层 [需要强一致] → 下层必须提供 [事务]
- 下层 [分片存储] → 上层必须处理 [分布式查询]
```

### 3.4 Trade-off Analysis 权衡分析

**触发条件**: 多个可行方案间选择，需要量化利弊

**执行步骤**:

1. **定义评估维度**: 性能、成本、复杂度、可维护性、安全、时间-to-market
2. **建立约束权重**: 当前场景下哪个维度是硬约束（必须满足），哪个是软约束（可妥协）
3. **方案映射**: 将各方案映射到维度空间
4. **帕累托最优**: 找出没有被其他方案全面超越的选项

**输出模板**:

```markdown
### 权衡分析: [决策主题]

**维度权重**:

- 一致性 (Hard) / 延迟 (Hard) / 成本 (Soft)

**方案对比**:
| 方案 | 一致性 | 延迟 | 成本 | 适用场景 |
|------|--------|------|------|----------|
| A. 强同步复制 | 强 | 高(100ms) | 高 | 金融交易 |
| B. 异步复制 | 最终 | 低(10ms) | 中 | 社交网络 |
| C. 本地缓存 | 弱 | 极低(1ms) | 低 | 配置读取 |

**决策**: 选择 [B]，因 [场景允许最终一致，且延迟要求 < 50ms]
**回退策略**: 当 [一致性冲突率 > 1%] 时升级到方案 A
```

### 3.5 Failure-Driven Design 故障驱动设计

**触发条件**: 设计高可用系统；或进行 Chaos Engineering 前的理论分析

**执行步骤**:

1. **故障枚举**: 列出所有可能的失效模式（网络分区、磁盘满、依赖服务挂、浏览器崩溃）
2. **级联分析**: 单个故障是否会导致雪崩？
3. **容错策略**: 熔断、降级、限流、冗余
4. **故障注入点**: 设计可测试的故障场景

**输出模板**:

```markdown
### 故障场景: [组件X失效]

**失效模式**: [慢查询/拒绝服务/数据损坏]
**级联影响**:

- 直接: 服务A超时
- 二级: 线程池耗尽 → 服务B不可用
  **容错设计**:
- 检测: 超时 + 错误率阈值
- 隔离: 舱壁模式（独立线程池）
- 恢复: 自动降级到缓存数据
```

---

## 4. Layer 3: Formal Verification 形式化验证层

**定义**: 使用数学方法证明设计的正确性，消除实现模糊性
**适用场景**: 安全关键系统、分布式一致性协议、并发控制、复杂状态机
**工具**: 类型系统、状态机模型、不变量断言、霍尔逻辑

### 4.1 Invariant-Driven Design 不变量驱动

**触发条件**: 系统必须维持关键属性（如"余额非负"、"数据不丢"）

**执行步骤**:

1. **定义全局不变量**: 用数学表达式描述必须永远为真的条件（∀x ∈ Data, P(x)）
2. **操作前置/后置条件**: 每个操作必须保持（或建立）不变量
3. **状态转移验证**: 证明所有可能的状态转移都不会违反不变量
4. **边界检查**: 初始化是否满足？故障恢复后是否仍满足？

**输出模板**:

```markdown
### 不变量定义: [系统状态]

**全局不变量 I**:

- I1: ∀account, balance ≥ 0
- I2: total_supply = Σ all balances
- I3: queue.size ∈ [0, capacity]

**操作: transfer(from, to, amount)**

- Pre: balance[from] ≥ amount ∧ amount > 0
- Post: balance[from]' = balance[from] - amount
  ∧ balance[to]' = balance[to] + amount
  ∧ total_supply' = total_supply (保持 I2)
- 验证: I1 不会被违反（因 Pre 确保 from 足够，to 接收后仍 ≥ 0）
```

**前端示例**:

> **不变量**: 表单提交时，所有必填字段已验证通过
>
> - Pre: `isValid(field) === true for all required fields`
> - Post: `apiCall.success || apiCall.error (无悬空提交状态)`

### 4.2 Design by Contract 契约式设计

**触发条件**: 定义模块/服务接口的严格语义

**执行步骤**:

1. **定义契约三元组**: {Precondition} Operation {Postcondition}
2. **副作用声明**: 明确列出操作修改了哪些状态（Frame Condition）
3. **异常契约**: 前置条件不满足时的行为（快速失败 vs 优雅降级）
4. **组合验证**: 串联操作时，前一操作的后置条件必须满足后一操作的前置条件

**输出模板**:

```typescript
// 伪代码 + 契约注释
function dequeue(queue: Queue<T>): T
  requires: !queue.isEmpty()          // 前置：队列非空
  ensures:
    queue.size' == queue.size - 1     // 后置：大小减1
    result == queue.head_old          // 返回原队首
  modifies: queue                     // 修改范围
  throws: EmptyQueueException if precondition violated
```

### 4.3 State Machine Refinement 状态机精化

**触发条件**: 复杂交互流程（工作流、审批流、游戏状态、协议实现）

**执行步骤**:

1. **抽象机**: 定义高层状态（如：Idle → Processing → Completed）
2. **精化机**: 添加子状态（Processing: Validating → Executing → Saving）
3. **精化证明**: 证明精化层的每个转移都对应抽象层的有效转移（观察一致性）
4. **死锁检测**: 检查是否所有状态都有出边（除终止态外）

**输出模板**:

```markdown
### 状态机: [流程名称]

**抽象层**:
Idle --start--> Running --finish--> Completed
|
--cancel--> Cancelled

**精化层 (Running)**:
Running --validation_fail--> Error
Running --validation_ok--> Executing --save_ok--> Completed
--save_fail--> Error

**验证**:

- 精化层从 Executing 到 Completed 对应抽象层 Running 到 Completed
- 无死锁：Error 状态可 reset 到 Idle，Completed/Cancelled 为终止态
```

### 4.4 Type-Driven Design 类型驱动

**触发条件**: 使用强类型语言（TypeScript/Rust/Haskell），利用类型系统防止非法状态

**执行步骤**:

1. **使非法状态不可表示**: 用类型约束排除无效组合（如用 `NonEmptyArray` 而非 `Array`）
2. **状态作为类型**: 将运行时状态提升到编译期（如 `LoggedInUser` vs `Guest`）
3. **依赖类型**: 类型依赖于值（如 `Vector<N>` 长度在类型中）
4. **总函数**: 确保所有输入都有定义输出（用 Sum Type 处理所有分支）

**输出模板**:

```typescript
// 例：防止未加载数据被访问
type AsyncData<T> =
  | { status: 'loading' }
  | { status: 'error'; error: Error }
  | { status: 'success'; data: T };

// 编译器强制处理所有情况，无空指针异常
function render<T>(asyncData: AsyncData<T>): View {
  switch (asyncData.status) {
    case 'loading': return <Spinner />;
    case 'error': return <Error msg={asyncData.error} />;
    case 'success': return <DataView data={asyncData.data} />;
  }
}
```

---

## 5. 决策树与使用流程

### 5.1 何时使用哪一层？

```
开始设计
  │
  ├─ 完全陌生领域？ ──Yes──> Layer 1 (对比迁移建立认知)
  │   No
  ├─ 需要证明设计必要性？ ──Yes──> Layer 2 (反证式推理)
  │   No
  ├─ 涉及并发/安全/一致性？ ──Yes──> Layer 3 (不变量/契约)
  │   No
  └─ 常规 CRUD/简单界面？ ──> Layer 2 (分层+权衡) 足够

紧急程度评估：
- 紧急 (小时级): Layer 1 → 快速方案 → 标记风险
- 标准 (天级): Layer 1 → Layer 2 → 详细设计
- 关键 (周级): Layer 1 → Layer 2 → Layer 3 → 形式化验证
```

### 5.2 完整工作流（系统设计 SOP）

**Phase 1: 探索（Layer 1）**

1. 使用 **对比迁移** 收集 3 个相似系统方案
2. 使用 **模式匹配** 识别标准架构模式
3. 输出：候选架构草图（3 个选项）

**Phase 2: 验证（Layer 2）**

1. 对核心机制使用 **反证式推理**（证明为什么必须有消息队列/缓存/分片）
2. 对整体架构使用 **分层抽象** 划分边界
3. 对选型使用 **权衡分析** 确定最终方案
4. 使用 **故障驱动** 设计容错策略
5. 输出：带约束条件的设计文档

**Phase 3: 固化（Layer 3 - 可选但推荐）**

1. 定义关键 **不变量**（系统必须永远为真的属性）
2. 为核心接口编写 **契约**（前置/后置条件）
3. 复杂流程使用 **状态机精化** 建模
4. 使用 **类型系统** 在代码层固化约束
5. 输出：可验证的规格说明 + 类型定义

---

## 6. 输出格式规范

要求 Agent 输出设计方案时，必须包含以下章节：

```markdown
# 系统设计方案: [项目名称]

## 1. 直觉层扫描 (Layer 1)

- 参照系统: [List]
- 识别模式: [Pattern]
- 直觉风险: [List]

## 2. 核心机制验证 (Layer 2)

### 2.1 反证式推理

- [机制名]: [必要性证明]

### 2.2 分层架构

- [层定义表格]

### 2.3 关键权衡

- [决策矩阵]

## 3. 形式化保证 (Layer 3 - 如适用)

### 3.1 不变量

- I1: [定义]

### 3.2 状态机 (如适用)

- [状态转移图]

### 3.3 类型定义 (伪代码)

- [ADT 定义]

## 4. 风险与回退

- [故障场景及应对]
```

---

## 7. 示例：设计一个分布式任务调度系统

**指令**: "使用本技能设计一个支持百万级任务/天的分布式调度系统"

**Agent 执行过程**:

### Layer 1: 对比迁移

- 参照：Celery (Python), Sidekiq (Ruby), Kubernetes Job
- 模式匹配：需要 Worker Pool + 持久化队列 + 重试机制

### Layer 2: 反证式推理

**问题**: 为什么需要延迟队列（Delayed Queue）？

- 否定：所有任务立即执行
- 约束：任务有定时触发需求（如"明天中午发送邮件"）；瞬时流量可能压垮下游
- 矛盾：立即执行无法满足时间约束；无缓冲导致雪崩
- 必然：必须引入可排序的延迟队列（时间轮或优先队列）

**分层**:

- API 层：接收任务，验证schema
- 调度层：维护时间堆，触发就绪任务
- 执行层：Worker 池，实际执行业务逻辑
- 存储层：任务持久化，状态机维护

### Layer 3: 不变量与状态机

**不变量**:

- I1: 任务状态 ∈ {Pending, Scheduled, Running, Success, Failed, DeadLetter} （无非法状态）
- I2: 同一任务同一时刻只被一个 Worker 执行（互斥）
- I3: 至少执行一次（At-least-once delivery）

**状态机精化**:

```
Pending --schedule--> Scheduled --dispatch--> Running --success--> Success
                                           --fail+retry<3--> Scheduled
                                           --fail+retry>=3--> DeadLetter
```

**契约**:

```typescript
function dispatch(task: Task): void
  requires: task.status === 'Scheduled' && task.scheduledTime <= now()
  ensures: task.status' === 'Running' && task.workerId !== null
  modifies: task.status, task.workerId, task.startTime
```

---

## 8. 限制与注意事项

**不适用场景**:

- UI/UX 细节设计（需用设计思维而非系统思维）
- 纯粹的业务逻辑编排（过于简单，无需三层）
- 探索性数据科学（假设-验证周期太短）

**常见陷阱**:

- **过度形式化**: 对简单系统使用 Layer 3 造成浪费（YAGNI 原则）
- **虚假反证**: 在 Layer 2 中构造不现实的约束来证明不必要的设计（必须在真实业务约束下推导）
- **直觉锁定**: 在 Layer 1 过早满意，跳过 Layer 2 验证（ Confirmation Bias）

**建议**: 始终从 Layer 2 开始，当不确定时使用 Layer 1 探索，当涉及资金安全/人身安全时使用 Layer 3。

