让 GPT-4 修改文件,真的太难了!

作者 | Kevin Lu
译者| 弯月
出品 | CSDN(ID:CSDNnews)
自 GPT-4 发布以来,我们一直在尝试让其修改长篇的代码文件 。尽管它在解决复杂问题或从零开始创建复杂系统方面表现出色,但在向一个 200 行代码的 Flask 服务器中插入日志时,它却举步维艰 。然而,显然后者更为实用 。
我们经常听到的一种抱怨是:“ChatGPT 可以完成这项任务,但你们的 Sweep.AI 却不能” 。这是因为 GPT-4 并不能一致地编辑长篇文件,它往往会在中途写入“#Rest of the code”,或错误地复制一段代码,而使用ChatGPT的人类可以轻松解决这个算法无法解决的问题 。因此 , 我们不能简单地通过从头开始重写文件的方式来修改文件 。
以下是我们做过的所有让 GPT-4 修改文件的尝试 , 以及由于 GPT-4 未能正确格式化或计数而导致的成功和失败 。

让 GPT-4 修改文件,真的太难了!

文章插图
版本 0:简单地重写整个文件
如前所述,完全重写文件存在两个主要问题:
1、对于超过 50 行的文件,GPT-4 最终会生成类似“#Rest of the code”的内容 。
2、文件太长 。拥有 k 个令牌的文件将需要 k 个输入令牌和 k 个输出令牌 。
3、GPT-4 会错误地复制代码 。它有时会删除或添加额外的注释或空白,或更改缩进 。
我们来看一个如何解决第一个问题的示例 。
在本文中,我将使用以下简短的 Flask 服务器实现作为我们正在编辑的文件的示例 。出于简洁考虑,我选择了一个简短的示例,因此对于这个特定示例,GPT-4 也许不会出现这些错误,但在较大的文件中经常会出现类似的错误 。
让 GPT-4 修改文件,真的太难了!

文章插图
要求 GPT-4 添加日志,我们可能会得到以下内容:
让 GPT-4 修改文件,真的太难了!

文章插图
显然,我们不能仅凭这段代码创建拉取请求(PR)!我们必须撤销所有“#Rest of the code”的修改 。
版本 1:使用 difflib 修复“rest of the code”救命稻草 difflib
最简单的解决方案似乎是检查两个文件的差异 , 并回滚所有带有“Rest of the code”、“Remaining of the code”的部分 。
上面示例的差异如下所示:
让 GPT-4 修改文件,真的太难了!

文章插图
现在 , 我们只需撤销每个删除后面带一个形如 + # Rest of test 注释的部分 。具体来说,我们使用以下方法检查这些注释:
在这个示例中,它解决了问题:我们最终得到了我们所期望的结果,即在每个函数的开头有一个打印语句 。
限制
不幸的是,这个差异回滚系统的能力仍然相当有限 。首先,有时 GPT-4 会写下诸如“More unti tests here”,“Complete the implementation”,“...”等注释,有无限多可能 。其次,有些情况下,差异算法无法找到具体应当被替换的行 。
例如,让我们要求 GPT-4 添加一个删除端点,它的回应是:
让 GPT-4 修改文件,真的太难了!

文章插图
但差异算法返回的内容如下:
让 GPT-4 修改文件,真的太难了!

文章插图
回滚该差异只会产生:
让 GPT-4 修改文件,真的太难了!

文章插图
显然,这完全不是我们所期望的 。在 Sweep.AI 的最初几周中,由于这个问题,Sweep 会随机删除大段的代码 。
也许我们可以编写一个更智能的差异算法来捕捉这些讨厌的“Rest of code”注释 。但即使如此 , 从算法角度来看,也不可能确定GPT-4的意图是要删除一切并添加新的 delete_task 端点,还是要将 update_task 端点替换为 delete_task 端点 。
根本的问题在于 , 我们无法确定# Rest of code的意思是替换直到 update_task 的所有代码,还是仅仅是替换 create_task 端点 。我们需要不同的输入 。我们需要让 GPT-4 指出每个替换和修改标签的覆盖范围 。
版本 2:以行为单位修改或复制思路
如果可以让 GPT-4 编写一组具体的替换说明,我们就可以用新代码进行替换 。最初,我们采用了以下格式:
这段指令的意思是使用新的代码替换从 i(包含)到 j(不包含)的行 。
通常,我们更喜欢从 GPT-4 获得基于 XML 的响应,因为它们: