AI Native 团队完整开发落地手册

这份手册以 Anthropic《The AI-native SDLC Playbook》(Louis Claxton,2026-08-21)为骨架,补上我们自己团队跑下来踩过的坑:产物链、工作环境、验证系统、Eval、生产门禁,最后一个真实 bug 从头走到尾。命令和配置可以直接抄,路径和版本号按你仓库的实际情况替换。

2026 年 8 月,Anthropic 发布《The AI-native SDLC Playbook》。它讨论的不是模型能写多少代码,而是另一个更现实的问题:Agent 已经能在几小时内生成大量代码,规划、审查、部署却还是人速,代码快了,项目为什么没有一起快。

传统 SDLC 的每一环------PRD、估时、评审、审批------都诞生在 " 写代码最贵最慢 " 的年代。构建从几周压到几小时之后,原文总结出三个后果:

  1. 瓶颈转移。计划、审查/测试、部署位于构建两侧,仍按人的速度运行
  2. 控制失配。人写代码时逐行审查是合理的,Agent 写了大部分 diff 之后跟不上产量,要么审查队列堆积,要么代码带着未审查状态上线
  3. 治理成本上升。例外仍要走每周或每月开一次的委员会审批,接不住放大的代码量

所以要改的不是写代码这一步,是从想法出现到线上反馈回来的整条工作链。下面把原文的方法拆成可执行步骤。


一、产物链:用文件取代聊天记录

AI Native SDLC 把线性流程改成循环,贯穿循环的是一条提交产物链:

复制代码
intent.md → spec.md → plan.md → 代码与测试 → PR 与审查结论 → 事故记录 / 新的 intent.md

每个阶段结束时提交一个产物进版本控制,下一阶段从读取它开始。产物被接受这件事本身就是触发器:intent.md 被接受触发设计,spec.md 被批准触发 Plan Mode,PR 合并触发流水线,生产指标越界写出新的 intent.md,循环回到起点。

聊天记录撑不起这个位置。一次会话结束后,关键判断埋在几十轮对话里,下一个 Agent 拿不到同样的上下文;而提交的文件把当前结论固定下来,附带作者、时间和修改历史。这条 commit 链同时就是审计记录:谁提出了什么、Agent 生成了什么、谁批准了它。

链上跑着两个循环:

markdown 复制代码
执行回路(快循环,每个任务转一遍)
  实施 → 测试与构建 → 真实操作验证 → 独立 verifier → 人工接受
     ↑_______________验证失败,返回重做_______________|

学习回路(慢循环,跨任务沉淀)
  重复错误 → 知识库(CLAUDE.md / Skill / Hook / Eval)→ 影响下一次任务

快循环保证这一次做对了,慢循环保证下一次不再错。后面每一节都落在这两个循环上。

原文给了一条务实建议:不必把 Jira 或 Figma 全部迁成 Markdown,但每种产物必须指定唯一的事实来源,其他系统只存副本或链接,最低限度是互相记录 ID 和 commit SHA。

二、把问题定义清楚:intent.md

流程从 intent.md 开始。它写得糊,后面全糊------AI 会把定义里的模糊处用它自己的猜测填满,而且填得很快。

写问题,不写方案

最常见的失败是发起人写的是方案,不是问题:

markdown 复制代码
(差)给订单列表加一个导出按钮,用 CSV 格式
(好)运营每周五手动从后台逐页复制订单数据做对账,
      每次花 2 小时且容易漏页,需要能把订单数据批量取走的方式

方案式定义把实现选择提前锁死了:为什么是 CSV?为什么是按钮而不是定时邮件?检验办法是把陈述里的实现词删掉,看问题还成不成立。" 加导出按钮 " 删掉按钮就不成立了,说明它写的是方案。

模板

markdown 复制代码
# Intent: 登录后应回到来源页而不是首页
Author: 张三(运营端). Status: draft.

## 谁
运营人员(非技术,只用后台界面)

## 什么场景 / 触发条件
从订单详情页被踢到登录页,每周五对账时高频发生

## 现在的行为
登录成功后落在首页,需要手动重新导航回订单页

## 期望的行为(可验证)
- 登录成功后回到来源页
- 直接访问深层链接,登录后也回到该页

## 约束
- 不改后端 session 机制
- 兼容现有认证方式

## 明确不做
- 不做 SSO
- 不改订单查询接口

## 开放问题
- 运营后台是否走同样逻辑?(待确认,先按同样逻辑实现)

" 期望的行为 " 这一节是分水岭:每一条都必须能翻成一个测试。" 提升体验 " 不是定义,是不可验收的愿望。

三类信息比 " 要什么 " 更容易漏:

  1. 边界(不做什么)。没有边界,AI 会顺手把相关的都做了,然后进你的审查队列
  2. 约束(不能动什么)。技术债、遗留系统、性能红线全在你脑子里,AI 一无所知
  3. 反例(失败长什么样)。比如 " 导出文件用 Excel 打开乱码(UTF-8 BOM 问题,上次踩过)"。反例把抽象要求变成可判定的对错,约束力常常强于正面描述

用 AI 对抗性补全:三轮

自己列的要素永远是自己已经想到的,AI 问出来的才是你漏掉的。

第一轮,口述加提问:

