把 AI 放进一次合并请求:一个批量归档功能的交付闭环

原文链接

AI 辅助编程实战:从需求边界到可审查交付

开发中最容易出现的误解是:只要把需求丢给 AI,它就能交付一个功能。

实际上,AI 擅长整理上下文、生成候选方案、补全局部实现、解释报错和发现可疑点;需求边界、技术取舍、风险判断、测试验证与最终合并责任,仍然必须由人承担。

下面用一个基于常见内部系统改编的案例跑完整个闭环。它不是某个具体公司的真实项目复盘,但保留了团队开发中常见的权限、历史数据、接口兼容、测试与代码审查约束。

案例:给任务系统增加"批量归档"

团队已有一个任务系统。任务完成后不会立即删除,而是保留在"已完成"列表中。运营同学提出新需求:

当前项目的项目管理员可以一次选择多条已完成任务并归档;归档后,默认任务列表不再展示,但具备该项目归档查看权限的管理员可在归档列表中恢复。

这句话还不能直接开始写代码,因为它没有明确权限范围、状态转换、重复请求和返回结果。

先把需求翻译成可交付的边界

可以让 AI 先做"需求质检员":复述已知条件,列出歧义和潜在风险;但最终规则必须由产品、开发或负责人确认。

本例最终确认如下:

项目 确认结果
操作对象 仅允许归档状态为 completed 且尚未归档的任务
操作权限 只有当前项目的项目管理员可操作,成员只能查看
操作范围 单次最多归档 100 条,且任务必须属于当前项目
数据策略 不物理删除,写入 archivedAtarchivedBy
幂等性 已归档任务再次提交时不报错、不重复写入,并返回可识别原因
返回结果 返回成功数、跳过数,以及可安全披露的跳过原因
非目标 本期不做自动归档、跨项目批量操作和归档导出

可验收标准是:管理员能归档本项目中符合条件的任务;无权限用户不能产生写入;未完成、已删除、跨项目或不存在的任务不会被错误归档;重复点击不会产生重复副作用;归档后默认列表、归档列表、分页和筛选结果符合既有规则。

**人机分工很明确:**AI 可以帮助暴露问题,人必须决定规则。规则没有定下来,再漂亮的代码也只是把猜测固化进系统。

第一步:先拆"小变更",不要索要"一整个功能"

本例可以拆成六个任务:

  1. 确认数据模型:归档字段、恢复字段和必要索引。
  2. 定义接口契约:请求参数、响应、错误和幂等行为。
  3. 实现权限、项目归属和状态校验。
  4. 实现批量更新,并记录操作者与时间。
  5. 调整默认列表和归档列表查询。
  6. 补齐测试、变更说明、风险点和验证结果。

可以要求 AI 每次只处理一个任务,并固定返回:修改哪些文件、依赖哪些假设、尚未覆盖哪些场景、应执行哪些验证命令。这样得到的是一系列可追溯的候选变更,而不是一大段难以审查的代码。

第二步:让 AI 比较方案,而不是替你做架构决定

批量归档至少有两种实现方式。

方案 A:逐条读取并更新

读取任务、逐条校验、逐条更新并汇总结果。优点是失败原因细,缺点是数据库往返次数多,并且要明确部分成功时的事务语义。

方案 B:按条件批量更新,再计算结果

先验证当前用户是否为该项目管理员,再用"项目 ID + 任务 ID 集合 + 已完成 + 未归档"的条件批量更新;随后根据影响行数和补充查询计算成功、跳过结果。优点是通常更高效,缺点是要额外设计逐条原因的查询和并发语义。

本例选择方案 B,因为单次最多 100 条,且只要求汇总级结果。需要注意:仅凭 updateMany 的影响行数,通常不能区分"不存在""跨项目""未完成"和"已归档";如果接口承诺逐条原因,就必须补充受控查询,或调整接口契约。

AI 可以比较复杂度、失败模式和索引需求,但事务边界、ORM 能力、并发规则以及是否值得提前抽象,必须由开发者结合现有代码库决定。为了一个归档功能新增通用规则引擎、事件总线或多层策略类,可能只是过度设计。Google 的代码审查实践也强调,应优先解决已经明确存在的问题,而不是为想象中的未来需求堆叠复杂度。

