1. 这门课到底在讲什么:从"会写代码"到"会驾驭AI写代码"
第一次看到"AI时代的软件工程"这个说法,我脑子里冒出来的第一个念头是:软件工程不就是需求、设计、编码、测试、维护那一套吗,加个AI能变出什么花样来。直到我自己动手把一整套AI辅助开发流程跑通,踩了七八个坑之后才明白,这门课真正想教的不是"怎么让AI帮你写代码",而是"当写代码这件事本身变得廉价之后,一个工程师的价值到底在哪里"。
这个转变听起来有点虚,但落到实操上非常具体。传统软件工程里,我们花大量时间在语法、API记忆、调试细节上,一个功能从想法到落地,编码可能占掉六成时间。而在AI深度介入之后,编码本身的时间被压缩到两成甚至更低,剩下的时间全部转移到了另外几个环节:怎么把模糊的需求拆成AI能准确执行的指令、怎么设计系统边界让AI生成的模块能拼在一起、怎么验证AI产出的代码真的可靠、怎么在AI给出十个方案时快速判断哪个是对的。这些能力,才是这门课的核心。
我写这篇笔记的目的很直接:把我在实践这套方法论时真正有用的东西整理出来,包括每个环节为什么这么设计、具体怎么操作、参数怎么定、哪些地方最容易翻车。适合两类人看——一类是已经用AI写过一些代码但总觉得"差点意思"的开发者,另一类是还没系统接触过AI辅助工程、想搞清楚这套东西到底靠不靠谱的工程师。不管你现在是什么水平,只要你想弄明白"AI时代软件工程"这几个字背后的真实含义,这篇内容应该能给你一些能直接抄作业的东西。
2. 整体设计思路:为什么这套方法论和传统软件工程不一样
2.1 核心矛盾:AI让编码变快,但让"判断"变难
传统软件工程的核心矛盾是"人力有限",所以我们要用各种流程、规范、评审来节省人力。敏捷开发、代码评审、CI/CD,本质上都是在解决"人不够用"的问题。但AI介入之后,矛盾变了。编码不再是瓶颈,瓶颈变成了"判断力"——AI可以在几秒内生成两百行代码,但你得判断这两百行能不能用、有没有隐藏的边界问题、和现有系统会不会冲突。
我举个自己遇到的真实场景。当时我要给一个数据处理模块加一个"异常值自动标记"的功能,直接让AI生成,它给了我一版用统计方法(Z-score)的实现,代码写得很漂亮,注释也全。但我一看就发现问题:我的数据里有大量非正态分布的字段,Z-score在这种数据上会误判。如果我是一个刚入行的开发者,很可能就直接用了,因为代码看起来没问题。这就是AI时代的新陷阱——代码质量本身很高,但方案选择可能是错的。
所以这套方法论的整体设计思路,是把工程师的精力从"写"转移到"判断"和"约束"上。具体来说,它强调三件事:第一,在让AI动手之前,先把问题的边界、约束、验收标准想清楚;第二,把大任务拆成AI能独立完成的小块,每块都有明确的输入输出;第三,建立一套快速验证机制,让AI的产出能被人高效审查。
2.2 方案选型:为什么是"人定框架、AI填内容"而不是反过来
市面上关于AI辅助开发的做法大致分两派。一派是"AI主导",你把需求丢给AI,让它从架构到代码全包;另一派是"人主导",人定好架构和接口,AI只负责填充具体实现。我两种都试过,最后坚定地站在第二派。
原因很实际。AI主导的模式在demo阶段很爽,你描述一个需求,它给你一个能跑的东西。但一旦项目要迭代、要维护、要和别人的代码集成,问题就来了。AI生成的架构往往"看起来合理但经不起推敲",比如它可能把所有逻辑塞进一个类里,或者用了一个在你团队技术栈里根本不存在的库。更麻烦的是,当你想改一个功能时,你面对的是AI写的、你没有完全理解的代码,改起来比从头写还累。
"人定框架、AI填内容"的模式则把风险控制住了。人负责的是那些"一旦错了后面全错"的决策:模块怎么划分、接口怎么定义、数据怎么流转、异常怎么处理。这些决策不需要写很多代码,但需要经验和判断,正好是人擅长而AI不擅长的。AI负责的是那些"有明确输入输出、可以独立验证"的部分:一个具体的算法实现、一个数据转换函数、一段正则表达式、一个单元测试。这些部分即使AI写错了,影响范围也有限,改起来快。
提示:判断一个任务该不该交给AI,我的经验标准是——如果这个任务的验收标准能用一句话说清楚,且不依赖对全局的理解,就可以交给AI;如果验收标准需要"看情况",那就自己来。
2.3 和传统流程的衔接:不是替代,是插入
很多人以为AI时代的软件工程是把传统流程推翻重来,其实不是。它更像是在传统流程的每个环节里插入了一个"AI加速器"。需求分析阶段,AI可以帮你把模糊描述转成结构化文档;设计阶段,AI可以帮你生成接口草案和数据结构;编码阶段,AI可以生成具体实现;测试阶段,AI可以生成测试用例;维护阶段,AI可以帮你理解陌生代码。
但每个环节的"人机分工"不一样。需求阶段AI是助手,帮你整理思路,但需求的优先级和取舍必须人来定;设计阶段AI是参谋,给你几个方案,但选哪个必须人来拍板;编码阶段AI是主力,但关键逻辑和边界处理必须人来审;测试阶段AI是苦力,帮你覆盖各种情况,但测试策略必须人来定。
我自己的做法是画一张"人机分工表",把每个环节的任务分成三类:人独立完成、AI独立完成、人机协作。这张表不是固定的,随着你对AI能力的了解会不断调整。比如一开始我什么都不敢让AI独立做,后来发现单元测试这种有明确标准的任务完全可以放手,就把更多测试工作交给了AI。
3. 核心细节解析:每个环节到底怎么做
3.1 需求拆解:把"我想要"变成"AI能执行"
这是整个流程里最容易被低估的环节。很多人觉得需求拆解就是把大需求切成小需求,其实远不止。AI执行任务时,它需要的是"无歧义的指令",而人类的需求描述天然带有大量隐含信息。比如你说"做一个用户登录功能",人类工程师会自动脑补出密码加密、会话管理、错误提示、防暴力破解这些东西,但AI不会,它可能只给你一个最基础的账号密码比对。
我的做法是用一个固定的模板来拆解需求,每个任务必须回答五个问题:输入是什么、输出是什么、边界条件有哪些、异常怎么处理、验收标准是什么。这五个问题逼着我把隐含信息显性化。举个例子,同样是"用户登录",拆解之后会变成:输入是用户名和密码字符串,输出是登录成功后的会话令牌或失败原因,边界条件包括用户名长度限制、密码复杂度要求、连续失败次数限制,异常处理包括网络超时、数据库连接失败、账号被锁定,验收标准是正确凭证能登录、错误凭证返回明确提示、连续五次失败后锁定十分钟。
这个模板看起来啰嗦,但它带来的好处是巨大的。当AI拿到这样一份拆解时,它生成的代码质量会明显提升,因为它不再需要"猜"你的意图。而且这份拆解本身就是一份验收清单,后面测试的时候直接照着检查就行。
注意:拆解需求时不要一次性拆太细。我的经验是拆到"一个任务能在半小时内完成并验证"这个粒度就够了。拆太细会导致任务之间依赖关系复杂,反而增加管理成本。
3.2 提示词设计:不是"会说话"就行
提示词这个东西,网上教程很多,但大部分都在教"怎么说话让AI更听话",我觉得这个方向有点偏。提示词的本质不是"话术",而是"信息传递的效率"。你要做的是在最短的篇幅里,把AI完成任务所需的所有信息准确传递过去。
我总结了一个提示词的四段式结构,实测下来比那些花哨的技巧管用得多。第一段是角色和背景,告诉AI它现在是什么身份、在什么项目里工作,这部分决定了AI调用哪些知识;第二段是任务描述,用前面拆解出来的五个问题来写,越具体越好;第三段是约束条件,包括技术栈限制、代码风格要求、不能使用的库、性能要求等;第四段是输出格式,明确告诉AI你要什么形式的产出,是完整代码、还是代码加解释、还是只要思路。
举个具体的例子。我要让AI写一个"从日志文件里提取错误信息并按类型统计"的函数。差的提示词是"帮我写一个日志分析函数"。好的提示词是:"你是一个Python后端工程师,现在需要处理一个日志分析任务。输入是一个文本日志文件路径,每行格式为'时间戳 级别 模块 消息'。输出是一个字典,键是错误类型(从消息中提取),值是该类型出现的次数。边界条件:文件可能不存在、可能为空、可能有格式不正确的行。异常处理:文件不存在时抛出FileNotFoundError,格式错误行跳过并记录警告。验收标准:给定一个包含10行日志的测试文件,能正确统计出各错误类型数量。约束:只用标准库,不用pandas,代码要有类型注解。输出格式:完整函数代码加简短注释。"
这两版提示词的效果差距是肉眼可见的。后者生成的代码基本可以直接用,前者生成的代码我得改一半。所以提示词设计的关键不是"礼貌"或"技巧",而是"信息密度"。
3.3 代码审查:AI写的代码怎么快速判断能不能用
AI生成的代码有一个特点:表面质量很高,变量命名规范、注释齐全、格式整齐,很容易让人放松警惕。但我踩过的坑告诉我,AI代码的问题往往藏在"看起来没问题"的地方。我总结了一套快速审查的方法,分三步走。
第一步看"方案层"。先不看具体代码,看AI用的是什么思路。比如让它写一个排序,它用的是快排还是归并,时间复杂度是多少,适不适合我的数据规模。这一步能过滤掉大部分"方案性错误"。第二步看"边界层"。重点检查空值、零值、极大值、极小值、重复值这些边界情况有没有处理。AI经常在正常流程上写得很完美,但边界处理要么漏掉要么写错。第三步看"集成层"。检查AI用的接口、库、数据格式和我现有系统是否一致。AI有时候会用一些"它觉得合理"但实际不存在的接口。
这三步走下来,一个两百行的函数大概五分钟能审完,比逐行读效率高得多。而且审查过程中发现的问题,我会直接反馈给AI让它改,而不是自己动手改。这样做的原因是,自己改容易改出新的问题,而且下次遇到类似任务AI还是会犯同样的错。让AI改,一方面它能学到我的偏好,另一方面我也能确认它真的理解了问题。
提示:审查AI代码时,我有个习惯是让它"解释自己的代码"。具体做法是问它"这段代码在输入为空时会怎么执行"或者"如果输入数据量增大十倍,这段代码的性能瓶颈在哪里"。AI的解释有时候会暴露它自己都没意识到的问题。
3.4 测试策略:AI生成测试,但人来定"测什么"
测试是AI最能发挥价值的环节之一,因为测试用例的生成有很强的模式性,AI很擅长。但这里有个陷阱:如果你让AI"自己决定测什么",它往往会测那些容易测的,而不是那些真正需要测的。比如它会测正常输入、测几个常见边界,但可能漏掉那些"业务逻辑上特殊"的情况。
我的做法是把测试分成两层。第一层是"AI自主测试",让AI根据函数签名和文档生成基础测试用例,覆盖参数类型、边界值、异常路径这些通用情况。第二层是"人工指定测试",我根据业务理解,列出那些"必须验证"的场景,让AI针对这些场景生成测试。比如一个订单金额计算函数,AI自主测试会覆盖正数、负数、零、极大值,但我会额外指定"会员折扣叠加优惠券"、"跨境订单税费计算"、"退款后重新计算"这些业务场景。
这样做的好处是测试覆盖率和测试有效性都上去了。而且我发现一个有意思的现象:当我明确告诉AI"要测哪些业务场景"时,它生成的测试用例质量比它自主生成的还要高,因为它有了明确的靶子。
4. 实操过程:一个完整任务的端到端记录
4.1 任务背景与拆解
为了让你看到这套方法论怎么落地,我完整记录一个我最近做的任务。任务本身不复杂:给一个内部工具加一个"数据导出"功能,支持把查询结果导出成CSV和JSON两种格式,并且要能处理大数据量(十万行以上)不卡死。
按照前面的方法,我先拆解需求。输入是查询结果集(一个二维数据结构)和目标格式(CSV或JSON),输出是文件路径或文件流。边界条件包括:结果集为空、结果集包含特殊字符(逗号、引号、换行符)、结果集包含非ASCII字符、数据量超过内存限制。异常处理包括:磁盘空间不足、目标路径无写入权限、格式不支持。验收标准是:一万行数据导出时间不超过三秒,十万行数据不出现内存溢出,CSV格式能被Excel正确打开,JSON格式能被标准解析器解析。
拆解完之后我发现,这个任务其实可以分成三个子任务:格式转换逻辑、大数据量的分块处理、文件写入的异常处理。三个子任务相对独立,可以分别交给AI做。
4.2 提示词与AI产出
第一个子任务,格式转换。我的提示词是:"你是一个Python工程师,需要实现一个数据格式转换函数。输入是一个二维列表(每行是一个列表,元素是字符串或数字),输出是CSV格式的字符串。要求:正确处理包含逗号、引号、换行符的字段(用标准CSV转义规则),正确处理非ASCII字符(UTF-8编码),不使用csv模块(因为要自己控制转义逻辑)。输出完整函数代码加注释。"
AI给的实现基本可用,但我审查时发现一个问题:它处理引号转义时用的是简单的双写引号,但没有处理字段首尾空格的情况。按照CSV标准,如果字段包含逗号或引号,整个字段要用引号包裹,字段内的引号要双写。AI的实现漏掉了"字段包含换行符时也要包裹"这个情况。我把这个问题反馈给它,它很快就改对了。
第二个子任务,分块处理。这个任务稍微复杂一点,因为涉及内存管理。我的提示词里明确写了:"数据量可能超过内存,需要分块读取和写入。每块大小可配置,默认一千行。要求:使用生成器模式,不一次性加载所有数据。输出一个可配置块大小的导出函数。"
AI给的方案是用生成器逐块产出,然后逐块写入文件。这个思路是对的,但它在实现时犯了一个典型错误:它在每块写入后都调用了一次flush,导致十万行数据要flush一百次,性能反而下降。我审查时通过"性能瓶颈在哪里"这个问题发现了它,让它改成每十块flush一次,性能就正常了。
第三个子任务,异常处理。这个相对简单,AI一次就写对了。但我在审查时补充了一个它没想到的情况:如果导出过程中程序被中断,已经写入的部分文件怎么处理。我让它加了一个"写入临时文件、完成后重命名"的逻辑,避免产生半成品文件。
4.3 集成与验证
三个子任务分别完成后,我把它们拼在一起。拼接过程中发现一个接口不一致的问题:格式转换函数返回的是字符串,但分块处理函数期望的是可迭代的行。这个问题在拆解阶段其实可以避免,如果我当时把接口定义得更明确的话。不过发现得早,改起来也快,让AI把格式转换函数改成生成器模式就行了。
验证阶段我用了前面说的两层测试。AI自主测试覆盖了空数据、单行数据、包含特殊字符的数据。我额外指定了三个业务场景:十万行数据的性能测试、包含中文和emoji的数据、导出过程中模拟磁盘满的情况。三个场景里,性能测试通过(十万行导出耗时约两秒),中文和emoji测试发现了一个编码问题(AI在写文件时没指定编码,用了系统默认编码),磁盘满测试发现异常处理不够友好(报错信息不明确)。这两个问题都反馈给AI修好了。
整个任务从拆解到完成,大概花了两个小时,其中写代码的时间不到半小时,剩下都是拆解、审查、验证。如果按传统方式自己写,我估计要三到四小时。效率提升是明显的,但更重要的是,整个过程我心里很有底,因为每个环节我都清楚在做什么、为什么这么做。
5. 常见问题与排查技巧实录
5.1 AI生成的代码"看起来对但跑起来错"怎么办
这是最常见的问题,也是新手最容易慌的地方。我的排查思路是"从外到内"分三层。第一层,确认输入输出是否符合预期。很多时候不是代码逻辑错,而是输入数据的格式和AI假设的不一样。比如AI假设输入是列表,你传的是元组,或者AI假设字符串是ASCII,你传的是中文。第二层,用最小用例复现。把出错的场景简化到不能再简化,看还错不错。如果最小用例也错,那就是逻辑问题;如果最小用例不错,那就是边界或数据问题。第三层,让AI自己debug。把错误信息、输入数据、期望输出一起发给AI,让它分析原因。AI在debug方面其实挺强的,因为它能同时看到代码和错误。
我遇到过一个典型例子:AI写的一个日期解析函数,在测试环境跑得好好的,一到生产就报错。排查发现是生产环境的日期格式里包含了毫秒,而AI的实现只处理到秒。这种问题靠读代码很难发现,但用最小用例一测就出来了。
5.2 AI"忘记"之前的约定怎么处理
多轮对话里,AI经常会忘记前面说过的约束。比如你第一轮告诉它"不要用第三方库",聊到第五轮它又用上了。这不是AI故意不听话,而是它的上下文窗口有限,或者注意力被后面的内容分散了。
我的应对方法是"关键约束重复声明"。每次让AI做新任务时,把最重要的两三条约束再写一遍,哪怕前面已经说过。另外,我会把约束写成"检查清单"的形式,让AI在输出前自己对照检查。比如"输出前请确认:1. 没有使用第三方库;2. 所有函数都有类型注解;3. 异常处理覆盖了文件不存在的情况"。这个做法实测能显著降低约束遗忘率。
5.3 性能问题怎么提前发现
AI生成的代码在功能上通常没问题,但性能上经常有隐患。我总结了几种AI代码常见的性能陷阱:不必要的循环嵌套、重复计算、频繁的IO操作、大数据量的内存拷贝。排查方法是在审查阶段就问AI"这段代码的时间复杂度和空间复杂度是多少",如果它说不清楚或者明显不对,就要警惕。
另外,对于数据量可能很大的任务,我会在提示词里直接加上性能要求,比如"数据量可能达到十万行,要求时间复杂度不超过O(n log n)"。有了明确要求,AI生成的代码性能通常会好很多。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决思路 |
|---|---|---|---|
| 代码逻辑正确但结果不对 | 输入数据格式与假设不符 | 打印实际输入,对比AI假设 | 明确输入格式或加数据校验 |
| 多轮对话后AI违反约束 | 上下文遗忘 | 检查最近几轮对话 | 重复声明关键约束 |
| 小数据正常大数据卡死 | 性能陷阱 | 问AI复杂度,或实测大数据 | 加性能要求,优化算法 |
| 测试环境正常生产报错 | 环境差异 | 对比环境配置和数据 | 明确环境要求,加兼容处理 |
| AI反复犯同一个错 | 反馈不够具体 | 检查反馈内容 | 给出具体错误示例和期望结果 |
提示:这张表里的"解决思路"不是让你自己动手改,而是让你知道该给AI什么反馈。记住,你的角色是"判断和指导",不是"代劳"。
6. 我踩过的坑和总结出的经验
6.1 不要相信"AI一次就能写对"
这是我最早踩的坑。刚开始用AI写代码时,它给什么我用什么,结果就是各种隐藏问题在后期爆发。后来我养成了一个习惯:不管AI的代码看起来多完美,我都要走一遍审查流程。这个习惯救了我很多次。有一次AI写的一个数据校验函数,逻辑看起来天衣无缝,但我审查时发现它在处理"空字符串"时返回了True(表示校验通过),而业务上空字符串应该是不合法的。这种问题不审查根本发现不了。
6.2 拆解粒度比提示词技巧更重要
我花了很多时间研究提示词技巧,后来发现效果提升有限。真正带来质变的是"拆解粒度"。同一个任务,拆成三个子任务分别让AI做,和一次性让AI做,质量差距是巨大的。原因是AI在处理复杂任务时,注意力会被分散,每个部分都做得"差不多"但都不够好。拆开之后,每个子任务AI都能集中精力做好。
6.3 建立自己的"提示词模板库"
我把自己常用的提示词结构整理成了几个模板,比如"算法实现模板"、"数据处理模板"、"测试生成模板"。每次遇到类似任务,直接套模板改内容,效率很高。模板的价值在于它把"想清楚要什么"这个过程标准化了,减少了每次从零开始思考的成本。
6.4 定期回顾AI犯过的错
我有个习惯是每周花半小时回顾这周AI犯过的错,把它们分类整理。比如"边界处理遗漏"、"性能陷阱"、"接口不一致"这几类是我遇到最多的。整理之后,我会在后续的提示词里针对性地加上预防措施。这个习惯让我的AI协作效率在两个月内提升了一倍多。
6.5 不要用AI替代思考
这是最重要的一条。AI可以帮你写代码、查bug、生成测试,但它不能替你想清楚"要做什么"和"为什么这么做"。我见过一些人,用AI用得很溜,但项目做得一塌糊涂,因为他们把思考也外包给了AI。AI是一个执行力极强的助手,但方向必须你来定。方向错了,执行越快错得越远。
7. 这套方法论的适用边界
说了这么多好处,也得说说它不适用的情况。第一,探索性任务不适合。比如你要研究一个全新的算法或者做一个技术选型调研,这种任务没有明确的输入输出,AI帮不上太多忙,反而可能给你一堆看似合理但实际没用的建议。第二,高度依赖领域知识的任务要谨慎。比如涉及特定行业规范、内部系统细节的任务,AI缺乏这些背景知识,生成的代码可能"技术上正确但业务上错误"。第三,安全敏感的任务要格外小心。AI生成的代码可能包含安全漏洞,比如SQL注入、路径穿越这些,必须经过严格的安全审查。
我自己的判断标准是:如果一个任务我能用几句话把验收标准说清楚,且不涉及敏感信息,就可以放心交给AI;如果验收标准需要大量背景知识才能理解,或者涉及安全、合规,那就自己来或者只让AI做辅助。
8. 后续可以怎么扩展
这套方法论本身也在进化。我最近在尝试的方向是把"代码审查"这一步也部分自动化。具体做法是写一些检查脚本,自动检查AI生成的代码是否符合我的约束(比如有没有用第三方库、有没有类型注解、复杂度是否超标)。这样我只需要审查那些脚本检查通过的部分,效率又能提升一截。
另一个方向是建立"项目知识库"。把项目的架构、接口、约定整理成文档,每次让AI做任务时把相关部分作为上下文传给它。这样AI生成的代码会更贴合项目实际,减少集成时的问题。这个方向我还在摸索,目前的效果是集成问题减少了大概三成,但维护知识库本身也需要成本,需要找到平衡点。
还有一个我觉得很有潜力的方向是"AI结对"。不是让AI单方面生成代码,而是让它扮演一个"审查者"的角色,我写代码它来审。我试过几次,AI在发现边界问题和性能隐患方面确实有一套,有时候能指出我自己都没注意到的问题。这个模式可能更适合有一定经验的开发者,因为你需要有能力判断AI的审查意见对不对。
最后分享一个我最近才想明白的点:AI时代的软件工程,核心能力不是"会用AI",而是"知道什么时候不用AI"。工具越强,判断力越值钱。这个判断力来自对业务的深入理解、对系统的全局把握、对风险的敏感度,这些东西AI给不了你,只能自己积累。所以别把时间都花在学AI工具上,留一部分给那些"AI替代不了"的能力,那才是你的护城河。