我想解决 粗糙描述。先不要提任何方案。你的任务是问我问题,一次最多 5 个,直到你能向一个没参与的工程师完整转述这个问题。从影响面最大的信息缺口问起。

第二轮,复述加强制列假设:

用你自己的话复述这个问题,然后单独列出:你目前做出的所有假设(无论多小),以及哪些信息你仍然没有。

这一步的价值在假设列表。AI 不会把空白留白,它会默认填上;假设列表就是把它的默认填充摊到桌面上让你逐条否决。

第三轮,落文件:

基于以上讨论生成 intent.md。规则:保留 " 开放问题 " 一节;你做出的每个假设必须显式标注,不允许写进正文装成事实;不包含任何实现方案。

退出检查清单

写完后过这五条,有一条不过就回去改:

  1. 新会话测试:开一个全新会话只给它 intent.md,它能准确复述问题吗。它就是未来读这份文件的 Agent
  2. 可测试性:每条期望结果能直接翻成测试用例吗
  3. 边界存在:能指出至少一件明确不做的事吗
  4. 假设已摊牌:假设列表里还有没被确认或否决的项吗
  5. 方案零渗透:文件里还有没有实现词(按钮、接口名、表结构)

没确认的事项写进 " 开放问题 ",让后续阶段带着它们去找决策者,比让 AI 在生成时静默替你拍板好得多------静默的决定你永远不会审查。

三、规格与计划:spec.md 与 plan.md

spec.md:产品负责人审,但不写

通过审核的 intent.md 交给 Claude 生成 spec.md,生成时读取团队的品牌、安全、合规、UX 规则(以 Skill 形式存在,见第四节):

Read the attached intent.md and produce a requirements and design spec. Apply the skills available to you. Document the spec fully as spec.md, ready to hand to the engineering team. Describe clearly any areas of concern, especially where you cannot satisfy contradicting policies.

产品负责人对照原始意图审查规格,看三点:

  1. 每条验收标准能翻成测试吗
  2. intent 里的开放问题是标着,还是被偷偷决定了
  3. 有没有夹带 intent 没要求的东西

Agent 无法满足的要求、规则之间的冲突必须在这里标出来,在工程介入之前解决,不能等开发阶段靠工程师猜。

原文没明说、但实践中很关键的一点:文档生产的价值在下降,产品判断的价值在上升。AI 能快速生成 PRD 和设计规格,产品经理的精力就要移到 " 问题是否值得解决、约束有没有遗漏、生成结果是否满足用户需求 " 上。实现越快,一个错误判断进入代码的速度也越快。

plan.md:先审查计划,再生成代码

工程师拿到通过审核的 spec.md 后,构建仍然不会立即开始。在 Claude Code 的 Plan Mode 里:

  1. 给 Claude intent.md 和 spec.md,要求生成实施计划:改哪些文件、按什么顺序、用什么测试证明结果
  2. 追问三个问题:这个改动可能破坏什么?风险最高的步骤在哪?你考虑过又放弃的方案是什么,为什么?
  3. 迭代计划,直到满意
  4. 提交被接受的版本为 plan.md

接受标准很朴素:一个没有参与前面对话的工程师,只看 plan.md 能否独立完成任务。不能就继续改。

这是全流程性价比最高的审查点。Plan Mode 下 Claude 只能读代码不能改文件,设计审查发生在代码生成之前,此时改方向还只是改一份文档;plan.md 的每次修改和最终接受者都留在 git 历史里。实施偏离计划时,在同一 commit 里更新 plan.md(可以用 hook 强制同步)。

plan.md 示例:

markdown 复制代码
# Plan: 登录后回来源页(from intent.md 2026-09-28)

## 改动文件
src/auth/redirect.ts(新增), src/router/guards.ts,
src/auth/__tests__/redirect.test.ts

## 实施顺序
1. guards.ts 中记录来源路径到 sessionStorage
2. 登录成功回调读取并跳转
3. 兜底:无来源记录时回落首页

## 风险
guards.ts 被三个路由模块共用,改动需跑全部路由相关测试

## 证明
redirect.test.ts 覆盖四种入口场景;
手动验证:深层链接 → 登录 → 回到原页面(附截图)

Auto Mode:自主程度跟着护栏走

计划通过后 Agent 开始实施。等 CLAUDE.md 和测试能力成熟之后,常规任务可以进入 Auto Mode,工程师不再逐次确认文件编辑,注意力转向审查完整产物。适用条件是三条同时成立:规格清楚、影响范围小、已有测试覆盖。高风险任务仍要逐步确认。团队不会因为 Agent 能连续工作就立刻放开所有权限------自主程度跟着护栏成熟度走。

四、把团队经验写进工作环境

Agent 的工作环境由三层配置构成。写错地方,效果是要么重要约束被淹没,要么根本不被执行。先做分流:

经验类型 去处 加载时机
每次会话都需要的最小上下文:命令、边界、高频坑 CLAUDE.md(项目根) 每次会话开头,强制读
只属于个人的偏好 CLAUDE.local.md(gitignore) 同上
特定类型任务的完整流程:发版、迁移、审查标准 .claude/skills/名字/SKILL.md 触发该任务时才加载
违反会出事、不能靠建议的约束 .claude/settings.json 里的 Hook 每次工具调用,机器执行
大段背景:架构决策、设计文档 docs/,CLAUDE.md 只留指针 需要时自己去读

