如何使用开发容器为ChatGPT启用GitHub Codespaces?

如何使用开发容器为ChatGPT启用GitHub Codespaces?

OpenAI最近推出了一项名为ChatGPT插件的测试功能。从本质上讲,这项功能使第三方工具能够与GPT模型互动。为了帮助开发者为ChatGPT创建自己的插件,OpenAI推出了一个快速入门库作为指南。为了进一步提高可访问性,OpenAI的开发者倡导者Logan Kilpatrick联系了使用基于浏览器或基于云的集成开发环境(IDE)的技术专家。Logan的目标是使开发者能够在本地或使用基于浏览器的IDE(如CodeSandbox和Replit)使用快速启动库。这样一来,开发者可以直接在他们的浏览器中构建和试验插件,而不需要克隆资源库。幸运的是,名单上的一个基于云的环境是GitHub Codespaces。Logan向我提出了他的目标,我很兴奋地接受了这个挑战。

我对将GitHub Codespaces加入快速启动仓库感到兴奋,有三个主要原因:

  • 我将获得ChatGPT插件的使用权,我想这些插件的等待名单是永无止境的。
  • 我将获得在不熟悉的环境中配置GitHub Codespaces的经验。我对GitHub Codespaces的经验只限于基于JavaScript的项目。
  • 我是个书呆子。

上周,我正式提交了一个拉取请求,为项目启用GitHub Codespaces。Codespaces团队已经审查了它,我现在正在等待OpenAI团队做同样的事情。同时,我将分享我在整个经历中所学到的东西,希望你也能更多地了解GitHub Codespaces!

先决条件:

这不一定是一个你应该一步步遵循的教程,但如果你确实想遵循它,你将需要获得以下工具。

  • ChatGPT账户
  • ChatGPT插件
  • GitHub账户
  • 了解GitHub Codespaces的目的可能会有帮助。你可以从我之前的博文中了解它。

GitHub Codespaces的简短总结

GitHub Codespaces允许你在托管在云端的容器中进行编码。这有助于开发人员更快地上岗,在任何设备上编码,并在一个一致的环境中编码。我认为这个特定的ChatGPT快速入门插件库的最大好处是,开发人员可以尝试插件的功能,而不需要在本地克隆项目或运行任何设置脚本的麻烦。他们可以在不切换上下文和不离开GitHub的情况下进行尝试。最重要的是,他们不需要做任何设置。注意:你可以在GitHub Codespaces中打开任何项目。GitHub Codespaces的用户界面可以类似于你最喜欢的IDE–比如Visual Studio Code或JetBrains,但它只是在你的浏览器中。你还可以配置GitHub Codespaces来安装所有的依赖项并运行项目,以减少开发者开始工作的时间。

下面是我在为这个项目设置GitHub Codespaces时采取的步骤和学到的经验:

Step 1: 让项目在本地运行

在配置GitHub Codespaces之前,我需要回答的第一个问题是: _这个项目是如何工作的?最终的结果是什么?_

我按照仓库的 README.md 中的本地设置说明找到了答案。说明很简单:安装所需的软件包,然后运行该项目。随后,服务器将在本地的 localhost:5003 上运行。

在ChatGPT中,我选择了 “develop your own plugin” 选项。

安装ChatGPT插件

按照指示,我向ChatGPT提供了服务器运行的本地地址 – localhost:5003。

本地地址 - localhost:5003

经过这一切,我能够利用这个插件,用ChatGPT创建一个简单的待办事项清单。

用ChatGPT创建一个简单的待办事项清单

如果你想试试,请查看这里的README。

在整个过程中,我注意到这个项目没有前端,所以我只有一个目标–当任何人在代码空间中打开这个项目时,服务器应该运行。

Step 2: 在GitHub代码空间中打开存储库

这一步可以确保我所做的任何改动都与 GitHub Codespaces 实际兼容。仓库中的代码可以在 GitHub Codespaces 中直接访问,但如果没有配置,它就不会开始运行我的项目或安装依赖。因此,下一步是添加一个名为devcontainer.json的配置文件。

Step 3: 添加一个开发容器

开发容器,俗称dev容器,是Docker容器,为项目设置了一个定制环境。我可以用一个dev容器来自动:

  • 安装必要的扩展
  • 参考环境变量
  • 转发端口
  • 安装依赖项
  • 运行我的项目
  • 运行脚本
  • 还有更多

