# Incremental Implementation

> 以增量方式交付改动。适用于实现任何涉及多个文件的功能或改动，也适用于你即将一次性写大量代码，或任务大到不适合一步落地的时候。

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

---


# 增量实现

## 概览

用薄的纵向切片来构建系统：实现一小块，测试它，验证它，再继续扩展。避免一次把整个功能全部做完。每一个增量都应该让系统保持在可工作、可测试的状态。这种执行纪律，能让大型功能变得可控。

## 何时使用

- 实现任何多文件改动
- 根据任务拆解落地新功能
- 重构现有代码
- 任何你想在测试前一口气写超过约 100 行代码的时候

**不适用的场景：** 单文件、单函数，并且范围已经很小的改动。

## 增量循环

```
┌──────────────────────────────────────┐
│                                      │
│   Implement ──→ Test ──→ Verify ──┐  │
│       ▲                           │  │
│       └───── Commit ◄─────────────┘  │
│              │                       │
│              ▼                       │
│          Next slice                  │
│                                      │
└──────────────────────────────────────┘
```

对于每个切片：

1. **Implement**：实现最小但完整的一块功能
2. **Test**：运行测试，如果还没有测试就补测试
3. **Verify**：确认这一块真的符合预期，例如测试通过、构建成功、手工检查正常
4. **Commit**：用清晰的提交信息保存进度，参见 `git-workflow-and-versioning`
5. **Move to the next slice**：继续推进，不要推倒重来

## 切片策略

### 纵向切片（首选）

一次打通一条完整路径：

```
Slice 1: Create a task (DB + API + basic UI)
    → Tests pass, user can create a task via the UI

Slice 2: List tasks (query + API + UI)
    → Tests pass, user can see their tasks

Slice 3: Edit a task (update + API + UI)
    → Tests pass, user can modify tasks

Slice 4: Delete a task (delete + API + UI + confirmation)
    → Tests pass, full CRUD complete
```

每个切片都能交付一个真实可用的端到端能力。

### 先定义契约的切片方式

当前后端需要并行开发时：

```
Slice 0: Define the API contract (types, interfaces, OpenAPI spec)
Slice 1a: Implement backend against the contract + API tests
Slice 1b: Implement frontend against mock data matching the contract
Slice 2: Integrate and test end-to-end
```

### 风险优先切片

先处理最危险、最不确定的部分：

```
Slice 1: Prove the WebSocket connection works (highest risk)
Slice 2: Build real-time task updates on the proven connection
Slice 3: Add offline support and reconnection
```

如果 Slice 1 失败，你会在投入 Slice 2 和 3 之前就知道。

## 实现规则

### 规则 0：简单优先

在写代码之前，先问一句：“能工作的最简单方案是什么？”

写完之后，再用下面这些问题回看：
- 能不能用更少的代码实现？
- 这些抽象真的值回它们的复杂度吗？
- 资深工程师会不会看完后问一句“你为什么不直接……？”
- 我是在为假想的未来需求设计，还是只为当前任务服务？

```
SIMPLICITY CHECK:
✗ Generic EventBus with middleware pipeline for one notification
✓ Simple function call

✗ Abstract factory pattern for two similar components
✓ Two straightforward components with shared utilities

✗ Config-driven form builder for three forms
✓ Three form components
```

三行相似代码，通常也比过早抽象更好。先实现朴素、显然正确的版本，只有在正确性已经通过测试证明后再考虑优化。

### 规则 0.5：范围纪律

只改任务要求你改的内容。

不要：
- 顺手“清理”你改动旁边的代码
- 在没修改的文件里重排 import
- 删除你并未完全理解的注释
- 因为“看起来有用”就擅自加功能
- 只是阅读某个文件，却顺手把它语法现代化

如果你发现范围外有值得改进的地方，记录下来，但不要顺手修：