判断口诀:每次都要放 CLAUDE.md,特定任务才要放 Skill,必须执行放 Hook,只是背景放 docs 加指针。

CLAUDE.md:规则的写法决定它是否被遵守

CLAUDE.md 的定位是 " 一名新成员第一天需要知道的一切,且仅仅是这些 "。用 /init 生成初稿,然后裁剪到一页以内------每次会话开始都会读它,过期内容直接占用上下文。

规则写成三段:规则本身、一句为什么、怎么验证。" 为什么 " 不是装饰,它让 Agent 能在新场景下泛用这条规则,也防止三个月后有人清理时误删:

markdown 复制代码
# 电商后台

## 命令
- 构建: pnpm build
- 测试: pnpm test(会起 postgres docker,先确认 daemon 在跑)
- 单文件: pnpm vitest run src/auth/login.test.ts
- lint: pnpm lint && pnpm format
- 本地服务: pnpm dev(端口 3000,测试账号见 .env.example)

## 架构边界
- 金额计算必须用 decimal.js,禁止浮点
- 路由守卫集中在 src/router/guards.ts,禁止页面组件各自实现
- src/api/ 只放请求封装,不写业务逻辑

## 已知坑(Agent 常犯)
- 改表格组件易破坏虚拟滚动,改完必跑其 __tests__
- 时间统一 dayjs,不引入 moment
- 改 schema 前先跑 pnpm db:migrate:check。
  原因: projects 表有触发器,直接 drop 列会丢历史数据(2026-06 事故)

## 完成定义
报告"完成"前必须附上 build 输出 + 相关测试输出;UI 改动附截图。

维护纪律比初始内容更重要:

  1. 同一种错误第二次出现时立即写进去。第一次纠正,第二次固化
  2. 每月审一次,已不再犯的规则删掉,否则它在稀释重要规则的权重
  3. 超过一页就该清理,或下沉到 Skill、docs

CLAUDE.md 进 git,修改走 PR,和代码一样被 review。Agent 遵循的指令本身就是可审计的。

Skill:可复用的任务级流程

某类操作有固定的多步流程,又不是每次会话都发生时,从 CLAUDE.md 升级成 Skill:

arduino 复制代码
.claude/skills/release/
  SKILL.md          说明和步骤
  gen-changelog.sh  配套脚本
yaml 复制代码
---
name: release
description: 发布新版本时使用。涵盖版本号规则、changelog 生成、预发验证和上线检查。
---

# 发布流程
1. 从 main 拉最新,确认 CI 绿;不绿则停止
2. 版本号 semver;changelog 用 ./gen-changelog.sh 生成,
   人工补充"用户可见的变化"一节
3. 禁止直接 pnpm publish,必须用 pnpm release
   (封装了 build + tag + 推送,漏步骤会发坏包)
4. 预发验证清单:登录 / 下单 / 支付回调三个链路各走一遍

frontmatter 里的 description 决定 Agent 何时自动加载它,要写 " 什么时候用 ",不是 " 这是什么 "。Skill 在 git 里统一维护:安全标准或前端规范变化时改同一个版本,下一次相关任务自动拿到新版,团队规范不再靠口头传达。

原文的经验法则:必须一致应用的组织知识写成 Skill,属于日常上下文的留在 CLAUDE.md,一次性的写在 prompt 里。

Hook:建议与强制的分界

CLAUDE.md 和 Skill 都是建议,Agent 可能忽略、长会话可能遗忘。满足以下任一条的约束要下沉为 Hook:

  • 违反会造成数据丢失或安全问题(不许动 migrations,不许删生产数据)
  • 已经被违反过两次以上,靠提醒压不住
  • 纯机械判断(格式、命名、文件路径),没必要消耗人的注意力

典型的场景是修 bug 期间禁止改测试文件,防止 Agent 通过降低检查标准让结果变绿。

.claude/settings.json:

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash ${CLAUDE_PROJECT_DIR}/.claude/hooks/no-test-edit.sh"
          }
        ]
      }
    ]
  }
}

.claude/hooks/no-test-edit.sh:

bash 复制代码
#!/bin/bash
set -euo pipefail

# 只在"修 bug"这个状态下拦。否则第三步写复现测试时,
# 这个 Hook 会把新增的测试文件也一起挡掉。
[[ -f "${CLAUDE_PROJECT_DIR}/.claude/fix-in-progress" ]] || exit 0

file=$(jq -r '.tool_input.file_path // empty')

