使用 Node.js + OPEN AI 实现一个自动生成图片项目

大家好,我是 ConardLi。

最近 ChatGPT 非常火,它是由 OpenAI 开发的一种大型语言模型,它可以通过学习大量文本来了解人类语言并生成文本,我身边的程序员们用过之后都觉得要失业了。。。

它背后的 OpenAI 是一家人工智能研究机构,在人工智能领域一直处于领先地位,它的目标是通过人工智能的研究来帮助人类,现在大火的伊隆·马斯克(Elon Musk)正是这家公司的创始人之一。

真有这么神么?为了验证一下,我们就让 ChatGPT 来帮我们实现一个基于 OPEN AI 的自动创建图片的项目,我们先看看做好之后的效果,让 AI 为它自己生成一个形象:

不得不说,这图片有点让人背后一凉的感觉...

接下来我们就从头开始吧,以下所有的代码均为在我的问题和引导下 ChatGPT 自动生成。

问题1:如何使用 Node.js 借助 OPEN API 的能力实现自动生成图片?

ChatGPT 的回答:


使用 Node.jsOPEN API 可以通过以下步骤实现自动生成图片:

首先,安装 Node.js 和必要的依赖包,如 openapi 库。可以使用以下命令完成安装:

代码语言:javascript
复制
npm install openapi

然后,创建一个 JavaScript 文件,并通过 require 命令引入 openapi 库。

接下来,可以使用 OPEN API 的图像生成功能,编写代码来生成图片。

最后,运行 JavaScript 文件,即可自动生成图片。

如果需要了解详细的步骤,可以查看 OPEN API 文档或者示例代码,以获取更多信息。


好,下面我们知道了他为 Node.js 开发者提供了一个 openainpm 包,接下来我们的项目里调用这个 npm 包就好了。

问题2:这个包大概怎么用?详细说说?

ChatGPT 的回答:


1.在 OPEN AI 网站上注册帐户,并获取 API 密钥。

在项目中安装必要的依赖包,如 openai 库。可以使用以下命令完成安装:

代码语言:javascript
复制
npm install openai

2.创建一个 JavaScript 文件,并通过 require 命令引入 openai 库。

3.设置 OPEN AI 密钥,可以通过以下方式完成:

代码语言:javascript
复制
const openai = require("openai");
openai.setApiKey("YOUR_API_KEY");

4.使用 OPEN AI 提供的方法调用 API,并传入必要的参数。例如,如果要使用 GPT-3 模型生成文本,可以使用以下代码:

代码语言:javascript
复制
openai.completions.create({
  model: "text-davinci-002",
  prompt: "Once upon a time",
  temperature: 0.5
}).then((response) => {
  // do something with the response
});

5.处理 API 的响应,例如将生成的文本保存到本地文件。


好,这里面有一个关键点是初始化 OPEN AI 时需要一个密钥,下面我们来问问它怎么获取这个密钥。‘

问题3:详细点说明在哪里获取密钥?

ChatGPT 的回答:


如果要在 OPEN AI 网站上注册帐户并获取 API 密钥,可以按照以下步骤操作:

  • 打开 OPEN AI 网站,在首页上方点击“Sign In”按钮。
  • 在弹出的登录页面中,点击“Create an account”链接。
  • 在新页面中,填写相关信息,完成注册。
  • 注册完成后,登录到帐户中,然后点击“API Keys”链接,即可获取 API 密钥。

好,我们下一步到 OPEN AI 注册一个账号,你可能会发现下面的提示:

这是因为 OPEN AI 暂时不在中国提供服务,所以国内的小伙伴想要使用还是有一定门槛的,你可能需要下面几个条件:

  • 访问国外网站(一定要选择海外节点)
  • 注册时开启一个无痕浏览器(因为 OPEN AI 可能会根据你本地缓存的信息判断你的国家)
  • 使用一个海外的邮箱账号进行注册(推荐 outlook,无需海外手机号验证,随便申请)
  • 使用一个海外手机号或者虚拟电话的平台进行验证(推荐 sms-activate,租个印度手机号只需要1块钱)