```
NOTICED BUT NOT TOUCHING:
- src/utils/format.ts has an unused import (unrelated to this task)
- The auth middleware could use better error messages (separate task)
→ Want me to create tasks for these?
```

### 规则 1：一次只做一件事

每个增量只改变一个逻辑点，不要混杂关注点：

**坏例子：** 一个提交同时新增组件、重构旧组件并修改构建配置。  
**好例子：** 拆成三个提交，每个只做一类改动。

### 规则 2：始终保持可编译

每个增量之后，项目都必须能构建，已有测试都必须通过。不要在切片之间让代码库处于损坏状态。

### 规则 3：未完成功能用 Feature Flag 包住

如果功能还没准备好给用户用，但你需要提前合并增量：

```typescript
// Feature flag for work-in-progress
const ENABLE_TASK_SHARING = process.env.FEATURE_TASK_SHARING === 'true';

if (ENABLE_TASK_SHARING) {
  // New sharing UI
}
```

这样你就能把小步增量合并到主干，同时不暴露未完成功能。

### 规则 4：安全默认值

新代码默认应该采取安全、保守的行为：

```typescript
// Safe: disabled by default, opt-in
export function createTask(data: TaskInput, options?: { notify?: boolean }) {
  const shouldNotify = options?.notify ?? false;
  // ...
}
```

### 规则 5：对回滚友好

每个增量都应该能独立回退：

- 增量式改动，比如新增文件、新增函数，最容易回滚
- 修改现有代码时，改动要小而聚焦
- 数据库迁移要有对应的回滚迁移
- 不要在同一个提交里既删除旧东西又放入新替代品，拆开提交

## 与 Agent 协作

当你指挥 agent 以增量方式实现时：

```
"Let's implement Task 3 from the plan.

Start with just the database schema change and the API endpoint.
Don't touch the UI yet — we'll do that in the next increment.

After implementing, run `npm test` and `npm run build` to verify
nothing is broken."
```

对每个增量，明确说明哪些在范围内，哪些不在范围内。

## 增量检查清单

每做完一个增量，都确认：

- [ ] 改动只做了一件事，而且做完整了
- [ ] 所有现有测试仍通过（`npm test`）
- [ ] 构建成功（`npm run build`）
- [ ] 类型检查通过（`npx tsc --noEmit`）
- [ ] Lint 通过（`npm run lint`）
- [ ] 新功能按预期工作
- [ ] 已用清晰提交信息完成提交

## 常见自我安慰

| 自我安慰 | 现实 |
|---|---|
| “最后一起测就行” | Bug 会叠加。Slice 1 的 bug 会让 Slice 2-5 全部建立在错误基础上。每个切片都要测。 |
| “一次做完更快” | 只有在一切正常时它才“看起来更快”。一旦出问题，你根本不知道 500 行改动里是哪一行引入了故障。 |
| “这些改动太小了，不值得分开提交” | 小提交几乎没有成本。大提交会隐藏 bug，也让回滚变痛苦。 |
| “Feature flag 之后再加” | 如果功能还没完成，就不应该让用户看见。现在就加。 |
| “这个重构很小，可以顺便做” | 功能和重构混在一起，会让评审和排障都更困难。拆开做。 |

## 危险信号

- 在不跑测试的情况下连续写超过 100 行代码
- 一个增量里混入多个无关改动
- 出现“我顺手再加一下这个”的范围膨胀
- 为了追求速度跳过测试或验证
- 切片之间构建或测试处于失败状态
- 大量未提交改动越积越多
- 在第三个用例出现前就先设计抽象
- 因为“反正我都在这了”而去动范围外文件
- 为一次性操作新建通用工具文件

## 验证

完成一个任务的所有增量后，确认：

- [ ] 每个增量都已单独测试并提交
- [ ] 全量测试通过
- [ ] 构建干净
- [ ] 功能按 spec 端到端正常工作
- [ ] 没有遗留未提交改动

