2792 字
约 9 分钟
17
S24-B04 · AI 编程工具入门:补全、对话与任务委派的分工

同一个工具,有人用它省下半天,有人用了两天修它生成的代码。差别不在模型多聪明,在用错了档位:拿补全去做重构,拿对话去改一个它看不见的文件,拿委派去跑一个没有测试的项目。

这篇把 AI 编程工具拆成三种能力,讲清每种适合什么粒度、为什么失效、边界在哪。


1. 三类能力:粒度决定用法

能力 输入 输出 适合粒度 失败代价
行内补全 光标前后文 + 少量相关文件 几行到几十行 单函数、样板代码、重复结构 低,删掉重打
对话式修改 你的描述 + 你贴的代码 一段 diff 或整文件 单文件、明确的小改动 中,要读懂 diff
任务委派 目标 + 可访问的仓库 多文件改动 + 命令执行 跨文件、有测试保护的改造 高,改动面大

粒度错配的典型表现:用补全写一个要改五个文件的功能(它看不到其他文件,只能猜接口);用委派改一行常量(启动成本远大于收益)。


2. 补全为什么"猜错"

补全看到的世界很小,而且以光标为中心。

它通常能看到 它通常看不到
当前文件光标前后的文本 同项目另一个包里的实现
编辑器打开的少量相关文件 运行时的真实数据形状
类型签名(若有 LSP 支持) 你在需求文档里的约定
// 光标停在这里,补全只能靠命名和上文猜
public List<Article> findTopN(int n) {
    // 它很可能补出 repository.findAll() 再 subList
}

让补全变准的办法不是换模型,是把约束放进它看得见的地方:写清返回类型、先写一行注释说明边界("n 为 0 时返回空列表")、把要用的接口先 import 进来。


3. 对话式修改:给约束,而不是给形容词

差的要求 好的要求
"帮我优化一下这个方法" "把 O(n²) 找重复改成 Set 去重,保持返回顺序,n<1000 时不引入新依赖"
"加个错误处理" "HTTP 失败时返回 Result.fail(code),不要抛给上层"
"按我们的风格改" "贴两个同目录已有方法,照这个结构改"

可用模板:现状 → 约束 → 示例 → 验收。

现状:ArticleService#publish 目前直接抛 RuntimeException。
约束:不要改方法签名;不要引入新依赖;异常要转成 Result.fail。
示例:参考 CommentService#add 的写法。
验收:空标题返回 code=400 而不是 500;现有单测全部通过。

形容词("优雅""健壮""高性能")在模型那里没有可执行含义,它只能按训练分布里最常见的样子补——那通常不是你仓库里的样子。


4. 任务委派:三个前提与四类失败

前提 为什么必须 不满足会怎样
可验证 需要一个客观信号判断"做完了" 只能逐行读 diff,成本高于自己写
可回滚 改动在分支/补丁上,不是直接改主干 出问题要手工挑拣回退
有测试 让机器自己发现"改坏了" 它说"已完成",你就信了
失败模式 表现 预防
局部最优 修了报错,绕过真正的设计问题 任务里写"不要绕过校验,说明原因"
范围蔓延 顺手重构了三个无关文件 明确"只允许改 A/B 两个文件"
幻觉 API 调用了不存在的方法 编译/测试即暴露;否则要求它引用具体文件行
静默降级 测试被改成能过,而不是代码改对 禁止修改测试断言

委派时把这三条写成任务的一部分,比事后 review 便宜:

任务:把 ArticleService#publish 的异常处理改成 Result.fail。
允许改动:src/main/java/**/ArticleService.java
禁止:改方法签名、改测试断言、新增依赖
完成标准:mvn -q test 全绿;补 2 个边界单测(空标题、重复提交)
回滚:改动只落在一个分支,不直接提交主干

5. 上下文工程:给什么、给多少、怎么自己找

问题 做法
给什么 直接相关的实现文件 + 接口定义 + 一段同类写法
给多少 够判断即可;整包粘贴会稀释关键信息
自己找 给检索手段:允许读目录、允许 grep 符号,并要求"先定位再改"
先定位,不要直接改:
1. grep -rn "publish(" src/main/java 找出所有调用点;
2. 读 ArticleService 与 CommentService,比较异常处理差异;
3. 只输出改动计划,等我确认后再动文件。

