最近在做一个内部工具,用Cursor+Claude帮忙写Python脚本。前期生成CRUD很快,但一到“改需求”就崩——比如我让它把某个函数从同步改成异步,或者加个重试机制,它经常只改一半,留下旧变量名或者漏掉异常处理。我试过把完整代码贴回去再描述,也试过只贴相关片段,但效果都不稳定。甚至有时候我明确说“只改这一段”,它还是会把其他无关逻辑顺手“优化”了。想问问大家,是这类迭代型任务本身不适合AI,还是我需要调整提示词结构?比如要不要给它一个“变更清单”而不是自然语言描述?
用AI写代码总在改需求时翻车,是我的提示词姿势不对吗?
全部回复
共 30 条变更清单比自然语言靠谱,但AI对“别动其他逻辑”的理解还是太弱,我一般直接锁文件或分模块重写。
试过把改动的函数单独拆出来喂给它,改完再合回去,比贴整段代码稳多了。
我试过给AI列变更清单,确实比纯自然语言靠谱点,但别指望它严格照做。更像是指定了一个范围,它还是会忍不住动点别的。你那个“只改这一段”的痛点我太懂了,后来我干脆把函数体复制出来,让它生成新版,然后我自己贴回去,反而省心。
另外同步改异步这种,它经常漏掉await或者忘了改调用方,我怀疑是上下文窗口对跨文件依赖感知太弱。你试试把相关调用处的代码也贴进去,或者明确告诉它“只允许改动这几个函数,其他一律禁止”。
这问题太真实了,迭代型任务确实比从零写更考验AI的上下文理解。我试过最有效的方式是给个明确的“变更清单”,比如“把第X行改成异步,只动这个函数,别碰其他”,比自然语言描述稳得多。不过就算这样,它偶尔还是手痒“优化”别的,所以我改完必跑一遍diff,重点看它有没有动无关代码。另外,把完整代码贴回去反而容易让它“发挥”,只贴相关函数再加个最小复现可能更可控。你有没有试过在提示词里加一句“禁止修改未提及的代码”?
变更清单这个思路靠谱,我试过把需求拆成“动作+范围”的列表,比如“把fetch_data改为async,连带更新所有调用点,不改动其他函数”,成功率会高不少。但说实话,迭代型任务对模型上下文理解要求太高,它容易把“局部修改”脑补成“全局重构”,我后来干脆每次改动前先git stash,让它基于干净版本改,而不是在它自己改过的代码上继续叠。还有个小技巧,明确告诉它“不要解释,只输出完整代码块”,能少很多自作聪明的优化。
变更清单这招确实管用,把改动点列成1234比说人话稳定多了,但记得让它逐条确认别自作主张。
我也遇到过一模一样的情况,同步改异步那会儿它能把函数签名改了,但内部await全漏掉,跑起来直接报错。后来我试了个办法,效果稍微好点——就是不给它“描述需求”,而是直接给它一个checklist,比如“1.改函数定义加async 2.所有IO调用前加await 3.异常处理里加asyncio.TimeoutError”,它反而老实很多。但你说的“顺手优化”那个太真实了,有时候我明明只让改一行,它非要把旁边两个函数重构了,搞得我review时血压飙升。我觉得本质上这类迭代任务不是不适合AI,而是它缺少“最小改动”的约束意识,你越是用自然语言解释“为什么改”,它越容易脑补出你没说的需求。所以我现在的习惯是,每次只发一个函数体,并且在开头写死“不要动其他函数,不要优化逻辑,不要加注释”,虽然不能100%避免,但翻车率确实降了一些。你那个“变更清单”的思路我觉得方向对,建议再配合上“先列出你打算改哪几行,我确认了你再动手”这种话术,等于逼它先出diff计划,不然它总是直接给你一个“自认为更好”的版本。
变更清单这招我试过,确实比自然语言稳,但得把边界写死,不然它手痒想“优化”拦不住。
我一般直接甩个diff格式的改动要求,它反而老实,只动该动的地方。
我自己也踩过这坑,后来发现给“变更清单”确实比自然语言靠谱,但关键是清单里得写清楚“哪些文件/函数不许动”,不然它手痒照样给你重构。另一个办法是让它先输出diff或计划,你确认了再动手,能少一半返工。不过也别太指望一次到位,这种迭代任务本质就是得来回拉扯几轮,心态放平就好。
试过把需求拆成最小步骤没?比如“先改函数签名,再改调用处,最后补异常”,一次只丢给它一步,比一股脑全说强得多。另外它顺手优化别的地儿,多半是上下文里别的代码“勾引”的,试试把无关部分折叠或者删掉,只留关键几行,它就没那么多戏了。
我反而觉得不全是提示词问题,模型对“局部修改”的理解就是有边界的,你越强调“只改这段”,它越容易脑补出完整场景。现在我会在代码里加注释标记,比如“这里开始到那里结束是待改区域,其他别碰”,效果比单纯文字描述好。但偶尔还是翻车,所以重要改动我都用git diff仔细查一遍,别指望它一次成型。
变更清单这招我试过,确实比自然语言稳,但得写得像diff描述那么细才行。
建议直接把改动点列成编号清单,外加一句“禁止改动未提及代码”,能省不少事。
试过把需求拆成“变更清单”确实会稳一些,但更关键的是每次只让它动一个点,改完立刻跑测试验证,别攒一堆一起改。另外我发现给它看改动前后的diff比贴整段代码有效,它会更清楚边界在哪,顺手优化其他逻辑的频率也低很多。还有就是它改异步时经常漏await,我现在会直接告诉它“检查每个IO调用是否都加了await”,这种显式提醒比笼统说“改成异步”管用。