好,注册完成后我们就拥有了一个 OPEN AI 的密钥:

下面开始实现项目了,我们选择 koa 框架,向 ChatGPT 询问项目细节。

问题4:使用 koa 框架 + OPEN AI 来实现自动生成图片的项目

ChatGPT 的回答:


1.使用 koa 框架和 OPEN AI 实现自动生成图片的项目,可以按照以下步骤进行:

2.首先,安装 Node.js 和必要的依赖包,包括 koa 框架、openai 库和其他必要的包。可以使用以下命令完成安装:

代码语言:javascript
复制
npm install koa openai

3.然后,创建一个 JavaScript 文件,并通过 require 命令引入 koa 框架和 openai 库。

4.接下来,可以使用 koa 框架的中间件和路由功能,编写代码来实现服务器端的逻辑。

5.在服务器端代码中,设置 OPEN AI 的 API 密钥,并使用 openai 库提供的方法调用 API,生成图片。

6.最后,启动 Node.js 程序,即可通过浏览器或其他客户端访问服务器,实现自动生成图片的功能。


ChatGPT 告诉我们需要这六个步骤,但是没有告诉我们具体的代码怎么写,我们尝试继续追问:

问题5:列出第3步的详细代码

ChatGPT 的回答:


第三步,使用 koa 框架的中间件和路由功能,编写服务器端的逻辑。下面是一个简单的示例代码,它可以处理来自客户端的 POST 请求,并使用 openai 库生成图片:

代码语言:javascript
复制
const Koa = require("koa");
const openai = require("openai");

const app = new Koa();

// 设置 OPEN AI 的 API 密钥
openai.apiKey = "your-api-key";

// 定义中间件,用于处理请求和响应
app.use(async (ctx, next) => {
if (ctx.method === "POST") {
// 获取请求中的参数
const { model, prompt } = ctx.request.body;

// 使用 openai 库调用 API,生成图片
const response = await openai.completions.create({
  model,
  prompt,
  max_tokens: 2048,
  temperature: 0.5,
});

// 将生成的图片返回给客户端
ctx.body = response.data.complete;

}
});

// 启动服务器
app.listen(3000);


看过代码后我发现他调用了 openai.completions.create 方法,里面传入了四个参数,这些参数都是啥意思呢?再问问他吧:

问题6:completions.create 接收的四个参数的含义是什么

ChatGPT 的回答:


completions.createopenai 库提供的方法,它用于调用 OPEN AI 的 API,生成图片。该方法接收四个参数,分别是:

  • model:指定要使用的模型。OPEN AI 有多种模型可供选择,每种模型都具有不同的特点和功能。使用时需要根据需求和 API 文档选择适当的模型。
  • prompt:指定要生成的图片的文本内容。此参数指定的文本内容会作为模型的输入,模型会根据文本内容生成图片。
  • max_tokens:指定生成图片的最大长度。此参数指定生成图片的最大长度,单位为字符。如果超过指定长度,模型会按照指定长度截断。
  • temperature:指定生成图片的随机性。此参数指定生成图片的随机性,取值范围为 0 到 1。如果设为 0,则模型会按照原文内容生成图片,不会有随机性;

例如,下面是一个调用 completions.create 方法的例子,它使用了预训练的 GPT-3 模型,生成了长度为 100 个字符,随机性为 0.5,词频惩罚为 0.0 的图片:

代码语言:javascript
复制
openai.completions.create({
model: "text-davinci-002",
prompt: "The quick brown fox jumps over the lazy dog.",
max_tokens: 100,
temperature: 0.5,
frequency_penalty: 0.0,
})

回答中有名次解释也有代码示例,还是比较清晰的,第一个参数 model 代表模型,那么究竟有哪些模型,适合在什么场景使用呢?我们继续追问:

问题7:介绍下 openai.completions.create 中常见 model 的特点和应用场景

