AI 软件开发落地流程
概述
为「以大模型 / 智能体为核心」的软件提供一套可落地、带里程碑闸门的生命周期。融合传统五阶段工程、AI 特有风险节点、Agent 生命周期与红线闸门。核心原则:每阶段有明确 Gate;AI 风险在设计阶段就内置(不只是测试阶段才查);所有平台事实必带验证标签。内置「编码约束(下笔即约束)」子章节(见下文),LLM 应用的前端 / 后端代码同样需遵守传统代码质量护栏(异步配对 / 兜底校验 / 闭包状态校验 / cache-buster / 双保险互斥)。
何时使用
- 用户要规划 / 设计 / 评审 / 执行 AI 软件或智能体项目开发。
- 用户需要 AI 软件开发流程、阶段清单、Gate 定义或阶段计划。
- 用户要评判、扩展或套用「AI 软件开发流程」。
- 任何涉及构建、评审、发布 Agent 专家或 AI 应用的任务。
路径判定树(最先执行)
开工前先分类,路径不同则 P2/P3 做法不同:
- 交付物是「上架到平台的独立 Agent 专家」(如 QClaw 专家),只负责专家产物、不自建后端/数据库?
→ 路径 B(Agent-native):遵循zhao_qclaw_agent_dev_constraints的 Agent 约束,本 skill 仅作节奏参考;P2 不画模块图、P3 不写物理数据库设计。 - 交付物是「自己开发、含 LLM 能力的应用/系统」(网站、RAG 客服、内部 Copilot、Vibe Coding 工具)?
→ 路径 A(AI 增强软件):下方主流程。 - 两者都有(专家 + 自有后端)?
→ 拆成两个子项目,分别走 B 和 A,不要混在一个流程里。
判断不清默认走 A,但 P3 的「专家产物」部分按 B 处理。
红线闸门(最高优先级)
阶段未达 Gate、决策方未说「做 / 执行 / 改」之前,内层「工具调用」降级为只读——禁止建文件、写代码、执行命令。想清楚 ≠ 决策方拍板。
内层六步(每阶段内运行)
意图识别 → 技能路由 → 信息收集 → 规划执行 → 工具调用 → 迭代优化。
①–④ 为分析(红线约束下只读);⑤ 确认后才解锁;⑥ 把 bad case 回流到记忆 / 知识库。
六条贯穿纪律
① 领域先谈(先聊透业务实质再套框架)
② 验证标签(平台事实必带 [已核实 / 待验证 / 推测],禁止用「应该可以」替代实测)
③ 节点-边-条件边(设计用状态图,不画模块流程图)
④ 安全防护内置(提示注入 / 越狱 / 记忆投毒,设计即考虑,非仅测试)
⑤ 人在回路预设(何时拉人、授权怎么确认、降级到人工)
⑥ 可观测(设计阶段定义 tracing / logging 规范,支撑 bad case 归因)
阶段骨架(默认路径 A;行内标注 B 差异)
- P0 立项筹备 — Gate 0:决策方确认《项目场景说明书》。动作:场景锁定 + 不做清单;四方角色(发起 / 使用 / 复核 / 接管);形态判定(知识库问答 vs 完整 Agent);资源盘点;领域讨论(三问:真实瓶颈?AI 能 / 不能解决什么?人类专家判断依据?);产出(场景说明书 + 验收指标 + 成本 + 降级预案)。
- P1 需求分析 — Gate 1:《需求规格》+ 评审签字。动作:调研带 AI 能力标签;AI 边界矩阵(全自动 / 半自动 / 不支持);可行性 POC(标
[已核实 / 待验证]);数据合规校验;MoSCoW 排序;规格文档;跨团队评审。B 差异:增敏感类合规(不得定位专业服务替代、加 AI 标识与免责、危机信号强制转介)。 - P2 系统设计 — Gate 2:状态图 + 技术方案 + 编码约束清单。动作:整体架构标 AI↔传统边界;状态图(节点-边-条件边,含回环 / 重试上限 / 退出 / 终态);详细设计(记忆方案 + 工具调用规范);模型选型(五维:能力 / 速度 / 成本 / 部署 / 数据安全);Prompt 体系;2.6 安全防护设计;2.7 HITL 设计;2.8 可观测 / tracing 设计;2.9 编码约束定义(下笔即约束):动手前列出本模块编码护栏——异步回调须请求-响应配对(token/AbortController/取消上一个);兜底定时器须带「状态仍有效」校验;异步回调引用的当前状态须用 current===n/token 校验不信任闭包捕获值;改 img/video src 带 cache-buster;写「双保险」前先确认两道保险不会互相覆盖/顺序错乱;POC;设计评审。B 差异:省物理库;2.6 / 2.7 强制(上架红线)。
- P3 建包实现 — Gate 3:专家产物齐全 + 核心用例可运行 + 约束验证通过。动作:专家产物(四层结构);WBS(标传统 / AI);AI 开发工作流加「自动生成 ≠ 自动上线」闸门;AGENTS.md 约束;工具链打通;质量管控(交叉评审 + SonarQube + AI 代码强制人工审查);3.7 供应链 / 依赖投毒扫描;3.8 按 P2.9 约束写代码 + 约束验证:编码严格遵循 P2 定义的编码护栏;交付前逐条验证约束是否被满足(grep/静态检查/真实环境回归,尤其竞态序列、缓存命中、异常输入),而非等 bug 出现再补;Git(AI commit 标注)。
- P4 测试验证 — Gate 4:测试报告达标。动作:环境一致(模型版本 / 参数);功能 / 兼容 / 安全 / 性能含 AI 灰色地带;AI 内容专项(准确 / 安全 / 一致 / 可控 / 鲁棒);独立智能体交叉校验;4.5 红队 / 对抗测试(注入 / 越狱 / 记忆投毒);性能压测(P50 / P95 / P99、Token 吞吐、队列、内存);缺陷根因标注;报告。
- P5 评测标定 — Gate 5:评测报告 + 回归通过。动作:指标定义(轨迹级 vs 结果级);5.2 在线指标前置(完成率 / 满意度 / 留存 / 负反馈率);标注集 / eval 集(正常 / 边界 / 异常;每类 ≥20 条为
[推测],按规模调);阈值标定(基线 → 期望 → 成本);更新后回归(模型 / Prompt / Skill 变更跑全 eval);报告。 - P6 运营进化 — Gate 6:持续运行。动作:部署带版本快照(模型 / Prompt / 知识库);6.2 灰度发布(禁直接全量);稳定性监控(7–14 天);效果持续监控(抽检 + 情感分析 + 定时 eval);6.5 自主迭代护栏(变更须 eval 门 + 人工抽样,否则只建议不自动生效);6.6 合规审计与遗忘机制(用户删除权);技术债务治理;飞轮(bad case → 根因 → 修复);复盘(含「P1 待验证项是否验证」)。
验证标签纪律
每条平台事实或影响决策的判断,必带其一:
- [已核实·来源]:官方文档 / 白皮书 / 搜索 / 实测确认,写明来源。
- [待验证·计划:…]:知道去哪查但还没查,写明计划,不得据此让用户动手。
- [推测·依据:…]:基于有限信息推断,可能错,写明依据。
禁止把未核实内容写成确定结论。
编码约束(下笔即约束)
核心原则:约束在 P2 设计阶段定义、P3 编码阶段遵守并验证,不要等 bug 出现再补。凡涉及异步、状态、重复触发的代码,下笔即框住自己。
P2:定义约束(Gate 2 必需产物)
动手写代码前,针对本模块列出「编码护栏」,至少回答:
- 是否会被连续 / 高频调用(翻页、跳转、搜索输入、轮询)?→ 若是,异步回调必须做「请求-响应配对」。
- 是否有异步回调(onload / setTimeout / setInterval / Promise / fetch)?→ 若是,定义配对与取消机制。
- 是否改 img / video / iframe 的 src?→ 若是,定义 cache-buster 策略。
- 是否写「双保险 / 兜底」?→ 若是,先确认两道保险不会互相覆盖或顺序错乱。
P3:遵守 + 验证(Gate 3 交付前必做)
- 编码严格按 P2 护栏写。
- 交付前逐条验证约束满足:用 grep / 静态检查 / 真实环境回归(竞态序列、缓存命中、异常输入、兜底触发时机),而非等用户截图打脸才补。
通用约束清单(默认遵守)
- 请求-响应配对:任何带异步回调且可能重复触发的函数,必须有配对机制——计数器
token自增、取消上一个、或AbortController。只有「最后一次 / 最新」调用才允许落地渲染或写状态。 - 兜底不无脑:定时器 / 重试绝不无条件执行,必须带「仍是最新页 / token 匹配 / 请求未取消」校验。
- 不信任闭包捕获的「当前状态」:异步回调里引用的当前页 / 当前选中项 / 当前请求,必须用
current===n或token校验,不信任闭包值。 - 改媒体 src 带 cache-buster(如
?_=${token}),避免命中旧缓存引发 onload 行为异常。 - 双保险互斥:写两道以上保险前,先问「它们会不会互相覆盖 / 顺序错乱」;若会,合并为单一可信路径。
- 最小改动:修 bug 时只加护栏,不重写主逻辑,降低引入新 bug 的概率。
前端异步专项(典型案例)
- 翻页 / 轮询 / 搜索联想:用
token自增,onload / onerror / timeout 回调首行校验if (token !== latest) return; - fetch 竞态:用
AbortController在新请求时 abort 旧请求;或维护latestReqId。 - 图片懒加载:src 带 cache-buster;
complete状态不要误判为「新图已就绪」。 - 反例(曾踩坑):
imgEl.onload = () => render(n)闭包 + 无条件setTimeout(render, 60)→ 快速连点翻页时旧 n 的回调覆盖新渲染,导致「页码与热区数分裂」。修复即上述 token 配对。
UI 区域 / 坐标类专项(典型案例)—— 像素证据 > 肉眼估计
- 禁区:「用户说『区域/位置不对』时凭肉眼估坐标」/「坐标看上去差不多就先写」 → 几乎一定踩坑。
- 正确做法:拿到"不对"反馈后立即用
cv2像素扫描拿真实 bbox,再写坐标: - 白色块(如对话气泡白底):
cv2.inRange(im, (230,230,230), (255,255,255)) + cv2.connectedComponentsWithStats→ 过滤后得连通块 bbox = 真实元素轮廓 - 蓝字 / 红字:转 HSV,
cv2.inRange(hsv, (H_lo,S_lo,V_lo), (H_hi,S_hi,V_hi))+ 连通块扫描 - 红色箭头 / 标志:
cv2.inRange(im, (B_lo,G_lo,R_lo), (B_hi,G_hi,R_hi))BGR 三元组 - 必须确认:
cv2.inRange第二参是三元组 tuple(标量会被解释成lo==up,要求像素 == 该值)。常见坑:用 235 一个标量结果 0 像素,必须(230,230,230), (255,255,255)。 - 写完后双态截图对照像素扫描 bbox,肉眼不替代证据。
验证约束(我的假设 ≠ 用户原话)
根问题:写完一个 feature / 修完一个 bug / 完成一个页面后,开发者(包括 AI)常用「我自己的技术指标」当验证——「hot 数对、坐标对、元素存在」——但这不是用户在意的。用户在意的是他截图里那一条条症状有没有消失。
硬约束(红闸门):
写代码前:把"用户原话"列出来当断言
- 禁止写"完美渲染""坐标对""hot 数 == 12""播放成功"这类自己的假设当断言。
- 必须把用户原话(或可观测的 bug 症状)逐条转成
if判断: - 用户说"音标完全遮挡了" → 断言 = "大白牌 bbox 与 hot bbox 不重叠"
- 用户说"播放按钮直接取消不需要" → 断言 = ".tag { display: none }"
- 用户说"但是要显示清楚" → 断言 = "popover display:block + ipa 字号 ≥14px"
- 每条断言必须能直接挂到一帧截图的像素或一段 DOM 的属性,禁止"看上去对"。
交付前:双态对照
- 默认态截图(不 hover 不点击) + 触发态截图(hover 或点击之后的瞬间)。
- 对照依据 = 用户最近一次给的截图或文字症状清单。逐条勾掉才能宣称完成。
- 未勾掉的项 = 未完成,无论 self-test 自认为多对。
反模式(已知错误归因)
- ❌"我以为我改了" ≡"改对了"。
- ❌"代码逻辑顺" ≡"用户感受对"。
- ❌遇到 bug 反复出现就怪"模型容量不够" —— 真实问题是缺上述验证硬循环,与模型容量无关。
- ❌注释自夸("chant hot 已移到 (3,2,43,16)" 与数据 y=2% 自相矛盾却没发现)—— 改完必须做"代码自检"(注释 vs 数据 / 输入 vs 输出)。
套模板(Playwright 断言骨架)
# 用户原话逐条 -> 断言
# 1. "X 完全遮挡了" -> 不重叠 bbox
assert not bbox_overlap(hot.bbox, popover.bbox), "用户原话: X 完全遮挡了"
# 2. "Y 直接取消不需要" -> 不渲染某元素
assert el_display('.y') in ('none', 'no-element'), "用户原话: Y 直接取消不需要"
# 3. "保留窗口..." -> 默认常驻
assert getComputedStyle(popover).display == 'block', "用户原话: 保留窗口显示"
# 4. 边界 -> 点击仍触发播放(功能不丢)
assert page.evaluate('window.__played') >= 1, "点击 happy 触发 audio.play"
> 验证通过 ≠ 完成 = "用户再来截图还有没有 bug"。
详细参考
完整可执行清单(每阶段勾选项、B 路径差异、Gate 速查表、落地工具清单)见 references/process.md。