您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center 汽车系统工程   模型库  
会员   
   
基于SysML和EA进行系统设计与建模
7月16-17日 深圳+线上
UAF架构体系与实践
7月23-24日 北京+线上
Spec Driven Development 工程化实践
7月28-29日 北京+线上
     
   
 订阅
软件工程的基本功,才是驯服 AI 的正确方式
 
作者:老徐
  3   次浏览      
 2026-7-14
 
编辑推荐:
文章通过 Matt Pocock 的工作坊内容,详细阐述了在和 AI(尤其是大语言模型)协作编程时遇到的五个常见痛点,并一一给出解决方案,希望对你的学习有帮助。
本文来自于徐道AI,由火龙果软件Alice编辑推荐。

所有人都说,AI 是一个全新的范式。它确实在改变很多事情。但真正能让人和 AI 协作得又快又稳的那些方法,几乎没有一个是新的。

越聊越蠢、写完才发现理解错了、垃圾输入导致垃圾输出、反馈总是来得太晚,这些问题,每个天天用 AI 写代码的人都遇到过。而解决这些问题的方法,其实就藏在多年前的软件工程书里。

这篇文章的内容来自 Matt Pocock 的一场工作坊视频。Matt Pocock 原本是教 TypeScript 的老师,这几年主要在教如何使用 AI 写代码。在这场两小时左右的工作坊里,他把核心观点总结成一句话:AI 不是新范式,和 AI 协作最管用的方法,是软件工程的基本功。

下面是他讲到的五个常见痛点,以及五个对应的、早就存在的解决办法,此外还有一个延伸的工作方式。

一、AI 越聊越蠢

跟 AI 聊得好好的,聊到一半,它突然开始犯低级错误。前面表现正常,后面质量明显下降。

这不是错觉,而是大语言模型的一个特性。这个现象可以描述为模型有一个「聪明区」和一个「愚蠢区」。每次往上下文里增加内容,模型内部需要处理的关系数量会以更快的速度增长,而不是简单的线性增长。因此上下文窗口越长,模型需要处理的内部关联就越复杂,计算负担也越重。

所以无论使用的是 200K 还是号称 1M 的上下文窗口,一旦上下文用到大约 100K 左右,或者填充到窗口容量的 40% 左右,模型的表现就会开始下降。

不过 Matt 也指出,超长上下文并非全无用处。对于从海量信息中检索或查找特定细节这类任务,比如从几部大部头著作里找出某个具体细节,超长上下文反而是合适的工具。但一旦涉及编程或复杂的逻辑推理,就应该把任务控制在「聪明区」范围内,也就是大致 100K token 左右,避免 AI 因为注意力过载而进入「愚蠢区」,做出错误的判断。

那么号称支持 1M 上下文的产品是做什么用的?Matt 的看法比较直接:这类产品实际上只是把更多的「愚蠢区」也卖给了用户。

解决模型越用越蠢这个问题的方法并不新鲜。Martin Fowler 在《重构》里提到过, 《程序员修炼之道》 里也提到过:不要一次性接手超出自己处理能力的任务。

这条建议原本是写给开发者本人的,提醒人不要因为任务过大而失去判断力。现在这个建议同样适用于和 AI 协作:把任务拆小,每次只让 AI 完成一件能在「聪明区」范围内处理好的事情。目前「聪明区」大致对应 100K 左右的上下文长度,这个范围以后会扩大,但目前还没有扩大。

二、和 AI 的理解对不齐

另一个更隐蔽的问题是:AI 写了很多内容,回头一看,跟原本想要的完全是两回事。

很多人认为问题出在需求文档写得不够清楚,于是这两年出现了一种做法:先写好详细的需求文档,交给 AI 生成代码;代码有问题,就不看代码本身,而是回去修改需求文档,再重新生成一次。

Matt 尝试过这种方法,结论是行不通。因为这种做法本质上还是让 AI 随意发挥,只是把关注点从代码转移到了文档上。而代码才是真正需要检验的地方,忽视代码本身,最终还是会遇到同样的问题。

那么真正缺少的是什么?《人月神话》的作者弗雷德里克·布鲁克斯,在另一本书《设计的设计》里提到过一个概念,叫做「设计概念」:指的是一群人共同做一件事时,彼此之间对「我们究竟在做什么」形成的共同理解。人和 AI 之间缺少的,正是这种共同理解,而不是一份文档。

Matt 的做法是使用一个叫做「Grill Me」的 Skill:让 AI 像面试官一样,每次只问一个问题,持续追问,直到双方在理解上完全一致。每个问题它还会附带一个建议答案,用户只需要确认或者修正就可以。

效果很明显。他要给课程平台增加一个积分系统,需求方 Sarah 在 Slack 上只说了一句话:留存率不好,加一些游戏化的元素。把这句话交给 Grill Me 之后,AI 连续提出了一系列问题:积分要不要追溯到历史课程?连续打卡是否计分?进度类的事件比较嘈杂、容易被刷分,是否要排除在外?