ChatGPT 的回答:


OPEN AI 提供了多种预训练的模型,用于满足不同的应用场景。例如,下面是一些常见的模型及其特点和应用场景:

  • text-davinci-002:这是一种大型模型,可以完成各种自然语言处理任务。它具有非常强大的语言理解能力,可以用于文本生成、问答、机器翻译等应用。
  • image-alpha-001:这是一种图像生成模型,可以根据文本内容生成对应的图像。它具有非常高的生成质量,可以用于图像生成、图像修复、图像分类等应用。
  • dialogue-babi-001:这是一种对话生成模型,可以根据上下文生成相应的对话。它具有较高的语言流畅性和逻辑性,可以用于对话生成、聊天机器人、问答系统等应用。

这些模型仅是 OPEN AI 提供的部分模型,实际应用中还有更多模型可供选择。


好了,API 的基本概念都了解清楚了,下面我们来继续实现,上面的代码还是比较简陋的,把核心逻辑直接挂载在 koa 上了,没有加任何路由,我们来优化一下:

问题8:优化第三步的代码,为服务端逻辑增加一个路由

ChatGPT 的回答:


代码语言:javascript
复制
const Koa = require("koa");
const openai = require("openai");
const Router = require("koa-router");

const app = new Koa();
const router = new Router();

// 设置 OPEN AI 的 API 密钥
openai.apiKey = "your-api-key";

// 定义路由,处理 POST 请求
router.post("/", async (ctx, next) => {
// 获取请求中的参数
const { model, prompt } = ctx.request.body;

// 使用 openai 库调用 API,生成图片
const response = await openai.completions.create({
model,
prompt,
max_tokens: 2048,
temperature: 0.5,
});

// 将生成的图片返回给客户端
ctx.body = response.data.complete;
});

// 启用路由
app.use(router.routes());

// 启动服务器
app.listen(3000);

上述代码中,我们首先引入了 koa-router 插件,并创建了一个 Router 实例。然后,定义了一个路由,处理来自客户端的 POST 请求。最后,启用了路由,并启动服务器。

使用路由的优点是可以对不同的请求方法和路径分别处理,使得代码更加清晰和维护方便。实际应用中,可以根据需求和 API 文档,添加更多路由处理不同的请求。


帮我们引入了 koa-router 插件,代码看起来像点样子了,接下来我们开始实现前端页面,继续提问:

问题9: 创建一个HTML页面,用户输入 model、prompt 参数,然后调用上面的接口在页面展示生成后的图片

ChatGPT 的回答:


