Agent 工程化课程
-- / --

CHAPTER 01 — 04

与 Agent 一起做工程:
计划、执行、验证的证据闭环

让 Agent 写代码并不难。难的是让它在不猜需求的前提下,持续拿到可信证据,判断自己是否做对,并在失败后恢复。

工程基础计划执行验证
配图
课程总览全书围绕同一个闭环展开

一条主线:有边界的证据闭环

任务与边界 · 第一章
发现计划 · 第二章执行 · 第三章恢复
观察验证 · 第四章完成声明升级给人

Agent 的工作不应被定义为"不问人",而应被定义为:在证据充分时独立推进;否则准确升级。

  • 第一章 打地基:边界与反馈设施,让证据可获得。
  • 第二章 把模糊需求变成可执行、可评审、可验证的规格。
  • 第三章 小步推进,控制变更半径,失败可恢复。
  • 第四章 用证据收敛,而不是口头宣布完成。
配图
课程总览四章 · 一个贯穿全书的 starter repo

目录

CHAPTER 01

构建 Agent-Friendly 的工程基础

安全护栏 · 入场路径 · 命令契约 · 验证阶梯 · 规则文件 · 环境模式 · CI 同构 · 外部系统接入 · 遗留改造

CHAPTER 02

计划:从需求到可执行方案

何时计划 · 头脑风暴 · 苏格拉底式提问 · 任务输入 · 事实发现 · BDD Spec · 多视角评审 · 修改计划

CHAPTER 03

执行:小步推进,控制变更半径

任务 DAG · 串行与并行 · 子代理分工 · TDD · 小步修改 · 长任务与上下文 · 失败处理

CHAPTER 04

验证:用证据收敛,而不是口头完成

证据基线 · BDD 回放 · 证据矩阵 · 验证手段 · 四级强度 · 回归阶梯 · 反向评审 · 交付格式

CHAPTER 01

构建 Agent-Friendly 的工程基础

Agent-friendly 不是某个工具、某份规则文件或某套容器方案的属性,而是仓库、执行环境和工程约定共同形成的工程能力:Agent 能发现正确入口,通过稳定命令执行任务,获得可行动的反馈,并在意图或证据不足时及时升级给人。

本章搭建这层工程基础;后三章沿"计划 → 执行 → 验证"的闭环,用它完成一次完整的开发任务。

配图
第一章 · 工程基础§1 本章目标与适用边界

学完本章,你应该能够

  1. 证据审计一个仓库的 Agent-friendly 程度,而不是凭"Agent 好像能跑"判断。
  2. 识别开发闭环中缺失的环节:发现、执行、观察、验证、恢复或升级。
  3. 为项目设计最小可用的命令、反馈、环境和 CI 契约。
  4. 区分工具偏好与工程原则,把同一原则迁移到不同语言和平台。
  5. 为破坏性操作建立机械护栏,而不是依赖提示词提醒。

边界:本章不承诺 Agent 能独立判断业务是否正确。工程只能提供验证业务意图的手段,不能替代清晰需求、领域判断和责任人批准。

原则可迁移:示例用 Node.js / TS,结论不依赖语言

通用能力Node / TSPythonGoRust
固定工具链packageManager + lockfilepyproject.toml + lockfilego.mod / go.sumrust-toolchain.toml + Cargo.lock
快速静态检查tsc --noEmitRuff、Pyrightgo vetgo buildcargo check、Clippy
定向测试Vitest / Jestpytestgo testcargo test
稳定任务入口package scripts / MakeMake / tox / noxMake / TaskCargo / Just
第一章 · 工程基础§2 Agent-Friendly:有边界的证据闭环(一)

闭环的七个环节

环节含义
发现知道项目入口、目录结构、命令和约束在哪里
计划识别将修改的范围、风险和验证方式
执行通过稳定、非交互的入口完成开发操作
观察获得结构清晰、位置明确的输出
验证用与任务匹配的证据判断结果,而不只看退出码为 0
恢复失败后可以重试、回滚或缩小问题范围
升级意图、安全或验收依据不足时,停止猜测并询问责任人

为什么退出码不是证据:训练期研究已观察到模型会用 sys.exit(0) 伪造测试全绿。

配图
第一章 · 工程基础§2 Agent-Friendly:有边界的证据闭环(二)

工程建设的三个层级,顺序不能颠倒

  1. 安全护栏:凭据隔离、破坏性操作的机械防护、可逆性。
  2. 证据闭环:操作可发现、可执行、可观察、可验证、可恢复。
  3. 效率优化:降低反馈延迟、上下文消耗和重复工作。

CLI、MCP、LSP、容器和缓存都属于实现手段。不能为了更快而绕过护栏,也不能用更多工具掩盖验收标准缺失。

配图
第一章 · 工程基础§3 安全护栏

三件必须做的实事

  1. 凭据隔离:开发、测试、生产凭据分离,Agent 默认拿不到生产写权限;不把 SSH key、云凭据、浏览器配置和 Docker socket 无条件暴露给执行环境。
  2. 破坏性命令的机械护栏:脚本本身拒绝危险目标,而不是靠规则文件写一句"不要在生产运行"。
  3. 危险操作留人工批准点:外部写操作提供 dry-run 或变更预览;push、merge、deploy、改写共享历史留给人确认。

规则文件只能提醒,脚本校验和 CI 才能形成真正的控制。

示例:db:reset 的机械护栏

#!/usr/bin/env bash
set -euo pipefail

case "${DATABASE_HOST:-}" in
  localhost|127.0.0.1|db) ;;
  *)
    echo "refusing to reset a non-local database" >&2
    exit 1
    ;;
esac

test "${APP_ENV:-}" = "development" || {
  echo "APP_ENV must be development" >&2
  exit 1
}

pnpm exec prisma migrate reset --force
第一章 · 工程基础§4 可复现的 Agent 入场路径(一)

Golden Path:从零到可验证状态

读取项目说明检查工具链安装冻结依赖启动隔离依赖
初始化开发数据运行快速验证启动应用

三个职责不同的入口

入口职责
doctor只读检查,报告缺少的工具、端口、配置和服务状态
bootstrap幂等初始化工具链、依赖和开发数据
dev启动应用,不偷偷执行破坏性迁移或重置
配图
第一章 · 工程基础§4 可复现的 Agent 入场路径(二)

Node.js 项目至少固定这五件事

  • Node 版本:.nvmrc、Volta、asdf 或等价机制。
  • 包管理器版本:package.json#packageManager
  • 依赖解析结果:提交 lockfile,CI 使用 frozen install。
  • 配置契约:提交 .env.example,启动命令显式加载环境变量。
  • 数据初始化:迁移和 seed 可重复执行,失败信息明确。

要求不是"任意顺序都成功",而是依赖关系显式、初始化幂等、重复执行可预测。不要让 test 暗中重置共享数据库,也不要让 dev 隐式修改不可恢复的状态。

示例入场命令

pnpm run doctor
pnpm install --frozen-lockfile
docker compose up -d --wait
pnpm run db:migrate
pnpm run db:seed
pnpm run check:quick
pnpm run dev
第一章 · 工程基础§5 稳定的工程命令契约(一)

一组位于根目录、本地与 CI 共用的任务入口

能力建议入口契约
环境诊断doctor只读,指出缺失项和修复方式
初始化bootstrap幂等,可重复执行
开发dev一条命令启动,能正常停止
快速检查check:quick面向编辑循环,快速且无外部副作用
定向测试test -- <target>参数可透传,能指定文件或用例
完整验证check覆盖提交前必须通过的检查
构建build产物可重复,失败可定位
数据准备db:migrate / db:seed目标环境明确,seed 幂等

Node.js / TypeScript 示例

pnpm run dev
pnpm run build
pnpm run typecheck
pnpm run test -- src/services/PricingService.test.ts
pnpm run test -- -t "rejects expired codes"
pnpm run lint
pnpm run lint:fix
pnpm run check

命令名称不必跨团队统一,但同一仓库必须只有一套权威入口。Makefile、Justfile、Taskfile、package scripts 都可以实现这份契约。

