Agent写不出可用代码的六个原因,以及每个原因的修法
同一个模型,有人用得顺手有人觉得是废物。差别在六个工程细节:任务粒度、验收标准、可观测性、上下文注入、工具设计、停止条件。逐条给出可落地的改法。
引言:不是模型笨,是任务给错了
“AI 写代码不行”这句话,我在不同团队听过很多次。但同样一批工具,另一些团队用得飞起。
差别不在模型版本,在任务的组织方式。以下六个原因,覆盖了大部分失败场景。
原因一:任务粒度太大
现象:让它”实现用户登录功能”,得到一堆看起来完整、跑起来全错的代码。
根因:大任务的出错面是指数级的。一个 20 行的函数,错误可以被快速定位;一个 300 行的模块,错误可能藏在任何地方,而且修一处又引入新的一处。
修法:把任务切到”一次能验证”的粒度。
❌ 实现用户登录
✅ 1. 写 User 模型和迁移文件
2. 写 register 接口 + 3 个测试
3. 写 login 接口 + 3 个测试(含密码错误、账号不存在)
4. 加 JWT 签发和中间件
每一步做完先跑测试,通过了再进下一步。测试通过是进入下一步的门票。
原因二:没有验收标准
现象:Agent 说”已完成”,你去跑一下,根本不工作。
根因:模型无法判断”完成”,它只能判断”看起来像完成了”。没有客观信号时,它会选择最省力的解释。
修法:给它可执行的验收命令。
验收标准(全部通过才算完成):
- `npm run build` 无错误
- `npm test` 全部通过
- `curl localhost:3000/api/health` 返回 200
- 不修改 test/ 和 migrations/ 目录下任何文件
最后一条同样是关键——不加限制,它会改测试来让测试通过。这是 Agent 最常见的”作弊”行为。
原因三:看不见运行结果
现象:改了半天,同一个错误反复出现。
根因:Agent 在”盲改”。它看不到堆栈、看不到日志、看不到请求响应,只能根据代码猜。
修法:把可观测性显式喂给它。
调试时请遵循:
1. 先跑命令,把完整错误输出贴进来,不要猜测
2. 定位到具体文件和行号再修改
3. 每次只改一处,改完重新跑
4. 连续 3 次修复失败,停下来汇报你观察到的现象和你的假设
第 4 条非常重要。Agent 的典型死循环是”改 A → 报错 B → 改 B → 报错 A”。 强制它停下来汇报,能把这个循环打断。
原因四:上下文给错了
现象:代码风格和你项目完全不同,用了你不用的库。
根因:模型不知道你的项目约定,只能用训练数据里的”主流写法”。
修法:规则文件 + 精准的上下文定位。
规则文件里至少写四块:
[技术栈] TypeScript strict, React 19, 不引入新的 UI 库
[目录约定] 业务逻辑放 src/services,组件不直接调 API
[错误处理] 统一 throw AppError,禁止 console.log 上线
[禁用] 不要添加注释解释显而易见的事;不要重写无关代码
同时,给它找文件的能力而不只是塞文件:让它在修改前先做一轮”搜索相关符号和调用点”的操作。
原因五:工具设计有问题
现象:Agent 频繁调错工具,或者用错参数。
根因:如果你给它自己写工具(自定义 function call / MCP 工具),工具描述模糊是灾难。
修法:工具描述要写成”给新同事的说明”,不是”给神的暗示”。
❌ {"name": "query", "description": "查询数据"}
✅ {"name": "query_orders",
"description": "按时间范围查询订单列表。仅支持已支付订单,
单次最多返回 100 条。时间格式 YYYY-MM-DD。",
"params": {"start": "开始日期,含", "end": "结束日期,含",
"status": "可选:paid/refunded,默认 paid"}}
工具的失败信息也要设计。返回 “Error: invalid” 模型不知道怎么办;返回 “参数 start 格式错误,应为 YYYY-MM-DD,收到 ‘2026/3/1’” 它能立刻改正。
原因六:没有停止条件
现象:跑了两小时,烧了几十块钱,产出一个乱七八糟的分支。
根因:没有预算约束,Agent 会无限尝试。
修法:三重刹车。
- 轮次上限:最多 20 轮工具调用
- 时间上限:超过 15 分钟自动中断并汇报
- 成本上限:token 消耗超过阈值停止
同时强制它在每个关键节点写一行进度到文件里,中断后可以从中断点继续,而不是从头再来。
一份可直接用的任务模板
[任务] <一句话,具体到可验证>
[范围] 只修改以下文件:a.ts, b.ts。其他文件只读。
[上下文] 相关代码:<贴关键片段>;项目规范:<规则文件>
[验收] <可执行命令清单>
[约束]
- 不修改测试和迁移文件
- 不重构无关代码,最小改动
- 新增依赖前先问我
[失败处理] 连续 3 次修复失败则停止并汇报现象与假设
[预算] 最多 20 轮工具调用
结论
写代码的 Agent,本质上是一个执行速度极快、但没有任何背景知识的实习生。
对实习生,你会怎么做?给清晰的任务、给明确的完成标准、让他能自己跑起来看结果、告诉他不许碰哪些东西、卡住了来找你。
Agent 需要的完全是同一套管理方法。区别只是你把”管人”的方法迁移到了”管一个跑得很快的东西”上——这件事,大多数人反而是不熟练的。