AI-native SDLC · 第 1 篇
AI 能不能像人一样把软件打磨出来?我拿一个 IAM 平台试了半年
让 AI 写代码不难,难的是知道它写对没有。我用 auth9 这个项目试了一套办法:QA 文档当规格,16 个 skill 把规划、测试、修复、部署串成一个闭环。
这是《同一套方法论,我用了三次,结果各不一样》的上半篇。最早的版本是 2026 年 2 月写的,放在 auth9 仓库的
docs/blog-ai-native-sdlc.md里,有英中日三种语言。这一版是按项目结束时(6 月 27 日,491 次提交)的状态重写的。
我想弄清楚的一件事
2026 年初,我想回答一个问题:如果几乎所有代码都让 AI 写,能不能做出一个真正能上生产的东西?
不是 demo,不是周末小项目。得是一个复杂到能把方法论逼出原形的系统,而且安全要求高到”差不多能用”根本不算数。
我选了 IAM,也就是身份和访问管理。它里面全是互相咬合的东西:多租户隔离、OIDC 和 OAuth2、Token Exchange、层级 RBAC、webhook 签名、审计日志。一个决定做错,会在十几个地方冒出隐蔽的 bug。做 TODO 应用证明不了什么,任何方法在简单问题上都好看。
结果就是 Auth9,一个自托管的 Auth0 替代品,Rust 后端、React Router 7 前端、TiDB、Keycloak,线上有个实例在 auth9.c9r.io。代码几乎全是 AI 写的,每一步几乎都由 skill 驱动。但 Auth9 本身只是副产品,我真正在试的是那条流水线。