第一章 · 工程基础§5 稳定的工程命令契约(二)

命令设计的七条要求

  1. 从项目根可发现:不要求 Agent 猜先进哪个子目录。
  2. 支持非交互模式:CI 和 Agent 不会无限等待输入。
  3. 退出码可信:成功为 0,失败为非 0,不吞掉子进程错误。
  4. 输出可行动:指出失败文件、位置、期望值、实际值和最小复现命令。
  5. 参数可透传,支持单文件级运行:file-scoped 反馈回路比全项目扫描快一个量级,直接决定 Agent 的迭代速度。
  6. 副作用显式:普通检查不暗中安装依赖、修改共享数据或访问生产系统。
  7. 本地与 CI 共用:CI 调用项目命令,不复制另一套隐藏脚本。
配图
第一章 · 工程基础§6 快速且可行动的验证阶梯(一)

与任务风险匹配的验证阶梯

层级目的常见检查
编辑循环数秒内发现局部错误格式化、静态检查、单文件测试
任务验证证明改动满足局部目标定向单元测试、契约测试、局部集成测试
提交前验证发现跨模块影响构建、相关测试集、迁移检查
PR 门禁保护主分支全量检查、集成测试、安全扫描
定期验证覆盖高成本场景全量 e2e、性能、兼容性、长时间测试

速度目标按仓库规模、硬件和冷热缓存建基线。可以给编辑循环设激进预算,但不要为了"一分钟"指标删除必要测试——优化反馈路径,不牺牲覆盖范围。

配图
第一章 · 工程基础§6 快速且可行动的验证阶梯(二)

确定性 = 受控、可记录、可重放

确定性不等于禁止时间、随机数和网络:

  • 时间通过 fake clock 或固定时区控制。
  • 随机测试记录 seed,失败可复现。
  • 单元测试不访问真实第三方服务。
  • 集成测试可以访问隔离的本地数据库和 Compose 网络。
  • e2e 使用受控环境,保存截图、trace、日志等失败产物。

好的失败输出直接支持下一步行动

FAIL tests/users.test.ts:42
Expected: HTTP 409 with code USER_EXISTS
Received: HTTP 500 with code INTERNAL_ERROR
Reproduce: pnpm test -- tests/users.test.ts \
  -t "rejects duplicate email"
Artifact: artifacts/users-duplicate/server.log

避免只输出"测试失败",或把真正错误吞进数千行日志。Agent 能否恢复,取决于反馈是否包含定位、差异、复现方式和相关产物。

第一章 · 工程基础§7 项目知识、规则文件与机械护栏(一)

写 CLAUDE.md / AGENTS.md:一条官方判据,两条实践检验法

逐行判据

对每一行问"删掉这行会不会导致 Agent 出错?"不会就删。过长的指令文件会让重要指令淹没在噪音中——写得越多,遵循得越差。

复述检验法

让 Agent 逐字复述你的构建命令。凡是它复述不出的内容,它就不会遵循。"be careful""where possible"这类模糊指令会被可靠地忽略。

命令优先于散文

每条指令尽量回答"什么命令能证明这件事做对了"。Agent 可以通过退出码验证命令,却无法验证一段描述性文字。

维护方式建议被动维护:Agent 每犯一次错,就追加一行针对性规则防止复发;定期用逐行判据清理。这比一次性写"大而全"的文档有效得多。

配图
第一章 · 工程基础§7 项目知识、规则文件与机械护栏(二)

约束放在哪里:四步判断顺序

适合写进项目指令

权威任务入口和推荐验证顺序 · 偏离默认约定的风格与测试指令 · 无法由工具判断的业务/历史背景 · 哪些操作需要批准、哪些资源禁止访问 · 典型实现的文件指针

不适合放进去

能由 formatter、Linter、类型系统机械检查的规则 · 通用 git / 语法教程 · 频繁变化无人维护的文件清单 · 仅靠提示词无法真正阻止的安全要求

  1. 能否通过脚本或系统机制直接禁止?
  2. 能否通过 CI、测试或 Linter 自动检查?
  3. 能否通过生成器或脚手架减少错误路径?
  4. 前三者都不适合时,再写进项目指令。

例:"不能修改既有迁移"不应只写进规则或 pre-commit hook。关键约束应在 CI 中与目标分支比较,并提供有审批记录的例外流程——pre-commit 只能提供更早反馈,不能保护主分支。

第一章 · 工程基础§8 环境模式:Host、Container 与 VM 的取舍

四个目标,四种模式,按条件选择

Agent-friendly 环境的四个目标:工具链可固定 · 环境可从零重建 · 测试与多 checkout 相互隔离 · 反馈延迟可接受。

模式优势主要风险适用条件
工程在 host,依赖在容器本地 IO 快、调试直接主机凭据暴露、跨平台漂移可信仓库、受控开发机
Dev Container环境一致、隔离较好文件 IO、镜像维护成本跨平台团队、统一工具链
一次性 VM / 云端沙箱隔离最强、易清理启动和资源成本不可信代码、高自主度任务
Nix / 声明式环境复现性强学习和维护成本已有相关基础设施的团队

并行 checkout:隔离 Compose 项目与端口

export COMPOSE_PROJECT_NAME="app-$(basename "$PWD")"
export POSTGRES_PORT=55432
export REDIS_PORT=56379
docker compose up -d --wait

依赖容器要有 healthcheck 与 --wait;真实项目固定补丁版本或 digest;开发密码不得复用到共享或生产环境;测试数据用临时数据库或独立 schema,不与开发环境共用持久状态。

第一章 · 工程基础§9 本地与 CI 同构

CI 保护主分支,并与本地共用同一套入口

门禁是否阻塞说明
冻结依赖安装lockfile 不一致或安装失败即阻塞
静态检查和 Linterwarning 是否阻塞由项目明确规定
构建 / 打包防止类型通过但产物失败
单元与集成测试按项目风险决定覆盖范围
迁移和结构检查涉及相关变更时验证升级、回滚或兼容性
secret / 依赖 / 许可证按组织策略确定性工具 + 明确基线
e2e、性能、兼容性按成本分层PR、合并队列或定时任务
LLM Review默认建议性发现疑点,不作为正确性证明

健康的 CI 还应明确

  • 使用哪个运行时和 lockfile 安装方式。
  • 服务依赖如何启动并等待 ready。
  • 超时、重试、缓存和并发取消策略。
  • 失败日志、截图、trace 和产物保存在哪里。
  • 哪些检查可豁免、谁能批准、记录在哪里。

敏感目录用 CODEOWNERS、人工审批和针对性安全检查。LLM Review 可以要求"必须运行并处理意见",但不能把概率性输出当作正确性批准。

第一章 · 工程基础§10 外部系统接入:CLI、API 与 MCP 决策框架

没有天然更优的协议,只有更合适的通路

维度CLI直接 API / SDKMCP
可组合性shell 管道强需要代码编排取决于客户端与工具设计
结构化输出取决于 --json 等能力通常最好通常为结构化结果
状态保持取决于具体工具可自行设计适合封装有状态能力
上下文成本可控,但日志可能很大由适配层控制取决于发现与加载机制
审计依赖凭据和 shell 环境可精细设计可由服务端集中治理
部署成本安装、认证、升级维护集成代码本地或远程服务运维

选择顺序:只读还是有副作用?→ 能否最小权限 + 审计?→ 是否需要结构化结果或长状态?→ 上下文消耗多少?→ 团队能否稳定维护?

实践原则

  • 能用脚本就不用 MCP:脚本可版本管理、可测试、不额外占上下文;常见例外只有浏览器自动化这类有状态会话。
  • 统一日志:控制台、服务器、浏览器日志写到同一位置,给 Agent 一个"读最近 N 行"的简单命令。
  • 查询优先结构化输出,在工具侧过滤,不把整份日志塞入上下文。
  • 数据库"只读"由专用账号和权限保证,名称本身不提供只读性。
  • 批量写操作先 dry-run,再逐项执行并保留结果。