case "$file" in
  *.test.*|*/__tests__/*)
    jq -nc '{hookSpecificOutput:{
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "修 bug 期间禁止改测试文件。若测试本身有误,停下来向用户说明。"
    }}'
    ;;
esac
exit 0

三个容易写错的地方:

  1. PreToolUse 的拦截要用 hookSpecificOutput.permissionDecision(取值 allow/deny/ask),早期文档里的顶层 {"decision":"block"} 已经不适用这个事件。另一种等效写法是直接 exit 2,把原因写到 stderr
  2. Hook 超时会放行,不会阻断工具调用。所以 Hook 里只做秒级的判断,别放过重的检查,完整测试留给 commit 和 PR 阶段
  3. ${CLAUDE_PROJECT_DIR} 比相对路径稳,Hook 的工作目录不保证是仓库根

还想更省事一点的话,可以改成 " 只拦 git 已跟踪的测试文件 ":新建复现测试自动放行,改老测试一律拒绝,就不需要 .claude/fix-in-progress 这个开关了。代价是功能开发期间正常修改老测试也会被拦。

经验捕获的完整循环

objectivec 复制代码
错误发生
  → 第 1 次: 会话内纠正,继续
  → 第 2 次: 写入 CLAUDE.md 的"已知坑"
  → 第 3 次仍发生(说明建议压不住): 升级为 Hook 强制
  → 规则 3 个月不再触发: 删除

五、验证系统:让 AI 先拿出证据

Agent 报告任务完成,这句话本身没有证明力,验证系统的输出才是证据。原则只有一条:证据先到,完成声明在后。

层 时机 执行者 证据形式 证明什么
L1 任务内反馈回路 会话内反复运行 Agent 自检 测试输出、构建日志、截图 这次改动符合 spec
L2 独立 verifier 声称完成后,一次性 新上下文 Agent 对照 spec 的核对报告 完成声明本身可信
L3 PR 审查 合并前 AI 按 REVIEW.md + 人 审查意见 + CI 无回归、符合规范
L4 Eval 配置变更时、定期 CI 重跑历史任务 历史任务通过率 Agent 体系整体没退化
L5 生产监控 上线后持续 确定性脚本 错误率、失败率 真实使用成立

分层的目的就是让内层便宜且快,把大多数问题拦在里面,外层只处理内层的逃逸。L1 失败的修复成本是分钟级,L5 失败是事故级。验证信号来得越晚,堆到你面前的未审查产物越多。

L1:任务内反馈回路

每个会话必须有一条可反复运行的回路,四个要求:快(秒到分钟级)、客观输出(退出码、日志、diff,不是 " 看起来没问题 ")、命令写进 CLAUDE.md、失败即循环(改、重跑,直到绿,禁止跳过或删测试)。

CLAUDE.md 验证块:

markdown 复制代码
## 验证
- 构建: pnpm build(必须以 "Build succeeded" 结束)
- 测试: pnpm test(全绿;永不 skip 或删除失败测试)
- lint: pnpm lint(零警告)
报告任何任务完成前运行以上三项并粘贴输出。
如果测试失败,修代码,不是修测试。

修 bug 走固定协议,这是最值得照抄的一条:

  1. 先让 Claude 写一个能复现 bug 的失败测试,运行并确认它以预期原因失败,提交这个测试
  2. 确认后只许改代码让它通过,不许碰测试文件(上面的 hook 兜底)
  3. 跑全量相关测试,附输出

一个先于修复存在、且 Agent 改写不了的测试,才是 "bug 已修复 " 的证明。

UI 任务需要另一种证据:给 Claude 浏览器或截图工具,给它设计稿,让它实现、截图、对比、调整地迭代。两三轮视觉迭代是正常成本。

遗留项目没有测试怎么起步:不要求补齐全量。最小集是 build 通过加类型检查,加上关键路径(登录、下单)三五个 e2e,加核心页面截图基线。然后执行一条增长规则:从今天起每个 bug 修复必须先写复现测试,测试资产随真实错误自然生长。

L2:独立 verifier

同一个会话里的 Agent 会为自己的产出辩护------它带着自己的推理路径,倾向确认自己没错。最终判定必须来自一个只读产物、不带会话记忆的新上下文:

yaml 复制代码
.claude/agents/verifier.md
---
name: verifier
description: Agent 声称任务完成后,用它做一次独立验收
tools: Bash, Read
---
只允许读:intent.md、spec.md、plan.md 和当前 git diff。
1. 运行全部测试和构建,附原始输出
2. 逐条核对 spec 验收标准:满足 / 不满足 / 无法验证
3. 报告 diff 中超出 spec 范围的改动
禁止修改任何文件。只报告,不修复。

两条职责不要混淆:反馈回路贯穿任务反复运行,verifier 只在声称完成后做一次独立判断。如果让同一个会话一边做一边自己验收,独立性就没了。

L3:PR 审查

Claude 在审查环节是双向的:按 REVIEW.md 审查代码,也处理自己收到的审查意见、重跑检查,直到 PR 只剩人要审的内容。

REVIEW.md(仓库根,技术负责人维护):

shell 复制代码
# 审查指令

## 检查轮次(每条 finding 标注所属轮次)
- Bugs: 逻辑错误、边界情况、隐蔽回归
- Security: 注入风险、认证缺口、PII 入日志
- Compliance: 改动是否符合 spec.md、plan.md 和设计原则

## Important 的定义
只把会破坏行为、泄露数据、违反策略的标为 Important;
风格和命名是 Nit。

## Nit 上限
每次审查最多报 5 条 nit,其余汇总为计数。

## 不报告
src/gen/ 下的生成文件和 CI 已强制检查的内容。

分工线:AI 负责机械检查,人只判断两件事------实现是否符合原始意图(回到 intent.md 对照)、剩余风险能否接受。逐行读代码不再是你的工作,逐条核对意图才是。

写代码的 Agent 没有批准权限,分支保护始终要求 code owner 确认。职责分离在 AI Native 团队里依然成立。

回流规则:审查中第二次出现的同类错误写回 CLAUDE.md。因为审查也读 CLAUDE.md,这个错误从下一个 PR 起就会被拦住,一次返工换一条永久规则。

六、完整案例:修一个真实的 bug

把前面的方法串起来走一遍。任务是第二节那个 " 登录后跳回首页 ",环境是一个 pnpm + vitest + vue-router 的仓库,下面的输出都是当次运行的结果。示例里的 import 路径按你自己仓库的结构替换。

第 0 步:建任务目录,写 intent

bash 复制代码
mkdir -p docs/tasks/2026-09-28-login-redirect

intent.md 用第二节的模板,5 分钟写完(可以口述让 Claude 整理)。提交:

bash 复制代码
git add docs/tasks/2026-09-28-login-redirect/intent.md
git commit -m "intent: login redirect to source page"

第 1 步:生成并审查 spec

Claude 生成 spec.md 后审查,实际发现一个问题:spec 把 " 运营后台是否同样处理 " 这个开放问题直接写成了 " 运营后台一并修改 "------它替我们做了决定。处理方式是打回,把这条改回 " 仅改 C 端,运营后台列入不做 ",运营后台留待确认后另开任务。

如果当天没审这份 spec,静默做出的决定要等到 PR 阶段甚至上线后才被发现。

第 2 步:Plan Mode 出计划

先让 Claude 进 Plan Mode(此时它只能读代码),产出的就是第三节那份 plan.md。追问 " 可能破坏什么 " 时,Claude 指出 guards.ts 被三个路由模块共用,这一条直接写进了 plan.md 的风险节,后面的验证范围因此扩大到全部路由测试。

第 3 步:先写复现测试,确认它红

让 Claude 只写测试,不许改业务代码:

ts 复制代码
// src/auth/__tests__/redirect.test.ts
import { describe, it, expect, beforeEach } from 'vitest'
import { router } from '@/router'
import { submitLogin } from '@/auth/session'

describe('登录后回来源页', () => {
  beforeEach(async () => {
    sessionStorage.clear()
    await router.replace('/dashboard')
  })

  it('深层链接被踢到登录页后,登录成功回到原页面', async () => {
    await router.push('/orders/123')        // guards 记下来源并跳登录
    await submitLogin('13800000000', 'pass-123')
    expect(router.currentRoute.value.path).toBe('/orders/123')
  })

  it('没有来源记录时回落首页', async () => {
    await router.replace('/login')          // 直接打开登录页,无来源路径
    await submitLogin('13800000000', 'pass-123')
    expect(router.currentRoute.value.path).toBe('/dashboard')
  })
})

第二条是防回归的对照组,改动前就该通过;第一条是本次的复现测试。运行:

scss 复制代码
$ pnpm vitest run src/auth/__tests__/redirect.test.ts

 ✓ redirect.test.ts (2 tests) 312ms
   ✗ 深层链接被踢到登录页后,登录成功回到原页面
     → expected '/dashboard' to be '/orders/123'

 Test Files  1 failed (1)
      Tests  1 failed | 1 passed (2)

失败原因正是预期的那个(跳去了 /dashboard 而不是 /orders/123)。提交这个红灯测试,然后打开拦截开关,让接下来只允许改业务代码:

bash 复制代码
git add src/auth/__tests__/redirect.test.ts
git commit -m "test: reproduce login redirect bug (red)"
touch .claude/fix-in-progress        # 本地开关,不要提交

第 4 步:修代码,期间 hook 真的拦了一次

Claude 修改 guards.ts 并新增 redirect.ts。中途它想 " 顺手 " 调整刚写的测试里的断言,被 Hook 拦下,会话里出现提示:

复制代码
修 bug 期间禁止改测试文件。若测试本身有误,停下来向用户说明。

它停下来说明意图,我们确认测试本身没问题,它继续修代码。这就是这条 Hook 要保护的东西:Agent 不能通过降低检查标准让自己变绿。

第 5 步:全量验证,证据随完成声明一起给

bash 复制代码
$ pnpm test
 Test Files  12 passed (12)
      Tests  47 passed (47)      ← 含 plan.md 风险节要求的全部路由测试

$ pnpm build
Build succeeded (4.2s)

UI 部分按 plan.md 的证明节,用 Playwright 走了一遍真实流程并截图(深层链接、登录、回到原页三张),贴进 PR。

第 6 步:verifier 独立验收

新开会话跑 verifier subagent,它的报告:

css 复制代码
验收标准核对(spec.md #L12-L18)
  [满足] 登录成功后回到来源页 ....... redirect.test.ts 通过
  [满足] 深层链接直接访问同样处理 ..... redirect.test.ts 通过
  [满足] 不改后端 session 机制 ........ diff 无后端文件
超出范围的改动
  src/theme/colors.ts +2 行         ← 与本任务无关的颜色调整
建议:拆出或还原

verifier 抓到一个没人注意的越界改动(Claude 顺手改了个颜色值),还原。写代码的那个会话自己没觉得这算越界,新上下文才看得见。

第 7 步:PR,AI 审查,人批准

Claude 按 REVIEW.md 自审,给出 1 条 Important(登录失败时 sessionStorage 未清理,可能串号)、2 条 Nit。Important 修掉,Nit 留 follow-up。CI 绿,代码负责人批准合并。合并后关掉修 bug 开关:

bash 复制代码
rm .claude/fix-in-progress

第 8 步:沉淀

bash 复制代码
mkdir -p evals/cases/003-login-redirect
cp docs/tasks/2026-09-28-login-redirect/intent.md evals/cases/003-login-redirect/task.md

criteria.md 写判定标准:复现测试通过、diff 只含 guards.ts 和 redirect.ts、无越界改动。这道考题进套件,见下一节。

整个任务人的实际投入:intent 5 分钟、审 spec 10 分钟、审 plan 15 分钟、批 PR 5 分钟,共 35 分钟,其余是 Agent 在跑。对比之前同类 bug 的处理(口头描述、生成、人肉逐行看、漏测回归再返工),这 35 分钟花在了判断上,而不是检查上。

七、Eval:给生产代码的机器做回归测试

Eval 是最容易被误解的一环。普通测试检验代码改对没有,Eval 检验生产代码的那台机器变好还是变坏了。

你的产出依赖两层东西:

markdown 复制代码
Agent 配置(模型 + CLAUDE.md + Skill + prompt + Hook)
        ↓ 生产
     代码改动
        ↓ 检验
   L1 测试(只能检验代码这一层)

L1 测试检验不了第一层,但你一直在改第一层:升级模型、给 CLAUDE.md 加条规则、改 Skill 流程、调 prompt。每次变更都等于换了一台生产代码的机器,新机器处理今后所有任务的水平是变好了还是变坏了,这就是 Eval 补的洞------把改配置当成改代码对待,有回归测试,有门禁。

一个实际被 Eval 拦下来的改动

我们往 CLAUDE.md 加过一条 " 所有金额必须用 decimal.js"。两周后例行重跑考题,通过率从 46/50 掉到 41/50。掉的那 5 道题里,有 3 道的 diff 显示 Claude 在纯展示的场景(页面标题里的订单数、日志计数)也强行包了一层 BigDecimal 转换,改坏了三处渲染。没有 Eval,这些问题会等审查队列爆掉或线上出显示异常才被发现。处理:把规则改成 " 涉及金额计算的逻辑必须用 decimal.js,纯展示和计数不需要 ",通过率回到 49/50,合并。

case 结构与生命周期

bash 复制代码
evals/cases/003-login-redirect/
  task.md         当初的原始任务描述(就是 intent.md)
  criteria.md     判定标准:复现测试通过、只改 guards.ts 和 redirect.ts、无越界改动
  expected.patch  被接受的那份 diff(参考答案,用于对比而非逐行比对)

重跑:干净 worktree 里用当前配置把 task.md 原样执行一遍,按 criteria.md 判定,对全部 case 汇总通过率。通过率明显下降,这次配置变更就停止合并。

规模与 CI

原文建议收集 20 到 50 个真实任务,作为活的套件维护:模型进步后,曾经有区分度的 case 会失去作用,要持续从监控和新事故中补充。

CI 集成(evals/check.sh 的职责是读 criteria.md、跑复现测试、比对 diff 范围,输出 pass/fail):

bash 复制代码
name: Agent evals
on:
  pull_request:
    paths: ['CLAUDE.md', '.claude/**', 'evals/**']
  schedule:
    - cron: '0 2 * * *'

env:
  # 这两项必须钉死,否则两次通过率不可比
  CLAUDE_CODE_VERSION: 'x.y.z'      # 换成团队当前使用的版本
  EVAL_MODEL: 'your-model-id'       # 换成 CI 实际调用的模型

jobs:
  evals:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: npm install -g @anthropic-ai/claude-code@$CLAUDE_CODE_VERSION
      - name: Run eval suite
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          mkdir -p results
          pass=0; total=0
          for dir in evals/cases/*/; do
            name=$(basename "$dir")
            git worktree add "/tmp/$name" -b "eval-$name"
            ( cd "/tmp/$name" \
              && claude -p "$(cat "$GITHUB_WORKSPACE/$dir/task.md")" \
                   --model "$EVAL_MODEL" \
                   --allowedTools "Read,Edit,Bash(make test:*)" \
                   --output-format json > "$GITHUB_WORKSPACE/results/$name.json" )
            total=$((total+1))
            "$GITHUB_WORKSPACE/evals/check.sh" "$GITHUB_WORKSPACE/$dir" \
              "$GITHUB_WORKSPACE/results/$name.json" && pass=$((pass+1))
          done
          echo "eval pass rate: $pass/$total"

