AI 编程新范式:Vibe、Agentic 与 Spec 实战指南

AI 编程新范式:Vibe、Agentic 与 Spec 实战指南

从「让 AI 写代码」到「让 AI 按契约交付」------10 个章节,一条由浅入深的完整实践路径。

文中涉及厂商自述的量化指标均标注来源与口径,正式引用前请以发布方官方口径复核。

目录

  1. 三种编程范式的核心差异与企业应用场景
  2. [Vibe Coding 自然语言驱动开发快速上手](#Vibe Coding 自然语言驱动开发快速上手)
  3. [Agentic Coding 智能体工作流环境搭建](#Agentic Coding 智能体工作流环境搭建)
  4. [Spec Coding 规格说明书生成代码实操](#Spec Coding 规格说明书生成代码实操)
  5. 从需求分析到代码落地的完整演进路径
  6. 多范式混合使用的最佳实践策略
  7. 常见生成错误分析与精准排错技巧
  8. [提升 AI 编程产出质量的关键提示词方法](#提升 AI 编程产出质量的关键提示词方法)
  9. 本地项目集成与自动化测试验证流程
  10. 面向未来的开发者技能转型与进阶建议

01 三种编程范式的核心差异与企业应用场景

在动手之前,先把三个词的坐标系搞清楚,再把镜头拉到企业现场------看不同职能、不同变更、不同合规要求下,各自该落在哪一档。后面的 9 章都建立在这一章的地基上。

1.1 一句话定位三种范式

Vibe Coding

凭感觉下指令,不看代码只看结果。用自然语言反复描述现象,逼近一个"能跑起来"的东西。它是探索工具,不是交付方式。

Agentic Coding

把执行权交给智能体。AI 能自己规划、读写文件、跑命令与测试、根据报错自我修正。它描述的是执行方式,不规定意图怎么写。

Spec Coding

**先写结构化规格,再让智能体照着做。**规格(而非代码)是真相源与契约。它解决的是 Agent 变强后暴露的新瓶颈:AI 不知道该写什么。

1.2 关键认知:它们不在同一个维度

把三者平铺对比会造成严重误解。正确的坐标系是两条正交的轴:横轴是「AI 自主度」(执行方式) ,纵轴是「意图的形式化程度」(契约方式)。Vibe 和 Spec 是横轴之上的两种契约模式,Agentic 描述的是横轴的高端位置。

图 1 | Vibe 与 Spec 是「契约层」的两端,Agentic 是「执行层」的高端位置------三者不是并列关系。

低形式化(意图即写即弃) 高形式化(规格是契约 / 真相源)
低自主(人写代码) 传统文档驱动开发 · 重规格 · 零自主(瀑布模式) AI 自动补全时代 · 低自主 · 低形式化(2021--22)
高自主(AI 执行) Vibe Coding · 高自主 · 低形式化 · 意图只活在一次性对话里 Spec Coding / Agentic Eng. · 高自主 · 高形式化 · 产出可追溯

为什么这个坐标系重要
它解释了 Karpathy 为什么在 2025 年提出 Vibe Coding、不到一年又改口说"我们进入的是 agentic engineering"------他不是在推翻自己,而是从右上象限的视角指出:光有高自主不够,还得有高形式化。也解释了为什么 Claude Code / Cursor 的 Plan 模式只算"最轻量的 spec-first":意图先对齐再执行,但方案单次会话、用毕即弃,没有 constitution、没有归档回路。

1.3 全维度对比

维度 Vibe Agentic Spec
本质定位 低摩擦的探索方式 AI 自主执行的工程能力 以规格为契约的研发方法论
真相源 对话历史(易失) 代码 + 规则文件 规格文档(可版本控制)
验证方式 主观:"跑起来就行" 自动化:编译 / 测试 / lint 规格对齐 + 验收标准 + 测试
适用规模 单文件、单次会话、原型 多文件、跨模块、长任务 跨人、跨会话、长期维护的系统
上手成本 极低 中:需会写规则文件与测试 较高:需规格写作与流程纪律
典型失败模式 意图漂移、幻觉接口、上下文坍塌 范围蔓延、级联错误、工具误用 过度设计、评审过载、流程僵化
团队协作 基本无法协作 可协作但缺共享契约 规格即协作界面

1.4 企业场景全景:谁在什么环节用哪一种

在企业里,范式选择几乎不由"技术偏好"决定,而由三个客观因素决定:谁在做(职能)、做什么(变更类型)、受什么约束(行业合规)。下面把这三个维度依次铺开,这也是本章最实用的一张对照地图。

1.4.1 按企业职能:每个角色该用哪一种
职能 / 角色 典型 AI 任务 推荐范式 判断理由与主要风险
产品 / 业务分析 需求原型、流程草图、竞品拆解 Vibe 零成本试错,产出物不进生产库。**风险:**原型被当成需求直接交付
前端 / 应用开发 页面迭代、组件抽象、样式微调 Agentic + 轻量 Spec 有 diff 与视觉回归兜底。**风险:**范围蔓延、重复造轮子
后端 / 核心服务 接口、数据模型、事务与并发逻辑 完整 Spec + Agentic 涉及契约与数据,必须可追溯。**风险:**幻觉接口、级联错误
测试 / 质量工程 用例生成、边界补充、回归脚本 Agentic(强验证约束) 测试是 Agent 的方向盘。**风险:**覆盖真空------自己生成自己测
运维 / SRE 部署脚本、告警规则、故障复盘 Vibe → 归档固化 先跑通再固化,脚本必须留档。**风险:**直接对生产环境动手
数据 / 算法 取数脚本、特征工程、Notebook 分析 Vibe / Agentic 探索性高,但结果需可复算。**风险:**口径不一致、结论不可复现
安全 / 合规 扫描规则、威胁建模、审计报告 Spec 优先 需要依据与留痕。**风险:**依赖生成结论、缺独立验证
技术负责人 / 架构师 规范、模板、架构决策、效能度量 Spec(治理层) 规范即代码,需版本化与评审。**风险:**规范漂移、写了没人遵守
1.4.2 按变更类型:规格该写到多深
变更类型 典型例子 推荐范式 规格深度 爆炸半径
一次性、可丢弃 临时报表、数据清洗、格式转换 Vibe 不写规格 极小
小步、可逆 文案样式、单文件修复、补注释 Vibe / Agentic 一句话验收 小
模块级 新增接口、重构一个类、补一个字段 Agentic + 轻量 Spec 验收标准 + 接口契约 中
跨模块 表结构变更 + 多端适配 + 数据迁移 完整 SDD 四文档 + ADR 记录 大
核心 / 受监管 支付、权限、账务、风控、对账链路 完整 Spec + 强门禁 四文档 + ADR + 人工签核 极大

图 2 | 企业真实的一天不是"选一种范式",而是三种范式按时间顺序交替出现------这正是第 6 章要讲的分层策略。

维度 上午 · 探索(Vibe) 白天 · 实现(Agentic) 傍晚 · 沉淀(Spec)
典型活动 把想法变成可交互原型 摸清新框架 / 新 API 行为 一次性脚本与数据清洗 快速验证需求是否成立 单模块功能迭代 Bug 定位与修复 重构与批量改名 先写失败测试再实现 跨模块变更先立规格 接口 / 数据模型评审 记录 ADR 关键决策 归档为下次变更基线
产出 可运行 Demo,不入主干 可评审的 diff + PR 可追溯的契约文档

贯穿全天:版本控制 · 自动化测试 · CI 质量门禁 · 人工评审 · 审计留痕

1.4.3 按行业与合规约束:合规会直接改写技术选型
行业 / 属性 核心约束 范式倾向 额外硬性要求
金融 / 银行 可审计、可追溯、变更留痕 Spec 主导,Agentic 执行 每笔变更能解释"为什么";禁止直连生产库;双人复核;Agent 不持有生产凭据
医疗 / 健康 隐私合规、数据敏感 Spec 主导 数据脱敏;Agent 不接触生产患者数据;操作全程留痕
政企 / 国企 流程合规、信创适配 Spec 主导 全流程审批留痕;文档先行;变更可回溯到具体规格版本
互联网 / SaaS 迭代速度、灰度能力 Agentic 为主 + 轻量 Spec 契约测试兜底;强灰度与一键回滚;上线后监控告警齐备
传统制造 / 工业 产线安全、实时性 Spec 主导,Agentic 受限 硬实时逻辑不交给 Agent;先离线 / 仿真验证再上产线;设备参数需人工签核
企业内部工具 低风险、需求量大 Vibe 为主 凭据不外泄;产物发布前人工过一遍;避免把内部敏感数据贴进外部工具
1.4.4 三个典型企业剧本

剧本 A · 运营临时看板

**背景:**运营要一张"本周各渠道转化"的临时看板,明天就要看。

**怎么做:**用 Vibe 直接生成取数脚本 + 简易看板页面,跑通即可。

**为什么用 Vibe:**一次性、明天就废弃、唯一用户就是运营本人。

**落地要求:**不进主干仓库;数据库用只读账号;用完即弃。

剧本 B · 订单模块迭代

**背景:**订单列表要支持按渠道筛选,并修复一处金额精度问题。

**怎么做:**先写一段验收标准 + 明确"不做什么",再让 Agent 按任务逐个实现。

**为什么不用完整 SDD:**改动局限在单模块、同一人负责、可快速回滚。

**落地要求:**先补失败测试;每任务 30--90 分钟;全量测试通过再合并。

剧本 C · 权限模型重构

**背景:**RBAC 要支持数据行级权限,涉及 12 张表与全部接口。

**怎么做:**四文档齐备------constitution 定安全红线,requirements 写 EARS 验收,design 记录数据模型与 ADR,tasks 拆到可勾选。

**为什么必须完整:**跨人协作、受审计、长期维护、错了影响全系统授权。

**落地要求:**规格进版本库;关键节点人工签核;Agent 只在受限分支与只读库上工作。

企业里最常见的三个翻车现场
**① 原型直连生产。**Vibe 做出的"能跑"版本被当成成品交付,缺权限校验、审计日志与异常兜底。

**② 规范只写不守。**AGENTS.md 写了"禁止直连生产库",却没在工具权限上真正限制,Agent 照样连了------规则引导行为,但不是安全边界 。

**③ 审查成橡皮图章。**让另一个 Agent"审查"AI 写的代码,却没有机器可判定的判据。审查 Agent 只会说"看起来不错"------这不叫审查,这叫多烧 token。

1.5 场景速选:这次任务该用哪一种

场景 推荐范式 判断依据
0→1 原型、一次性脚本、学习新栈 Vibe 爆炸半径小、活不过一周,规格收益覆盖不了成本
单人负责的模块、Bug 修复、重构 Agentic + 轻量 Spec 先写一句验收标准,成本增加 <10%,返工率显著下降
多人协作 / 核心系统 / 受监管链路 完整 SDD 需要可追溯、可审计、跨人共享的单一真相源
维护十年以上的存量系统 Spec-anchored 以「变更」为单位积累规格,逐步把隐性知识显式化

本节的四个结论
① 不是三选一 :Agentic 是执行底座,Vibe 与 Spec 是底座之上的两种契约模式。现实主流是「Spec 定契约 + Agent 执行 + Vibe 探索」的三层结构。

② 判断标准是「爆炸半径」 :改动会影响多少人、多久、多核心,决定你该投入多深的规格。

③ Vibe 不是低级 :它把"想法→可交互实物"从天级压到分钟级,这个价值无可替代;错的只是把它用在长生命周期的生产系统上。

④ 企业里由职能与合规定档 :角色、变更类型、行业约束三个维度会直接给出答案------合规等级越高、爆炸半径越大,就越往 Spec 收;越靠探索与效率,就越往 Vibe 放。

02 Vibe Coding 自然语言驱动开发快速上手

Vibe 的价值是把"想法→可交互实物"的时间从天级压到分钟级。这一节教你三分钟上手,同时给出不翻车的边界。

2.1 三分钟上手流程

图 3 | Vibe 的循环:描述 → 生成 → 贴现象 → 再生成。核心技巧是"用现象代替评价"。
#mermaid-svg-c1Z6mfHbPiKSMCMI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-c1Z6mfHbPiKSMCMI .error-icon{fill:#552222;}#mermaid-svg-c1Z6mfHbPiKSMCMI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-c1Z6mfHbPiKSMCMI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .marker.cross{stroke:#333333;}#mermaid-svg-c1Z6mfHbPiKSMCMI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-c1Z6mfHbPiKSMCMI p{margin:0;}#mermaid-svg-c1Z6mfHbPiKSMCMI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .cluster-label text{fill:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .cluster-label span{color:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .cluster-label span p{background-color:transparent;}#mermaid-svg-c1Z6mfHbPiKSMCMI .label text,#mermaid-svg-c1Z6mfHbPiKSMCMI span{fill:#333;color:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .node rect,#mermaid-svg-c1Z6mfHbPiKSMCMI .node circle,#mermaid-svg-c1Z6mfHbPiKSMCMI .node ellipse,#mermaid-svg-c1Z6mfHbPiKSMCMI .node polygon,#mermaid-svg-c1Z6mfHbPiKSMCMI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .rough-node .label text,#mermaid-svg-c1Z6mfHbPiKSMCMI .node .label text,#mermaid-svg-c1Z6mfHbPiKSMCMI .image-shape .label,#mermaid-svg-c1Z6mfHbPiKSMCMI .icon-shape .label{text-anchor:middle;}#mermaid-svg-c1Z6mfHbPiKSMCMI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .rough-node .label,#mermaid-svg-c1Z6mfHbPiKSMCMI .node .label,#mermaid-svg-c1Z6mfHbPiKSMCMI .image-shape .label,#mermaid-svg-c1Z6mfHbPiKSMCMI .icon-shape .label{text-align:center;}#mermaid-svg-c1Z6mfHbPiKSMCMI .node.clickable{cursor:pointer;}#mermaid-svg-c1Z6mfHbPiKSMCMI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .arrowheadPath{fill:#333333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c1Z6mfHbPiKSMCMI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-c1Z6mfHbPiKSMCMI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c1Z6mfHbPiKSMCMI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-c1Z6mfHbPiKSMCMI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .cluster text{fill:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI .cluster span{color:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-c1Z6mfHbPiKSMCMI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-c1Z6mfHbPiKSMCMI rect.text{fill:none;stroke-width:0;}#mermaid-svg-c1Z6mfHbPiKSMCMI .icon-shape,#mermaid-svg-c1Z6mfHbPiKSMCMI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c1Z6mfHbPiKSMCMI .icon-shape p,#mermaid-svg-c1Z6mfHbPiKSMCMI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-c1Z6mfHbPiKSMCMI .icon-shape .label rect,#mermaid-svg-c1Z6mfHbPiKSMCMI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c1Z6mfHbPiKSMCMI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-c1Z6mfHbPiKSMCMI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-c1Z6mfHbPiKSMCMI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 不满意回到此
① 说清"做完的样子"

一句话描述可见结果
② 让它先生成

不打断,先看整体效果
③ 贴现象去微调

贴报错原文,不说"不对"
④ 能跑就提交

立刻 git commit

2.2 工具选择

工具 适合 特点
Bolt.new / v0 / Lovable 从 0 起一个可交互页面 浏览器内即时预览,非程序员友好,适合验证 UI 想法
Replit Agent 边写边跑、要托管 云端环境开箱即用,适合小工具与教学
Cursor Composer 已有仓库里做原型 多文件编辑能力强,可在真实项目内探索

2.3 让 Vibe 少翻车的表达技巧

不要说 改成
"这个按钮不好看" "按钮再大一点,主色改成品牌蓝 #185FA5,圆角 8px"
"有 bug" "点提交后页面空白,控制台报错原文如下:<粘贴完整报错>"
"加个登录" "加一个邮箱+密码登录页,登录成功跳到 /dashboard,失败在按钮下方显示红字提示"
"优化一下" "列表超过 50 条时改成虚拟滚动,首屏渲染 < 200ms"

2.4 三条自保规则

  1. **先定验收,再开聊。**哪怕一句话:"做完后,我要能在 X 页面点 Y,看到 Z。"这一个习惯对结果质量的提升,超过换任何工具。

  2. **小步提交。**每得到一个能跑的状态就 git commit。Vibe 的致命伤是"改着改着回不去了",频繁提交是唯一的解药。

  3. **设置转正门槛。**原型一旦决定长期维护,必须补三样东西:类型/测试、一份简短规格、一次人工代码走查。这一步叫"从 vibe 到工程的转股",跳过它,原型就会变成技术债的发源地。

别在错误的场景用 Vibe
生产系统、权限/认证/支付/删库逻辑、多人协作的同一代码库、跨会话的中大型特性、受监管行业的核心链路------这些场景里 Vibe 的"边际成本随项目变长急剧上升"会迅速反噬。

03 Agentic Coding 智能体工作流环境搭建

Agentic 时代,你最重要的"代码"不是业务逻辑,而是那套决定 AI 行为边界的项目上下文。本节把它拆成可照抄的四件套。

3.1 核心理念:环境就是上下文装配

同一个模型,在同一个项目上表现可能天差地别,差别几乎全来自"喂给它的上下文质量"。所以搭建 Agentic 工作流的第一件事,不是选工具,而是把项目知识装配成机器可读的结构。现代主流 Agent 用四个机制完成这件事------它们分工清晰、互不替代:

机制 回答什么问题 典型载体
项目规则 这个项目该怎么做事? AGENTS.md(跨工具标准)/ CLAUDE.md(Claude Code)
技能 Skill 某类重复任务怎么做? SKILL.md,按需加载,不占常驻上下文
工具 MCP 怎么访问外部系统与数据? .mcp.json / .cursor/mcp.json 等 MCP 配置
子代理 Subagent 哪类任务可以隔离出去? 独立上下文 + 工具白名单(最小权限)

一句话原则
规则(Rules)管"该怎么做",MCP 管"能碰到什么" ------两者要在同一个仓库里互相引用。例如 AGENTS.md 里应写"查表结构用 db-readonly 这个 MCP server,禁止直连生产库"。规则文件引导行为,但它不是安全边界;硬约束必须落在权限、hooks 与 CI 上。

3.2 仓库上下文结构(可直接照抄)

图 4 | 左侧是文件放在哪,右侧是加载优先级------常驻上下文要瘦,详细约定按需拉取。

仓库根目录(常驻上下文) 分层加载原则(按需拉取)
AGENTS.md --- 项目规则:命令 / 约定 / 禁区 ① 全局规则(组织级):~/.claude/CLAUDE.md --- 跨项目通用偏好
CLAUDE.md --- 首行 @AGENTS.md,仅补工具专属内容 ② 项目规则(仓库级):AGENTS.md --- 本仓库的约定与命令
.mcp.json --- MCP server 定义(不含密钥) ③ 目录规则(模块级):.cursor/rules/*.mdc / .claude/rules/ 按 glob 生效
.agent/ 或 devprompts/ --- 分主题的详细约定(按需引用) ④ 任务时上下文:按需检索 / 注入,用完即走,不常驻
.claude/skills/ --- SKILL.md:重复流程,按需加载 原则:常驻的越少越好,按需的越准越好
.claude/agents/ --- 子代理定义(工具白名单)

3.3 AGENTS.md 该写什么(写错了等于没写)

最常见的失败是把 AGENTS.md 写成"偏好清单"或"架构说明书"。它不是文档,而是能约束行为的契约 。检验标准只有一条:Agent 在你不在场时,能否仅凭这份文件做对事。

该写 示例(好) 不该写(坏)
精确命令 提交前运行 pnpm test:unit,全绿才能 commit "记得测试你的改动"
硬性边界 不得修改 packages/infra/ 与任何 *.sql 迁移 "小心不要改坏东西"
项目结构要点 业务代码在 src/modules/*,共享工具在 src/shared 大段架构散文
约定与惯用法 错误统一抛 AppError,禁止返回裸字符串错误 "代码要写得优雅"
延伸阅读指针 API 规范见 devprompts/api-patterns.md 把全部细节内联进规则文件
复制代码
# AGENTS.md(示例骨架,控制在 100--200 行)

## 项目概览
Spring Boot 3.3 + JPA 的 RBAC 权限服务。单体部署,本地文件存储。

## 常用命令
- 构建:mvn -q clean package
- 单元测试:mvn test
- 提交前必跑:mvn verify(含 Checkstyle + 测试)
- 单类测试:mvn test -Dtest=ClassName

## 代码约定
- 分层:controller → service → repository,禁止跨层直调
- 错误处理:统一抛 BusinessException,由 @ControllerAdvice 转响应
- 命名:接口 I 前缀,实现 XxxImpl
- 新增依赖必须说明理由,且不得引入 Lombok 之外的注解处理器

## 禁区(硬约束)
- 不得修改 src/main/resources/db/migration/**(迁移脚本需人工评审)
- 不得改动 application-prod.yml
- 不得访问生产数据库(MCP 仅提供 db-readonly)

## 延伸阅读
- API 契约:devprompts/api-patterns.md
- 测试规范:devprompts/testing-guidelines.md

三个易踩的坑
① 重复即失效 :任何与代码/配置重复的信息都会过期,用"指向脚本/文件"代替"复述内容"。

② 常驻成本 :规则文件每次会话都会加载、消耗 token;冗长的多步流程应移入 Skill(按需加载)。

③ 语义漂移 :半年后没人更新规则文件,AI 会忠实遵守一份已经过时的约定------把"更新 AGENTS.md"写进 PR 检查清单,并在 CI 里加一个路径漂移检查(验证文件中提到的路径/命令真实存在)。

3.4 MCP:跨工具的工具层契约

MCP 是 Agent 连接外部系统(数据库、内部 API、工单系统)的事实标准接口。要注意:规则层没有跨工具标准,但工具层有------MCP 就是那个标准;只是各工具的配置文件路径与字段名不同,需要分别生成。

工具 配置文件路径 字段约定
Claude Code .mcp.json(项目根) 顶层 mcpServers;注意不是 .claude/mcp.json
Cursor .cursor/mcp.json 顶层 mcpServers
VS Code / Copilot .vscode/mcp.json 用 servers 键,不是 mcpServers
Codex CLI .codex/config.toml(项目)或 ~/.codex/config.toml(全局) TOML 格式
复制代码
// .mcp.json(Claude Code / Cursor 通用结构;密钥用环境变量引用)
{
  "mcpServers": {
    "db-readonly": {
      "command": "npx",
      "args": ["-y", "@myorg/mcp-postgres-ro"],
      "env": { "DATABASE_URL_RO": "${env:DB_URL_RO}" }
    }
  }
}

安全红线
一个 MCP server 可能持有凭据并访问真实系统。**配置文件与密钥不得进入共享或全局可读路径;只授予它完成任务所需的最小权限。**用环境变量引用密钥,并在 .env.example 里声明需要哪些变量。给 Agent 一个"只读"的数据库入口,就是把误删生产库的概率降到接近零的最简单办法。

3.5 分步搭建清单

  1. **锁定验证环境。**先把测试框架跑到能一键执行(mvn verify / pnpm test)。没有可自动判定的验证信号,Agentic 就没有方向盘与刹车,这一步不能跳过。

  2. **写 AGENTS.md。**运行一次工具的 /init 生成初稿,再按 3.3 的表逐条改造,压到 100--200 行,命令与边界放最前。

  3. **拆出 devprompts/。**把长约定(API、测试、数据库、部署)拆成按主题的文件,AGENTS.md 只留指针。

  4. **配 MCP(按需)。**先只接只读数据源,密钥走环境变量,配置提交进版本库但不含密钥。

  5. **加 hooks 与权限。**危险命令(删除、强推、写生产库)设为人工确认;在 CI 里加规则文件的路径漂移检查。

  6. **跑一次基线任务。**选一个中等复杂度的真实任务,观察 Agent 是否能在不追问的情况下走完闭环,把暴露的歧义逐条补回 AGENTS.md。

环境就绪的判据
把仓库交给一个"第一次接触它的 Agent",它能仅凭 AGENTS.md + 代码完成一次改动并通过验证,不需要你在旁边反复解释。达到这个状态,环境就算搭好了。

04 Spec Coding 规格说明书生成代码实操

Spec 的关键不在"写得多",而在"把 Agent 必然会自行猜测的决策点全部写死"。这一节给出一套可复用的四文档结构与一份真实示例。

4.1 四文档的单向约束关系

图 5 | 四份文档各回答一个问题,且前者约束后者。这是 SDD 与"随便写点提示词"的本质区别。
#mermaid-svg-YiM3mAft72JizhXA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YiM3mAft72JizhXA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YiM3mAft72JizhXA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YiM3mAft72JizhXA .error-icon{fill:#552222;}#mermaid-svg-YiM3mAft72JizhXA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YiM3mAft72JizhXA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YiM3mAft72JizhXA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YiM3mAft72JizhXA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YiM3mAft72JizhXA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YiM3mAft72JizhXA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YiM3mAft72JizhXA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YiM3mAft72JizhXA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YiM3mAft72JizhXA .marker.cross{stroke:#333333;}#mermaid-svg-YiM3mAft72JizhXA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YiM3mAft72JizhXA p{margin:0;}#mermaid-svg-YiM3mAft72JizhXA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YiM3mAft72JizhXA .cluster-label text{fill:#333;}#mermaid-svg-YiM3mAft72JizhXA .cluster-label span{color:#333;}#mermaid-svg-YiM3mAft72JizhXA .cluster-label span p{background-color:transparent;}#mermaid-svg-YiM3mAft72JizhXA .label text,#mermaid-svg-YiM3mAft72JizhXA span{fill:#333;color:#333;}#mermaid-svg-YiM3mAft72JizhXA .node rect,#mermaid-svg-YiM3mAft72JizhXA .node circle,#mermaid-svg-YiM3mAft72JizhXA .node ellipse,#mermaid-svg-YiM3mAft72JizhXA .node polygon,#mermaid-svg-YiM3mAft72JizhXA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YiM3mAft72JizhXA .rough-node .label text,#mermaid-svg-YiM3mAft72JizhXA .node .label text,#mermaid-svg-YiM3mAft72JizhXA .image-shape .label,#mermaid-svg-YiM3mAft72JizhXA .icon-shape .label{text-anchor:middle;}#mermaid-svg-YiM3mAft72JizhXA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YiM3mAft72JizhXA .rough-node .label,#mermaid-svg-YiM3mAft72JizhXA .node .label,#mermaid-svg-YiM3mAft72JizhXA .image-shape .label,#mermaid-svg-YiM3mAft72JizhXA .icon-shape .label{text-align:center;}#mermaid-svg-YiM3mAft72JizhXA .node.clickable{cursor:pointer;}#mermaid-svg-YiM3mAft72JizhXA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YiM3mAft72JizhXA .arrowheadPath{fill:#333333;}#mermaid-svg-YiM3mAft72JizhXA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YiM3mAft72JizhXA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YiM3mAft72JizhXA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YiM3mAft72JizhXA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YiM3mAft72JizhXA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YiM3mAft72JizhXA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YiM3mAft72JizhXA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YiM3mAft72JizhXA .cluster text{fill:#333;}#mermaid-svg-YiM3mAft72JizhXA .cluster span{color:#333;}#mermaid-svg-YiM3mAft72JizhXA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YiM3mAft72JizhXA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YiM3mAft72JizhXA rect.text{fill:none;stroke-width:0;}#mermaid-svg-YiM3mAft72JizhXA .icon-shape,#mermaid-svg-YiM3mAft72JizhXA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YiM3mAft72JizhXA .icon-shape p,#mermaid-svg-YiM3mAft72JizhXA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YiM3mAft72JizhXA .icon-shape .label rect,#mermaid-svg-YiM3mAft72JizhXA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YiM3mAft72JizhXA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YiM3mAft72JizhXA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YiM3mAft72JizhXA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} constitution.md

项目宪法 · 最高裁决权
requirements.md

要做什么 + 如何验收
design.md

怎么做 + 为何这样
tasks.md

先做什么 + 依赖谁

约束自上而下单向传递:下层不得推翻上层;歧义时以 constitution 裁决。

文档 回答的问题 关键内容
constitution.md 不可变的全局原则 测试标准、架构约束、命名规范、安全红线(跨会话长期有效)
requirements.md 做什么 + 如何验收 用户故事 + 验收标准,推荐 EARS 句式
design.md 怎么做 + 为何这样 架构、数据模型、API 契约、关键 ADR 决策记录
tasks.md 先做什么 + 依赖谁 离散、可追踪、可逐个验证的实现任务

4.2 实操示例:一个"CSV 导出"功能的规格

先看一个坏 prompt,再看它对应的三份规格片段------差别不在字多,而在决策点是否被写死。

坏 prompt
「加一个把用户数据导出成 CSV 的功能,做得好看点。」

requirements.md(EARS 句式)
复制代码
### REQ-001 导出入口
WHEN 管理员在用户列表页点击「导出」并选择时间范围,
THE SYSTEM SHALL 生成该范围内的用户数据 CSV 文件。

### REQ-002 字段与顺序
THE SYSTEM SHALL 按以下顺序输出列:
id, username, email, role, status, created_at

### REQ-003 大数据量策略
WHEN 导出行数 > 50000,
THE SYSTEM SHALL 改为异步生成,并在完成后以邮件发送附件,
且前端提示「导出已提交,稍后查收邮件」。

### REQ-004 编码兼容
THE SYSTEM SHALL 使用 UTF-8 with BOM 编码,以保证 Excel 直接打开无乱码。

### REQ-005 权限与审计
WHEN 发起导出,
THE SYSTEM SHALL 校验调用者具备 user:export 权限,
AND 记录一条审计日志(操作者、时间范围、行数、结果)。

### 明确不做什么(范围边界)
- 不导出已删除用户的历史快照
- 不提供自定义列选择(本期不做)
- 不支持导出为 Excel/xlsx
design.md(数据模型 + 契约 + ADR)
复制代码
### 接口契约
POST /api/users/export
Content-Type: application/json
Body: { "from": "2026-01-01", "to": "2026-10-01" }

200 同步(行数 ≤ 50000):返回 CSV 流,Content-Disposition: attachment
202 异步(行数 > 50000):{ "taskId": "exp_8f3a", "channel": "email" }
403 无权限;422 时间范围非法(from > to 或跨度 > 366 天)

### 错误码
EXPORT_FORBIDDEN / EXPORT_RANGE_INVALID / EXPORT_QUOTA_EXCEEDED

### ADR-002 为什么同步阈值定在 50000
实测单次导出 5 万行约 6s,超过则网关超时风险上升;
阈值放在配置项 export.sync-threshold,便于后续调整。

### ADR-003 为什么用 BOM 而不是 GBK
下游以 Excel 为主,BOM 方案无需转码且不损失字符集;
代价是部分旧版解析器需跳过头部 3 字节,已在 README 说明。
tasks.md(可勾选、带依赖)
复制代码
- [ ] T1 新增 UserExportService 与服务层单测(依赖:无)
- [ ] T2 定义 DTO 与字段顺序常量(依赖:T1)
- [ ] T3 实现权限校验 + 审计日志(依赖:T1)
- [ ] T4 实现同步导出(BOM 编码)(依赖:T2)
- [ ] T5 实现 50000 行阈值与异步任务(依赖:T4)
- [ ] T6 邮件附件通道(依赖:T5)
- [ ] T7 集成测试:权限、边界、异步三条路径(依赖:T3,T5)
- [ ] T8 更新 README 与接口文档(依赖:T7)

注意这份规格做了什么
它把 Agent 一定会自己猜的每一个点都写死了:字段与顺序、同步阈值、编码方案、权限点、审计字段、错误码、异步降级路径、以及"不做什么"。剩下的编码工作 Agent 几乎不需要再做决策。

4.3 规格质量自检清单

要素 自检问题
问题与动机 为什么做?不做的代价是什么?一两句说清了吗
范围边界 是否显式写出了"不做什么"?(这是范围蔓延的根源)
功能需求 是否用 WHEN...SHALL... 句式覆盖了所有触发条件
数据模型 表结构、字段类型、约束、迁移策略是否明确(别让 Agent 猜列名)
接口契约 路径、请求/响应、错误码是否齐全(防幻觉接口的关键)
非功能需求 性能、并发、安全、合规、可观测性是否交代
失败路径 超时、重试、降级、幂等、部分失败怎么处理
验收方式 怎样算完成?哪些测试必须通过?
禁区 哪些文件/模块不许碰,哪些依赖不许引入

4.4 工具选择

工具 工作流 适合谁 / 取舍
Spec Kit 七阶段关卡 社区最活跃、独有 constitution;缺点是七阶段对小型改动偏重
Kiro requirements→design→tasks 开箱即用独立 IDE,可追踪性最好;绑定其 IDE 与模型
OpenSpec propose→apply→archive 最轻量、不绑 IDE;因归档时更新规格,最接近 spec-anchored
Plan Mode 只读研究→方案→批准→执行 最轻的 spec-first,SDD 入门坡道;方案不沉淀,跨人共享不够

必须听到的反方声音
Thoughtworks 的 Birgitta Böckeler 批评最扎实:SDD 容易"小题大做"(把小缺陷扩展成 4 个用户故事、16 条验收标准)、可能加重评审负担("我宁愿审代码,也不愿审一堆 markdown")、并可能放大评审过载与幻觉。务实回应是分档------按变更的爆炸半径决定规格深度,对单个空值检查级别的小改动,走完整流程是纯粹浪费。

05 从需求分析到代码落地的完整演进路径

前面三节各讲一种范式,这一节把它们串成一条从模糊需求到可交付代码的完整流水线,并标出每一步人类该站在哪里。

5.1 全链路流水线

图 6 | 七个阶段里,人类真正不可替代的是「立契约」与「把质量关」;中间的实现与验证交给 Agent 与自动化。
#mermaid-svg-hkFyovNtzjj2VPKR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hkFyovNtzjj2VPKR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hkFyovNtzjj2VPKR .error-icon{fill:#552222;}#mermaid-svg-hkFyovNtzjj2VPKR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hkFyovNtzjj2VPKR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hkFyovNtzjj2VPKR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hkFyovNtzjj2VPKR .marker.cross{stroke:#333333;}#mermaid-svg-hkFyovNtzjj2VPKR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hkFyovNtzjj2VPKR p{margin:0;}#mermaid-svg-hkFyovNtzjj2VPKR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hkFyovNtzjj2VPKR .cluster-label text{fill:#333;}#mermaid-svg-hkFyovNtzjj2VPKR .cluster-label span{color:#333;}#mermaid-svg-hkFyovNtzjj2VPKR .cluster-label span p{background-color:transparent;}#mermaid-svg-hkFyovNtzjj2VPKR .label text,#mermaid-svg-hkFyovNtzjj2VPKR span{fill:#333;color:#333;}#mermaid-svg-hkFyovNtzjj2VPKR .node rect,#mermaid-svg-hkFyovNtzjj2VPKR .node circle,#mermaid-svg-hkFyovNtzjj2VPKR .node ellipse,#mermaid-svg-hkFyovNtzjj2VPKR .node polygon,#mermaid-svg-hkFyovNtzjj2VPKR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hkFyovNtzjj2VPKR .rough-node .label text,#mermaid-svg-hkFyovNtzjj2VPKR .node .label text,#mermaid-svg-hkFyovNtzjj2VPKR .image-shape .label,#mermaid-svg-hkFyovNtzjj2VPKR .icon-shape .label{text-anchor:middle;}#mermaid-svg-hkFyovNtzjj2VPKR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hkFyovNtzjj2VPKR .rough-node .label,#mermaid-svg-hkFyovNtzjj2VPKR .node .label,#mermaid-svg-hkFyovNtzjj2VPKR .image-shape .label,#mermaid-svg-hkFyovNtzjj2VPKR .icon-shape .label{text-align:center;}#mermaid-svg-hkFyovNtzjj2VPKR .node.clickable{cursor:pointer;}#mermaid-svg-hkFyovNtzjj2VPKR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hkFyovNtzjj2VPKR .arrowheadPath{fill:#333333;}#mermaid-svg-hkFyovNtzjj2VPKR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hkFyovNtzjj2VPKR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hkFyovNtzjj2VPKR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hkFyovNtzjj2VPKR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hkFyovNtzjj2VPKR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hkFyovNtzjj2VPKR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hkFyovNtzjj2VPKR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hkFyovNtzjj2VPKR .cluster text{fill:#333;}#mermaid-svg-hkFyovNtzjj2VPKR .cluster span{color:#333;}#mermaid-svg-hkFyovNtzjj2VPKR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hkFyovNtzjj2VPKR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hkFyovNtzjj2VPKR rect.text{fill:none;stroke-width:0;}#mermaid-svg-hkFyovNtzjj2VPKR .icon-shape,#mermaid-svg-hkFyovNtzjj2VPKR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hkFyovNtzjj2VPKR .icon-shape p,#mermaid-svg-hkFyovNtzjj2VPKR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hkFyovNtzjj2VPKR .icon-shape .label rect,#mermaid-svg-hkFyovNtzjj2VPKR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hkFyovNtzjj2VPKR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hkFyovNtzjj2VPKR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hkFyovNtzjj2VPKR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 验证不通过,带失败信号回到实现
① 需求澄清

说清问题与验收
② 立规格

requirements / design
③ 消歧与拆解

clarify → tasks
④ Agent 实现

逐任务编码,先写失败测试
⑤ 自动验证

编译 / 测试 / lint / 扫描
⑥ 人工把关

架构 / 安全 / 偏离说明
⑦ 交付与归档

合并 · 规格归档为基线

人类主战场:①②③ 立契约、⑥ 把关质量;AI 负责 ④⑤⑦。

5.2 每个阶段的产物与人类角色

阶段 关键产物 谁主导 门禁(做不完不许进下一步)
① 需求澄清 一句话问题 + 验收标准 产品 / 开发者 能用一句话说清"做完的样子"
② 立规格 requirements.md / design.md 开发者 + Agent 辅助 "不做什么"已写明;接口契约齐全
③ 消歧与拆解 澄清问答记录 / tasks.md Agent 提问,人回答 Agent 无未解决的歧义
④ 实现 代码 + 失败测试先行 Agent 任务粒度 30--90 分钟,逐个提交
⑤ 自动验证 测试报告 / 扫描结果 CI 全绿;覆盖率与复杂度达标
⑥ 人工把关 评审意见 / 偏离说明 人(聚焦架构与安全) Agent 已输出"偏离说明"
⑦ 交付与归档 合并记录 / 归档规格 人 + CI 规格归档,作为下次变更基线

5.3 最关键的连接点:验收标准直通测试用例

整条链路里,真正把"需求"和"可验证的实现"焊在一起的,是**给定(Given)/ 当(When)/ 则(Then)**这组句式。它既是需求描述,又能几乎原样变成测试代码------这是 SDD 最实用的一个杠杆。

图 7 | 一份写好 Given/When/Then 的验收标准,本身就是测试用例的骨架------这是把"规格"变成"可执行判据"的最短路径。
#mermaid-svg-OZPNd0qXNz94tB4W{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OZPNd0qXNz94tB4W .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OZPNd0qXNz94tB4W .error-icon{fill:#552222;}#mermaid-svg-OZPNd0qXNz94tB4W .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OZPNd0qXNz94tB4W .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OZPNd0qXNz94tB4W .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OZPNd0qXNz94tB4W .marker.cross{stroke:#333333;}#mermaid-svg-OZPNd0qXNz94tB4W svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OZPNd0qXNz94tB4W p{margin:0;}#mermaid-svg-OZPNd0qXNz94tB4W .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OZPNd0qXNz94tB4W .cluster-label text{fill:#333;}#mermaid-svg-OZPNd0qXNz94tB4W .cluster-label span{color:#333;}#mermaid-svg-OZPNd0qXNz94tB4W .cluster-label span p{background-color:transparent;}#mermaid-svg-OZPNd0qXNz94tB4W .label text,#mermaid-svg-OZPNd0qXNz94tB4W span{fill:#333;color:#333;}#mermaid-svg-OZPNd0qXNz94tB4W .node rect,#mermaid-svg-OZPNd0qXNz94tB4W .node circle,#mermaid-svg-OZPNd0qXNz94tB4W .node ellipse,#mermaid-svg-OZPNd0qXNz94tB4W .node polygon,#mermaid-svg-OZPNd0qXNz94tB4W .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OZPNd0qXNz94tB4W .rough-node .label text,#mermaid-svg-OZPNd0qXNz94tB4W .node .label text,#mermaid-svg-OZPNd0qXNz94tB4W .image-shape .label,#mermaid-svg-OZPNd0qXNz94tB4W .icon-shape .label{text-anchor:middle;}#mermaid-svg-OZPNd0qXNz94tB4W .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OZPNd0qXNz94tB4W .rough-node .label,#mermaid-svg-OZPNd0qXNz94tB4W .node .label,#mermaid-svg-OZPNd0qXNz94tB4W .image-shape .label,#mermaid-svg-OZPNd0qXNz94tB4W .icon-shape .label{text-align:center;}#mermaid-svg-OZPNd0qXNz94tB4W .node.clickable{cursor:pointer;}#mermaid-svg-OZPNd0qXNz94tB4W .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OZPNd0qXNz94tB4W .arrowheadPath{fill:#333333;}#mermaid-svg-OZPNd0qXNz94tB4W .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OZPNd0qXNz94tB4W .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OZPNd0qXNz94tB4W .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OZPNd0qXNz94tB4W .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OZPNd0qXNz94tB4W .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OZPNd0qXNz94tB4W .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OZPNd0qXNz94tB4W .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OZPNd0qXNz94tB4W .cluster text{fill:#333;}#mermaid-svg-OZPNd0qXNz94tB4W .cluster span{color:#333;}#mermaid-svg-OZPNd0qXNz94tB4W div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OZPNd0qXNz94tB4W .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OZPNd0qXNz94tB4W rect.text{fill:none;stroke-width:0;}#mermaid-svg-OZPNd0qXNz94tB4W .icon-shape,#mermaid-svg-OZPNd0qXNz94tB4W .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OZPNd0qXNz94tB4W .icon-shape p,#mermaid-svg-OZPNd0qXNz94tB4W .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OZPNd0qXNz94tB4W .icon-shape .label rect,#mermaid-svg-OZPNd0qXNz94tB4W .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OZPNd0qXNz94tB4W .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OZPNd0qXNz94tB4W .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OZPNd0qXNz94tB4W :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 几乎原样翻译
需求侧:Gherkin 场景

Given...When...Then...
测试侧:JUnit 用例

@Test export_csv_columnOrder()

需求侧(Gherkin):

gherkin 复制代码
Given 管理员已登录且有 user:export 权限
When 点击导出,时间跨度 30 天
Then 返回 CSV,列顺序为 id, username, email, role, status, created_at
And 文件以 UTF-8 BOM 编码

测试侧(JUnit):

java 复制代码
@Test void export_csv_columnOrder() {
  var r = export(authAdmin(), range(30));
  assertThat(r.header()).isEqualTo("id,username,email,role,status,created_at");
  assertTrue(r.hasUtf8Bom());
}

这条链路的分水岭
有可自动判定的验证信号(编译、测试、lint),Agent 就能自己试错、自己收敛;没有,它只能"看起来对"。所以 ⑤ 自动验证不是流程的装饰,而是 ④ 能自动化的前提。

06 多范式混合使用的最佳实践策略

2026 年真正跑得顺的团队,几乎都不是"三选一",而是按变更的爆炸半径分层。这一节给出分层模型、决策树与团队落地路线。

6.1 按爆炸半径分层

图 8 | 越往上爆炸半径越大,规格投入越重;底部的五条是三层共享的工程底线,任何一层都不能省。

层级 范式选择 适用场景
第 1 层 · 探索层 Vibe:不写规格,但小步提交 原型 · 一次性脚本 · UI 微调 · 学习新栈
第 2 层 · 日常交付层 Agentic + 轻量规格:先写验收标准,再让 Agent 跑 单模块特性 · Bug 修复 · 重构
第 3 层 · 系统层 完整 SDD:constitution + 规格 + 设计 + 任务 跨模块 · 跨人 · 长期维护 · 受监管链路

贯穿三层:版本控制 · 自动化验证 · 权限边界 · 审计留痕 · 人在回路

6.2 决策树:这次改动该走哪一档

判断问题 命中 走哪一档
这段代码三个月后还需要改吗? 不需要 Vibe 直接开干,记得频繁 commit
改动是否局限于单文件、且你能一眼看懂整个 diff? 是 Agentic + 一句验收标准即可
是否涉及数据模型、接口契约、权限或资金? 是 完整规格:至少写清数据模型与契约
是否有第二个人(或第二个 Agent)会碰同一块代码? 是 规格必须是共享契约,进版本库
是否有现成的自动化测试能判定对错? 否 先补测试再动手,否则 Agent 只能帮你"看起来对"
失败后是否需要向他人解释"为什么这么设计"? 是 规格即解释材料,也是审计证据

6.3 团队落地的三个阶段

阶段 动作 观察指标 成功判据
试点期 (1--4 周) 单个小组、单仓库;建立 AGENTS.md 与验证环境;只允许 Agent 提 PR PR 返工率、AI 代码合并率 团队能稳定用 Agent 完成日常小改动
规范期 (1--2 月) 引入轻量规格模板与决策树;把 hooks、CI 质量门禁接上;建立审查 Skill 首次通过率、评审耗时、回归缺陷数 中等变更能"规格先行"稳定交付
规模化期 (3 月+) 多 Agent 编排、并行会话、多角色分工;规格归档与回归测试进 CI 交付周期、人均产出、成本/PR 跨模块变更也能可追溯、可审计

6.4 混合使用时最容易犯的四个错

① 全场景一把梭

要么所有小改动都写四文档(过度),要么生产系统也 Vibe(危险)。正确做法是让决策树而非习惯决定深度。

② 规格写完就扔

用 Plan Mode 出了方案、做完不回写归档,下次变更又要从零推理。归档规格 = 给未来省时间。

③ 用规范文件当安全边界

写了"禁止删库"就以为安全了。规则引导行为,但硬约束必须落在权限、hooks、分支保护与 CI。

④ 只有生成没有验证

多跑几个 Agent 互相审查,但没有可执行判据,结果只是多烧 token。Generator 与 Verifier 之间必须有机器可判定的判据。

四条红线(无论哪一层都不能省)
① 版本控制 :Agent 动手前先提交,产出单独分支;② 自动化验证 :没有机器可判定的信号就不算完成;③ 权限边界 :文件系统、命令、网络、凭据四层最小权限;④ 人在回路:合并需要测试全绿 + 至少一人审阅,受监管链路额外签核。

07 常见生成错误分析与精准排错技巧

AI 生成代码的错误不是随机的,它们高度集中在六类模式上。认清模式,就能把"到处救火"变成"按图排错"。

7.1 六类高频错误与识别信号

错误类型 典型表现 识别信号 根因
幻觉接口 调用不存在的 API 方法、配置键或数据库字段 编译通过、运行时炸;"这个方法文档里没有" 凭训练记忆混用版本,缺少依赖规格
意图漂移 选了"合理默认值",但和真实需求不一致 代码看着对,跑出来不是你要的 需求中的决策点没写死,Agent 自行填空
上下文坍塌 长任务后半段忘记前面决策,自相矛盾 同一会话内前后实现风格/约定反转 关键决策只在对话里,没落到文件
范围蔓延 顺手重构了无关模块,diff 失控 PR 里出现任务之外的改动 没有"不做什么"约束,任务粒度太粗
级联错误 修一个 bug 引入三个新 bug 改完后红测变多而非变少 缺少回归保护,改动未跑全量测试
覆盖真空 测试"看起来很全"却没测关键分支 覆盖率不低,但线上仍出低级缺陷 测试由 AI 一并生成、无人校验有效性

7.2 排错五步法

图 9 | 排错五步法。核心纪律:先锁现场、再复现、后解释,最后把根因补回规格形成免疫。
#mermaid-svg-pKzhkmRVH1A6Zjlw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pKzhkmRVH1A6Zjlw .error-icon{fill:#552222;}#mermaid-svg-pKzhkmRVH1A6Zjlw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pKzhkmRVH1A6Zjlw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .marker.cross{stroke:#333333;}#mermaid-svg-pKzhkmRVH1A6Zjlw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pKzhkmRVH1A6Zjlw p{margin:0;}#mermaid-svg-pKzhkmRVH1A6Zjlw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .cluster-label text{fill:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .cluster-label span{color:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .cluster-label span p{background-color:transparent;}#mermaid-svg-pKzhkmRVH1A6Zjlw .label text,#mermaid-svg-pKzhkmRVH1A6Zjlw span{fill:#333;color:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .node rect,#mermaid-svg-pKzhkmRVH1A6Zjlw .node circle,#mermaid-svg-pKzhkmRVH1A6Zjlw .node ellipse,#mermaid-svg-pKzhkmRVH1A6Zjlw .node polygon,#mermaid-svg-pKzhkmRVH1A6Zjlw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .rough-node .label text,#mermaid-svg-pKzhkmRVH1A6Zjlw .node .label text,#mermaid-svg-pKzhkmRVH1A6Zjlw .image-shape .label,#mermaid-svg-pKzhkmRVH1A6Zjlw .icon-shape .label{text-anchor:middle;}#mermaid-svg-pKzhkmRVH1A6Zjlw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .rough-node .label,#mermaid-svg-pKzhkmRVH1A6Zjlw .node .label,#mermaid-svg-pKzhkmRVH1A6Zjlw .image-shape .label,#mermaid-svg-pKzhkmRVH1A6Zjlw .icon-shape .label{text-align:center;}#mermaid-svg-pKzhkmRVH1A6Zjlw .node.clickable{cursor:pointer;}#mermaid-svg-pKzhkmRVH1A6Zjlw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .arrowheadPath{fill:#333333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pKzhkmRVH1A6Zjlw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-pKzhkmRVH1A6Zjlw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pKzhkmRVH1A6Zjlw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-pKzhkmRVH1A6Zjlw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .cluster text{fill:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw .cluster span{color:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pKzhkmRVH1A6Zjlw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-pKzhkmRVH1A6Zjlw rect.text{fill:none;stroke-width:0;}#mermaid-svg-pKzhkmRVH1A6Zjlw .icon-shape,#mermaid-svg-pKzhkmRVH1A6Zjlw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pKzhkmRVH1A6Zjlw .icon-shape p,#mermaid-svg-pKzhkmRVH1A6Zjlw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-pKzhkmRVH1A6Zjlw .icon-shape .label rect,#mermaid-svg-pKzhkmRVH1A6Zjlw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pKzhkmRVH1A6Zjlw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-pKzhkmRVH1A6Zjlw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-pKzhkmRVH1A6Zjlw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ① 固定现场

先 commit 当前状态,保证可回滚
② 复现最小

写一条失败测试,把问题锁死
③ 先解释

让 Agent 说根因,再谈修复
④ 最小修复

只改必要处,跑全量测试
⑤ 补防线

把该写死的补进规格

③ 是关键:让 AI 先解释再动手,可避免它"随机改到看起来不报错"。

7.3 症状→根因→动作 速查表

你看到的症状 最可能的类型 立刻做什么
编译过了,一跑就 500 / 方法不存在 幻觉接口 把真实 API 签名/依赖版本喂进去;加契约测试锁死
功能都能跑,但行为不是你要的 意图漂移 补齐验收标准;把默认值显式写死
改到一半,Agent 开始推翻前面约定 上下文坍塌 停下,把决策写进 plan/规格,开新会话让它读回
PR diff 远超预期 范围蔓延 拒收,补"不做什么",任务切到 30--90 分钟
修完 A,B/C/D 挂了 级联错误 先补回归测试,每步跑全量而非只跑相关用例
覆盖率不低,线上仍出问题 覆盖真空 先写测试再让 AI 实现;用变异测试抽检有效性

两个高杠杆技巧
① "先解释,后修复" :调试时明确要求 Agent 先说出根因,再动手。如果它的解释是错的,你就知道修复一定也是错的------省下大量反复。

② "偏离说明" :任务收口时要求 Agent 输出"哪里没按方案做、为什么"。这一步能把静默偏离(偏离了设计却没告诉你)变成显式信息,是 SDD 落地的关键小动作。
别和 AI 硬碰硬
同一个错误纠正两次仍不奏效,就回滚重来,换一种完全不同的问法或换模型。在多轮偏航的上下文里继续拉扯,只会让错误越叠越深------这是最常见的 token 浪费来源。

08 提升 AI 编程产出质量的关键提示词方法

在 Agentic 时代,提示词工程的重心已经从"措辞技巧"转向"上下文工程"。这一节给出可复用的公式、七个模式与一份模板。

8.1 从提示词工程到上下文工程

2026 年的一个共识是:强模型已经内化了大量推理,过度指导反而会降低质量 。与其堆砌"请你一步步思考",不如把精力放在三件事上------给对上下文、收紧约束、定义验证。一条好提示词要提供四样东西:

图 10 | 提示词四要素。弱提示词只描述任务,强提示词定义整个工程问题。

Context 上下文 Task 任务 Constraints 约束 Verification 验证
语言 / 框架 / 版本 具体要建 / 改什么 性能 / 安全 / 兼容 期望的测试
架构、相关文件 一次只做一件事 禁止的做法 验收标准
数据形状、现有风格 限定目标文件 不许碰的文件 输出格式

弱提示词只描述任务,强提示词定义整个工程问题。
核心公式
你是 [角色/技术栈]。目标:[具体结果]。上下文:[架构/文件/数据形状]。约束:[1] [2] [3]。输出:[格式]。验收标准:[怎样算对]。

8.2 七个高杠杆提示词模式

模式 做法 示例要点
① 约束优先 先说"不要做什么",再说做什么 "加 JWT 认证:不改现有路由、复用现有 User 模型、token 存 httpOnly cookie(非 localStorage)、24h 过期"
② 给出输出形状 用代码骨架告诉它格式 贴一段目标测试的 describe/it 结构,让 AI 填实现
③ 引用现有代码 指向同类实现作为范式 "完全按 src/routes/users.ts 的模式写订单接口"
④ 提供数据契约 给输入/输出 JSON 或类型 贴真实响应示例 + 目标类型定义,减少字段猜错
⑤ 迭代式细化 一次一步,逐步收紧 先模型 → 再校验 → 再接口;每步小到可快速评审
⑥ 解释"为什么" 给出动机而非只给指令 "改用 Map 是因为需要保证插入顺序"------AI 会顺带处理相关边界
⑦ 限定范围 明确只碰哪些文件 "仅在 middleware.ts 内改动,不要动其他文件"

8.3 一份可直接套用的模板

复制代码
你在这个项目里工作:Spring Boot 3.3 + JPA(阿里 Java 开发规范)。

【目标】
为「用户导出」加一个 POST /api/users/export 接口。

【上下文】
- 分层:controller → service → repository
- 复用现有 UserRepository 与 PermissionService
- 参考同类实现:src/main/java/.../UserQueryController.java

【约束】
- 不引入新的第三方依赖
- 不修改 db/migration/**
- 返回 400 处理参数非法;403 处理无权限;201 返回任务/文件标识
- 使用异步仅当行数 > 50000

【输出】
- Controller + Service + DTO 代码
- 对应的 JUnit 测试:正常、无权限、超阈值异步 三条路径

【验收标准】
- mvn verify 全绿
- 无未处理的受检异常
- 审计日志包含操作者、时间范围、行数

8.4 反模式(做了会变差)

不要做的

  • 把整个文件粘进去说"修一下"------应指向具体问题区

  • 连续发 4--5 个改动却不评审------分歧会累积

  • 同一个错误纠正两次还硬碰------应回滚换思路

  • 用 AI 做改个变量名这种琐事------比手改更慢

  • 堆砌"请一步步思考"------强模型上反而降质

应该做的

  • 先给版本号(框架大版本间 API 常不兼容)

  • 用 @文件 引用代替粘贴(保持上下文新鲜)

  • 复杂任务先用只读模式做研究,再动手

  • 每 3--4 次修改就完整评审一遍

  • 把反复用到的提示沉淀成团队模板库

一句话总结这一节
提示词不是在"求一个更好的答案",而是在设计一个让好答案可复现的接口------定义上下文、约束、失败模式与验收标准。这不是措辞技巧,是系统设计。

09 本地项目集成与自动化测试验证流程

没有自动验证的 Agentic Coding,等于让 AI 蒙眼高速驾驶。这一节把验证做成五层门禁,让"看起来对"变成"机器判定对"。

9.1 五层质量门禁

图 11 | 越靠下越全面也越慢。前两层要"快且透明",后三层才是真正的裁决。

层级 时机 内容
第 1 层 · 编辑时 编辑器 / Agent 内 实时类型检查、内联 lint、保存即格式化(秒级反馈,不阻断)
第 2 层 · 提交前 pre-commit hooks 格式化 + 高价值 lint + 受影响单测(目标 30 秒内,超时会被绕过)
第 3 层 · 推送后 CI:构建 + 全量测试 编译、全量单测、集成测试、覆盖率门槛、依赖漏洞扫描
第 4 层 · 预发布 E2E + 性能 + 安全 端到端路径、性能回归、SAST/DAST、许可证与 SBOM 检查
第 5 层 · 合并闸门 AI 审查 + 人工签核 质量门禁通过 + 至少一人审阅架构与安全;受监管链路额外签核

越靠下越全面也越慢;前两层要"快且透明",后三层才是真正的裁决。

9.2 第 2 层:pre-commit 配置示例

复制代码
# .pre-commit-config.yaml(Python 示例;Java 可用 Checkstyle + Spotless 对应实现)
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace      # 清理 AI 引入的无关字符
      - id: end-of-file-fixer
      - id: check-added-large-files
        args: ['--maxkb=500']
  - repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
      - id: black                    # "独裁式"格式化,消除风格争论
  - repo: local
    hooks:
      - id: fast-unit-tests
        name: Fast unit tests
        entry: pytest tests/unit -q --maxfail=1
        language: system
        pass_filenames: false
        always_run: true

一个容易被忽略的设计点
pre-commit 必须快 (目标 <30 秒)且只对暂存文件相关的内容检查 。超过 30 秒,开发者就会开始用 --no-verify 绕过它------再好的门禁也形同虚设。阻止提交(fail)而不是仅警告,这样问题在上下文最新鲜时就被修掉。

9.3 第 3 层:CI 质量门禁

复制代码
# .github/workflows/quality.yml
name: Quality Gates
on: [pull_request]
jobs:
  gates:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build & Test
        run: mvn -B verify            # 编译 + 单测 + 集成测试
      - name: Coverage Gate
        run: mvn jacoco:check         # 低于阈值直接失败
      - name: Dependency Scan
        run: mvn org.owasp:dependency-check-maven:check
      - name: Rule Drift Check
        run: bash scripts/check-agents-paths.sh   # 校验 AGENTS.md 提到的路径真实存在

注意最后一步「规则漂移检查」------它验证 AGENTS.md 里提到的路径、命令是否真实存在。这是整个配置里投入产出比最高的一项自动化:简单、枯燥,但每周都能抓到真实问题。

9.4 TDD + Agent:把"方向盘"交给测试

Kent Beck 把 TDD 称为与 AI Agent 协作时的 superpower------因为 Agent 极易引入回归,而单元测试提供了一道自动的回归防线。标准循环如下:

  1. 人写一条失败测试(红)------用验收标准直译,把"要什么"钉死。

  2. Agent 生成最小实现(绿)------只写够让测试通过的量。

  3. CI 跑全量测试------所有测试必须通过,才进入下一步。

  4. Agent 重构(保持绿)------改善结构,CI 复跑验证没破坏任何东西。

  5. Agent 补边界测试------补齐空值、超时、并发等边界。

  6. 最终 CI 检查 → 合并批准------通过即交付,并把根因与新约束回写规格。

闭环的更高形态:让 Agent 自我问责
把质量扫描器接入 Agent(如通过 MCP 连接 SonarQube),可以形成「生成 → 扫描 → 读问题 → 自动修复 → 复扫」的闭环,Agent 在提 PR 前就先把质量门禁跑通。但必须设护栏 :给修复循环设迭代上限 (如最多 N 轮),否则会出现"改坏---修好---又改坏"的死循环空转。同时要求 Agent 只在质量门禁通过后才建议提交。

9.5 一次改动的完整命令流

复制代码
# 1. 锁现场
git checkout -b feat/user-export
git commit -am "chore: baseline before AI change"

# 2. 先写失败测试(红)
#    编辑测试文件,描述期望行为
mvn test -Dtest=UserExportTest      # 预期:失败

# 3. 让 Agent 实现(绿)
#    Agent 按 tasks.md 逐任务实现,每个任务跑全量测试
mvn verify                          # 预期:全绿

# 4. 收口
#    要求 Agent 输出「偏离说明」;人工评审架构与安全
git add -A && git commit -m "feat: user export (see spec/2026-10-user-export)"

# 5. 归档规格,作为下次变更基线
git add spec/ && git commit -m "docs: archive user-export spec"

验证层的判据
判断一道门禁值不值得加,只问一句:**它能否在几秒到几分钟内,给出机器可判定的对错?**能,就加进流水线;不能(比如"代码是否优雅"),就交给人,但要让人聚焦在架构与安全,而不是逐行语法。

10 面向未来的开发者技能转型与进阶建议

这场迁移的主线不是"AI 越来越会写代码",而是人类的抽象层级在不断上移。这一节谈清楚:什么在贬值、什么在升值,以及该怎么走。

10.1 抽象层级的上移

图 12 | 从写语法、写逻辑到写意图、写契约。抽象层级每上一层,人被解放一次,也对表达精度要求更高一档。
#mermaid-svg-f78Syhi5BDuFwCgx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-f78Syhi5BDuFwCgx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-f78Syhi5BDuFwCgx .error-icon{fill:#552222;}#mermaid-svg-f78Syhi5BDuFwCgx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-f78Syhi5BDuFwCgx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-f78Syhi5BDuFwCgx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-f78Syhi5BDuFwCgx .marker.cross{stroke:#333333;}#mermaid-svg-f78Syhi5BDuFwCgx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-f78Syhi5BDuFwCgx p{margin:0;}#mermaid-svg-f78Syhi5BDuFwCgx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-f78Syhi5BDuFwCgx .cluster-label text{fill:#333;}#mermaid-svg-f78Syhi5BDuFwCgx .cluster-label span{color:#333;}#mermaid-svg-f78Syhi5BDuFwCgx .cluster-label span p{background-color:transparent;}#mermaid-svg-f78Syhi5BDuFwCgx .label text,#mermaid-svg-f78Syhi5BDuFwCgx span{fill:#333;color:#333;}#mermaid-svg-f78Syhi5BDuFwCgx .node rect,#mermaid-svg-f78Syhi5BDuFwCgx .node circle,#mermaid-svg-f78Syhi5BDuFwCgx .node ellipse,#mermaid-svg-f78Syhi5BDuFwCgx .node polygon,#mermaid-svg-f78Syhi5BDuFwCgx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-f78Syhi5BDuFwCgx .rough-node .label text,#mermaid-svg-f78Syhi5BDuFwCgx .node .label text,#mermaid-svg-f78Syhi5BDuFwCgx .image-shape .label,#mermaid-svg-f78Syhi5BDuFwCgx .icon-shape .label{text-anchor:middle;}#mermaid-svg-f78Syhi5BDuFwCgx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-f78Syhi5BDuFwCgx .rough-node .label,#mermaid-svg-f78Syhi5BDuFwCgx .node .label,#mermaid-svg-f78Syhi5BDuFwCgx .image-shape .label,#mermaid-svg-f78Syhi5BDuFwCgx .icon-shape .label{text-align:center;}#mermaid-svg-f78Syhi5BDuFwCgx .node.clickable{cursor:pointer;}#mermaid-svg-f78Syhi5BDuFwCgx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-f78Syhi5BDuFwCgx .arrowheadPath{fill:#333333;}#mermaid-svg-f78Syhi5BDuFwCgx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-f78Syhi5BDuFwCgx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-f78Syhi5BDuFwCgx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-f78Syhi5BDuFwCgx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-f78Syhi5BDuFwCgx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-f78Syhi5BDuFwCgx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-f78Syhi5BDuFwCgx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-f78Syhi5BDuFwCgx .cluster text{fill:#333;}#mermaid-svg-f78Syhi5BDuFwCgx .cluster span{color:#333;}#mermaid-svg-f78Syhi5BDuFwCgx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-f78Syhi5BDuFwCgx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-f78Syhi5BDuFwCgx rect.text{fill:none;stroke-width:0;}#mermaid-svg-f78Syhi5BDuFwCgx .icon-shape,#mermaid-svg-f78Syhi5BDuFwCgx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-f78Syhi5BDuFwCgx .icon-shape p,#mermaid-svg-f78Syhi5BDuFwCgx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-f78Syhi5BDuFwCgx .icon-shape .label rect,#mermaid-svg-f78Syhi5BDuFwCgx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-f78Syhi5BDuFwCgx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-f78Syhi5BDuFwCgx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-f78Syhi5BDuFwCgx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 每一次上移释放生产力,也把"把事情说清楚"的成本推高
写语法

汇编 / 早期语言
写逻辑

高级语言 / 框架
写意图

自然语言驱动生成
写契约

规格 / 边界 / 验收

歧义从未像今天这样昂贵------这是本期转型的核心命题。

10.2 什么在贬值,什么在升值

正在贬值 正在升值
逐行手写样板与 CRUD 结构化沟通:把模糊需求变成精确契约
记忆 API 细节(可检索替代) 领域建模与架构判断
追求"写得最快" 验证设计:怎么证明它对
单点编码熟练度 代码审计、威胁建模、AI 评测(Eval)
按部就班的执行 任务分解与多 Agent 编排

一个值得记住的判断
OpenAI 的 Sean Grove 提出:写代码只占程序员价值的 10--20%,其余 80--90% 是"结构化沟通"------理解用户、提炼需求、规划与验证(该比例为修辞表达,非实测数据)。AI 越能干,这个论断越接近现实:把问题说清楚,正在成为最核心的开发技能。

10.3 分阶段进阶路线

阶段 目标 具体动作
0--1 月 会用 把 Agent 变成日常工具 搭好验证环境与 AGENTS.md;每天用 Agent 完成一个小改动;练习"约束优先 + 输出形状"两式提示词
1--3 月 会控 能控制产出质量 把 TDD 循环跑顺;接入 pre-commit 与 CI 门禁;建立个人排错五步法与提示词模板库
3--6 月 会设 能设计规格与流程 用四文档写真实特性;为仓库维护分层规则;能判断"这次该走哪一档"并落地决策树
6 月+ 会编 能编排多 Agent 交付 编排 Maker/Critic/Tester 多角色;把规格归档与回归测试接进 CI;沉淀团队级规范与培训

10.4 角色在重构,但价值没有消失

开发者的新角色

  • 系统架构师:定边界、定契约、定取舍

  • 意图管理者:把业务语言翻译成可执行规格

  • 质量守门人:设计验证、审查架构与安全

  • Agent 编排者:分解任务、协调多角色、控成本

尚未解决的难题

  • 初级工程师不再靠写 CRUD 练手,培养体系出现断层------行业还没有好答案

  • "知识空心化":团队没人真正理解系统,只会"再问一次 AI"

  • 长程任务的目标保真与错误累积,仍是可靠性瓶颈

  • 评测与审计的职业标准尚未成形

给个人的三条建议
**① 把"说清楚"当核心技能练。**写规格、写验收标准、写约束,比多背一个 API 更保值。

**② 别放弃读代码与做验证的能力。**当 Agent 产出越来越快,能判断对错 的人才是稀缺的。

**③ 建立自己的度量。**记录返工率、首次通过率、评审耗时------用数据判断你的工作流是否真的在变好,而不是凭感觉。
写在最后
这套指南里所有的方法,本质上都在做同一件事:把"人与人之间的默契"外化成"机器可读的契约"。Vibe 让你快,Agentic 让你省,Spec 让你稳------而把三者按爆炸半径编排起来的能力,才是新范式真正的门槛。

参考来源

· Karpathy 关于 vibe coding 与 agentic engineering 的公开表述(2025--2026)

· GitHub Spec Kit / AWS Kiro / OpenSpec / BMAD-METHOD / Tessl 官方文档与发布公告

· Thoughtworks 技术雷达与 Birgitta Böckeler 关于 SDD 成熟度的分析

· 各主流 Agent 工具(Claude Code / Cursor / VS Code Copilot / Codex CLI)关于 AGENTS.md、MCP 与 hooks 的官方文档

· Kent Beck 关于 TDD 与 AI Agent 协作的观点

· 2026 年多篇关于提示词工程、上下文工程与 AI 代码质量门禁的行业实践文章

本报告中的量化指标均标注来源与口径,涉及厂商自述的数据缺少独立第三方验证,建议在正式决策材料中以官方口径复核后再引用。

相关推荐
武子康1 小时前
LingBot-World 能连续生成一小时,为什么回到原地仍可能变样?
人工智能·llm·agent
AIGCmagic社区1 小时前
多模态Jev专题:OmniMed-Jev多标签可靠误差降到原来的1/126
人工智能·aigc·jev模型
鶴哥只手遮天1 小时前
第 16 章 模型与 Provider 抽象层
人工智能·开源
鬓戈1 小时前
LLM 训练原理、L20 单卡训练可行性与 nanoGPT 入门
人工智能
xsd202411181 小时前
微信开源 WeVisDoc:端到端文档解析模型
人工智能
skywalk81631 小时前
光明记忆(LIMS)v2.3 — 智能记忆管理平台(未开放版本)
人工智能·记忆·光明
弈语道破AI1 小时前
一稿出片!双十一品牌宣传AI视频生成工具推荐:即梦 Seedance 2.5 全球首发
人工智能·音视频
通信大模型1 小时前
中国科学 信息科学 | TokenCom: 面向多模态和多任务Token通信的视觉-语言模型
人工智能·计算机视觉·语言模型
LeeZhao@1 小时前
【具身智能】VLA-DM0.5:让机器人真正理解世界
人工智能·计算机视觉·机器人·agi