第一章 · 工程基础§11 遗留项目改造优先级

先查硬门槛,再按阻塞程度投资

层级内容
P0 安全与可运行无生产写权限与无关凭据 · 干净环境可安装启动 · 至少一个可信验证入口 · 破坏性命令有机械护栏。P0 未通过,不让 Agent 自主开发新功能。
P1 快速证据闭环定向测试与快速静态检查 · 失败输出可定位可复现 · 测试状态隔离 · 本地与 CI 同一组入口
P2 知识与护栏项目指令说明命令/结构/边界/批准点 · 高频错误由 Linter/测试/CI 自动阻止 · 规则有作用域与负责人
P3 环境与外部接入环境可重建、支持并行 checkout · 外部工具最小权限、可审计
P4 效率缓存、增量、并行 · LLM Review、自动分诊 · 基于真实遥测优化成本

证据分级与排序依据

  • 0:不存在。
  • 1:存在,但依赖人工步骤、偶尔失败或缺少证明。
  • 2:可重复执行,有命令输出、CI 记录或测试结果作证据。

改造优先级 = 风险 × 发生频率 × 阻塞时间。不要用未经测量的"必然提速十倍",记录改造前后的首次启动时间、定向测试延迟、失败恢复时间和 CI 通过率。

第一章 · 工程基础§12 练习:仓库审计 + 朴素基线裸跑(45 分钟)

审计一个故意有缺陷的 starter repo

仓库预埋的缺陷

  • 只有全量测试,没有定向测试入口。
  • 环境变量缺少示例和启动前检查。
  • Compose 没有 readiness 检查,数据库偶发启动失败。
  • 开发和测试共用数据库状态。
  • 项目指令只写风格偏好,没有命令和边界。
  • CI 使用一套与本地不同的隐藏命令。

练习任务

  1. 运行 pnpm run doctor 或现有命令,记录可复现证据。
  2. 找出证据闭环断点(至少 3 个),按 P0~P4 排序。
  3. 只修复最阻塞的一项,不做无关重构。
  4. 浏览朴素基线裸跑记录(artifacts/chapter-1/baseline/):"支持创建用户"一句需求直接交给 Agent 的完整过程。

裸跑记录是后三章的对照物:第二章复盘它猜了什么,第三章复盘它怎么失控,第四章复盘它的完成声明缺什么证据。裸跑结果不计分——价值恰恰在于暴露问题。

不通过红线

  • 使用生产或共享环境写凭据。
  • 删除测试、跳过检查让审计结果变绿。
  • 没有可复现命令和证据,只报告"已经完成"。

验收量表 7 个维度(安全护栏、入场路径、定向反馈、错误输出、环境隔离、本地与 CI、裸跑记录),每项 0–2 分;总分 ≥11 / 14 且无 0 分项为通过。复盘三问:哪个断点浪费最大?为什么先改这一项?裸跑中哪个行为最意外?

第一章 · 工程基础本章总结

Agent-friendly = 有边界的证据闭环

  • 凭据隔离,破坏性命令有机械护栏,危险动作留人工批准点。
  • 项目入口可发现,环境可以从零重建。
  • 命令稳定,反馈快速且可行动,支持单文件级验证。
  • 规则文件只写 Agent 猜不到且删掉会出错的内容,能机械检查的交给工具。
  • 本地和 CI 使用同一套工程契约。
  • CLI、API、MCP、Host 和 Container 都按条件选择;能用脚本就不用 MCP。
  • 意图或证据不足时,Agent 必须正确升级。

这层基础建好以后,后续章节才有条件讨论如何让 Agent 规划需求、执行修改和验证结果。

配图

CHAPTER 02

计划:从需求到可执行方案

让 Agent 直接跳到写代码,可能产出"解决了错误问题"的代码。回看第一章的裸跑记录:拿到"支持创建用户"后,Agent 自行选定了校验规则、猜测了错误码、顺手引入了团队没在用的库。

计划阶段做三件事:把人的意图澄清成任务边界;把项目现状查清楚;把需求固化成可执行、可评审、可验证的规格和计划。

配图
第二章 · 计划§1 本章目标与适用边界

学完本章,你应该能够

  1. 判断任务需要多厚的计划,以及什么时候不需要计划。
  2. 把模糊需求改写为 Agent 可执行的任务说明。
  3. 用苏格拉底式提问把隐含假设、边界和验收标准问出来。
  4. 在制定实现方案前完成事实发现。
  5. 把需求整理成 BDD Spec,让业务预期可以被执行和验证。
  6. 使用子代理从多角度评审计划,降低单一路径偏见。
  7. 用有据可查的修改与验证计划为后续执行指路。
适用

小到中等规模新功能 · 局部 bug 修复 · 有清晰验收标准的重构 · 测试补齐、接口调整、配置修复等工程任务

暂不覆盖

多团队大型架构迁移 · 高风险生产变更 · 没有明确责任人的业务决策 · 需要真实用户、合规、财务或法务判断的需求取舍——可复用本章闭环,但需额外的审批、灰度、审计和回滚机制

第二章 · 计划§2 何时计划,何时不计划

计划不是免费的:三档投入

任务规模判据计划投入
一句话 diff一句话能说清改动不计划,直接做;仍走常规验证兜底
常规任务涉及 2 个以上模块,或有失败路径需要设计走完整闭环,产物保持轻量
高风险任务涉及数据、兼容性、外部系统,或需求歧义大完整闭环 + 多视角评审 + 人工确认点
头脑风暴苏格拉底式提问任务输入事实发现BDD Spec多视角评审修改与验证计划

原则:先处理需求侧的不确定性,再处理工程侧的不确定性,最后再让 Agent 制定执行计划。有疑问按上一档处理;但发现自己在给改错字的任务写 BDD Spec,停下来。

一句话例外(Anthropic)

能用一句话描述 diff——改错字、加一行日志、重命名变量——就跳过计划直接做。给这类任务写计划纯属浪费。

规模不匹配的教训(Thoughtworks 实测)

spec 驱动工具曾把一个小 bug 修复膨胀成 4 个用户故事、16 条验收标准。"我宁愿审代码,也不愿审这些 markdown"——计划把审阅负担从代码转移到文档,文档比代码还难审时,计划就是负资产。

第二章 · 计划§3 头脑风暴:先发散,再收敛

打开可能性,而不是马上决定实现

适合发散的问题

  • 这个需求可能有哪几种业务解释?
  • 成功路径、失败路径和边界路径分别是什么?
  • 现有系统里有没有相似功能可以复用?
  • 可能影响哪些模块?最小可交付版本是什么?
  • 哪些部分可以延后,不应混入本次任务?

收敛后的产物

产物作用
候选解释暴露需求歧义
候选实现路径比较成本和风险
不做清单防止范围膨胀
待确认问题明确需要人决策的点
每次只问一个问题(Harper Reed 的需求打磨)

让 Agent 每次只问一个问题,连续追问迭代出详细规格,最后固化成文档。人能认真回答的问题一次只有一个,而 Agent 的下一个问题可以基于上一个回答调整方向。

两个要避免的错误

一开始就让 Agent 选定单一路径 · 把所有想法都放进本次实现范围

配图
第二章 · 计划§4 苏格拉底式提问:把隐含假设问出来

用连续问题逼近清晰需求

目标澄清

这个需求最终要改变哪个用户可观察行为?只交付最小版本,必须包含什么?

边界澄清

哪些模块允许修改?哪些现有行为必须保持不变?哪些场景明确不在本次范围?

验收澄清

成功路径、失败路径如何判断?需要什么测试、日志、截图或请求记录作为证据?

风险澄清

是否涉及权限、删除、计费、隐私或外部系统?是否允许连接共享环境?现有代码和需求冲突时以谁为准?

目标不是让人回答所有问题,而是把"不知道"显性化。只要某个问题会改变实现或验证方式,就应该在计划阶段暴露出来。

什么时候用

  • 用户给的是愿望,不是验收标准。
  • 需求里有"合理""默认""正常""优化"等模糊词。
  • Agent 准备自行补全业务规则。
  • 修改可能影响权限、数据或兼容性。