您可以创建一个前端页面,用于给用户输入 model、prompt 参数,然后通过 AJAX 请求调用上面的接口生成图片,并在页面上展示生成的图片。具体方法如下:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Generate Image</title>
</head>
<body>
<h1>Generate Image</h1>
<form id="form">
<label for="model">Model:</label>
<input type="text" id="model" name="model" value="text-davinci-002" />
<br />
<label for="prompt">Prompt:</label>
<input type="text" id="prompt" name="prompt" value="The quick brown fox jumps over the lazy dog." />
<br />
<button type="submit">Generate</button>
</form>
<div id="image"></div>
<script>
// 监听表单提交事件
document.querySelector("#form").addEventListener("submit", async (event) => {
// 阻止表单提交的默认行为
event.preventDefault();

    // 获取表单中的参数
    const model = document.querySelector(&#34;#model&#34;).value;
    const prompt = document.querySelector(&#34;#prompt&#34;).value;

    // 发送 AJAX 请求,生成图片
    const response = await fetch(&#34;http://localhost:3000&#34;, {
      method: &#34;POST&#34;,
      headers: {
        &#34;Content-Type&#34;: &#34;application/json&#34;,
      },
      body: JSON.stringify({ model, prompt }),
    });
    const data = await response.json();

    // 在页面上展示生成的图片
    const image = document.querySelector(&#34;#image&#34;);
    image.innerHTML = `&lt;img src=&#34;data:image/jpeg;base64,${data}&#34; /&gt;`;
  });
&lt;/script&gt;

</body>
</html>


好了,代码生成出来了,我们要把他挂到服务器上,继续提问:

问题10: 将这个 HTML 页面绑定到 koa 的路由上

ChatGPT 的回答:


要将 HTML 页面绑定到 koa 的路由上,需要在 koa 中使用 koa-static 插件,具体方法如下:

代码语言:javascript
复制
const Koa = require("koa");
const openai = require("openai");
const Router = require("koa-router");
const serve = require("koa-static");

const app = new Koa();
const router = new Router();

// 设置 OPEN AI 的 API 密钥
openai.apiKey = "your-api-key";

// 定义路由,处理 POST 请求
router.post("/", async (ctx, next) => {
// 获取请求中的参数
const { model, prompt } = ctx.request.body;

// 使用 openai 库调用 API,生成图片
const response = await openai.completions.create({
model,
prompt,
max_tokens: 2048,
temperature: 0.5,
});

// 将生成的图片返回给客户端
ctx.body = response.data.complete;
});

// 使用 koa-static 插件,绑定静态文件目录
app.use(serve("./public"));

// 启用路由
app.use(router.routes());

// 启动服务器
app.listen(3000);

使用 koa-static 插件绑定静态文件目录时,指定的目录就是静态文件目录,所有需要访问的静态文件,如 HTML、JavaScriptCSS 文件,都需要放到这个目录下。

在上述代码中,我们将静态文件目录设置为 public,因此需要把 HTML 文件放到 public 目录下,才能被正确访问。

例如,如果你的 HTML 文件名为 index.html,则需要把它放到 public 目录下,访问时的 URLhttp://localhost:3000/index.html。这样,当浏览器访问该 URL 时,就会返回 index.html 文件内容。


代码中帮我们引入了 koa-static 插件,并且指向了 public 文件夹,我们把 HTML 文件丢进去。

下面我们尝试启动项目:

然后点击 Generate 后发现服务报错了:

这个报错是为啥,我们继续问问 ChatGPT

问题11: 代码报错了:Cannot destructure property 'model' of 'ctx.request.body' as it is undefined

ChatGPT 的回答:


koa 中,要获取请求中的参数,可以在中间件函数中使用 ctx.request.body 对象,但需要注意,默认情况下,koa 不会对请求的数据进行解析,因此 ctx.request.body 中是没有参数的。

如果你想要获取请求中的参数,则需要在 koa 中使用 koa-bodyparser 插件,该插件能够自动对请求的数据进行解析,并将解析后的结果放入 ctx.request.body 对象中。

代码语言:javascript
复制
const Koa = require("koa");
const openai = require("openai");
const Router = require("koa-router");
const serve = require("koa-static");
const bodyParser = require("koa-bodyparser");

const app = new Koa();
const router = new Router();

// 设置 OPEN AI 的 API 密钥
openai.apiKey = "your-api-key";

// 使用 koa-bodyparser 插件,对请求数据进行解析
app.use(bodyParser());

// 定义路由,处理 POST 请求
router.post("/", async (ctx, next) => {
// 获取请求中的参数
const { model, prompt } = ctx.request.body;

// 使用 openai 库调用 API,生成图片
const response = await openai.completions.create({
model,
prompt,
max_tokens: 2048,
temperature: 0.5,
});

// 将生成的图片返回给客户端
ctx.body = response.data.complete;
});

// 使用 koa-static 插件,绑定静态文件目录
app.use(serve("./public"));

// 启用路由
app.use(router.routes());

// 启动服务器
app.listen(3000);

上述代码中,我们在 koa 应用中使用了 koa-bodyparser 插件,对请求的数据进行了解析。在路由处理函数中,通过 ctx.request.body 获取请求中的参数,并调用 openai API 生成图片。

在实际应用中,可以根据需要,调整 koa-bodyparser 插件的配置,以满足个性化的需求。


然后我们继续运行代码,发现代码又报错了:

这个报错继续让 ChatGPT 自己解决吧,于是我按照官方示例进行引导:

问题12:使用 openai.createImage 改写以上代码

ChatGPT 的回答:


代码语言:javascript
复制
const Koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const serve = require("koa-static");
const { Configuration, OpenAIApi } = require("openai");

const app = new Koa();
const router = new Router();

const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

app.use(bodyParser());

app.use(serve("public"));

router.post("/api/generate-image", async (ctx, next) => {
const { model, prompt } = ctx.request.body;

const response = await openai.createImage({
model: "image-alpha-001",
prompt,
});

const data = await response.json();

ctx.body = {
url: data.url,
};
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000, () => {
console.log("Server is listening on port 3000");
});


这时候服务端代码的基本逻辑已经差不多了,我们再让 ChatGPT 把我们的前端代码美化一下:

问题13:页面太丑了,用 CSS 美化一下,加点动画效果

ChatGPT 的回答:


代码语言:javascript
复制
<style>
/* 居中布局 */
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
font-family: sans-serif;
}

/* 表单样式 */
form {
display: flex;
flex-direction: column;
align-items: center;
width: 50%;
min-width: 300px;
padding: 1em;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
background-color: white;
}

form > div {
margin-bottom: 0.5em;
display: flex;
align-items: center;
}

label {
font-weight: bold;
margin-right: 0.5em;
}

input[type="text"] {
width: 100%;
padding: 0.5em;
border: 1px solid #ccc;
border-radius: 5px;
}

button {
margin-top: 1em;
padding: 0.5em 1em;
border: none;
border-radius: 5px;
background-color: #0070f3;
color: white;
font-size: 1em;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
}

button:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

/* 图片展示区域样式 */
#image-container {
margin-top: 1em;
display: none;
width: 100%;
max-width: 500px;
height: auto;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
animation: fadeIn 0.5s;
}

#image {
width: 100%;
height: auto;
}

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>