最后一句很关键:先让它给方案,再让它动手,能把"改错方向"的成本从一次重构降到一次对话。


6. 验收条件:可执行优于形容词

不可验收 可验收
"代码要健壮" "n=0、n 为负、列表含 null,三种输入各有一个单测"
"性能要好" "10 万条数据下单次调用不产生全表扫描(看执行计划)"
"不要破坏现有功能" "mvn test 全绿;git diff --stat 只涉及 ArticleService.java"
"接口保持兼容" "不改任何 public 方法签名,新增方法用 default 实现"

检验方法:能不能用一条命令或一次断言判断真假。不能,就还不是验收条件。


7. 审查生成代码:四个重点与四种假象

审查点 具体看什么
边界条件 空集合、null、0、负数、超长字符串、并发重复提交
错误处理 异常是被吞了、转了,还是包装成了误导性的类型
依赖引入 新库是否必要、版本是否与现有 BOM 冲突
性能陷阱 循环里查库(N+1)、无界缓存、全量加载后过滤

"看起来对"的四种假象:

假象 为什么骗过人 怎么破
能编译、demo 能跑 happy path 过了,边界没测 补边界单测再合
命名和注释很专业 命名不改变逻辑正确性 只读逻辑分支,不看命名
测试是绿的 测试可能是它顺手改的 检查 diff 里有没有测试文件
复杂度看着合理 常数因子可能极大(全表扫描伪装成查询) 看实际调的是哪个方法、哪条 SQL

8. 凭据与敏感信息

不该给模型的 原因 替代做法
生产密钥、token 会进请求日志与上下文缓存 用占位符 API_KEY,本地 .env 注入
真实用户数据 可能被写进生成代码或日志 造同结构的假数据
完整 .env、证书私钥 一次粘贴就扩散到不可控位置 上下文排除,只给变量名
内部地址与账号 生成代码里可能硬编码 改成配置项引用
.env
.env.*
*.pem
*.p12
secrets/

工具侧也要设排除:把 node_modules、dist、日志、数据文件从上下文里排掉,既省 token 也减少误读。


9. 协作规范

项 建议
提交粒度 一次生成对应一个可回滚的 commit,别把重构与功能混在一起
AI 参与标注 commit message 或 PR 描述写明哪部分生成、人审了什么
团队约定 哪些目录允许 AI 改、哪些必须人工写(迁移脚本、权限校验)
评审重点 按"陌生同事的 PR"标准审,不因为快就放宽

标注不必写成长篇,一句话说清"哪部分是生成的、人审了什么"就够:

feat(article): 发布失败返回 Result.fail

人工:接口约定、错误码表
AI:异常转换 + 2 个边界单测(已逐行复核 diff)

10. 成本与速度

选择 什么时候划算
小模型做补全、大模型做设计 补全调用频繁容错高;设计一次错代价大
补全优先 改动在光标附近、你已知道怎么写
对话优先 要跨几处一致修改、要解释理由
委派优先 有测试、改动面广、你能审 diff
不用 AI 需求没想清,或代码你读完也不懂(生成完更不懂)

11. 排错表:常见坑

坑 症状 改法
让它改看不见的文件 生成的代码调用不存在的方法 先贴文件或允许它读仓库
没有测试就委派 "已完成"但跑起来 500 先补最小测试,或要求它先写测试
生成代码直接合主干 边界 bug 上线才发现 走分支 + 评审 + CI
过度依赖 半年后读不懂自己的仓库 关键模块人工写,生成部分要能讲清
一次给太多上下文 回答变慢、抓不住重点 只给相关文件,让它自己检索

12. 边界

场景 说明
需求还不明确 先想清要什么,AI 只能加速已想清的事
强合规代码 权限、加密、审计日志要人写并人审
无测试的历史包袱 委派前先补测试,否则改动不可验证
一次性脚本 对话生成即可,不必进仓库也不必评审

13. 自测

  1. 补全为什么在跨文件改造上容易出错?
  2. "帮我优化一下"缺少哪三样东西?
  3. 任务委派的三个前提分别防的是什么?
  4. 为什么"测试是绿的"可能是一个假象?
  5. 验收条件的检验标准是什么?
  6. 什么情况下最该选择"不用 AI"?
S24-B04 · AI 编程工具入门:补全、对话与任务委派的分工
https://www.clxhxhhr.top/posts/6055/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。