cover

gpt-engineer 体验记录

本文记录了使用 gpt-engineer 开发一个简单的 Web 应用程序的经历,并在后文粗浅地解析了一下 gpt-engineer 的源码。

2024-02-15

是一个使用大模型自动开发应用程序的 LLM 应用,其官方仓库中介绍的功能是:

  • 使用自然语言定义软件功能;
  • 由 AI 自动编写和执行代码;
  • 提供反馈让 AI 进行改进。
heading

使用 gpt-engineer 创建一个应用程序

根据官方文档的说明,下面将使用 stable 版编

gpt-engineer
创建一个应用程序。
Python
版本为 3.10,使用
venv
gpt-engineer
创建一个虚拟环境并初始化相关文件。

mkdir gpt-engineer-sample cd gpt-engineer-sample python3 -m venv venv source venv/bin/activate python -m pip install gpt-engineer mkdir app touch app/prompt

完成初始化后,首先在

目录下编写对应用程序的要求:

使用 Next.js@14 实现一个 Web 应用程序,这个 Web 应用程序有以下 3 个页面: 1. 登录 2. 用户主页 3. 广场页 在“登录”页面中,用户需要: 1. 输入用户名 2. 输入密码 3. 点击登录 3.1 用户存在且密码匹配则跳转至“用户主页” 3.2 用户不存在或密码匹配失败则显示“登录失败”弹框 系统预置的用户为: 用户名:admin 密码:admin 在“用户主页”中,用户可以: 1. 上传新的图片 1.1 如果图片的名称中不包含“cat”,则弹框提示“图片名称中不包含 cat,请重新上传” 1.2 如果图片名称中包含“cat”则完成上传 2. 查看我上传的图片 2.1 以瀑布流的形式展示用户已经上传的图片,按照上传时间逆序排序 3. 退出登录 在“广场页”中,用户可以: 1. 查看所有用户上传的图片 1.1 以瀑布流的形式展示所有用户上传的图片,按照上传时间逆序排序
app/prompt

完成上述操作后,使用下面的脚本开始创建应用程序:

export OPENAI_API_KEY=<api-key> gpte app

gpt-engineer
创建过程中,会输出其思考过程及需要执行的操作,同意操作后即可开始创建项目。测试项目是使用 Next.js 框架开发,因此初始化时需要等待一段时间。创建完成后项目文件会写入到
app
目录中,使用
npm run dev
启动应用程序。

生成的代码中可能会存在一些细微的语法错误,比如缺少 import 语句,进行简单的修复后打开应用,发现生成的应用中没有添加任何的样式,但是

prompt
中的要求基本上都完成了。对于许多细节可以继续使用
gpt-engineer
improve 模式进行优化。

heading

使用 gpt-engineer 优化已有项目

如上所述,

gpt-engineer
能够生成可用的应用,但是仍有许多可以调整的地方。下面将说明使用
gpt-engineer
优化已有项目的方法。

首先创建一个文件夹用于保存用户 prompts:

mkdir app/.prompts mv app/prompt app/.prompts/prompt.0_init

然后创建一个新的 prompt 用于指导

gpt-engineer
如何优化:

touch app/prompt echo '在“用户主页”中,添加前往“广场”页的按钮' >> app/prompt

输入完成后使用下面的指令让

gpt-engineer
开始优化代码:

gpte app -i # -i 或 --improve

