结对编程辅助

本页定义 Driver/Navigator 职责分工、25 分钟 Pomodoro 轮换节奏、真实的 Driver+Agent 协作会话记录、分歧决策规则,以及增量提交的 git commit 格式规范。

SKILL 可规定会话结构:先对齐任务边界与验收标准,再由「驾驶员」实现小块逻辑,「导航员」(人或 Agent)负责命名、边界情况与与现有模式一致性。下文按节展开,并附一轮驾驶员/导航员循环示意图。

角色分工

驾驶员(Driver)拥有编辑焦点:输入代码、运行命令、触发测试。职责是保持小步前进,并在每个可验证点停下来。导航员(Navigator)不抢键盘(除非轮换),持续对照团队约定:可读性、错误处理、与周边模块的耦合方式。

Driver 负责(持有键盘):
  ✓ 打开编辑器,输入具体代码
  ✓ 运行测试命令:npm test / pytest / go test ./...
  ✓ 执行 git add / commit(按导航员确认后)
  ✓ 保持每步 ≤ 10 行改动,每步可通过测试或失败明确
  ✗ 不做架构决策,不跳过测试验证步骤

Navigator 负责(不持有键盘):
  ✓ 大声检查命名是否与仓库约定一致
  ✓ 标出遗漏的错误处理分支与边界情况
  ✓ 对照已有模块检查耦合方向是否合理
  ✓ 记录分歧点(见下方分歧决策规则)
  ✓ 在交换前用一句话总结:「接下来要做 X,风险是 Y」
  ✗ 不在驾驶员打字时并行重写代码

每 25 分钟强制交换(Pomodoro 变体):
  [0-25 min] Driver 实现 → Navigator 导航
  [25 min]   5 分钟切换:交接上下文 + 提交当前增量
  [30-32 min] 2 分钟复盘:本轮完成了什么、下轮目标是什么
  [32-57 min] 新 Driver 接手(原 Navigator 变 Driver)
原则:同一时刻只有一个「方向盘」。导航员若发现驾驶员在隧道视野里加速,应打断并建议缩小本轮目标,而不是事后在 PR 里一次性吐槽。

当前视角(仅本页)

轮换节奏

每完成一个可运行增量(绿测、或明确失败的单测)、或每修好一个与本轮目标直接相关的失败用例后,考虑交换角色,减轻疲劳与认知偏差。紧急 hotfix 可压缩为「你写我审」的短回合,但仍要口头过一遍变更面与回滚点。

  [ 对齐本轮目标 + 验收标准 ]
                    │
                    ▼
            ┌───────────────┐
            │    DRIVER     │  敲键盘、跑测、小步提交
            └───────┬───────┘
                    │
                    ▼
            ┌───────────────┐
            │   NAVIGATOR   │  命名 / 边界 / 与现有模式一致
            └───────┬───────┘
                    │
                    ▼
            [ 本轮可运行增量完成? ]
                    │
         ┌──────────┴──────────┐
         │ no                  │ yes
         ▼                     ▼
  [ 继续:缩小范围或补信息 ]   [ 轮换角色 或 记录决策 ]
  • 轮换前用一句话交接:「接下来文件 X 里要实现 Y,已知风险是 Z。」
  • 长时间会话建议设墙上时钟提醒,避免两人同时陷入实现细节。

Agent 作导航员

Agent 适合承担导航员角色时:主动要求展示调用栈、相关文件片段或测试输出,避免在信息不足时大段改写。人类驾驶员应定期口述当前假设(「我认为这里会先走缓存」),便于模型纠正方向而非附和幻觉。

下面是一段真实的 Driver(人类)+ Agent(导航员)协作会话记录:

Driver:「我要给 checkout API 加一个优惠码校验,现在在写 validateCoupon 函数」

Agent(导航员):「好,我看到你要调用 coupon.findOne(),在写之前:
  1. findOne 返回 null 时你打算怎么处理?
  2. 同一个用户同一订单用两次同一优惠码的情况考虑了吗?」

Driver:「第一个我返回 { valid: false, reason: 'NOT_FOUND' },
       第二个还没考虑,先跳过吧」

Agent:「跳过可以,但先加个 TODO 注释:
  // TODO(JIRA-456): 防重用校验,同用户同码只能用一次
  这样后续 PR 可以追踪」

Driver:「好,加上了。现在写测试——」

Agent:「先不写实现,先写一个失败的测试:
  it('should reject invalid coupon code', async () => {
    const result = await validateCoupon('INVALID', orderId);
    expect(result.valid).toBe(false);
    expect(result.reason).toBe('NOT_FOUND');
  });
  测试红了之后再写实现,TDD 步骤。」

