如何打造你自己的 AI 软件工程师(像 Devin 那样)
扩展 DeepSeek 的强化学习蓝图路线到AI的其他方面
Nikhil Anand

图片由GPT-4o生成
“AI 软件工程师”这个概念,其实已经不再遥远了。已经有一些技术在逐步让软件工程这件事变得越来越简单。• Devin,被宣传为世界上第一个 AI 软件工程师,是去年推出的。• Cursor,是个 VS Code 的替代方案,在做项目时能更方便接入 AI,最近越来越受欢迎。• 类似 Claude 和 GPT-4 这样的 LLM,可以帮你写代码、修代码。随着越来越多的人在研究 LLM 的推理能力,事情只会变得越来越容易。
AI 软件工程师 vs 普通 LLM
普通的 LLM 也能写代码,那它跟 AI 软件工程师有什么区别?那我们就得更精确地定义一下这些术语了:AI 软件工程师,是一种 AI 助手,它能查看一个 Git 仓库中的多个代码文件,并且根据它要执行的具体任务,判断需要修改哪些文件。比如说,你有一个 AI 项目的仓库,你需要修一个 bug——每次用户选择 Mistral 模型时,AI 助手加载失败。

作为一名软件工程师,你得找到包含这个 bug 的文件,并且修复它。(作者提供图片)
作为一名软件工程师,你首先得搞清楚要修改哪个代码文件才能修这个 bug。举个例子,你可能会去看看模型加载的那个文件,看看问题是不是出在那里。如果涉及的变量或函数是从别的文件导入的,你也得翻一翻那些文件,看看问题是不是从那里来的。一个普通的 LLM 解决不了这个问题,因为我们在提问的时候,没法把所有的文件都扔进 LLM 里。我们可能得自己先找好文件,再把它丢给 LLM 让它修 bug。

我在让 Claude 修某个代码文件里的 bug。(作者提供图片)
那我们怎么定义 AI 软件工程师呢?AI 软件工程师,就像普通的软件工程师一样,会通过不断地提交 PR(pull requests)来修复代码中的某些方面。比如我们想打造一个推理能力更强的 AI 助手,第一个 PR 可能是建立 AI 助手的基本框架,第二个 PR 是设置训练流程,以此类推。

每个 PR 就是一个对代码库的扩展提交。(作者提供图片)
AI 助手需要一个个顺着写这些 PR,要么自己写,要么在用户引导下完成。

AI 软件工程师在执行用户/老板提供的任务时可能会做的事。(作者提供图片)
怎么打造一个 AI 软件工程师(SWE)?
最近 DeepSeek 模型出来后,很多人可能都在想——LLM 能不能用强化学习(RL)来学会如何成为更好的软件工程师?我前不久写了一篇博客,讲 RL 训练技术有多强大,如果你还没看,建议去看看。
RL 的强大之处就在于:LLM 不用我们手把手教,也能自己学会解决问题。那我们能不能把它应用到软件工程任务上呢?
我们先来定义一下这个任务。
任务目标
我们的目标是让 AI 助手像软件工程师一样,给定仓库当前的状态和待完成的任务,自动在仓库里做出所需的修改。
如何训练 AI 成为一个 SWE
要让 AI 做到这一点,我们会用 DeepSeek 用来提升推理能力的同一个 RL 训练流程。RL 是个很强的通用技术。意思就是说,在一个场景下用它(比如提升推理),也能让它在其他场景下表现得更好。所以 DeepSeek 做的那些训练,可能也能提升 AI 在软件工程任务上的表现。但如果我们用一些专门的软件工程示例去教它,会不会效果更好?
要做到这点,第一步就是得收集一些数据,用来训练 LLM。
数据收集
为了训练 LLM,我们需要收集一些能教它在以下条件下该做出哪些修改的数据:
当前代码的状态,以及
需要被修改的函数。
那这些信息我们去哪儿找呢?
Git PR。
Git PR(Pull Request)本质上是一个提议,想把一组变更从一个分支合并到另一个分支。当你在用 GitHub 做项目时,你通常会对仓库做一些修改,然后用一条提交信息(commit message)把这些改动提交上去,说明你完成了什么任务。之后你会拉一下仓库的当前状态,然后把你的改动合并进去。

随着仓库的逐步变化,我们可以看到它在 PR 发起前的演变过程。(作者提供图片)
所以,一个 pull request 就包含了我们需要的所有信息——仓库之前的状态、要完成的任务、以及为完成这个任务所做的修改。