你可以通过打开Visual Studio Code命令面板添加一个默认的开发容器。这个默认的配置文件包含了你需要的基本项目,以使项目运行。要打开Visual Studio Code命令调色板,使用以下键盘快捷键:(Shift+Command+P / Ctrl+Shift+P)。然后,搜索 “Add dev container configuration files” 的选项。

搜索 "Add dev container configuration files" 的选项

它将提示你指定项目的语言,因为每个开发容器都略有不同,取决于语言、框架、版本和其他环境因素。在这个案例中,该项目是基于Python的,所以我们会选择Python。

Python

不幸的是,我没有听从建议,通过命令调板添加开发容器。相反,在我的项目的根部,我创建了一个名为.devcontainer的文件夹。在该文件夹中,我创建了一个名为devcontainer.json的文件。我从一个过去的 Python 项目中复制并粘贴了一个开发容器到 devcontainer.json 中。我这样做是因为开发容器的例子包括如何利用postAttachCommand和postCreateCommand的例子。然而,这是一个很大的错误,我不建议这样做,因为我最后复制和粘贴了不同的行,我认为这是任意的,但它们影响了项目,我不得不删除这些行。

我的建议是使用命令调色板来添加一个赤裸裸的开发容器,然后再从那里进行定制。

下面是我们的模板devcontainer.json文件的样子:

我的建议是使用命令面板来添加一个原始的开发容器,然后从那里进行定制。

这是我们的模板 devcontainer.json 文件的样子:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

Step 4: 定制开发容器

在这一点上,版本库现在有一个开发容器,但它仍然不运行或安装任何东西,因为这个开发容器只是模板,它对我的项目需要自动运行的东西一无所知。

安装依赖项

基于本地的设置,这个项目的第一步是通过运行这个命令来安装依赖项:

pip install -r requirements.txt

我需要让GitHub Codespaces运行这个命令,这样开发者就不必手动运行它了。我在 postCreateCommand 中加入了这一行。 postCreateCommand 负责在容器被创建后运行命令。这一行看起来像这样:

postCreateCommand: pip install -r requirements.txt

所以现在,我的开发容器看起来像这样:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements.txt",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

端口转发

在dev容器中,有一个选项可以定义一个容器在本地可用的端口列表。从本地设置中,我看到首选端口是 localhost:5003,所以我把它添加到 devcontainer.json 文件中的 forwardedPorts 数组中。

下面是这一行的样子:

"forwardPorts": [5003],

下面是我的 devcontainer.json 文件的样子:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [5003],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements.txt",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

运行项目

要在本地运行项目,开发者必须手动运行:python main.py,但我希望GitHub Codespaces能代替它。我在devcontainer.json文件中使用postAttachCommand属性来运行这个命令。

postAttachCommand使脚本在客户端连接到代码空间后在终端运行。这是我添加的一行:

"postAttachCommand": “python main.py”

下面是我的 devcontainer.json 文件的样子:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [5003],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements.txt",
“postAttachCommand”: “python main.py”
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

Step 5: 通过重建容器进行测试

我对我的开发容器做了所有这些改变,但我需要检查它是否真的能工作,所以我通过Visual Studio Code命令调色板重建了我的容器,并选择了 “Rebuild container” 的选项。

Rebuild container" 的选项

重建完成后,我看到Codespace自动安装了所需的软件包,并在localhost:5003上运行服务器。它还为我把端口转发到一个随机生成的URL上,看起来像是这样的:

https://USERNAME-CODESPACE-NAME-vrpqrxxrx7x2rxx-5003.preview.app.github.dev

我把随机生成的URL复制并粘贴到ChatGPT中,但我收到错误信息,说ChatGPT找不到清单文件,也无法安装该插件。

Step 6: 调试

端口可见性

我了解到,ChatGPT找不到清单的原因之一是我的转发端口是私有的,所以ChatGPT无法访问代码。幸运的是,我可以通过右键点击端口,将可见性从 “private” 切换到 “public”,手动改变端口可见性。

端口可见性