gpt-engineer
在开始优化前会在 shell 中使用 vim 显示一个文件选择器,在这个文件中会列出项目目录中的文件列表,需要通过修改此文件(取消文件前的注释 #)来选择需要优化的文件。完成后使用
:wq
保存并退出,然后
gpt-engineer
就会开始优化相关文件中的代码。

gpt-engineer
优化的结果中可能存在错误,在完成后需要检查并修复文件中的问题。由于
gpt-engineer
在修改文件前并不会进行备份,为了避免错误的修改导致的问题,在进行优化前最好还是手动将创建一次
git commit

示例项目迭代了 15 次 improve,虽然依旧不能算得上是一个完备的应用程序,但是基本功能也算是 OK。

heading

生成效果

在简单使用了一段时间后(约莫两个小时,模型是

gpt-4-1106-preview
,开销 0.9$),总的来说
gpt-engineer
的生成的应用程序的代码质量还算不错,至少没有明显的错误,并且要求的需求也完成了。结合 improve 模式进行迭代,开发体验尚可。只是依旧有以下几个问题需要注意:

  • 没有使用网络请求的能力,因此能够使用的知识完全依赖于 LLM,无法使用较新的技术;
  • 输出的代码大概率可用,但是还是会出现一些问题(缺少 import 语句、语法错误等),使用者还是需要具备一定的开发能力;
  • improve 前需要手动选择相关的文件,没有办法识别 import 语句并自动读取,因此如果项目复杂的话,还是需要手动确定需要调整的文件。
heading

gpt-engineer 源码分析

gpt-engineer 的源码算不上复杂,主流程非常简单:

  1. 解析参数;
  2. 初始化 LLM(model、azure_endpoint);
  3. 读取用户 prompt;
  4. 确定代码生成函数
  5. 确定代码执行函数
  6. 初始化 preprompts;
  7. 初始化
    DiskMemory
    DiskExecutionEnv
    CliAgent
  8. 执行
    agent.init
    (生成应用程序代码)或
    agent.improve
    (优化已有代码)
  9. 更新文件。

下面是一些核心概念的说明。

heading

代码生成函数

用于生成项目代码。根据启动时的参数,有以下三种生成方法:

heading

应用 ENTRYPOINT 文件

项目代码的入口文件。

生成方法:调用

方法生成,在该方法中使用
preprompts/entrypoint
和代码文件调用 LLM 生成入口文件。

执行方法:调用

执行代码入口文件。

heading

代码执行函数

该方法用于执行应用 ENTRYPOINT 文件。根据使用的参数不同有以下两种方式:

  • self_heal
    :使用
    -sh
    选项时使用此方法。该方法会读取 ENTRYPOINT 文件并尝试执行,如果执行失败则会将文件内容、执行的输出内容以及
    preprompts/file_format_fix
    整合为一条消息发送给 AI 以获取修复结果,并返回修复后的
    FilesDict
  • execute_entrypoint
    :直接执行 ENTRYPOINT 文件。
heading

代码优化函数

方法用于优化已有项目的代码的方法,在使用
-i
选项时会使用此方法。

该方法的执行步骤是使用

方法拼接
improve
PROMPT 和
philosophy
PROMPT 以生成系统 PROMPT,然后将使用
FileSelector
选中的文件的内容和用户 prompt 作为消息调用 LLM 获取优化意见,最后通过
overwrite_code_with_edits
方法覆写源文件。

heading

代码执行环境 DiskExecutionEnv

是一个在本地文件系统上运行代码并捕获执行输出的执行环境。其主要职责是通过子进程执行磁盘中的代码(ENTRYPOINT),并处理用户中断。

heading

上下文记忆 DiskMemory

时一个基于文件的键值存储,其中键对应于文件名,值对应于文件内容。该类实现了一个简易的支持 CRUD 的数据库。

heading

Preprompts 容器 PrepromptsHolder

用于加载并读取存储在磁盘上的预提示文本的容器。之所以需要该方法是为了方便通过
--use-custom-preprompts
使用自定义的 Preprompts

heading

临时文件存储 FileStore

用于管理临时目录中文件存储的模块。

heading

文件选择器 FileSelector

用于管理项目目录内文件选择和交互,提供了从终端交互式选择文件、保存选择以供以后使用,并与系统编辑器集成以直接修改文件的方法。

heading

CliAgent 智能体

管理使用 AI 模型进行代码生成和改进的生命周期。根据给定的提示协调生成新代码和改进现有代码,并利用记忆系统和执行环境进行处理。

在 Agent 实例中主要使用两个方法:

  • init
    方法:根据用户 prompt 创建一个项目。具体来说是使用代码生成函数生成项目代码,然后为项目创建 ENTRYPOINT 文件并执行 ENTRYPOINT。
  • improve
    方法:优化已有项目代码,内部操作仅为调用代码优化函数 improve 方法。