配图
第二章 · 计划§5 任务输入:从愿望到约束

给 Agent 的任务不应只有一句业务愿望

不充分的任务输入

"帮我加一个用户创建接口。"

更好的任务输入

新增 POST /users。请求体包含 emailname。创建成功返回 201 和用户 id;重复 email 返回 409 和 USER_EXISTS;email 格式非法返回 400 和 INVALID_EMAIL。只修改 API、service、repository 和相关测试,不改认证模块。使用本地测试数据库验证,不能连接共享环境。交付时给出修改文件、测试命令和结果。

类型作用示例
目标定义最终行为新增 POST /users
范围限制修改边界不改认证模块
验收标准定义完成证据成功、重复 email、非法 email 三类测试通过
禁止事项定义风险边界不连共享环境,不 push,不 merge

任务输入不需要提前设计所有实现细节。实现路径可以让 Agent 发现和建议,但业务行为、修改边界和验收标准必须尽量明确。

第二章 · 计划§6 事实发现:先读项目,再定实现

输出必须可引用、可检查,而不是泛泛总结

事实发现应回答

  • 入口在哪里?现有类似实现是什么?
  • 数据模型、接口约定和错误格式是什么?
  • 现有测试如何组织?
  • 哪些命令可以验证本次任务?
  • 哪些文件或模块属于高风险区域?
不合格输出

"项目结构比较清晰。" · "应该可以加一个 controller。" · "我会参考现有代码风格。" —— 没有可检查证据,不能支撑后续计划。

合格输出示例

  • 已有 POST /projects 实现路径,可复用路由、service、repository 分层。
  • 错误响应统一由 AppError 转换,错误码在 errors.ts 维护。
  • repository 层已有唯一键冲突处理。
  • API 测试使用独立测试数据库。
  • 提交前验证 pnpm run check;定向测试 pnpm run test -- tests/api/users.test.ts
第二章 · 计划§7 BDD Spec:把需求变成可执行规格(一)

Given / When / Then:业务预期的可执行表达

Feature: Create user

  Scenario: create user successfully
    Given the local test database has no user
          with email "a@example.com"
    When I submit POST /users with email
         "a@example.com" and name "Alice"
    Then the response status should be 201
    And the response should contain a user id
    And the user should be persisted in the
        local test database

  Scenario: reject duplicate email
    Given the database already has a user
          with email "a@example.com"
    When I submit POST /users with the same email
    Then the response status should be 409
    And the error code should be "USER_EXISTS"

  Scenario: reject invalid email
    When I submit POST /users with email "bad-email"
    Then the response status should be 400
    And the error code should be "INVALID_EMAIL"

计划阶段的三个作用

  • 逼出成功路径、失败路径和边界条件。
  • 让实现计划围绕可验证行为展开。
  • 为执行阶段的 TDD、验证阶段的证据矩阵提供输入。

BDD Spec 不一定要求引入 Cucumber 之类的框架。它首先是一种需求表达方式,其次才是测试工具选择。

写在事实发现之后:这样规格既反映业务预期,也贴合项目已有接口、错误码、数据模型和测试方式。它比自然语言需求更精确,又比直接写测试更容易让业务方 review。

第二章 · 计划§7 BDD Spec(二)· 业界对照:Spec 驱动开发

本课的"任务输入 + BDD Spec"是 SDD 的轻量版

工具流程固化方式特点
GitHub Spec KitSpecify → Plan → Tasks → Implement 四阶段斜杠命令每阶段内置人工检查点——审查、发现缺口、纠偏后才进入下一阶段
Kiro三个文件:requirements.md(用户故事 + EARS 记法验收标准:WHEN/THEN/SHALL)、design.md(架构、数据流、错误处理、测试策略)、tasks.md(带需求编号追溯的任务清单)spec 即项目资产,可追溯

是否采用这类工具,回到 §2 的规模判断:工具的阶段再完整,也救不了与任务规模不匹配的计划。

配图
第二章 · 计划§8 多视角评审:在定稿前找偏差

价值不是"人数更多",而是主动暴露偏见

评审视角关注点
产品评审需求是否完整,用户行为是否明确
架构评审实现路径是否符合项目结构,是否引入不必要复杂度
测试评审验收标准是否可测,失败路径是否覆盖
安全评审是否涉及权限、数据、凭据、外部系统
运维评审配置、迁移、日志、回滚和环境影响

评审对象是任务输入 + 事实发现 + BDD Spec 这组可检查产物,而不是一句模糊需求。没有子代理能力时,也可以要求同一个 Agent 按视角逐项自查。

使用方式

  1. 主 Agent 给出任务输入、事实发现、BDD Spec 和初步计划。
  2. 评审者只输出风险、缺口和建议,不直接改代码;只报影响正确性或既定需求的缺口
  3. 每个子代理只能访问完成评审所需的上下文。
  4. 主 Agent 汇总冲突意见,形成最终计划。
  5. 人只需要 review 关键分歧和高风险点。

典型发现:验收标准不完整 · 错误路径缺失 · 任务触碰权限判断 · Agent 准备绕过现有 service 层。

第二章 · 计划§9 修改与验证计划:从 Spec 到可执行步骤

每一步都要有理由和验证方式

无法使用的计划

"修改后端、补测试、运行检查。" —— 无法判断风险,也无法定位失败。

合格计划应包括

  • 修改哪些文件或模块;每一步为什么必要。
  • 每一步之后运行什么验证。
  • 哪些地方可能破坏兼容性。
  • 如果失败,如何缩小问题范围。
  • 是否需要用户确认业务问题。

示例计划

  1. 阅读现有用户路由、错误格式和测试工具,不修改代码。
  2. 把 BDD Spec 转成失败的 API 测试。
  3. 在 service 层补充用户创建逻辑,复用现有唯一键冲突处理。
  4. 增加 POST /users 路由和输入校验。
  5. 跑定向测试,让失败收敛到当前任务。
  6. 跑提交前验证入口,检查跨模块影响。

执行中偏离了计划,正确动作是回到计划修改它,而不是在对话里一句句追加纠正——计划是共同的锚点,锚点错了就改锚点。

第二章 · 计划§10 计划阶段检查清单

进入执行前,至少检查

  • 计划厚度是否与任务规模匹配。
  • 是否经过发散和收敛,而不是直接选定第一个方案。
  • 苏格拉底式提问是否暴露了关键假设。
  • 任务目标是否可测试;范围和禁止事项是否明确。
  • Agent 是否读取了相关现有实现。
  • BDD Spec 是否覆盖成功路径和关键失败路径。
  • 多视角评审是否发现计划盲点。
  • 修改计划是否具体到模块或文件;每一步是否有验证方式。
  • 是否存在需要用户确认的业务问题。
  • 如果计划失败,是否知道从哪里开始缩小问题。

计划产物不是为了占用时间,而是为了降低返工成本——如果某份产物既不降低返工也不帮助评审,砍掉它。

配图
第二章 · 计划课堂练习:计划阶段(50 分钟)

从"支持创建用户"到完整计划

核心必做

  1. 规模判断(口头,1 分钟内):属于三档中哪一档,为什么。
  2. 快速发散(5 分钟上限):候选解释 + 不做清单,随即用苏格拉底式提问补齐目标、边界、验收标准和风险;可采用"每次只问一个问题"。
  3. 把需求改写成完整任务输入。
  4. 只做事实发现,不修改代码,给出至少 3 条可引用结论。
  5. 写 BDD Spec:至少覆盖成功、重复 email、非法 email。
  6. 形成最终修改计划和验证计划。

进阶(课后):子代理或单 Agent 多视角自查。复盘:裸跑中哪次猜测(错误码、校验规则、依赖选择)会被本章哪个环节拦住?产物存入 artifacts/chapter-2/

练习环境卡(讲师课前提供)

技术栈Node.js / TypeScript / PostgreSQL
安装pnpm install --frozen-lockfile
定向测试pnpm run test -- tests/api/users.test.ts
提交前验证pnpm run check
相似实现POST /projects
任务约束不 push、不 merge、不连共享环境、不改认证模块
直接不通过

对业务歧义自行猜测 · 未明确环境和禁止事项 · BDD Spec 无法支撑后续验证

第二章 · 计划本章总结

好的计划让执行和验证高效清晰

  • 规模匹配:一句话 diff 不计划,高风险任务厚计划;计划产物本身有成本。
  • 发散再收敛:暴露可能性,最后明确边界。
  • 问出隐含假设:把"以为"变成"确认";每次只问一个问题。
  • 事实先行:读代码,找相似实现,再定方案。
  • 可执行的规格:BDD Spec 既是业务预期,也是验收标准。
  • 多视角评审:动手前让产品、测试、安全、架构都发言。
  • 计划是锚点:执行偏离时改计划,而不是追加纠正。
配图

CHAPTER 03

执行:小步推进,控制变更半径

两个有实证的失败模式:Agent 有强烈的"一次做太多"倾向——同时铺开多个功能,每个都半途而废;失败轨迹高度集中于"重复生成修复"的循环——连续产出修复却不运行测试。

这两类失败都不是靠"更强的模型"解决的,而是靠执行纪律:先确定依赖,再分配工作,最后执行修改——每一步都小、都有反馈。

配图
第三章 · 执行§1 本章目标与适用边界

学完本章,你应该能够

  1. 用有向无环图表达任务依赖,区分串行和并行任务。
  2. 判断什么时候需要子代理分工,什么时候单个代理足够。
  3. 用 TDD 建立可解释的反馈锚点。
  4. 用小步修改控制变更半径,使失败定位更容易。
  5. 用进度文件和上下文管理支撑跨会话的长任务。
  6. 在执行中失败时先定位,而不是连续大改。
  7. 保留关键命令和错误输出,为后续验证和交付提供证据。

本章假设计划已完成:任务输入、事实发现、BDD Spec、修改计划都已明确。

任务约束(不 push、不连共享环境、不修改认证模块)沿用计划阶段的任务输入,执行中不得自行放宽;边界发生变化时,暂停并升级给人。

第三章 · 执行§2 任务整理:用有向无环图表达依赖(一)

超过三五步的任务,用 DAG 替代线性待办

  • 节点表示任务,边表示依赖。
  • 没有入边的节点可以先做。
  • 没有互相依赖的节点可以并行。
  • 出现环,说明计划里有未解决的设计问题。

TDD 的 red-green-refactor 是节点内部的微循环,不是 DAG 里的依赖环。DAG 仍然表示任务之间的单向依赖。DAG 的价值不是画图,而是让"为什么这一步现在能做"变得可检查。

一个可执行的节点至少包含

字段作用
owner谁负责该节点
input / output依赖的上游产物 / 预期产物
read set / write set需要读取的范围 / 允许修改的范围
external state是否涉及数据库、队列、缓存、浏览器 profile、外部服务
validation完成该节点后运行什么验证
status / blocked reasonpending / running / blocked / done;卡住时缺什么
第三章 · 执行§2 任务整理:用有向无环图表达依赖(二)

示例:POST /users 的执行 DAG

A 写 API 测试   (input: BDD Spec)
B service 实现  (input: BDD Spec、事实发现)
C route 接入    (input: B)
D 文档更新      (input: 任务输入)
E 定向验证      (input: A、C)
F 提交前验证    (input: D、E)

A → E
B → C
C → E
D → F
E → F

计划阶段的产物——任务输入、事实发现、BDD Spec——是所有节点的公共输入,不再作为节点出现。A 与 B 可并行,D 与主链可并行;E 必须等 A、C 齐备。

配图
第三章 · 执行§3 串行任务:有依赖就不要并行

这些情况应该串行

  • 需求尚未澄清,后续实现依赖业务决策。
  • 数据模型未确定,接口和测试都依赖它。
  • 一个步骤的输出会改变下一个步骤的输入。
  • 多个步骤会修改同一文件或同一模块。
  • 验证结果会决定下一步是否继续。

串行执行示例

确认错误码写失败测试实现错误处理跑定向测试补成功路径

串行的好处是反馈清晰,代价是速度较慢。对高风险或依赖强的任务,清晰度比速度更重要

配图
第三章 · 执行§4 并行任务:无共享写入、无强依赖才并行

并行的三个前提与共享状态清单

并行前需满足

  1. 输入已经足够明确。
  2. 输出之间没有强依赖。
  3. 不会同时写同一文件或同一状态。

适合并行的例子

  • 一个子代理做只读事实发现,另一个整理测试现状。
  • 一个评审安全风险,另一个评审测试覆盖。
  • 文档更新与不重叠文件的测试补齐。

并行的收益来自减少等待,不来自放弃协调。多个会话并行时,用 git worktree 隔离各自工作区。

共享写入不只指同一个文件

共享对象典型风险
API contract / schema测试和实现基于不同接口
migration 链顺序冲突、回滚失败
fixture / seed / 测试数据库数据污染、重复运行失败
lockfile / 依赖配置安装结果不可预测
generated client / snapshot生成物覆盖、语义冲突
环境变量 / 配置文件本地和 CI 行为不一致
缓存、队列、外部服务状态验证结果不可复现
第三章 · 执行§5 子代理分工(一):主 Agent 编排,子代理只接任务包

执行型子代理必须有明确边界

子代理适合任务边界
测试代理根据 Spec 写测试、补回归不改生产代码
实现代理在既定范围内实现功能不改验收标准
审查代理检查 diff、找风险不直接修复,先报告
文档代理更新本次任务相关文档不改变业务逻辑
迁移代理处理 schema 或配置变更必须有回滚和验证计划

审查代理的任务包必须写明:只报影响正确性或既定需求的缺口。被要求找问题的评审者总会找出问题——不加边界,评审产出会淹没在风格意见里,追逐每条发现只会导致过度工程。

两个被实践验证有效的分工模式

Writer / Reviewer 双会话

实现和评审分别使用独立会话。新鲜上下文的评审者不会偏袒"自己刚写的代码",评审质量显著更高。

批量任务先试跑再全量

对一批同构任务(如逐文件迁移),先在 2-3 个文件上试跑,根据出错情况修正任务说明,再对全量执行。

第三章 · 执行§5 子代理分工(二):任务包与主 Agent 职责

主 Agent 是 integration owner

子代理任务包至少包含

任务目标:
Spec / DAG 版本:
可读范围:
可写范围:
禁止事项:
依赖节点:
预期产物:
必跑验证:
停止并上报条件:

子代理不能主导任务,只能在授权任务包内产出局部结果。分工的核心不是"并发越多越好",而是把不同类型的工作隔离,降低互相污染。

主 Agent 的编排职责

  • 明确每个子代理的输入和输出;避免两个子代理写同一文件。
  • 先检查文本冲突,再检查语义冲突、测试预期冲突、schema/API 契约冲突。
  • 合并后运行受影响测试,并更新 DAG 状态。
  • 某个子代理改了接口、schema、fixture 或测试约定,其他相关子代理必须刷新上下文。
  • 对高风险建议做人工升级;保留关键决策理由。
第三章 · 执行§6 TDD:先让失败可解释

未被执行过的代码,只能靠运气正确

Specfailing testminimal implementationpassing testrefactor

Agent 执行的四步操作法

  1. 先运行 baseline,区分既有失败和本次失败。
  2. 从 BDD Spec 选一个最小场景写测试,明确声明在做 TDD(否则 Agent 可能顺手把实现也写了)。
  3. 运行定向测试,确认失败且失败原因符合预期(red)。
  4. 确认 red 后再做最小实现,明确指示不许修改测试;迭代到 green,再处理下一个场景。

这个过程防止 Agent 同时改实现、改测试、改配置,最后不知道哪个动作让结果变绿。测试本身需要调整时,必须作为 Spec 或测试设计变更单独说明。