我检查了一下,看看是否有办法让GitHub Codespaces自动将这个端口设置为公共端口。然而,在我与GitHub Codespaces交谈后,我了解到没有简单的方法可以做到这一点,而且可能导致潜在的安全漏洞,所以我决定用户可以手动操作。

更新文件

我遇到的另一个问题是,有两个文件指定了URL localhost:5003。这些文件的名称是 openapi.yaml.known/ai-plugin.json 。然而,我的新URL是不同的。它现在类似于一个随机生成的URL,看起来像这样:https://USERNAME-CODESPACE-NAME-vrpqrxxrx7x2rxx-5003.preview.app.github.dev.

我觉得我陷入了僵局,我有两个选择:

  • 我可以让开发人员手动更新这些文件,以匹配他们新生成的端口。他们只需要按照README.md中的指示去做。我对这个方案的问题是,它让GitHub代码空间感觉很笨拙。用户已经需要更新端口的可见性,现在他们又要更新文件。(Boo, tomato, tomato, tomato)。我想把GitHub Codespaces表现得最好。
  • 或者我可以编辑源代码,把 localhost:5003 替换成 https://${CODESPACE_NAME}-5003.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}这样的文字。然而,这将破坏那些选择仍然在本地开发插件的开发者的体验。

我联系了Codespaces团队寻求帮助。他们建议我写一个脚本,如果在 Codespace 中打开版本库,动态更新这些特定文件中的 url。我写的脚本看起来像这样:

#!/bin/bash
set -e
# Determine the value of SITE_HOST based on whether the project is opened in a Codespace
if [ -n "$CODESPACE_NAME" ]; then
SITE_HOST="https://${CODESPACE_NAME}-5003.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}"
# Replace "localhost:5003" with the value of SITE_HOST in the ai-plugin.json file
sed -i "s#http://localhost:5003#${SITE_HOST}#g" .well-known/ai-plugin.json
# Replace "localhost:5003" with the value of SITE_HOST in the openapi.yaml file
sed -i "s#http://localhost:5003#${SITE_HOST}#g" openapi.yaml
fi

我没有让开发者手动运行这个脚本,而是通过在devcontainer.json文件中添加以下内容,使我的代码空间自动运行它:

"postAttachCommand": ".devcontainer/addcodespacename.sh && python main.py",

现在,在程序运行之前,代码空间将运行这个shell脚本并更新文件以使用正确的URL。

下面是我的devcontainer.json的样子:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [5003],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements.txt",
"postAttachCommand": ".devcontainer/addcodespacename.sh && python main.py",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

我重建了容器进行测试,一切都像预期的那样工作!

Step 7: 有利可图的东西

在创建代码空间后打开重要文件

这不是必须的,但我认为在代码空间创建后打开两个最重要的文件会很方便。因为这是一个新的项目,而且只是一个新的概念,我想让人们容易浏览这个项目。而我知道在 devcontainer.json 中有一个叫做 openFiles 的属性可以处理这个问题

下面是我添加的几行:

"customizations": {
"codespaces": {
"openFiles": [
".well-known/ai-plugin.json",
"openapi.yaml"
]
}
}
}

下面是我的 devcontainer.json 文件在这一点上的样子:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [5003],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements.txt",
"postAttachCommand": ".devcontainer/addcodespacename.sh && python main.py",
// Configure tool-specific properties.
"customizations": {
"codespaces": {
"openFiles": [
".well-known/ai-plugin.json",
"openapi.yaml"
]
}
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

Step 8: 清理

一切都在按我想要的方式工作,现在我只想清理任何未使用的属性和混乱的注释。

这就是我最终的devcontainer.json文件的样子:

// For format details, see https://aka.ms/devcontainer.json.
{
"name": "ChatGPT Quickstart Plugins",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11",
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
5003
],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements.txt",
"postAttachCommand": ".devcontainer/addcodespacename.sh && python main.py",
"customizations": {
"codespaces": {f
"openFiles": [
".well-known/ai-plugin.json",
"openapi.yaml"
]
}
}
}

下一步是什么?

我将等待OpenAI团队批准或建议对我的拉取请求进行修改。我很期待看到它被合并!我很乐意为开源项目贡献更多的开发容器,让那些想改善项目入职体验的人能够在GitHub代码空间内进行项目工作。(via Rizèl Scarlett

评论留言