三个必须守住的点:

  1. CLI 版本和模型 ID 都要钉死。升级这两个东西本身就是一次配置变更,要单独跑一轮 eval 再决定是否采用,否则通过率的波动分不清是配置改差了还是模型换了
  2. 每个 case 单独开干净 worktree,互不污染;跑完清掉分支和目录
  3. 表现下降的配置变更不许合并;每个生产事故都变成一个 case,长期留在套件里,同一种问题下次系统先于用户发现

八、生产门禁:Agent 到达门禁,但不能越过

扩大 Agent 执行范围之后,生产权限需要一条清楚的边界:Agent 可以完成发布前的全部准备,最后一次生产部署必须由指定人员授权。

把门禁写成 Hook

先列出必须保留的人工审批(发布授权、受保护路径修改),把每个门禁表达为 Hook。团队级 Hook 进 .claude/settings.json;不可协商的门禁进 managed settings(比如 allowManagedHooksOnly),由平台管理员控制,项目成员无法在本地关闭。阻止操作时要说明原因与授权路径,别让 Agent 猜下一步。

.claude/hooks/production-gate.sh:

bash 复制代码
#!/bin/bash
set -euo pipefail

cmd=$(jq -r '.tool_input.command // empty')

if [[ "$cmd" == *"deploy"* && "$cmd" == *"production"* ]]; then
  if [ -z "${RELEASE_APPROVAL:-}" ]; then
    echo "生产部署需要发布授权。请让发布经理走审批流程后重试。" >&2
    exit 2   # exit 2 阻止操作,stderr 的内容会返回给 Claude
  fi