TDD 尤其适合

  • bug 修复:先写复现测试。
  • API 行为变更:先写接口测试。
  • 重构:先补行为保护测试。
  • 边界规则:先写失败路径测试。
配图
第三章 · 执行§7 小步修改:每次只做一件事

"每次只做一个 feature"是被实测验证的关键约束

任务类型建议分段
新接口Spec → 测试 → route → service → repository → 验证
Bug 修复复现测试 → 最小修复 → 回归验证
重构行为保护测试 → 机械迁移 → 删除旧路径
配置修复复现环境 → 最小配置变更 → 启动验证

每一步都能解释

  • 为什么现在做这一步;预期改变什么。
  • 这一步不应该改变什么;做完后如何获得反馈。
机械护栏:feature 清单

把需求维护成一份 feature 清单(每项带验收标准和 pass/fail 状态),Agent 只被允许修改状态字段,不允许删除需求或修改验收标准。这是"实现代理不能改验收标准"的机器护栏版本——不靠提示词自觉,靠数据结构约束。

描述性提交 = 最廉价的恢复手段

每完成一步,用描述性 commit message 提交。清晰的提交历史让 Agent(和人)能够回滚糟糕的变更、恢复到可工作状态。

第三章 · 执行§8 长任务与上下文管理

上下文腐化是真实的失败模式

窗口填满后 Agent 会"遗忘"早期指令、犯更多错误;新会话对之前的工作一无所知,甚至看到已有进展就直接宣布任务完成。

技术适用具体做法
压缩 compaction大量来回对话的任务接近窗口上限时压缩历史,保留架构决策、未解决 bug 和实现细节,丢弃冗余工具输出
结构化笔记有明确里程碑的迭代开发进度持久化到窗口之外:NOTES.md、todo 清单、进度文件
子代理隔离可并行探索的复杂任务调研和大范围搜索交给子代理,只回报摘要,不污染主上下文

跨会话恢复的最小机制

  1. 维护进度文件(如 PROGRESS.md):已完成节点、当前节点、未解决问题、下一步。
  2. 新会话先读 git log 和进度文件,恢复状态后再动手。
  3. 会话结束前更新进度文件——给"下一个自己"的交接。
两条经验法则

同一问题纠正超过两次就不要再纠正:重开会话,用吸收了教训的更好任务说明重来——反复纠正的对话堆满失败尝试,持续干扰后续判断。不相关的任务之间清空上下文:上一个任务的细节对下一个任务是噪声。

第三章 · 执行§9 失败处理:先定位,不要掩盖

失败很正常,关键是失败后的动作

合格的失败处理顺序

  1. 保留失败命令和错误输出。
  2. 判断失败属于实现、测试、环境还是需求问题。
  3. 缩小复现范围。
  4. 做最小修复。
  5. 重新运行对应验证。
不合格的失败处理

删除失败测试 · 放宽断言 · 扩大 mock 让真实路径不再被测试 · 跳过检查 · 不解释原因就连续大改

实证研究归纳的失败反模式与这份清单逐条对应:重复相同动作却不跟进结果、连续生成修复而不运行测试、未经测试验证就终止任务。失败轨迹的共同特征是循环而不定位;成功轨迹每次失败后都先解释再行动。

测试变绿不是唯一目标。更重要的是确认变绿的方式是否仍然证明需求成立。

第三章 · 执行§10 执行阶段检查清单

执行中持续检查

  • 是否仍在原定范围内;DAG 中是否存在未解决的环。
  • 串行任务按依赖顺序推进;并行任务避免共享写入。
  • 子代理有清晰边界,没有互相覆盖。
  • 先建立可解释反馈,再推进实现。
  • 每次修改都有明确目的,每步都有提交。
  • 长任务有进度文件与恢复路径。
  • 优先复用现有模式;避免无关重构、格式化和依赖升级。
  • 失败后先定位再修复;保留关键命令和错误输出。
  • 风险变化时暂停升级。

执行阶段的核心能力不是"写代码",而是控制变更半径和依赖顺序

配图
第三章 · 执行课堂练习:执行阶段(55 分钟)

从计划到 TDD 执行

核心必做

  1. 把计划整理成任务 DAG(白板或文本),标出串行和可并行任务。
  2. 从一个 BDD 场景开始 TDD:先写失败测试,再做最小实现,过程中不许改测试。
  3. 每个关键步骤后运行定向反馈(pnpm run test -- <target>),并做一次描述性提交。
  4. 维护轻量进度文件(已完成、进行中、下一步各一行)。
  5. 避免无关重构、格式化和依赖升级;失败时保留错误输出,先定位再修复。

进阶(课后):子代理分工,审查子代理的任务说明必须包含"只报影响正确性或既定需求的缺口"。"新会话恢复"课后自行练习。产物存入 artifacts/chapter-3/

复盘

对照裸跑记录:哪次失控(一次改太多、失败后盲目重试、改了测试来过关)会被本章哪个方法拦住?

直接不通过

未经计划就开始修改 · 忽视 DAG 任意并行造成冲突 · 删除测试或放宽断言绕过失败 · 超范围大规模重构 · 没有记录失败和修复过程

验收量表:执行控制、失败处理两类,各 0–2 分;总分 ≥3 且无 0 分项为通过。

第三章 · 执行本章总结

执行 = 在计划的指导下有序推进

  • DAG 梳理依赖:先搞清楚什么必须先做,什么可以并行。
  • 串行和并行边界:依赖强就串行,无共享写入才并行。
  • 子代理有边界:任务包明确可写范围,评审者只报影响验收的缺口。
  • TDD 建立反馈:每个场景先红再绿,实现时不许改测试。
  • 每次只做一个 feature:小步推进加描述性提交,失败随时可回滚。
  • 长任务靠外部记忆:进度文件加 git log,新会话先恢复再动手。
  • 先定位再修复:失败不可怕,循环和掩盖才可怕。
配图

CHAPTER 04

验证:用证据收敛,而不是口头完成

Thoughtworks 实测:即使明确指令要求测试必须通过,AI 仍会频繁谎报构建和测试成功。训练期研究观察到的作弊手法:sys.exit(0) 伪造全绿、把 verify 改成恒返回 true、在 conftest.py 里跳过全部测试。

结论:干活的 Agent 不能给自己打分。验证必须外部化、证据化——不是"跑测试",而是建立证据和结论之间的对应关系。进入本章时功能开发已停止:只允许针对失败做最小修复,不允许借验证之名继续加功能。

配图
第四章 · 验证§1 本章目标与适用边界

学完本章,你应该能够

  1. 逐条回放 BDD Spec,不合并结论。
  2. 将每条验收标准映射到证据矩阵,并区分证据强弱。
  3. 为每条验收标准选择合适的验证手段。
  4. 为任务选定匹配风险的验证强度等级。
  5. 按回归阶梯收敛:从 BDD 回放和定向测试逐步扩展到提交前验证。
  6. 用反向评审找完成声明中的漏洞。
  7. 明确未验证内容和遗留风险,而不是隐瞒或假装完成。

本章假设计划和执行已完成,现在需要验证改动是否真的符合需求。上一章交来:按计划完成的修改、TDD 过程记录和关键命令输出。本章产出:每条验收标准的证据、明确的未验证清单,以及一份可审计的交付。

第四章 · 验证§2 可信证据的基线

证据的环境或来源说不清楚,完成声明不成立

可接受的证据来源

  • 本地隔离环境中的命令输出。
  • 自动化测试结果、数据库断言。
  • 脱敏日志和网络请求记录。
  • 浏览器 trace、截图或 video。
  • CI 运行结果。
不可接受的证据来源

  • 无法复现的环境。
  • 含生产数据、个人信息、密钥或真实账号的记录。
  • 只有口头描述,没有命令和环境说明。
  • 来自共享或生产环境的数据。
第四章 · 验证§3 BDD 回放:逐条验收,不合并结论

每个场景单独出结果

BDD 场景验证动作通过证据
create user successfully运行成功路径 API 测试状态码 201、返回 user id、数据库断言
reject duplicate email运行重复 email 测试状态码 409、错误码 USER_EXISTS
reject invalid email运行非法 email 测试状态码 400、错误码 INVALID_EMAIL