Driver:「明白,运行 npm test — 测试红了,现在写实现」
(25 分钟后)
Driver:「实现完了,测试绿了,准备提交」

Agent:「提交信息格式:feat(checkout): add coupon validation with NOT_FOUND handling
  然后交换角色——下一轮你来导航员」
约束 Agent:输出应可逐段应用(小 patch 或分步骤说明),禁止默认交付无法审阅的巨型 diff;若缺符号或路径,先问再写。

当 Agent 暂时充当驾驶员(例如生成脚手架)时,人类应切回导航员,显式验收每一步:编译、类型检查、与现有目录结构是否一致。

意见分歧决策规则

分歧发生时的处理步骤:
1. 导航员提出异议,驾驶员暂停,双方各用 1 句话陈述理由
2. 判断类型:
   a. 技术事实分歧(「这样写会有内存泄漏」)→ 写测试验证,数据说话
   b. 风格/命名分歧 → 查现有仓库规范;若无规范则 Driver 决定,记录 TODO
   c. 架构/设计分歧 → 超出本轮范围,记录为 ADR 草稿,本轮用最简单实现
3. 最终决策者:Driver 在本轮持有最终决策权
4. 分歧记录格式(写进 git commit body 或 PR 描述):
   [DECISION] 选择方案 A 而非 B,原因:XXX
   [DEFERRED] 方案 C 暂缓,待 JIRA-789 中确认

增量提交的 git commit 格式

# 每次 Pomodoro 结束后提交,格式:
# <type>(<scope>): <简短描述>(50 字内)
#
# [可选 body:本轮实现了什么 / 决策记录]

# 示例:
feat(auth): add JWT token refresh endpoint

- 实现了 POST /api/auth/refresh
- 过期 token 返回 401,非法签名返回 403
- [DECISION] 用 RS256 而非 HS256,支持多服务验证

test(auth): add unit tests for token refresh

- 覆盖正常刷新、过期 token、签名错误三个分支
- 使用 jest.useFakeTimers 模拟 token 过期

# 禁止的提交格式:
# git commit -m "fix stuff"        ← 无法追踪
# git commit -m "WIP"              ← 不可 revert 到有意义状态
# git commit -m "更新了很多文件"   ← 无具体语义

PR 与审查卫生

结对的价值一部分要沉淀给异步审查者:在 PR 描述中写清「结对结论」——哪些方案被否决、为什么、有没有未竟事项。复杂重构可链接 ADR 或 issue,避免审查者重复争论已在键盘前 resolved 的点。

  • 复杂改动结对前先跑通基线测试与类型检查,PR 只承载增量差异。
  • 需要后续跟进的项用 checklist 或 TODO(带 owner),不要只留在对话记录里。
审查友好:若结对时已拆好 commit,保持每个 commit 语义单一;审查者可以按提交顺序阅读,而不是面对一团历史。
---
name: pair-programming
description: Driver/Navigator 结对协作、Pomodoro 轮换、增量提交与分歧决策
---

# 会话开始(每次结对前执行)
1. 明确本轮目标(1 句话):「本轮实现 POST /api/coupon/validate,含 NOT_FOUND 和 EXPIRED 两个错误路径」
2. 明确验收标准:「npm test 绿,类型检查通过,有 ≥ 2 个测试用例」
3. 指定当前角色:Driver=人类,Navigator=Agent

# Driver 每步规范
4. 写测试(先 RED)→ 写实现(GREEN)→ 重构(REFACTOR)
5. 每步改动 ≤ 10 行,每步运行一次测试命令
6. 发现思路卡住时,出声描述当前状态,让 Navigator 介入

# Navigator 检查项(每步结束时)
7. 命名与仓库约定一致?(检查 src/utils/ 里的命名模式)
8. 错误分支有没有遗漏?(网络超时 / 数据库异常 / 并发情况)
9. 是否引入了新的外部依赖(需 review deps)?
10. 测试是否断言了可观察行为(而不只是实现细节)?

# 25min Pomodoro 轮换步骤
11. [25min] Driver 提交当前增量:git add -p && git commit -m "feat: ..."
12. [+5min] 交接口述:「我实现了 X,已知问题是 Y,下一步是 Z」
13. [+2min] 复盘:本轮达成了什么,下轮从哪里开始
14. 角色互换:原 Driver 变 Navigator,原 Navigator 变 Driver

# 分歧决策
15. 技术分歧 → 写测试验证,数据说话
16. 风格分歧 → 查仓库规范,无规范则 Driver 决定
17. 架构分歧 → 本轮用最简实现,记录 [DECISION] 注释待后续 ADR

# 会话结束
18. 推送分支,检查 CI 状态
19. 在 PR 描述中写「结对结论」:否决了哪些方案、遗留了哪些 TODO

返回技能库 更多技能入口