fi
exit 0

注册方式同第四节,matcher 用 "Bash"。环境变量只在本机有意义,别把它当成授权记录------真正的审批凭据应该落在发布系统或版本控制里,Hook 只做 " 没有凭据就拦住 " 这一层检查。

几条不能省的控制

  1. 分支保护:Agent 的一切改动只能以 PR 形式进入主分支,没有直达 main 的路径。写代码的 Agent 没有批准权
  2. 环境分级自主权:开发环境 Agent 自由部署,预发收紧,生产环境它只准备发布,发布经理授权
  3. 沙箱与最小凭证:非交互式运行在沙箱容器、网络白名单内,持有短期 scoped token,默认无生产凭证;每次运行使用 Agent 自己的身份,流水线日志能分开记录 Agent 做了什么和哪位工程师触发了这次运行
  4. 部署工具化:通过 MCP 把部署、状态查询、回滚封装成按环境开放的工具。Agent 拿到的是一份工具允许列表,不是一段携带完整凭证的任意脚本,即使它判断出错,影响范围也被限制在允许的工具内

回滚是最需要演练的路径

回滚必须是一条 Agent 可以直接运行的单条命令,并且在故障发生之前定期在预发环境验证过。线上故障时没有时间让 Agent 临时读复杂手册、猜哪个步骤还有效。先恢复服务:已演练的回滚命令让 Agent 在授权范围内执行确定动作,后续诊断再走正常审查。