不要把多个场景合成一句"用户创建测试通过"。某个场景没有验证,就必须单独标记为未验证。

配图
第四章 · 验证§4 证据矩阵与证据强度(一)

每条验收标准都应该有对应证据

验收标准对应证据
创建成功返回 201成功路径 API 测试或请求记录
重复 email 返回 409 + USER_EXISTS冲突路径测试
非法 email 返回 400 + INVALID_EMAIL校验失败测试
写入本地测试数据库测试环境配置和数据库断言
不修改认证模块修改文件列表和 diff review
不连接共享环境环境变量、命令输出或配置证明

矩阵直接暴露三类问题

  • 有需求但无证据。
  • 有测试但不对应验收标准。
  • 有证据但来自不可信环境。

矩阵还应记录环境证明:本地或测试 URL、脱敏数据库端点、测试账号类型、分支或 commit、测试数据来源、是否连接外部服务。

第四章 · 验证§4 证据矩阵与证据强度(二)

证据要区分强弱

强度示例说明
强证据CI 结果、自动化测试、数据库断言、contract 验证可重复、可审计,优先采用
中证据本地命令结果、Playwright trace、脱敏日志有价值,但要说明环境和数据
弱证据截图、人工描述、口头确认只能辅助说明,不能单独证明关键行为
不可接受无命令、无环境、无数据来源、无法复现不能支撑完成声明

截图始终是弱证据,只能作为 trace、日志和测试结果的附属,不能单独作为浏览器验证的交付物。

配图
第四章 · 验证§5 验证手段:选择能证明行为的工具(一)

标准不是工具是否高级,而是能否证明当前验收标准

手段适合证明什么常见证据
单元测试纯函数、规则、边界条件测试名称、输入输出、失败断言
集成测试模块协作、数据库读写、service/repository 行为测试命令、数据库断言、测试日志
API 测试HTTP 状态码、请求响应、错误码、鉴权行为请求样例、响应体、测试结果
契约测试前后端、服务间接口兼容性contract 文件、consumer/provider 验证结果
数据库 / 迁移验证schema 变更、数据兼容、回滚风险migration 命令、schema diff、回滚记录
浏览器 smoke少量关键 UI 能否打开和交互命令、浏览器项目、截图或 trace
E2E 测试用户跨页面、跨服务的完整路径E2E 命令、测试报告、必要时 trace/video
视觉回归布局、样式、关键 UI 变化screenshot diff、基准图、差异图
日志 / 可观测性验证后台任务、异步流程、告警和审计日志片段、job 状态、metric 或 event
脚本化人工验收暂无自动化能力但必须验证的关键路径操作步骤、环境、截图、操作者记录

Playwright 是工具,不是验证层级,所以不出现在上表中。

第四章 · 验证§5 验证手段(二):浏览器验证与合理组合

Playwright 的两种用法与验证组合

自动化 E2E 测试

把用户路径写成可重复运行的测试:登录、创建用户、提交表单、检查页面状态。

浏览器辅助验证

让 Agent 或工程师用真实浏览器执行固定步骤,保留截图、trace、video、console 和 network 作为证据。

浏览器验证尤其适合

  • 前端表单校验、按钮状态、路由跳转。
  • 登录态、cookie、localStorage、权限页面。
  • 前后端联调路径;异步加载、错误提示、toast。
  • 上传、下载、弹窗、多标签页等纯 API 测试覆盖不到的交互。

合理组合:浏览器验证不替代低层测试

规则单元测试
接口API / 集成测试
关键用户路径Playwright E2E
最终交付截图 + trace + 命令 + 结果
验证手段:Playwright E2E
命令:npx playwright test tests/e2e/create-user.spec.ts \
  --project=chromium --trace=on
环境:local app + local test database
覆盖场景:创建成功、重复 email、非法 email
证据:test result、trace.zip、失败时 screenshot

纯后端、无 UI 变更的任务不默认要求浏览器验证。

第四章 · 验证§5 验证手段(三):风险与官方测试代理

浏览器验证的常见风险

  • 选择器不稳定,页面轻微调整就误报。
  • 测试数据污染,重复运行不可靠。
  • 等待策略错误,把异步问题误判为功能失败。
  • 只验证 UI 文案,没有确认真实请求和数据状态。
  • 使用共享或生产环境,证据不可复现且有安全风险。

因此优先使用隔离 profile、测试账号、测试 URL、稳定 selector、隔离测试数据和明确等待条件,并尽量同时检查 UI、网络响应和后端状态。trace、截图和 network 日志必须脱敏。

进阶:Playwright 官方测试代理

三个代理构成"计划 → 生成 → 自愈"的 E2E 工作流:planner 探索应用并产出 specs/ 下的测试计划;generator 把计划转成 tests/ 下可执行测试;healer 在测试失败时重放失败步骤、检查 UI、给出补丁重跑,直到通过或按 guardrails 停止——自动修复也有停止条件,不能无限重跑到变绿。初始化:npx playwright init-agents --loop=claude

第四章 · 验证§6 验证回路的四级强度

给 Agent 一个能自己运行的通过 / 失败检查,回路就能闭合

强度做法适用
1 会话内迭代同一任务中要求 Agent 运行检查并迭代到通过常规任务默认
2 跨会话目标检查设为会话级目标条件,未达成不算完成多轮推进的中型任务
3 确定性门禁Stop hook 等机制以脚本运行检查,不通过则阻止回合结束必须机械保证的关键检查
4 独立复核拥有新鲜上下文的验证子代理尝试反驳结果高风险任务、完成声明存疑

无论哪一级,同一条证据要求:让 Agent 出示证据,而不是声称成功——测试输出、执行的命令及其返回、截图。

按任务风险选强度

任务风险最低验证要求强度
文案、注释、低风险文档人工 review 或格式检查1
局部纯函数修改定向单元测试1
API 行为变更接口测试和错误路径测试1–2
前端交互变更组件测试或浏览器验证2
跨页面用户路径E2E 测试和截图或 trace2–3
数据库变更迁移验证、数据断言、兼容性检查3
权限、支付、删除类自动化测试、人工确认、审计记录4

验证不足时,不强行宣称完成,而是明确:已验证什么、未验证什么、为什么、需要什么条件、当前能否交付 review。

第四章 · 验证§7 真实路径、Mock 与 CI 证据

测试通过 ≠ 真实路径已验证

Mock 的基本规则

  • 单元测试 mock 外部边界合理。
  • API / 集成验证尽量启动真实 app,走真实路由、中间件、service、repository 和本地测试数据库。
  • 不可控第三方可以 mock,但必须说明 mock 边界。
  • 权限、持久化、关键 API、外部副作用和审计路径不能只靠 mock 证明
  • 删除测试、放宽断言、扩大 mock,默认视为风险,需单独解释。

API 验证至少关注

  • 鉴权和权限边界。
  • 输入校验和错误格式。
  • 状态码、响应体、序列化格式。
  • 幂等性、重复请求、并发冲突。
  • 外部依赖失败、超时和重试。
  • 审计日志或关键事件。

数据库 / 迁移验证

  • 隔离测试库、fixture 或 seed;可重复创建和清理。
  • 唯一约束、并发写入和事务边界。
  • migration up/down 或回滚策略;旧数据兼容、重复运行幂等。

CI 证据应包含

  • commit 或 diff 基线。
  • CI job 链接、编号或日志位置。
  • 运行命令和测试报告路径。
  • artifact、coverage 或 trace 位置。
  • 失败重跑记录,尤其是 flaky test 处理说明。

没有 CI 时,说明为什么没有。

第四章 · 验证§8 回归阶梯:先定向,再扩展

全书统一的回归阶梯

BDD 场景回放定向测试相关模块测试API / 集成验证
浏览器 / E2E(涉及 UI 时)提交前验证CI
  1. 运行最小复现或定向测试。
  2. 修复当前任务直接相关失败。
  3. 运行相关模块测试。
  4. 涉及 UI 的任务运行浏览器验证。
  5. 运行提交前验证入口(pnpm run check)。
  6. 存在 CI 时,确认 CI 使用同一权威入口。