这些问题,Sarah 之前没有想过,Matt 自己一开始也没有想到。但每一个问题,都直接决定了这个功能最终做出来是好用还是不好用。

一次完整的追问过程,可能会问四五十个问题,持续一个小时左右。但问完之后,人和 AI 就对齐了。

追问结束后,AI 会把达成的共识整理成一份产品需求文档,但 Matt 并不会去看这份文档。这不是因为偷懒,而是他认为这一步没有必要:既然已经和 AI 对齐了理解,再去读文档,实际上只是在检验 AI 会不会写总结,而这恰好是 AI 最擅长的事情。他真正需要的是理解上的一致,而不是一份文档。

三、AI 按层写代码,反馈来得太晚

对齐完成后,开始写代码,下一个问题随之出现。

AI 有一个比较固定的习惯:按层来写代码。先把数据库全部建好,再把 API 全部写完,最后才处理前端部分。

这个顺序听起来很有条理,但实际上存在问题。等到终于看到一个可以操作的页面时,前面三个阶段已经全部完成了。而在此之前,是否跑得通没有任何反馈,AI 实际上是在没有验证的情况下持续写代码。

对应的老方法叫做 垂直切片 ,《程序员修炼之道》里称之为曳光弹。这个说法来自一个军事上的做法:夜间用高射炮射击飞机,普通子弹飞出去看不见轨迹,不知道是否打中目标,于是每隔几发子弹里掺入一发带有磷的 曳光弹 ,飞行轨迹可以被看见,从而据此调整射击方向。

写代码也是类似的道理。不要一层一层横向地铺开,而是要竖着切一刀:从数据库到 API 再到前端,做出一个功能范围很小,但从头到尾都能跑通的部分。

第一个切片完成之后,就能拿到实际的反馈,后续的开发工作也可以在这个已经验证过的基础上继续添加内容。

只有切片还不够,Matt 会把这些切片组织成一个看板:每个切片是一张可以独立认领的任务,并且标注清楚彼此之间的先后依赖关系。这样,一份原本线性排列的待办清单,就变成了一个有向无环图,能够并行处理的部分就并行处理,不需要等待的部分就先推进。

之所以用看板而不是一份线性的多阶段计划,是因为线性计划只能由一个人从头做到尾,而看板可以同时分配给多个 AI 智能体并行处理。

四、AI 写的测试存在问题

切片可以跑通了,但如何确认它是正确的?

很多人会让 AI 顺便把测试也写了,结果发现:AI 写的测试要么覆盖了一些无关紧要的边缘情况,要么为了让测试能够通过,把测试本身写得没有实际意义,测试失去了检验作用。

问题的根源还是那个「按层来写」的习惯:AI 先把整个实现写完,再回头补一层测试盖在上面。实现在先,测试在后,这样的测试自然可以被随意处理。

对应的方法是把顺序倒过来,采用测试驱动开发,也就是 红-绿-重构 的流程。先写一个必然会失败的测试,确认它确实是失败的,再去编写让它通过的实现代码。让 AI 先确定代码结构、再填充具体实现,可以避免测试被敷衍对待,因为在写代码之前,测试已经先一步规定好了代码应该达到的效果。

不过测试驱动开发只是解决问题的一个方面。真正决定 AI 输出质量上限的,是另一个更基本的原则:反馈循环的质量,决定了 AI 输出质量的上限。

AI 有没有运行测试、类型检查是否严格、报错信息是否清晰,这些因素直接决定了它能否写出可靠的代码。如果代码库本身缺乏良好的反馈机制,AI 写出来的代码质量就会很差。很多时候,代码质量不高的原因并不在于提示词写得不好,而在于代码库本身没有给 AI 提供足够的反馈信息。较差的代码库,会训练出较差的 AI 智能体。

五、模块设计得太浅,AI 和人都会迷路

有些代码库,AI 一旦介入就容易出问题,写出的代码总是偏离预期。与此同时还有另一个现象:用 AI 用得越多,对自己代码库的熟悉程度反而越低。以前每一行代码都是自己写的,现在大部分代码都没有亲自看过。

这两个现象,其实源于同一个问题:模块的组织方式不合理。

斯坦福大学教授约翰·奥斯特霍特在《软件设计哲学》中,把模块分成两种类型。

第一种是浅层模块:文件数量多而且体积小,每个模块只对外提供很少的功能,模块之间的依赖关系错综复杂。AI 在这样的代码库里,仅仅理清各个模块之间的依赖关系就要花费大量精力,测试的边界也很难划定,每个小函数是单独测试,还是把一组函数放在一起测试,如何模拟依赖对象,都成为问题。

第二种是深层模块:对外的接口很小且稳定,内部包含了大量的具体功能。AI 只需要理解这个较小的接口,就能够调用其中大量的能力,测试也相对容易,沿着接口的边界划定测试范围,就可以一次性覆盖内部大量的逻辑。

如果不主动干预,AI 在编写代码时会倾向于生成前一种浅层且分散的结构,代码库的组织方式也就完全交给了 AI 来决定。

