3179 字
约 10 分钟
17
S24-B05 · AI 编程工作流入门:从补全到任务交付

第一次用 AI 改代码的人常撞到同一个结果:原本能跑的模块,被"顺手优化"之后测试红了,而你说不清它动了哪一行。怪模型没意义——真正的问题是这次改动的半径超过了你愿意核对的半径。AI 编程的工作流不是"让模型写代码",而是把一次改动切到你能验证的大小,然后对它负责。这篇按一次任务的生命周期排:选入口 → 给上下文 → 写任务 → 小步交付 → 验证 → 读 diff → 提交。


1. 症状对照:坏在哪一步

现象 真实原因 对应环节
改完能跑,但写法和你项目格格不入 没给既有抽象与约定 上下文
一次改了 8 个文件,review 不动 任务粒度大于核对能力 交付节奏
报错说某个 API 不存在 幻觉,产物没人跑过 验证
功能对了,但两处无关逻辑被删 只看了新增行 读 diff
"快了一倍",两周后返工 只算了打字时间 收益核算

这五条都能在后面的环节里找到对应动作。

2. 四类入口各自擅长什么

入口 形态 擅长 不擅长
内联补全 光标处续写 重复模式、样板、局部改写 跨文件重构、需要全局理解
对话 贴代码问答 解释报错、比较方案、写独立函数 修改它看不见的文件
编辑器内 Agent 多文件编辑 + 调工具 有明确验收标准的改动 目标含糊、范围开放的任务
命令行 Agent 在仓库里自己跑命令 批量替换、跑测试、修流水线 需要人做取舍的判断

选错入口的代价不是"效果差一点",而是你拿到一份无法验证的产物:补全给你一行,你能读;Agent 给你一次提交,你得有能力审。

3. 补全的适用面与禁区

补全的强项是模式延续:你已经写了三遍的东西,第四遍让它续。弱项是需要判断力的地方。

# 好:意图写在注释里,补全只需延续结构
# 把 payload 里的字段名统一转成 snake_case,保持与既有 to_snake 一致
def normalize_keys(payload: dict) -> dict:
    ...

# 坏:注释只说"优化一下",模型只能猜
# TODO 优化
def normalize_keys(payload: dict) -> dict:
    ...
场景 用补全 理由
写第 N 个相似的 DTO/字段映射 是 模式稳定,错了肉眼可见
补 __repr__、日志语句、参数校验 是 局部、可读、无副作用
跨 5 个文件重命名一个概念 否 需要全局一致性,用 Agent 或 IDE 重构
改并发/事务/缓存失效逻辑 否 正确性依赖上下文,必须自己写或逐行审
不熟的框架 API 否 补全最爱在此处编造方法名

4. 上下文:给什么,给多少

"给太多等于没给"不是比喻。上下文里塞进十几个无关文件,模型的注意力被稀释,会开始在错误的地方找相似模式——它模仿了隔壁模块的写法,而那个模块的约定恰好是你要避开的。

必给 给了更好 给了有害
要改的文件全文 直接调用方的签名 整个仓库目录树
完整报错栈(含行号) 相邻的同类实现 与任务无关的历史代码
项目约定(命名、分层、错误处理) 相关测试文件 大段被注释掉的旧版本
验收方式(跑哪条命令) 依赖版本 三份互相矛盾的规范文档
【上下文包】
1 目标文件:src/order/refund_service.py(全文)
2 调用方:api/refund.py 第 42-58 行
3 报错:TypeError: unsupported operand ... (贴原始栈,别转述)
4 约定:金额用 Decimal;错误统一抛 BizError;不引入新依赖
5 验收:pytest tests/order/test_refund.py -q

第 4 条最容易漏。你不写"不引入新依赖",它就会给你装一个库;你不写"错误抛 BizError",它就返回 None。

5. 把需求写成任务:四要素

模糊指令的典型形态是"帮我改一下这个退款逻辑"。它缺的是可判定性。一个可交付的任务包含四段:

目标:退款金额为 0 时不要调用支付网关,直接置为成功
约束:只改 refund_service.apply();保持现有函数签名;
      金额用 Decimal;不新增依赖;不动 api 层
验收:新增用例 test_zero_amount_skips_gateway 通过;
      现有 12 个退款用例全绿
不要做:不要重命名方法、不要调整日志格式、不要顺手修 lint
要素 缺了会怎样
目标 它改了一个"相关"的地方,功能没动
约束 改动扩散到全仓,review 成本爆炸
验收 你说不清算不算完成,来回拉锯
不要做 顺手重构把无关行为改了

"不要做"这一条看着多余,实际是最省时间的一条:模型倾向于"既然来了就一起改好",而你的 review 预算只够看一处。

6. 小步交付:一次一个可验证的点

# 任务拆成三次提交,每次都能单独回滚
git switch -c feat/refund-zero
# 第 1 步:只加用例,跑红
git commit -am "test: zero amount skips gateway (red)"
# 第 2 步:只改 apply() 的一个分支,跑绿
git commit -am "fix: skip gateway when amount is zero"
# 第 3 步:只补日志,不影响行为
git commit -am "log: record zero-amount refund"