九、线上闭环:异常变回下一份 intent

部署完成后是循环的最后一环:检测交给确定性脚本,模型只在触发之后做诊断。

响应分级写在版本控制的 bands.yaml 里:

yaml 复制代码
metric: ci_test_failure_rate
baseline: rolling_30d
rules: western_electric
tiers:
  1sigma: { action: log }
  2sigma: { action: diagnose,
            tools: "Read,Grep,Bash(gh run view *)" }
  3sigma: { action: propose,
            routes: [pull_request, runbook:rollback-deploy] }

团队可以逐级审查 Agent 被允许做什么:

  • 1σ:只记录
  • 2σ:调用 Claude 做只读诊断,产出报告
  • 3σ:允许 Agent 开一个 PR 进入审查门禁,或触发事先批准过的回滚流程

检测必须确定性。" 什么时候该介入生产环境 " 这个决定不能交给概率模型。检测脚本本身进版本控制、写单元测试,基线用滚动窗口的均值和标准差,让控制带既能抓尖刺也能抓缓慢漂移。

异常被诊断后,Agent 把发现写成标准格式的 intent.md(异常证据、建议结果、受影响系统、开放问题),走和其他需求完全相同的流水线。负责人决定立即修复、排期或关闭;修复上线后补一个 Eval case。一个想法可以启动 intent.md,一次线上异常也可以,循环继续运转,人的判断始终留在意图、风险和生产授权这几个位置。

十、并行:worktree 与 subagent

两个概念要分清:

  • 并行会话:另一个完整的 Claude Code 实例,在独立的 git worktree 里做独立任务。会话之间彼此一无所知,驱动它们的工程师是唯一连接点
  • subagent:单个会话内部的局部助手,有自己的上下文窗口和工具限制,适合在多个任务里重复出现的工作(验证应用能跑、简化代码、探索代码库)
css 复制代码
claude --worktree feature-auth &
claude --worktree fix-rate-limit &

实操要点:

  1. 用 plan.md 判断哪些任务互相独立(不碰同一批文件),共享文件的任务在单会话里排队做
  2. 从两到三个会话开始,实际上限是一个人能可靠审查的流数------审查跟得上才加会话
  3. 重复性工作定义成 .claude/agents/ 下的 subagent,进 git 全团队共享

工程师的工作重心因此改变:从亲手修改每一处代码,转向分配任务、补充上下文、接受结果。

十一、小团队从哪里开始

原文主要写给已在使用 Claude Code 的大型企业(有平台工程师、有治理合规压力)。创业团队三个都没有,而且最大的成本不是工具钱,是流程维护时间------没人有空当流程管理员。所以筛选标准只有一句:它省下的返工时间是否大于建立和维护它的时间。

第一周必做(成本小时级)

  1. 产物链最小版:docs/tasks/日期 - 名字/ 下放 intent.md、spec.md、plan.md。纪律一条:plan 未过,不动代码
  2. 验证命令:CLAUDE.md 写死 build/test/lint 加完成定义。没测试的项目从 bug 复现协议起步攒资产
  3. 一页 CLAUDE.md:Hook 不预设,从第一个真实错误来
  4. 生产人工授权加回滚命令:唯一不能砍的。3 人团队也需要部署前 hook 暂停等人批准,回滚做成一条命令并在预发演练一次