一个 pull request(PR)中包含的所有信息。(作者提供图片)
所以,如果我们收集互联网上开源仓库里的几百万个 PR,我们就能拿到相当不错的一批信息,来教 LLM 在给定任务和旧代码状态的情况下如何修改代码。
提示 LLM
现在我们已经有了一套数据集,接下来我们要搞清楚的是,在训练过程中或在推理时,该怎么提示 LLM。
我们想要的是:给它旧的代码状态和要完成的任务,让它输出需要做出的代码修改。
但整个代码库没法全都上传,所以我们可能只提供两种类型的文件:
提交前后发生变化的文件
没变但可能相关的其他文件

比如 helpers.py 被修改了,那 test_helpers.py 可能就被认为是个相关文件。(作者提供图片)
我们可以用 LLM 来判断哪些“未变文件”是相关的,依据是文件名。这背后的想法是:LLM 不仅得知道要改哪些文件,还得知道哪些文件不能动。所以在训练中加入这个环节是非常重要的,这能帮它更好地学习。
定义奖励
说到具体的 RL 过程,那我们怎么定义“奖励”,才能激励 LLM 去学习呢?
我们会用一个简单的方法来定义奖励:衡量 LLM 输出的代码和 PR 中实际修改后的代码之间的差距。它们越相似,奖励就越高。

奖励是由预测出来的代码和期望的代码输出之间的差距决定的。(作者提供图片)
训练过程整体流程很简单:把每一个数据点传给 LLM,获取它的输出,然后把这个输出和实际应该输出的代码作对比,根据它们之间的相似度给予奖励。LLM 再根据这个奖励来调整它的策略,以优化整体表现。
那我们还能怎么提升这个过程呢?
课程式学习(Curriculum Learning)已经有研究表明,像训练学生一样,在 RL 训练过程中逐步提高任务难度,能让 LLM 学得更有效率。

