别对 AI 说"帮我写个系统":和 Agent 协作做完一个毕设后,我总结出 6 条提需求的规则
过去几个月,我的毕业设计(Spring Boot + Vue 的二手图书交易网站)和 18 篇技术文章,基本都是在 Agent 协作下完成的。
这段经历最大的收获不是"AI 真好用",而是一个反直觉的发现:
同一个模型,产出质量能差好几倍——差别几乎全在"你怎么说"。
文章目录
- 别对 AI 说"帮我写个系统":和 Agent 协作做完一个毕设后,我总结出 6 条提需求的规则
- 零、先做个对比
- 规则一:给它**上下文**,而不是给它**任务**
- 一个可以照着抄的模板
- 规则二:把大任务切成**能验收的小块**
- 规则三:明确写出**"不要做什么"**(这条最重要)
- 一个真实的例子
- 为什么"约束"比"要求"更重要
- 三句必须写进约束里的话
- 规则四:让它**先说方案,再动手**
- 规则五:要求**可验证的产出**,而不是"我完成了"
- 判断标准:能不能跑,不是能不能读
- 规则六:反馈要**具体到文件和行**
- 两个容易被忽略的边界
- 边界一:出现这三个信号,就该开一个新会话
- 边界二:这四类任务不要交给它(或者要格外小心)
- 七种最常见的"提需求反模式"
- 最后:Agent 放大了什么
零、先做个对比
需求 A:
帮我写一个二手书交易网站需求 B:
任务:实现图书发布接口 现状:BookController 已有 list 和 detail 两个方法; 统一返回体是 R{code,msg,data}; 表 t_book 已有 book_name/price/stock/status 字段; 逻辑删除字段是 deleted,查询必须过滤 约束:只改 BookController 和 BookService,不要新建文件 不要动返回体结构,不要顺手加其他接口 验收:POST /api/books 应返回 code=200, 并且 /api/books 能查到刚发布的这本两种提法用的是同一个模型,但产出差一个档次。
需求 A 的结果是"一份没人敢用的代码"——它会自己发明表结构、自己定义返回格式、自己决定用什么框架风格。它没有做错什么,它只是把你没说清楚的部分全部替你猜了一遍。
需求 B 的结果是"能直接合进项目的代码"。
区别不在模型,在信息量。下面这 6 条规则,就是我从这类反复翻车里总结出来的。
规则一:给它上下文,而不是给它任务
这条是所有问题的根源。新手最常见的思维是"我说得越简单,它越好懂"——实际上正好相反:
Agent 不会读心。你省略的每一条信息,它都会用自己的经验去补。而它补的那一版,多半和你的项目不一样。
我踩过最典型的例子:让它加一个模块,它自己发明了一套新的返回格式。代码本身没错,但和项目里其他 20 个接口的风格不一致,合进去之后前端还得单独适配。
一个可以照着抄的模板
【任务】要做什么(一句话) 【现状】现在是什么样(贴关键文件、表结构、已有约定) 【约束】不能做什么(见规则三) 【验收】我怎么判断你做对了(见规则五)四段里,"现状"是最容易被省掉、也最不能省的一段。判断标准很简单:
如果你把这段需求交给一个刚入职的同事,他能不能不问任何问题就做对?如果他会问,那 Agent 也需要知道答案。
一个具体的操作建议:提需求时把相关文件直接贴进去或指给它看,而不是靠描述。描述"我们有个统一的返回体"比不上直接贴一段R.java的代码——前者要它猜,后者它可以直接抄。
规则二:把大任务切成能验收的小块
"帮我把整个网站写完"这种需求,注定失败——不是因为它做不到,而是因为两道坎:
| 坎 | 说明 |
|---|---|
| 上下文会漂移 | 任务越长,它越容易忘记前面的约定,行为越来越"自由发挥" |
| 你无法验收 | 产出 5000 行代码时,你没法判断哪部分是对的、哪部分是错的。错了也不知道错在哪,只能推倒重来 |
正确做法:一个会话只做一件事,做完立刻验证。
❌ 帮我实现用户、图书、购物车、订单、支付、后台管理六个模块 ✅ 第一步:实现用户模块的注册和登录 做完后告诉我怎么验证(跑什么命令、看什么结果) → 我验证通过,再开下一个会话做图书模块为什么"做完就验证"这么关键:因为错误是会传染的。用户模块的表结构设计错了,后面五个模块都会跟着错,而等你发现的时候,已经写了六份需要重写的代码。
一个小技巧:如果一件事确实很大,先让它只做设计不做实现——“先给我一份模块划分和接口清单,不要写代码”。你确认设计之后,再逐个模块实现。审阅 30 行设计的成本,远低于回退 3000 行代码。
规则三:明确写出**“不要做什么”**(这条最重要)
如果这 6 条里只能记住一条,就记这条。
因为绝大多数翻车不是"没做到",而是"做多了"。
一个真实的例子
我曾经让 Agent 帮我补一个接口。它完成得很好——但顺手多做了两件事:在另一个文件里额外加了两个我没要的接口,还在文档里追加了几节内容。
它没有恶意,它觉得这是"帮忙"。结果呢?
我只能把整个改动整体回滚掉。
因为改动面已经失控了:我无法确认那两个多出来的接口有没有副作用,也无法保证文档改动和你想要的口径一致。在"整体回滚"和"逐个核对并接受额外改动"之间,前者更安全。
代价是:那次协作的所有产出都白费了。
为什么"约束"比"要求"更重要
| 作用 | 违反的后果 | |
|---|---|---|
| 要求 | 定义下限——“做到这样就行” | 没做到,继续改就好 |
| 约束 | 定义边界——“不许越过这条线” | 越过了,即使做得对也要推翻重来 |
要求是软的,约束是硬的。而人是天然倾向于"多给一点"的——你越不说边界,它越会"顺手帮你"。
三句必须写进约束里的话
· 只改 A 和 B 这两个文件,不要动 C · 不要新建任何文件、配置、文档 · 不要顺手补其他模块的接口第三句要单独解释一下:Agent 有很强的"把相关的事情一起做掉"的倾向(它认为这样更"完整")。但在真实项目里,“多做"的成本经常高于"少做”——因为多出来的东西需要额外的审查,而少做的部分你一眼就能看出来。
规则四:让它先说方案,再动手
这是投入产出比最高的一条习惯。
因为两个动作的成本差了一个数量级:
| 动作 | 成本 |
|---|---|
| 审阅一份方案(读十行"我打算改哪几个文件") | 低 |
| 回退一次执行(改了十个文件才发现方向错了) | 高 |
所以正确的顺序是:
❌ "开始改吧" ✅ "先说方案:打算改哪几个文件、为什么这么改、 有没有别的做法、有没有副作用。说完等我确认。"现在的 Agent 工具基本都支持这个模式(所谓"计划模式"或"只读模式"),关键是你要主动用它,而不是一上来就让它写。
一个特别实用的用法:让它在不确定的时候"只查不改":
这个问题你先不要改代码,只做分析: 看一下 OrderService 里为什么会返回 null, 列出所有可能的原因和对应的判断方法,先不动手。为什么要加"先不动手":Agent 有个很强的倾向是"看到问题就想修"。但排查阶段最怕的就是"边查边改"——改完之后,你连原始现场都没有了。(这一点和线上故障排查的第一原则完全一致:先止血,再定位;动手之前先把现场 dump 下来。)
规则五:要求可验证的产出,而不是"我完成了"
这是最容易被忽略的一条:AI 的自述不是证据。
它说"已完成",可能是真的改对了,也可能是只是看起来对——代码语法没错、逻辑看起来通顺,但跑起来报错。
所以每次协作都应该以"可验证的东西"收尾:
✅ 做完后告诉我三件事: ① 改了哪些文件(列出来) ② 怎么验证(跑什么命令、看什么结果) ③ 有哪些地方你不确定、需要我确认"第 ③ 项"特别值得要:主动说出"不确定的地方",比假装全对有用得多——那正是你最需要自己看一眼的地方。
判断标准:能不能跑,不是能不能读
这条原则我在写运维文章时反复用过,它同样适用于验收 AI 的产出:
不要看它说"完成了",要看那条命令的输出。
- 前端:
npm run build能不能过?F12 控制台有没有红色? - 后端:那个接口
curl一下返回什么?状态码是 200 还是 500? - 数据库:那条 SQL 影响了几行?
能跑通是唯一标准,代码好不好看是次要的。因为"看起来对"的代码一旦合进去,排查成本会转移到未来某个你完全不记得它的时刻。
规则六:反馈要具体到文件和行
这一条决定了"第二次协作"的质量。
模糊反馈的代价比你以为的大:
| 你说的 | 它理解的 | 它做的 |
|---|---|---|
| “不对” | 不知道哪不对 | 大范围重写(既然不知道错在哪,只能猜着多改) |
| “再改改” | 方向不明 | 可能把对的部分也改坏 |
| “这个页面不好看” | 只能靠猜审美 | 改一堆你没要求的地方 |
结果是改动面失控,本来只需要改一行,最后改了二十行,还引入了新 bug。
正确的反馈长这样:
❌ 不对,报错了 ✅ 调用 POST /api/books 返回 500, 日志里是 NullPointerException,位置在 BookService 第 87 行, categoryId 是 null 但代码直接用了它。 期望:categoryId 为 null 时默认为 1三个要素:现象、位置、期望。有了这三样,Agent 基本一次就能改对;缺了任何一样,它都只能猜。
顺手说个技巧:直接把报错原文贴进去——不要自己转述。你自己总结过的报错会丢掉关键信息(堆栈、行号、参数),而原始报错里往往已经写明了原因。
两个容易被忽略的边界
前面 6 条讲的都是"怎么提需求",但有两个边界问题同样重要——知道什么时候不该用它,和知道怎么用它一样值钱。
边界一:出现这三个信号,就该开一个新会话
Agent 的上下文是有限的。会话越长,它会越"健忘"——前面说好的约定会逐渐失效。三个典型信号:
| 信号 | 表现 |
|---|---|
| 开始遗忘约定 | 后面写的代码不再遵守你一开始定的命名规范或返回格式 |
| 开始重复问 | 又问一遍你已经说过的信息(比如表结构) |
| 开始"自由发挥" | 主动改动你没提过的地方,说明它已经"记不住"上次的约束了 |
处理方式很简单:开个新会话,把必要的上下文重新贴一遍。
听起来很麻烦,但比在一个已经漂移的上下文里反复纠正要便宜得多——你已经花在纠正上的时间,通常超过重开一次的成本。
一个实用习惯:把"项目约定"(技术栈版本、命名规范、返回体格式、目录结构)写成一份固定的说明,每次开新会话时贴一遍。这比指望它记着要可靠。
边界二:这四类任务不要交给它(或者要格外小心)
Agent 很强,但它有几个明确的短板:
| 类型 | 为什么 | 该怎么做 |
|---|---|---|
| 不可逆的操作 | 删数据、改生产配置、DROP/DELETE/rm | 让它给出命令,你自己执行。或者先在小范围试 |
| 依赖现场判断的事 | 它看不到你的屏幕、你不知道它"看到"的环境是什么样 | 把现象、日志、截图给它,让它做分析而不是做决定 |
| 涉及真实敏感信息的 | 密钥、密码、生产数据、用户隐私 | 不要贴给它。用占位符替换后再问 |
| 需要为结果负责的决策 | 架构选型、技术方案拍板 | 让它给候选方案和取舍,决定权留在你手里 |
最后一条我想多强调一句。
它可以替你做执行,但不该替你做决定——因为承担后果的是你。
这也是我这几个月协作里最有用的一个心态转变:把它当成一个执行能力极强、但需要你把关的同事,而不是一个"你问它答"的工具。你会给同事交代清楚背景和边界,也同样该给它交代清楚。
七种最常见的"提需求反模式"
按踩坑频率排序:
| # | 反模式 | 为什么不行 | 正确做法 |
|---|---|---|---|
| 1 | “帮我写个 XX 系统” | 信息量太低,它只能自己发明一切 | 拆成模块,一个会话一件事 |
| 2 | 不贴文件,全靠描述 | 描述必然丢失细节,它只能猜 | 直接把相关文件指给它 |
| 3 | 只说要什么,不说不要什么 | 它会"顺手多做",改动面失控 | 把边界写进约束 |
| 4 | 直接说"开始改" | 方向错了要回退大量代码 | 先要方案,确认再执行 |
| 5 | 相信"已完成" | AI 自述不是证据 | 要可验证的命令与预期结果 |
| 6 | 反馈说"不对" | 它只能大范围重写,越改越乱 | 现象 + 位置 + 期望 |
| 7 | 一次开一个超长会话 | 上下文漂移,约定逐渐失效 | 一个任务一个会话,做完验证 |
第 1、2、3 条占了翻车原因的一大半。如果只想改一个习惯,我建议先改第 3 条——因为它的代价最高(整体回滚),而成本最低(多写三行约束)。
最后:Agent 放大了什么
用下来我最深的感受是:
Agent 放大的不是你的技术能力,而是你"把问题说清楚"的能力。
- 一个能把需求写清楚的人,用 Agent 会快得离谱;
- 一个说不清楚需求的人,用 Agent 只会更快地做出错误的东西——因为试错循环变快了,错的方向也被放大得更快。
所以如果你问我"AI 会不会取代程序员",我觉得这个问题问偏了。更该问的是:
你团队里最会写文档、最能把一件事交代清楚的那个人,是不是一直比你产出高?
Agent 做的事情,本质上就是把"表达能力的收益"放大了:以前表达清楚能省一点沟通成本,现在表达清楚能直接换成产出。
从这个角度看,写文档、写清楚需求、把约束讲明白——这些以前被认为"不如写代码"的事,正在变成最值钱的技能。
互动时间:你用 AI 时踩过最亏的一次是什么?我这次是"它顺手多做,我整体回滚"——你的约束里有没有专门写"不要做什么"?如果没有,建议下次加上。评论区聊聊,这类经验互相分享一下能省很多时间。
本文属于「和 AI Agent 一起干活」系列。作者另有 18 篇运维实战文章(部署 / 监控 / 排查 / 备份 / 安全),见 个人主页。