我平时用 AI 写代码和排查 Bug,差不多有大半年了。如果让我用一句话总结感受,就是“真香,但也有脾气”。真香的地方在于,遇到重复性代码和难缠的报错,AI 能帮我节省大量时间;有脾气的地方在于,如果我自己都没想清楚需求和边界条件,问出来的结果往往又长又绕,甚至直接跑不通。后来我开始专门打磨自己的提问方式,把需求、输入输出、约束条件、期望返回格式都写清楚,AI 回答的可用率一下就上来了。
这篇文章不聊空泛的大道理,直接整理我平时最高频的 5 个场景:从零写功能模块、读懂别人代码、排查 Bug、重构老代码、批量生成测试用例。每个场景我都会放一段可以直接复制的 Prompt,再讲一讲我为什么要这样提问,以及实际踩过的坑。如果你正在尝试用 AI 提效,照着改就能用;如果你已经用得很熟练,也可以看看我的提问思路有没有值得互相借鉴的地方。
1. 场景一:从零开始写一个功能模块
1.1 不要一上来就说“帮我写个XX”
我见过很多同事用 AI 的第一步是把“帮我写个爬虫”直接扔进去,结果第一版代码基本没法直接用。不是 AI 笨,而是信息太少了。抓哪个网站、用什么解析库、要不要处理反爬、数据最后存成什么格式,这些都不说清楚,AI 只能给你一个最通用但也最“空壳”的版本。
我的做法是把它当成给新同事派活。你不能只说“把表填了”,至少要告诉表格从哪里来、填完交给谁、遇到缺数据该怎么办。写 Prompt 的时候,我会把功能目标、输入、输出、边界条件、技术栈这五件事都列出来,缺一不可。这样生成的代码虽然不是每一行都能直接用,但整体方向和代码结构通常是对的。
1.2 可复制的 Prompt
你是一位有 10 年后端开发经验的工程师。请用 Python 实现一个 CSV 文件清洗模块,要求如下: - 功能:读取指定路径的 CSV 文件,删除完全重复的行,并把日期列统一成 YYYY-MM-DD 格式。 - 输入:文件路径 path,CSV 至少有 id、name、created_at 三列。 - 输出:生成清洗后的新文件 output.csv;处理过程中打印每一类问题的行数。 - 边界情况:文件不存在时返回友好错误;日期解析失败时保留原始字符串并单独计数;空行直接跳过。 - 风格要求:代码简洁,函数控制在 30 行以内,关键逻辑写中文注释。 - 返回格式:先列举整体设计思路,再给完整代码,最后用 3 条以内列表说明关键点。这段 Prompt 里最关键的不是“实现功能”,而是“输入、输出、边界、风格、返回格式”这五个限定条件。你会发现它在提示里把“什么情况不用处理”也写了,比如日期解析失败保留原串。AI 收到这种指令后,写出来的代码就会带上异常处理逻辑,而不是只处理最顺的那条路径。
1.3 为什么“边界情况”这三个字这么值钱
没有边界提示时,AI 默认只写 happy path,也就是一切都正常时的流程。但真实的业务里,文件可能不存在、字段可能为空、日期格式可能混着 2024/01/01 和 2024-01-01,这些都是日常。
我在实际项目里写过类似工具,最崩溃的一次是处理客户给的 Excel,里面同一列日期有三种格式。如果没有提前和 AI 说清楚“按多种格式解析,解析不了就保留原值”,它生成的代码一遇到特殊格式就会抛异常,整个任务中断。所以我后来会刻意写“日期解析失败时保留原始字符串并单独计数”,这句话看着啰嗦,但它是在告诉 AI:你要对异常负责,而不是对理想情况负责。
1.4 踩过的坑:约束不够,AI 就会给你“全功能版”
另一个常见坑是提示词里不加范围,AI 会觉得你什么都想要。有一次我只想写个脚本批量重命名文件,结果 AI 给了我一个 300 行的完整工具类,带命令行参数解析、日志模块、配置文件读取,看着很专业,实际上我只需要三五个函数。
从那以后我学会了加“代码简洁”和“不要过度优化”。这两个词不是玄学,而是给 AI 的裁量边界。它知道你不是要一个工程级项目,而是要一个能解决问题的片段。当然,我也踩过反向的坑,就是 AI 因为“简洁”把必要的判空逻辑删了。所以我现在通常会补一句“关键逻辑写注释”,强制它把思路留下来,方便我 review 它有没有删掉不该删的东西。
2. 场景二:拿到一段看不懂的代码
2.1 让我头疼的往往不是自己写的代码
工作里最让人头疼的其实不是从零写,而是接手遗留系统。那些没有注释、命名混乱、还充满了跨文件调用的老代码,读起来非常消耗耐心。以前我会一行行断点去跟,现在我会先把整段代码复制给 AI,让它帮我从宏观到微观拆解一遍。
但这里有个使用细节:不要直接裸贴代码。AI 没有上下文的时候,它不仅看不懂你的业务背景,还可能因为代码片段不完整,给出误导性结论。我会在开头先介绍这段代码来自什么模块、大概在做什么事、我拿到了哪个文件里的哪部分。这个上下文对理解代码非常重要。
2.2 可复制的 Prompt
以下是一段 JavaScript 代码,来自一个订单状态流转模块。请帮我逐段解释作用,不要修改代码。 要求: - 先用不超过 50 字概括这段代码的用途; - 再按执行顺序拆解关键函数,说明每个参数的含义; - 指出 3 个最容易出错的地方; - 最后告诉我,如果我想让这段代码支持“取消订单”的新状态,在不动现有逻辑的前提下应该改哪里,只说明改动点,不要直接改代码。 代码: ```javascript // 这里粘贴你的代码这段 Prompt 的重点是“先解释,再给方向,但不直接改”。我发现很多人用 AI 读代码时,喜欢直接说“帮我优化一下”或者“帮我改成支持取消订单”,但 AI 连原逻辑都还没理清楚,改出来的方案容易破坏原有行为。你先让它解释一遍,自己再对照代码看它说得对不对,确认理解一致后,再让它动手改,成功率会高很多。 ### 2.3 实操心得:像带新人一样给它“边界” 我还会在 Prompt 里加一句“只说明改动点,不要直接改代码”,这算是我自己的一个习惯。因为 AI 一旦同时给你解释和改代码,很容易在解释部分和代码部分之间产生不一致,你会看到它解释得头头是道,结果代码里偷偷把某个变量的默认值改了。 另外,如果你是在看开源项目,最好把仓库名、项目版本、引用的框架都放进上下文里。有一次我排查一个 Java 老项目的逻辑问题,顺手把 Spring Boot 的版本号写了进去,AI 立刻提醒我那个版本里有个配置项的行为和现在不一样。这种信息量完全不同的回答,靠裸贴代码是拿不到的。 ## 3. 场景三:快速定位报错信息 ### 3.1 把“报错”当成一份线索清单 排查 Bug 是我用 AI 最多的时候,因为报错信息往往是“已知条件”最充足的输入。但很多人把报错一贴就完事,AI 给的答案也经常浮在表面上。后来我总结出一个报错排查模板:运行环境、完整报错、相关代码、我已尝试过的操作。这四样缺一不可。 运行环境指的是语言版本、框架版本、操作系统;完整报错不是只贴最后一行,而是把堆栈信息也带出来;相关代码是报错位置附近的片段,不是整个文件;已尝试操作就更重要了,它能让 AI 不浪费时间去推荐你已经排除掉的方案。 ### 3.2 可复制的 Prompt ```text 我在做一个 Python 数据分析任务,运行 pandas 脚本时遇到如下报错,请帮我定位原因并给出排查步骤。 - 版本环境:Python 3.11,pandas 2.0,Windows 11。 - 报错信息:Traceback (most recent call last): ... KeyError: 'price'
- 相关代码: ```python df = pd.read_csv("orders.csv") df["total"] = df["price"] * df["quantity"]- 我已经尝试过:重启解释器、检查文件路径是否存在,问题仍然出现。
请不要给“可能是数据格式问题”这种一句带过的答案。请按可能性从高到低列出 3 个原因,并为每个原因给出验证方法。
你可能注意到我在 Prompt 里专门写了“不要给一句带过的答案”,这很有用。因为默认情况下 AI 喜欢给那种安全但没用的回答,比如“请检查数据格式是否正确”。这句话本身没错,但没有操作步骤,你听完了还是不知道怎么办。加上这句要求之后,它会强制自己给出可执行的验证步骤,效用完全不同。 ### 3.3 一个真实排查实录 有一次我遇到的就是上面这个 KeyError,当时第一反应是“数据里没有价格列”?不过检查 CSV 后我发现列名明明叫 orice。因为列名拼写错了。我把代码和报错丢给 AI,它的第一个猜测就是列名不一致,还建议用 `df.columns` 打印全部列名去核对。这个操作很简单,但它从 Prompt 里的“我已尝试过”中知道我还没有打印列名,所以给出了一个更精准的排查方向。 还有一次遇到一个很隐蔽的 Bug,代码在本地跑得好好的,一到服务器就报编码错误。AI 根据我提供的中文数据和服务器操作系统信息,判断大概率是默认编码问题,直接建议我在打开文件时指定 `encoding="utf-8"`,顺手解决了。这种判断依赖的就是 Prompt 里的环境信息,如果你只贴报错不贴环境,AI 就只能在“编码问题”这个大类里猜,给不出精确结论。 ## 4. 场景四:重构与优化老代码 ### 4.1 重点:行为不变,接口不变 重构需求跟从零写不一样,最大的风险是“顺手改坏了逻辑”。AI 在优化代码时,经常为了减少分支或循环次数,把某些边界行为默认成“不可能发生”,然后删掉处理代码。这种事情我遇过不止一次。 所以我在重构类 Prompt 里一定会写两条硬性约束:业务行为不能有任何变化,对外接口不能变。这两句话看着简单,但能在很大程度上限制 AI 的自由发挥。它知道你是要“保持原样地改善结构”,而不是“凭你的喜好重写一套”。 ### 4.2 可复制的 Prompt ```text 请帮我重构这段 Java 代码。约束如下: - 业务行为不能有任何变化; - 对外接口、方法签名和返回值类型必须保持不变; - 把重复的配置读取逻辑提取成单独方法; - 拆分过长的 if-else 时,保持原有分支顺序; - 不要引入外部依赖; - 输出格式:先给出重构思路,再给出完整新代码,最后用表格列出“改动位置、为什么改、风险点”。 代码: ```java // 这里粘贴你的代码这段 Prompt 里有一句很关键:“不要引入外部依赖”。很多同事会忽略这一点,结果 AI 为了让代码简洁,直接建议引入一个新的工具库。这在个人项目里没问题,但在团队项目里,加依赖往往要走审批流程,要考虑兼容性、许可证、安全漏洞,绝不是顺手就能干的事。我踩过坑,它给我引入了一个辅助库,虽然代码短了,但因为团队技术栈里没有这个库,最后我还是得手工改回原生方案。 ### 4.3 为什么我要限制“不要引入外部依赖” 依赖问题是我特别想展开说的。“引入一个库”和“写一段原生代码”在 Prompt 里可能只差一个词,但在实际工程里差很远。你引入一个库,等于把一段不受自己控制的代码拉进生产环境,它的版本升级、已知漏洞、维护状态都会成为你的技术债。 所以我倾向于在重构时要求 AI 用现有技术栈自己实现逻辑。哪怕是多写几行,至少我知道每一行在干什么,出了问题也能自己改。如果你也在团队项目里用 AI 重构,建议把这条写进你的标准 Prompt 里,不要给 AI 太多自由度。 另外,重构完了一定要跑测试。我自己的流程是,先把重构前后的代码都交给 AI,让它自己列出行为差异点,然后我拿着这个差异表去对照测试用例。如果没有测试用例,我会先让 AI 基于重构前的代码生成一组基础测试,跑通了再去动重构。这等于给重构加一道安全带,值得养成习惯。 ## 5. 场景五:批量生成测试用例 ### 5.1 写测试用例最烦的就是穷举场景 说实话,写单元测试这件事里最消耗精力的不是写代码,而是穷举场景。边界值、异常输入、空值、非法值,这些都要一个个想。AI 在这件事上是真的强,因为它见过的规则组合比人多得多,只要我们把业务规则说清楚,它就能快速生成一张完整的测试矩阵。 我最早接触这个场景时,也以为 AI 生成测试用例只是“偷懒”,后来发现它生成正常路径的用例效率一般,但在边界条件和异常输入上,经常能想到我没想到的情况。比如一个金额计算函数,我通常只关心“满减”“折扣”这些正向规则,但它会主动补一个“订单金额为负数”的用例,虽然接口没写明,但这种防御性的测试思路反而帮我提前发现了代码里的漏洞。 ### 5.2 可复制的 Prompt ```text 根据以下接口定义和业务规则,请为 calculateDiscount 函数设计测试用例。 接口说明: - 参数:userId(字符串)、orderAmount(浮点数)、vipLevel(整数) - 返回值:折后金额(浮点数) 业务规则: - 非 VIP(vipLevel=0)不打折,返回原金额; - VIP1 满 100 减 10,不足 100 不打折; - VIP2 满 100 打 9 折,不足 100 不打折; - 折后金额保留 2 位小数; - 任何非法参数(负数金额、负数 VIP 等级)返回 -1。 输出格式:用 Markdown 表格输出,列为:用例编号、输入、预期输出、覆盖类型。 覆盖类型请标清:正常 / 边界 / 异常。这个 Prompt 的结构是“接口说明 + 业务规则 + 输出格式”,就是一个很标准的需求描述模板。真正有效的部分是业务规则,你要写得非常机械,让 AI 没有自由发挥的空间。因为只要规则有歧义,AI 生成的用例预期输出也会有歧义,最后你还是得一个个改。
这里有个小技巧:规则不要只写“满 100 减 10”,还要写清楚“不足 100 怎么办”。很多问题就出在没写“否则”分支上,AI 会假设它打折,但你实际的业务规则是它不打折。每个规则都配套一个 else 分支,这是我在多次踩坑后养成的习惯。
5.3 测试用例生成后的核对方法
AI 生成的测试用例不会 100% 准确,尤其是预期输出那一列,它经常是基于业务规则“推导”出来的,而不是真实计算过的。有一次它生成的用例里,VIP2 满 100 打 9 折,它写了折后是 90.00,但商品金额是 100.05 时,9 折应该是 90.045,我要求的规则是保留两位小数,那预期到底是 90.04 还是 90.05,就需要我自己确认四舍五入规则。
所以我给一个最终核对顺序:先验证规则描述是否一致,再检查非法输入是否有对应用例,最后自己跑一遍核心逻辑,用真实结果覆盖预期值。这套流程看着多走了一步,但能防止你拿着错误的预期去写断言,最后测试全绿却发现断言才是错的。
6. 几个让 AI 更“顺手”的小习惯
6.1 每次对话先定角色,再派任务
我发现很多人打开 AI 对话框,上来就是一句“帮我看看这个”,这其实很浪费。我更倾向于每段对话开头先把角色定下来,比如“你是一位熟悉 Python 数据分析的工程师”,然后再提需求。不要小看这句话,它对后续输出的影响很稳定。就好比你找一个前端同事和找一个后端同事看同一段代码,关注点完全不一样,AI 也是这样。
6.2 一次对话只做一类事情
另一个习惯是不要在一个对话里同时干“帮我解释代码、然后优化、再写测试”这三件事。AI 的上下文窗口是有限的,对话越长,它对最初需求的理解就越模糊。我现在倾向于把任务拆成多个独立对话,比如读代码就专门读代码,重构就专门重构,生成测试用例就专门生成测试用例。每个对话从干净的开场开始,带着完整的背景重新提问,反而比长对话更可控。
6.3 给自己搭一个可复用的 Prompt 库
用得多了之后,我给自己整理了一个 Prompt 库,其实就是一篇文章的本地文件或者收藏夹。里面每一类场景都有固定模板,用的时候把“CSV 清洗模块”替换成“用户导入模块”,把“Python”替换成“Go”,结构完全不用改。这样做的价值非常大,因为你会慢慢发现,真正提升效率的不是每一次和 AI 斗智斗勇,而是你已经积累了一整套经过验证的提问套路,以后每次开工只需要填空就行。
最后再分享一个我个人的体会:AI 写代码这件事,本质上是在帮你把“想法”快速变成“初稿”,但它并不替你思考。我踩过最多次坑,都是因为自己没想清楚边界和规则,就急着让 AI 输出。后来我养成了一个习惯,在按下回车之前先问自己一句:如果 AI 只给我一段残缺代码,我会不会一眼看出来?如果我自己都不知道需求是什么,AI 给出来的大概率也不是我想要的。把它当成人肉倍速的编译器,而不是帮你决定需求的 brain,你会用得比大多数人都稳。