第三步:把接口写成可验证的契约

http 复制代码
POST /projects/:projectId/tasks/archive
Content-Type: application/json

{
  "taskIds": ["task_101", "task_102", "task_103"]
}

成功响应示例:

json 复制代码
{
  "archivedCount": 2,
  "skipped": [
    {
      "taskId": "task_103",
      "reason": "ALREADY_ARCHIVED"
    }
  ]
}

还要提前规定空数组、重复 ID、超过 100 条、无权限、跨项目、未完成、已删除或不存在、数据库失败,以及请求期间发生并发恢复或状态修改时的行为。

常见错误是只按 ID 更新,遗漏 projectId 条件。权限、归属和状态应当同时出现在服务端的查询或更新条件中,而不能依赖前端传参或 AI 的口头保证。伪代码可以接近:

ts 复制代码
const result = await taskRepository.updateMany({
  where: {
    id: { in: uniqueTaskIds },
    projectId,
    status: "completed",
    archivedAt: null
  },
  data: {
    archivedAt: now,
    archivedBy: currentUser.id
  }
});

这段代码仍不完整:它没有展示管理员身份验证、参数校验、错误映射、审计日志、逐条跳过原因和事务边界。

第四步:让 AI 写局部代码,同时暴露假设

较好的顺序是:先解释仓库中相似功能,再草拟服务方法签名;人工确认接口和错误码后,实现最小更新逻辑;最后生成测试骨架和审查建议。每一步都要求 AI 标出假设,例如:

假设:TaskRepository 已有支持条件更新的 updateMany 方法;权限中间件已保证登录态;未覆盖:并发恢复任务与归档请求同时发生的情形。

假设清单能把隐蔽的模型幻觉变成可检查项目。GitHub 对 AI 编程助手的说明也提醒,模型建议不一定最优或完整,使用者仍需验证输出。

第五步:测试不是让 AI"补几个用例"

测试应从验收标准反推。可以先建立矩阵,再让 AI 补充测试骨架、测试数据和反例:

测试维度 关键场景 预期结果
正常路径 管理员归档 3 个已完成任务 3 条被归档,默认列表不再出现
权限 普通成员发起归档 无权限且不产生写入
归属 提交其他项目任务 ID 不更新,并按契约返回跳过或拒绝
状态 提交进行中的任务 不归档并返回原因
幂等 已归档任务再次提交 不重复写入,结果可解释
输入校验 空数组、重复 ID、超过 100 条 返回参数错误
并发 归档期间任务被恢复 符合既定事务或条件更新约定
查询回归 默认列表、归档列表、分页筛选 旧功能不受影响
失败处理 数据库异常或超时 返回统一错误,不泄露内部细节

还可以让 AI 扮演"反例生成器":如果删除 projectId 条件,哪条测试会失败?如果漏掉 archivedAt: null,重复请求会怎样?如果权限判断放在批量更新之后,数据会发生什么?

好的测试不只是"跑绿",还要确认错误实现确实会让测试失败。Google 的审查指南建议,在同一变更中检查生产代码及相应测试,并确认断言有效、不会产生假阳性。

第六步:用失败的生成结果练习审查

ts 复制代码
async archiveTasks(taskIds: string[]) {
  return this.taskRepository.updateMany({
    where: { id: { in: taskIds } },
    data: { archivedAt: new Date() }
  });
}

这段代码可能通过最简单的成功测试,但不能直接合并,至少存在以下问题:没有权限校验、项目归属限制、状态限制、幂等约束、操作者审计字段和可解释结果。它说明了一个关键现实:局部答案"看起来合理",不等于符合业务、工程和安全约束。

第七步:把 AI 放进代码审查,但不要把审批权交给它

提交 Pull Request 后,可以让 AI 总结改动、标出可疑空值路径、检查重复逻辑、解释失败流水线并提出候选问题;但作者和人工评审者仍需判断是否修复、是否符合仓库约定以及是否可以合并。GitHub 相关文档应以当前产品能力和团队权限配置为准,不能把 AI 的评论当成人工批准。