两点说明

BDD 回放和定向测试不是先后两个层级:回放是验收视角(逐条确认场景有结果),定向测试是实现手段(大多数场景正是通过定向测试回放的)。分开写是为了强调"先对照验收标准,再谈测试范围"。

浏览器 / E2E 是条件层:用户可观察行为发生在浏览器里,至少应有一个浏览器层面证据;只是后端纯规则变化,强行跑浏览器测试只会增加噪声。

不建议一开始就只运行全量检查:失败反馈过慢且噪声过大。也不建议只运行定向测试就交付:可能漏掉跨模块影响。

第四章 · 验证§9 子代理反向评审:专门找"完成声明"的漏洞

不证明完成,而是带着怀疑找反例

反向评审问题清单

  • 是否有验收标准没有证据?
  • 是否有测试只验证 mock,没有走真实路径?
  • 是否有前端行为变更但没有浏览器层证据?
  • 浏览器验证是否只检查页面出现,没查请求和数据状态?
  • 是否存在 flaky test,只是重跑变绿却没有解释?
  • 是否有失败路径缺失?环境证据不足(误连共享数据库)?
  • 是否有无关改动混入?测试被删除、断言被放宽、检查被跳过?
  • 是否有风险被写进总结,但没有处理方案?

任务说明必须包含边界:只报影响验收结论的缺口。被要求找问题的评审者总会找出问题,不加边界会产出大量与验收无关的意见,稀释关键风险。

产物:阻塞项与非阻塞项

类型含义处理
阻塞项影响验收结论修复或升级给人
非阻塞项不影响本次交付,但值得记录写入遗留风险或后续任务
第四章 · 验证§10 交付格式:让结果可审计

交付不应只是"已完成"

至少应包含

  • 修改摘要、涉及文件。
  • BDD 场景验证结果;环境和数据隔离说明。
  • 验证手段选择理由和强度等级。
  • 验证命令和结果;mock / stub / fake 使用说明。
  • CI 状态或未运行原因。
  • 浏览器验证产物(截图、trace 或 video)。
  • 未验证内容、遗留风险、需要用户决策的事项。

交付格式的价值是降低 review 成本:人不需要重新推理 Agent 做过什么,而是直接检查证据是否支持结论

推荐交付模板

完成内容:
- ...
修改文件:
- ...
BDD / 验收映射:
- ...
环境 / 数据:
- ...
验证手段与强度:
- ...
验证:
- 命令:...
- 结果:...
- 产物:...
Mock / CI:
- ...
未验证 / 风险:
- ...
建议下一步:
- ...
第四章 · 验证§11 完成判定与验证反模式

这些情况下,完成声明本身不成立

不能声明完成,只能报告进度、阻塞和所需条件

  • 验收标准没有对应证据。
  • 验证环境不可信,或可能连了共享 / staging / 生产。
  • 验证命令无法复现,或没记录命令、环境、数据来源。
  • 关键失败路径未验证。
  • 测试被删、断言被放宽、mock 被扩大,却没有合理说明。
  • 同类失败反复出现,只靠重跑变绿。
  • 涉及浏览器行为但没有浏览器层证据,且未说明原因。
  • 涉及不可逆操作,但没有审批、备份、dry-run、回滚和环境证明。

这份清单必须机械执行:Agent 有"让结果变绿"的系统性倾向,谎报成功在第三方实验中被反复观察到。

验证反模式

  • 只交付截图,不提供命令、环境、数据和 trace。
  • 删除测试、扩大 mock 或降低校验绕过失败。
  • 跳过 flaky 测试,或重跑变绿后不解释原因。
  • 为了让测试通过安装未知依赖或修改 lockfile。
  • 把含敏感信息的截图、trace、network 日志当证据。
  • 只写自然语言总结,不给验证证据。
  • 不区分强弱证据,混淆交付。
  • 用一条 E2E 替代所有低层测试,失败定位困难。
第四章 · 验证§12 验证阶段检查清单

交付前至少检查

  • 每条 BDD 场景是否都有结果;每条验收标准是否都有证据。
  • 证据是否来自可信环境;强度是否足够支撑完成声明。
  • 是否选定了与风险匹配的验证强度等级。
  • 是否说明环境、数据来源、mock 边界和 CI 状态。
  • 验证手段是否能证明对应行为。
  • 涉及浏览器行为时是否有浏览器层证据。
  • 是否覆盖成功路径和关键失败路径。
  • 是否按回归阶梯运行了与风险匹配的回归验证。
  • 是否经过反向评审;是否说明了未验证内容。
  • 是否列出修改文件和验证命令;是否存在需要用户决策的问题。
配图
第四章 · 验证遗留项目中的降级策略

没有完整测试,也能建立降级版验证

  • 没有测试框架:至少提供可复现命令和请求样例。
  • 没有 CI:至少记录本地验证环境和版本。
  • 没有类型检查:至少补充关键路径的运行验证。
  • 无法自动化所有 BDD 场景:至少明确哪些由人工验收,证据是什么。
  • 没有浏览器自动化但任务涉及浏览器行为:至少提供脚本化人工验收步骤、浏览器版本、截图和关键请求记录。

遗留项目中的目标不是一次性补齐所有工程基础,而是在每次任务中增加一点可验证性

配图
第四章 · 验证课堂练习:验证阶段(40 分钟)

用证据矩阵收敛这次交付

核心必做

  1. 逐条回放 BDD Spec,每条验收标准映射到证据矩阵(一张表完成)。
  2. 为每条验收标准标注验证手段,为任务选定验证强度等级。
  3. 按回归阶梯收敛到提交前验证(pnpm run check)。
  4. 明确未验证内容和遗留风险。
  5. 按交付格式提交最终结果,产物存入 artifacts/chapter-4/

反向评审由讲师现场演示:用新会话对某组的完成声明做反驳式检查。进阶(课后):Playwright 或等价浏览器验证。

终局复盘三问(对照裸跑记录)

  1. 裸跑时 Agent 的完成声明缺少哪些证据?按本章标准它能否声明完成?
  2. 计划、执行、验证三个环节各避免了裸跑中的哪次返工或哪个风险?
  3. 如果只允许保留一个环节的方法,你会保留哪个?为什么?
直接不通过

没有任何可复现验证证据 · BDD Spec 与验证证据无法对应 · 涉及浏览器交互但没有浏览器层证据且未说明 · 删除测试或放宽断言隐瞒失败

第四章 · 验证本章总结

验证的核心是建立清晰的对应关系

  • 干活的 Agent 不能给自己打分:验证外部化,证据必须出示而非声称。
  • 逐条回放 BDD:每个场景都要有结果,不能合并。
  • 证据矩阵:每条验收标准都要有对应证据,并区分强弱。
  • 选择合适手段:不是所有问题都用 E2E,匹配风险选手段。
  • 四级验证强度:从会话内迭代到独立子代理反驳,按风险选级。
  • 回归阶梯:从定向到全局,逐步扩展验证范围。
  • 反向评审:专门找完成声明的漏洞,只报影响验收结论的缺口。
  • 明确遗留风险:没验证的内容、需要什么条件、当前能否交付。
配图
结语四章 · 一个闭环 · 一个贯穿全书的对照物

闭环合上了

第一章 · 边界与反馈设施第二章 · 需求变规格第三章 · 小步执行第四章 · 证据收敛
  • 裸跑记录在每一章被重新打开:第二章看它猜了什么,第三章看它怎么失控,第四章看它的完成声明缺什么证据
  • 同一原则跨语言、跨工具迁移:固定工具链、定向测试、稳定入口、机械护栏。
  • Agent 的自主边界始终一致:证据充分时独立推进,否则准确升级。

下一步:第五章考试与第六章作业,把这套闭环用在你自己的仓库里。

配图
← → 翻页 · T 目录 · 点击右上按钮导航