好家伙,分分钟就写完了,下面我们来看看效果:

我们只问了 ChatGPT 13 个问题,他就帮我们写出了一个简单的图片生成程序,我在用的过程中就一直在感叹实在是再强大了,后续其实还可以问更多的问题来不断完善这个程序,比如:生成图片的过程中生成 loading 效果、为网站添加一些背景动画效果 ... 你可以在极短的时间里构建出一个出色的网站。

当然,它现阶段还有一些不太完善的地方,比如他并不能直接给你一段非常完美的代码,而是需要你持续引导。另外写出的代码也有一些 Bug,但是他也可以靠你的引导来找到这些 Bug,这个表现其实真的很像是一个真的程序员,而不是一个冷血的机器。

或许你会觉得,以上代码不就是启动了一个 Node.js 服务、调用了一些 API ,然后在前端把结果展示出来么,但是这可能是因为你对开发已经有一定经验了,觉得这些代码没什么难度。但是如果是作为一个刚步入职场的新同学,或者开发经验为零的人,让他去自己写出这些代码并且成功运行可能要花上一天的时间。但是现在有了 ChatGPT 的辅助或许只需要花上一个小时,这是一个质的飞跃,未来可能彻底改变软件开发这个行业。

根据我们的实验结果来看,他或许现在并不能完全替代一个完整的程序员,但却能让一个人程序员 1.5 个人的活,也可以帮助低级工程师快速成长,让排查 Bug、重构代码变得更简单。这不可避免的会影响到未来市场上对程序员数量的需求...

本项目的源码在下面,感兴趣的可以玩一玩,另外你也可以按照我的问题去引导 ChatGPT 帮你实现这个程序。

https://github.com/ConardLi/openai-nodejs-demo

最后,我让他帮我列了一下本文的大纲,另外项目的 readme.md 文件也是 ChatGPT 自动生成的 ~

你觉得这玩意有没有威胁到你?

最后

如果这篇文章帮助到了你,欢迎点赞和关注。