AI 辅助代码审查清单

  1. 正确性:验收标准、权限、项目归属、状态、幂等和并发是否完整。
  2. 可维护性:是否沿用既有分层、命名和错误处理,是否引入不必要抽象。
  3. 安全与隐私:是否遗漏后端授权;日志、提示词和测试数据中是否包含密钥、令牌、生产数据或个人信息;代理是否采用最小权限;高影响操作是否保留人工确认。
  4. 性能与数据规模:是否存在 N+1 查询,条件字段是否需要索引,批量大小和返回体是否合理。
  5. 异常处理:参数错误、无权限、状态冲突和系统错误是否区分,是否泄露内部细节,部分成功能否安全重试。
  6. 测试覆盖:是否验证数据库最终状态,移除权限或归属条件时测试是否会失败。
  7. 项目一致性:API、错误码、日志、审计、文档、接口定义和前端调用是否同步,变更是否便于回滚。

OWASP 关于具备代理能力的 LLM 应用建议采用最小功能、最小权限和人工确认原则;下游系统仍应独立完成授权校验,不能相信模型自行判断权限。

一页式工作流:每次让 AI 参与开发都留下这些产物

阶段 阶段产物 AI 可以做什么 人必须确认什么 通过条件
需求澄清 边界、非目标、验收标准、待确认问题 复述需求、发现歧义 业务规则与优先级 每条验收标准可验证
任务拆解 小任务清单、依赖关系、风险排序 拆分技术任务、列遗漏项 粒度与顺序 每项可独立测试或审查
方案设计 接口契约、数据变化、方案对比 比较路径、生成草图 架构取舍与兼容性 符合现有约定
局部编码 小范围 Diff、假设清单 编写样板、重构局部逻辑 业务条件、权限与异常 静态检查和测试通过
测试调试 测试矩阵、复现步骤 生成骨架、解释报错 边界和修复有效性 错误可复现且修复通过
代码审查 PR 描述、风险点、审查记录 总结改动、提出问题 是否修复、是否合并 人工审批和流水线通过

最后的边界:AI 可以加速,但不能替你交付

AI 辅助编程的效率,不是让开发者少思考,而是把重复整理、候选生成、代码解释和初步检查交给工具,让人把时间集中在理解业务、做取舍、验证结果和承担责任上。

真正的交付物不只是一段批量更新代码,而是一组可追溯证据:明确的验收标准、受约束的接口、可解释的异常处理、覆盖风险的测试、可审查的 Pull Request,以及人工确认后的合并决定。

可以从一个原则开始:每次让 AI 生成或修改代码,都要求它说明上下文、假设、未覆盖场景与验证方式;每次准备合并,都由人用测试和审查把这些回答逐一验真。

参考资料

相关推荐
智码看视界5 小时前
Day 56:AI辅助开发全面提效:Copilot + Cursor的Java开发
java·单元测试·copilot·cursor·后端开发·代码审查·ai辅助开发
树欲静而风不止867 小时前
制造企业研发数字化|APQP+QMS 一体化
软件工程
狂师7 小时前
AI 测试 | 把 UI 自动化测试执行固化成五步流程,这套AI Skill 思路可以直接抄
人工智能·agent·测试
老郑聊AI业财智造21 小时前
Transformer 技术架构与源码分析
人工智能·python·深度学习·语言模型·架构·transformer·软件工程
深维AI随笔2 天前
《构建之法》| 第一章概论:软件工程的“第一性原理“,一线交付工程师的读书笔记
大数据·软件工程
嘟哩DuliDuli3 天前
AI 短剧生成为什么要有角色库、场景库和镜头卡
android·人工智能·安全·ai·软件工程
老郑聊AI业财智造3 天前
Qwen技术架构与源码深度剖析
人工智能·语言模型·架构·系统架构·软件工程
老郑聊AI业财智造3 天前
DeepSeek技术架构与源码分析
人工智能·语言模型·架构·系统架构·软件工程
梁辰兴3 天前
软件工程:面向对象分析的基本任务与分析过程
软件工程·分析工具·面向对象分析·分析方法·梁辰兴·基本任务·分析过程