判断粒度是否合适:这次 diff 你能否在 5 分钟内逐行读完并说出每行的意图。读不完就继续拆。要它"重写整个模块"的请求,产出必然是一份你只能整体接受或整体拒绝的东西,而这两者都不是 review。

7. 验证责任:不跑就用等于赌博

# 拿到产物后的固定动作,顺序不要换
git diff --stat                     # 先看波及面
python -m compileall src             # 最低成本的语法/导入检查
ruff check src                       # 或项目既有 linter
pytest tests/order -q                # 相关用例
pytest -q                            # 全量,确认没碰坏别处

顺序的理由:--stat 在最便宜的位置拦住"改了 20 个文件";编译检查拦住幻觉 API;linter 拦住风格漂移;相关用例定位行为;全量用例抓那些"看起来无关"的连带破坏。

跳过任何一步,你都在用"它说它改了"替代"我确认它改了"。AI 的自我描述不是证据,命令输出才是。

8. 读 diff:先看它删了什么

git diff -U0                 # 只看变更行,噪音最少
git diff --diff-filter=D     # 只看被删除的文件
git diff | grep '^-' | grep -v '^---'   # 只看删除行

大多数人从新增行读起,因为那是"它做的事"。真正的风险在删除行:被删掉的一个 if、一行 return、一个 await,都能让功能在正常路径下照样跑通,只在边界条件下炸。

先看 找什么
删除行 有没有删掉守卫条件、错误分支、并发保护
新增依赖 是否引入了项目没在用的库
新增函数 是不是重复实现了已有的工具方法
改动范围 是否越过了任务声明的边界

最后一条是隐形陷阱:产物把断言从 == 100 改成 != 0,测试就绿了,而行为已经错了。

9. 三个真实失败模式

模式 表现 识别与处置
幻觉 API 调用不存在的方法、参数名错、版本对不上 跑编译或类型检查;查官方文档核对签名
静默改动无关代码 diff 里混进格式化、重命名、注释删除 git diff --stat 先扫文件数;按块 review
绕开既有抽象 直接 new 客户端、绕过 repository、复制粘贴而非复用 review 时问"这行为什么没走 X";要求它先读该抽象

三个模式的共同点是:产物本身常常能跑。所以靠运行来发现问题是不够的,必须配合 diff 阅读与对项目约定的先验知识。这也是为什么"不熟的领域不要靠 AI 学"——你没有先验,就识别不出绕开抽象这件事。

10. 提交粒度、review 关注点与真实收益

review 关注点 具体动作
边界与错误路径 只喂异常输入,不看正常路径
抽象一致性 是否复用既有 service/repository/util
隐式行为变化 日志、异常类型、返回值语义有没有变
可测试性 新增逻辑能否被单独构造用例
收益类型 真实吗 说明
打字速度 真,但占比小 编码时间里打字本来就不是大头
样板与重复代码 真,收益稳定 越模板化的仓库收益越高
陌生 API 的上手时间 真,但要核对 省的是查文档,代价是验证
返工减少 假,除非你加了验证 不跑测试的"完成"只是看起来完成
减少思考 假 判断、取舍、边界设计仍然全是你的活

把"打字快了"当成主要收益,就会得出"AI 让效率翻倍"的错误结论;真实收益集中在机械重复与首版草稿两处,而这两处的下一道工序都是人工核对。

11. 排错

现象 原因 处理
生成的代码 import 报错 幻觉模块名或版本不符 查 pip show/go doc 核对真实 API
改了 12 个文件 任务约束缺失 回退,重发带"只改 X 文件"的任务
测试通过但线上行为变了 断言被改宽 看测试文件的 diff,恢复原断言
它不读你指的抽象 只给了文件名没给内容 把该抽象的方法签名贴进上下文
每次产出风格都不一样 没给约定 在任务里固化命名与错误处理规则

12. 边界:这些活别指望工作流救你

场景 原因 替代做法
你不熟的领域 你无法验证,等于放弃 review 先读文档与既有实现,再让 AI 做机械部分
认证、加密、权限判定 错误是静默的,测试难覆盖 自己写,或对照成熟实现逐行核
需要长期维护的核心模块 风格与抽象的一致性比速度重要 只让 AI 做补全与小改
性能关键路径 需要测量而非生成 先 profile,再定向优化

一句话收口:AI 提升的是"产出草稿"的速度,"确认草稿正确"的成本仍然在你这边。工作流的全部意义,是让后者的成本可控。

自测

  1. 一次 Agent 改动涉及 8 个文件,你先用哪条命令判断该不该继续?
  2. 为什么"不要做"这一段在任务描述里最省时间?
  3. 上下文里塞进大量无关文件,具体会造成什么偏差?
  4. 读 diff 为什么建议先看删除行而不是新增行?
  5. "测试变绿"在什么情况下反而是危险信号?
  6. 哪两类任务即使工作流再规范也不该主要交给 AI?
S24-B05 · AI 编程工作流入门:从补全到任务交付
https://www.clxhxhhr.top/posts/6100/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。