出现信号再上的实践

实践 触发信号
Eval 套件 第一次大返工或事故发生时顺手存 1 个 case,攒到 5 个写循环脚本
REVIEW.md 审查队列第一次堵住
新 Hook 同类错误第二次出现
并行 worktree 单会话审查带宽有富余,从 2 个开始
分级门禁、自动运维、MCP 封装 有了平台工程师或真实合规压力

规则是长出来的,不是一次设计出来的。

高效利用的三个杠杆

  1. 人的时间从生产移到判断。产品负责人主要做 intent 和验收,工程师主要做 plan 审查和风险判断,AI 承担文档初稿、代码、机械审查。取消设计岗位不等于用户体验责任消失,用户路径和完成标准要更早进 intent 和 spec
  2. 管理瓶颈转移。新瓶颈是人的审查带宽,并行数等于可靠审查能力上限,审不过来的并行只是制造新队列
  3. 把学习速度当核心指标。进展不是 AI 生成了多少行,而是从想法到用户反馈回来的周期。方向错误的成本从周降到天,同一笔现金多出几轮试错机会

常见的失败方式

  • 流程超前:三个人建 Eval 平台、写门禁分级文档,流程吃掉开发时间
  • 反面同样致命:全程聊天不留产物,每个新会话重新解释一遍需求,重复解释是最贵的浪费
  • 数量错觉:汇报 AI 生成了几千行。代码量不是价值,通过验证的需求数才是
  • 工具囤积:买一堆 AI 工具不等于 AI Native。没有产物链和验证回路,工具只会更快地产出未验证代码
  • 跳过门禁求快:早期不用生产授权是最危险的省略,早期恰恰赔不起一次线上事故

今天下午就能做的三件事:仓库根建 CLAUDE.md(验证命令加完成定义,10 分钟);下一个需求强制走一遍 intent 到 plan,哪怕很糙;git worktree add ../proj-x -b feat-x 开第二个会话,感受一次并行和它的审查负担。

十二、如何度量落地效果

原文为每个 play 定义了先行指标和滞后指标,摘最有用的几个:

环节 先行指标 滞后指标
Plan 从首次对话到 intent.md 提交的耗时(周降到小时) intent 被产品负责人接受进入下一阶段的比例
Build 计划批准到 PR 合并的时间;首次实现即合并的比例 每个改动的返工次数;合并的 diff 与 plan.md 仍一致的比例
工作环境 Claude 重复犯 CLAUDE.md 已记录错误的频率 新成员首个 PR 合并的时间
Test Agent 代码的 CI 首过率 每个 PR 的审查时间;变更失败率
Eval Eval 通过率趋势;从事故到永久 case 的耗时 CI 拦截的回归 vs 逃逸到生产的回归
Deploy 流水线失败被自动分诊、无需叫人的比例 DORA 指标(部署频率、恢复时间等)

度量视角的转变:从生成了多少代码,转向有效需求通过审查、验证和部署的速度。

总结:判断是否真落地的三个标准

  1. 每个需求有留痕产物(intent、spec、plan),不依赖聊天记录
  2. Agent 能自己运行验证并附上证据。没有测试输出、日志、截图,完成二字无效
  3. 错误写回系统:要么变成规则(CLAUDE.md、Hook),要么变成资产(测试、Eval case),不允许修完就忘

这三件事没做到,Eval 平台、分级门禁都是装饰。

AI Native 团队不会因为购买了更多工具自然出现。它来自一条可以持续运行的工作链:AI 扩大执行能力并提供验证证据,人决定解决什么问题、并对风险和生产结果负责。循环不停运转,人的判断始终在循环之上。


参考:

相关推荐
四六的六1 小时前
Agent 长会话设计实战:从对话上下文到持久状态,把记忆写进检查清单
人工智能·个人开发·ai编程·ai产品·长上下文·ai代码生成·ai会话
ServBay2 小时前
基于Jev的浏览器Agent插件狂揽 21k star,3分钟教你解放双手
后端·aigc·ai编程
9i编程2 小时前
15. 把 DDD 开源脚手架化为自己的:第四次联调(一)——刚加载瘦身的 CLAUDE.md,问题就排着队来
人工智能·openai·ai编程
HelloWorld0012 小时前
告别大模型废话!给 Agent 装上 Jev“小脑”:70ms 决策实战与成本暴降 90% 的秘密
ai编程
TTc_3 小时前
Agent长上下文压缩为什么会反复失败
ai·ai编程
深蓝AI3 小时前
旗舰被小弟反超:Claude Sonnet 5.5 智能体编码凭什么压过 Opus 5.5
agent·ai编程
Sunny_G3 小时前
所见即所得编辑器原理实战:源码与渲染永不失真的三层一致性设计(Markdown/CodeMirror 装饰)
ai编程·harmonyos
ZzT4 小时前
用 Claude 设计 eval,再一轮轮把分数提上去
ai编程·claude
小虎AI生活4 小时前
月活3.82亿的豆包开始帮你打车,说人话办事的时代到了
aigc·ai编程