瓶颈根本不在写代码
用过 Copilot、Cursor、Claude Code 的人都知道,代码确实写得快了。但写代码从来不是最难的部分。难的是知道这段代码对不对,而且要知道得够快、够自动,不然验证就成了新的瓶颈。
AI 写出来的东西经常看着很对,一跑就倒:缺依赖、lint 不过、逻辑错。每次出错都由我去提示它,效率太低。所以我定了一条原则:验证必须和写代码一样自动化。AI 写完,自己测;测不过,自己修。我不做那个每次都要盯着报错的人。
反过来说,如果代码产出快了 10 倍,验证还靠人,那你只是得到了 10 倍的 QA 积压。
测试往前挪了一格
代码级的测试还在:cargo test 一两秒跑完,不依赖任何外部服务,我明令禁止 testcontainers 和真实数据库;Playwright 跑端到端;Vitest 管前端。这些也都是 AI 生成的。
我在这之前加了一层:QA 测试文档。就是一份结构化的说明,写清楚测什么、怎么测、在数据库里怎么核对结果。AI 生成,我审,然后 AI 执行:开浏览器点、调 API、查数据库、打 gRPC。说白了它更像传统的手工测试,只是自动化了。它现在还不能完全替代手工测试,但已经能扛下绝大部分。
顺序也变了。测试计划不是功能上线后补写的,而是功能规划完之后产出的第一份东西。它决定后面写什么代码、验什么、出问题时能抓到什么。
顺便说一下我对 spec-driven development 的看法:QA 文档才是 spec。设计文档描述你想要什么,但它没法告诉你有没有得到。QA 文档两件事都做:既定义预期行为,又能在跑着的系统上自动验证。设计文档过时了没人知道,QA 文档在现实偏离规格的那一刻就会失败。不能执行的规格,只是愿望。
那条流水线
16 个 Agent Skill 串在一起,每一步的输出是下一步的输入:
人 + AI ──► 规划功能
│
▼
┌─ 生成 QA / 安全 / UIUX 测试文档 (qa-doc-gen)
▼
┌─ 自动执行测试 (qa-testing, e2e-testing, ...)
▼
┌─ 失败 → 结构化工单 (docs/ticket/)
▼
┌─ 读工单 → 复现 → 修代码 → 重置环境
│ → 重跑测试 → 关工单 (ticket-fix)
▼
┌─ 周期性审计文档质量 (qa-doc-governance)
▼
┌─ 重构后对齐测试 (align-tests, test-coverage)
▼
┌─ 部署到 Kubernetes (deploy-gh-k8s)
└─────────────────────────
| 阶段 | Skill |
|---|---|
| 规划 | project-bootstrap |
| 编码 | rust-conventions、keycloak-theme |
| 测试文档 | qa-doc-gen、qa-doc-governance、feature-request-governance |
| 执行测试 | qa-testing、e2e-testing、performance-testing、auth9-grpc-regression |
| 修复 | ticket-fix、align-tests |
| 覆盖率 | test-coverage(各层不低于 90%) |
| 部署 | deploy-gh-k8s |
| 运维 | ops、reset-local-env |
每个 skill 就是一个 markdown 文件加几个脚本。同一套内容通过目录镜像和符号链接给 Claude Code、Gemini 和 Cursor 共用,不用维护三份。
信息交换我选了最土的办法:文件系统。docs/qa 放规格,docs/ticket 放工单。agent 玩 bash 玩得很溜,读写文件又准又快,而且整个过程留痕,出了问题回头就能翻。
一份真实的 QA 文档长什么样
这是租户 CRUD 那套测试里的一个场景:
初始状态:用户已登录管理后台;数据库中不存在同 slug 的租户。
测试步骤:确认左侧边栏存在”租户管理”入口 → 进入列表 → 点击”创建租户” → 填写名称
Test Company、slugtest-company、Logo URL → 点击”创建”。预期结果:显示成功提示;租户出现在列表中,状态为 Active。
预期数据状态
SELECT id, name, slug, logo_url, status FROM tenants WHERE slug = 'test-company'; -- 预期:存在一条记录,status = 'active' SELECT action, resource_type FROM audit_logs WHERE resource_type = 'tenant' ORDER BY created_at DESC LIMIT 1; -- 预期:action = 'tenant.create'
最后那段 SQL 是关键。AI 不能只看 UI 弹了”成功”就算过,它得去数据库里确认数据真的落了。“前端说成功、后端悄悄失败”这一整类 bug 就是这么抓出来的。
docs/qa/_manifest.yaml 是这些文档的清单,scripts/qa-doc-lint.sh 管格式。
AI 是怎么”打磨”的
ticket-fix 这个 skill 是整条流水线里最有意思的部分。测试失败会生成一张结构化工单,然后它:读工单、复现、做最小修复、重置环境(每次必做,不然环境脏了什么都测不准)、按工单原步骤重跑并留证据、分析假阳性、关工单。
假阳性分析是这套东西能转起来的关键。不是每个失败都是 bug。很多时候是测试本身有问题:命令少了个认证头,前置条件写得含糊,环境假设和 Docker 默认配置对不上,测试数据引用了根本不存在的东西。确认是假阳性之后,skill 不是把工单一关了事,它会回去改 QA 文档:把隐含要求写明,让示例命令能直接复制运行,补一张排障表。
所以不管失败原因是真 bug 还是测试写坏了,测试套件都会在每次失败后变得更好一点。软件和规格一起收敛。这就是我说的”打磨”。
这些批处理的结果会直接出现在提交标题里,比如:
Resolve 27 QA tickets: fix 9 bugs, close 14 false positives, defer 4 feature gaps
Fix 44 QA tickets: 3 bugs, 41 false-positive doc updates
整个项目里这样的提交有 36 次。
文档会烂,怎么办
测试文档会过时。路由改了、API 变了、权限重组了,一半的文档就在测一个已经不存在的行为。
我的办法是让它们一直被用。所有 QA 文档都被 agent 反复执行,文档一过时就会表现为一堆假阳性工单,想装看不见都不行。
qa-doc-governance 定期审计,按 P0(流程不可用)、P1(治理漂移)、P2(风格)分级,流程是 lint、分级、修、同步索引、出报告。可以在功能或重构后跑,也有每周脚本。有一条硬规则:每份文档必须带回归检查清单,哪怕文档漂了,清单也给你一条最小的验证路径。
qa-doc-gen 还带一个强制的跨文档影响分析:路由、token 模型、权限、UI 文案一变,就扫全部文档,每份受影响的都要标”需修补”、“需加注”或者”无需变更并写明原因”。不许只写新文档、放着旧文档烂。
那我自己干什么
- 规划:决定做什么,写验收标准,做架构取舍。
- 审阅:审 AI 生成的测试文档,审新功能第一版代码。QA 执行和工单修复的循环完全交给 AI。
- 纠偏:出假阳性时看根因分析;治理审计报 P0 时决定怎么修。
- 架构:领域建模、数据流、安全边界。
投入的个人时间和我以前做项目差不多,产出按我自己的估计超过以前的 10 倍。二十多轮迭代之后,AI 跑测试还是会产生工单,只是比早期少得多,每一轮应用都更完整一点。这和人类工程师靠反复 QA 一层层消 bug 没什么两样,区别是循环更快,而且每一轮都有记录。
我觉得人最核心的价值是定义”要做什么、不做什么”,然后提供判断力。有一件事我一开始没想到:要搭一个让 agent 能自己验证的环境,你得同时懂开发、基础设施和安全。这套方法反而更需要全栈的人。
我做开发时一直偏向极限编程,当 tech lead 的时候信任团队,但会用敏捷和测试驱动那套做风险管理。对 AI 的态度也一样:软件开发里已有的风险管理手段,尤其是极限编程的那些实践,大多数可以直接拿来管 agent。
它做不到的
- 真正新颖的架构决策还是得人来。AI 擅长实现它见过的模式。
- 威胁模型需要人的安全专业知识。自动化测试能覆盖已知模式,发现不了新的攻击路径。
- skill 组合和测试重点要按项目调。有的项目不需要 UI 测试,有的更看重 API 或数据层。
一些数字
| 项目 | 2026 年 2 月撰稿时 | 2026 年 6 月项目结束时 |
|---|---|---|
| Agent Skill | 16 | 16 |
| 测试文档 | 156(96 QA + 48 安全 + 12 UI/UX) | 224(155 QA + 47 安全 + 22 UI/UX) |
| 工具脚本 | 9 | 11 |
| skill 定义行数 | 约 2,300 | 2,725 |
| Rust 测试 | — | 2,710 |
| 提交 | — | 491,其中 copilot-swe-agent 24 次(约 5%) |
| 人 | 1 | 1 |
想自己试试
克隆仓库,读一遍 scripts/run-qa-tests.sh,然后跑它,agent 会自己起环境、开始执行整个 SDLC。或者打开 opencode 或 claude-code,直接说 execute all QA/security/UIUX tests。Gemini 也能跑这套。

这套办法不是只适合身份平台。它的核心就一句话:别只用 AI 把代码写快,用它把规划、测试、修复、部署之间的循环闭起来。