针对这个问题,Matt 的做法是:自己负责设计模块的接口,把具体实现交给 AI 完成。

这样一来,每个模块对使用者来说变成了一种介于黑盒和白盒之间的状态:清楚它应该完成什么功能、在什么条件下会有什么样的表现,但不需要了解内部每一行代码具体是怎么写的。这样既保留了对整个代码库结构的掌控,又不需要逐行审查每一个实现细节。这也是这场工作坊中比较关键的一个观点:不应该让 AI 决定代码库的组织结构,这部分应该由人来把控。

延伸:把人从具体实现工作中解放出来

到这一步,已经可以写出比较可靠、效率也比较高的代码了。但 Matt 的分享还有一个延伸的部分。

他把所有的工作任务分成两类:需要有人参与的,以及可以离开人、由 AI 独立完成的。

对齐理解、做出关键决策,这些环节必须有人参与,包括本人、领域专家、同事以及 AI,共同讨论确定。

而具体的实现工作,可以改造成完全由 AI 独立完成的任务。

具体的做法是:清空上下文,把看板上所有的任务都提供给 AI,让它自己从中挑选下一个要做的任务,按照测试驱动的方式实现,运行测试和类型检查,完成后提交代码。做完一个任务之后,再挑选下一个,如此循环。

这就是 Matt 所说的循环工作方式。其中一个关键细节是:AI 写完代码之后,需要清空上下文再进行审查。原因在于,如果刚写完代码、上下文还处于比较满的状态,这时候进行审查,实际上是在「愚蠢区」里审查自己刚写的代码,审查者的判断力反而比写代码时更差。清空上下文之后,审查工作可以回到「聪明区」进行。

整个流程可以理解为分成两班:白天由人来做计划、对齐理解、拆分看板任务、调整代码结构,把工作准备好;晚上由 AI 独立完成具体实现。第二天人回来查看代码、进行质量检查,把新的想法整理成看板上的新任务,如此循环。

贯穿整个过程中,Matt 反复强调一点:要保持对整体流程的掌控,也就是控制反转。工具会不断更新,框架会不断更换,今天认为最优的方案,明天可能就会过时。因此不应该把整条工作链路完全依赖于某一个封闭的产品。整个技术方案,应该是自己能够理解、也能够修改的,否则一旦出现问题,只能说这个东西不好用,却不知道该如何解决。

写在最后

这些问题背后,有一个共同的结论:解决 AI 使用中各种问题的方法,基本上都是早已存在的方法。

拆小任务、建立共同理解、垂直切片、测试驱动开发、深层模块、反馈循环、控制反转,这些概念都不是专门为 AI 而发明的,而是软件工程中原本就存在的基本方法。

AI 提高了这些基本方法的价值。以前把模块设计得比较深,是为了方便同事维护代码;现在把模块设计得比较深,是为了让 AI 少出错。以前写测试,是为了防止代码出现回归问题;现在写测试,也是为了给 AI 的输出质量设定一个上限。这些原本就存在的方法,在使用 AI 的过程中,发挥了更大的作用。

Matt 给出的一个具体建议是:找一些相关的、出版时间比较久的书来读,比如《程序员修炼之道》、《软件设计哲学》、《设计的设计》。重新读一读这些内容,会发现里面很多方法,今天用在 AI 身上依然适用。

最值得关注的方法,往往不在最新的框架里,而是在这些已经存在了一段时间的、比较基础的做法当中。软件工程的基本功,才是驯服 AI 的正确方式。

   
3   次浏览       
相关文章

基于图卷积网络的图深度学习
自动驾驶中的3D目标检测
工业机器人控制系统架构介绍
项目实战:如何构建知识图谱
 
相关文档

5G人工智能物联网的典型应用
深度学习在自动驾驶中的应用
图神经网络在交叉学科领域的应用研究
无人机系统原理
相关课程

人工智能、机器学习&TensorFlow
机器人软件开发技术
人工智能,机器学习和深度学习
图像处理算法方法与实践

最新活动计划
UAF架构体系与实践 7-23[北京]
SysML和EA系统设计与建模 7-16[深圳]
Spec 驱动开发(SDD)实战 7-28[北京]
AI辅助软件测试方法与实践 7-31[在线]
AI智能体开发技术实践 8-6[上海]
基于UML和EA系统分析设计 8-20[上海]
 
 
最新文章
AIGC技术与应用全解析
详解知识图谱的构建全流程
大模型升级与设计之道
自动驾驶和辅助驾驶系统
ROS机器人操作系统底层原理
最新课程
人工智能,机器学习和深度学习
人工智能与机器学习应用实战
人工智能-图像处理和识别
人工智能、机器学习& TensorFlow+Keras框架实践
人工智能+Python+大数据
成功案例
某综合性科研机构 人工智能与机器学习
某银行 人工智能+Python+大数据
北京 人工智能、机器学习& TensorFlow
某领先数字地图提供商 Python数据分析
中国移动 人工智能、机器学习和深度学习