随着训练的推进,我们逐步给 LLM 更难的任务。(作者提供图片)
现在我们是从 GitHub 上随机选了一些 PR,但我们其实可以按提交的“大小”排序来安排它们的训练顺序,比如,改动越少的 commit 可能就越容易推理。
当然我们也可以想别的办法,比如找一个更科学的指标,来判断每个 PR 推理难度的高低,然后按照从易到难的顺序排列数据集。
更干净的数据集与奖励函数数据集的“干净程度”是训练结束后提升 LLM 性能的主要瓶颈之一。DeepSeek 和其他研究者已经充分说明了这一点。
数据集:我们这套方法最大的问题之一就是,数据质量本身不受控。我们理想的情况是,PR 里都体现了“优秀的软件工程技能”,但如果我们是从网上随便抓 PR,这就不现实了。
奖励函数:如果某个问题有多种解法呢?LLM 采用的方式跟 PR 中代码的方式不一样,它就会被扣分,即便它的方法其实比原始方法还要好。这就是一个错误的信号,不能正确引导 LLM。
那有没有办法改进奖励函数和数据集呢?如果你们有什么好主意,欢迎留言!我今天就先讲到这儿
总结
AI 软件工程师这个概念,其实离我们并不远。而且,很可能很快就会开源,让全球的软件开发者都能轻松使用。
我们刚刚讲了一种可行的方法,用来构建一个 AI 软件工程师。这个过程还可以通过很多方式进一步优化。用 RL 来训练 LLM 还处在初期阶段,这个领域里还有很多“低垂的果实”,研究空间巨大。
我今年也打算正式进入这个领域,如果你也感兴趣,真心建议你也来探索看看。
如何打造你自己的 AI 软件工程师(像 Devin 那样)的更多相关文章
- [招聘] 上海耐斯特数字招聘3D图形软件工程师
公司介绍 上海耐斯特数字科技有限公司成立于2018年9月,致力于为中国原创动画.影视行业提供新一代核心技术解决方案和全流程技术服务.公司创始团队拥有国内外领先的行业背景与资源,在DCC软件开发方面具有 ...
- 连载《一个程序猿的生命周期》-《发展篇》 - 3.农民与软件工程师,农业与IT业
相关文章:随笔<一个程序猿的生命周期>- 逆潮流而动的“叛逆者” 15年前,依稀记得走出大山,进城求学的场景.尽管一路有父亲的陪伴,但是内心仍然畏惧.当父亲转身离去.准备回到 ...
- 1、软件工程师要阅读的书籍 - IT软件人员书籍系列文章
软件工程师要阅读的书籍估计是项目组内最多的.软件工程师处于项目组中最基础的人员储备阶层,与项目的关系最密切.当然,现在是大数据时代,我们无法全部看完所有相关的书籍,只能够先学习工作需要的知识,然后在项 ...
- [No00004D]深度思考好文:软件工程师的困境
昨天是我一同学结婚的好日子,同学们大家聊各自的工作,有个同学突然问了我一句:我们同学中好像做软件的不多?如果再细分,好像做网络相关的更少? 回想起当时为何读计算机信息管理的专业,是因为那时听说读电脑未 ...
- Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结
Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握常用的概念(ORM,IOC,AOP,event driv ...
- CEO应向软件工程师学习的7个技能
软件工程师的哪些技能是值得CEO学习的?显然,软件工程师是逻辑的,高效的,注重细节的,有计划的,并且大多数CEO也是如此.但是,软件工程师还有一些更微妙,甚至是令人懊恼的品质,那么CEO是否可以从中学 ...
- Google前工程经理王忻:如何准备软件工程师的面试
http://t.jobdu.com/thread-368-1-1.html 导读:原文作者王忻,Google前工程经理,2003年月加入Google,是Google Lively背后的主导力量,是G ...
- 转载:CEO应向软件工程师学习的7个技能
软件工程师的哪些技能是值得CEO学习的?显然,软件工程师是逻辑的,高效的,注重细节的,有计划的,并且大多数CEO也是如此.但是,软件工程师还有一些更微妙,甚至是令人懊恼的品质,那么CEO是否可以从中学 ...
- 软件工程师所需掌握的“终极技术”是什么?
软件工程师所需掌握的"终极技术"是什么? http://yunli.blog.51cto.com/831344/1019990 最近,我在微博上看到@程序员邹欣老师发的一条微博 - ...
- net软件工程师求职简历
Net软件工程师求职简历 姓 名: 王静静 性 别: 女 出生日期: 1991-12 籍 贯: 河北 居住地: 北京 学 历: 专科 E-mail: 335659753@qq. ...
随机推荐
- 即时通讯技术文集(第23期):IM安全相关文章(Part12) [共15篇]
为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第23 期. [- 1 -] 理论联系实际:一套典型的IM通信协议设计详解(含安全层设计) [链 ...
- 【Java 温故而知新系列】基础知识-03 基本类型对应之包装类
1.包装类都有哪些? 基本类型都有对应的包装类型,这些包装类提供了一种面向对象的方式来处理基本数据类型,允许它们被用于需要对象的场景,如集合框架.泛型等. 对应关系: 基本类型 包装类型 boolea ...
- [rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(01):为窗口设置布局(column、row)
前言 本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发. iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动. 本合集是基于新版本的关于分 ...
- .NET 依赖注入中的 Captive Dependency
大家好,上一篇我们分析了 .NET 依赖注入的默认行为,其实呢还没完全讲完.今天我先给大家出一道题: public interface IDbContext { } public class SqlS ...
- CDS标准视图:维护通知数据 I_PMNotifMaintenanceData
视图名称:维护通知数据 I_PMNotifMaintenanceData 视图类型:基础视图 视图代码: 点击查看代码 @EndUserText.label: 'Notification Mainte ...
- 第八章 (Nginx+Lua)流量复制/AB测试/协程
流量复制 在实际开发中经常涉及到项目的升级,而该升级不能简单的上线就完事了,需要验证该升级是否兼容老的上线,因此可能需要并行运行两个项目一段时间进行数据比对和校验,待没问题后再进行上线.这其实就需要进 ...
- 分圆多项式(cyclotomic polynomial)
最近论文中经常遇到分圆多项式,现在系统的学习一下! 本原单位根 之前介绍n次单位根,现在详细学习一下n次本原单位根(n-th primitive unit root) 一个复数是n次单位根,当且仅当具 ...
- 面试题:关于StringBuffer()源码的深度理解Debug分析
import org.junit.Test; /** * @author CH * @create 2021 上午 11:23 */ public class IDEADebug { @Test pu ...
- delphi编写sql脚本文件批量执行程序
程序使用DelphiXE11.1开发,用到控件UniDac9.1.1,QDAC里面的Qlog组件. 程序实现了SQL脚本文件批处理执行应用,运行效果图. 文件.pas代码 unit main; int ...
- 第15章 流与IO
第15章 流与IO 15.1 .NET 流的架构 .NET 流的架构主要包含三个概念:** 后台存储 . 装饰器 以及 流适配器 **,如图所示: C7.0 核心技术指南 第7版.pdf - p655 ...