image-20230622133025662

聊天机器人正在改变我们在线互动的方式。多亏了 OpenAI API,制作智能的、上下文感知的聊天机器人现在对任何初出茅庐的 Web 开发人员来说都是触手可及的。

在本教程中,我将教您使用 GPT-4 API 构建您自己的聊天机器人所需了解的一切。

目录

我们正在构建的应用程序

img您将构建的应用程序的屏幕截图

了解KnowItAll,这是一个具有非凡对话能力的聊天机器人。您可以向它提问、让它创建内容、纠正语言、建议编辑或翻译。它甚至可以根据请求编写代码。

先决条件

在本教程中,您将使用 HTML、CSS 和普通 JavaScript。对 JavaScript 有基本的了解就足够了——您不需要非常先进。

您还需要一个免费的 OpenAI 帐户,可以在此处获取。您注册时获得的免费积分应该足以完成本教程。当您完成注册过程时,请务必将您的 API 密钥复制并粘贴到安全的地方,因为您很快就会需要它。

本教程使用 GPT-4 模型。在撰写本文时,GPT-4 有一个等待名单(您可以在此处加入)。但如果您还没有访问它,请不要担心,GPT-3.5-turbo 模型与我们在本教程中所做的一切完全兼容,并且现在可供所有人使用。

如果您不知道 OpenAI 模型是什么,请不要担心,我们稍后将详细讨论它们。

好的,让我们开始编写一些代码!

应用程序的 HTML 和 CSS

在深入研究 JavaScript 和 AI 组件之前,我们需要建立此应用程序的 HTML 和 CSS 基础。下面,我嵌入了一个 Scrim,它是一个交互式代码编辑器/截屏视频。在此稀松布中,您可以:

  • 浏览该项目中使用的 HTML 和 CSS
  • 单击“预览”可在迷你浏览器中查看项目
  • 观看 HTML 和 CSS 的演练解释并随时暂停以玩转代码。

如果你想在本地运行这段代码,你可以点击右下角的齿轮图标 (⚙️) 并选择下载为 zip。您将获得一个包含所有 HTML、CSS 和图像资源的压缩文件夹。您可以解压缩该文件夹并在 VS Code 或您喜欢的任何开发环境中打开它。

单击此处查看此稀松布的全屏版本。

我想提请您注意 index.html 的第 22-24 行,其中包含来自聊天机器人的硬编码气泡以开始对话:

<div class="speech speech-ai">
    How can I help you?
</div>

index.html 的第 22-24 行

正如您从本文顶部附近的屏幕截图中看到的那样,每次对话都以聊天机器人询问我如何帮助您开始?请注意两个 CSS 类speechspeech-ai,它们为对话泡泡设置样式。

除此之外,这个 HTML 和 CSS 没有什么特别不寻常的地方,我们不会在本教程中过多提及它。但在继续之前,请花点时间通读一下或观看演练。

如何存储 API 密钥

由于 OpenAI API 是该项目的核心,您需要将 OpenAI API 密钥存储在应用程序中。

⚠️ 请记住——您的 API 密钥在这个仅限前端的项目中容易受到攻击。当您在浏览器中运行此应用程序时,您的 API 密钥将在开发工具中的网络选项卡下可见。这意味着您应该只在本地运行该项目。

如果您想部署此项目以便共享它并将其包含在您的投资组合中,在完整的YouTube / Scrimba课程的第三部分中,我展示了如何使用 Netlify Serverless Functions 在部署时安全地隐藏 API 密钥。

好的,警告已经消失,让我们继续前进。在您的项目文件夹中,创建一个名为的新文件env.js来保存您的 API 密钥。

里面env.js设置了一个 constprocess来保存一个具有单个属性的对象env。这会将您的 API 密钥存储在键/值对中,其中键是OPENAI_API_KEYAPI 密钥本身,值是 API 密钥本身。(请注意,下面代码中的 API 密钥不是真实的!)

export const process = {
    env: {
        OPENAI_API_KEY: "sk-123456789123456789123456789123456789123456789123"
    }
}

环境js

这是更新后的稀松布,显示了迄今为止的所有项目代码:

如何将 API 密钥导入到index.js

接下来,在 的顶部,使用此导入语句index.js导入您的 API 密钥。env.js

import { process } from '/env.js'

索引.js

这是命名导入,这意味着您将要导入的实体的名称包含在花括号中。现在,整个process对象将在 中可用index.js

当您从多个文件中使用 JavaScript 时,您需要告诉浏览器期待模块化 JavaScript。所以添加type=”module”到script标签中index.html

<script src="index.js" type="module"></script>

索引.html

为了检查您是否犯了任何导致您出现错误的打字错误,请process从内部注销index.js

import { process } from '/env.js'

console.log(process)
//{env: {OPENAI_API_KEY: "sk-123456789123456789123456789123456789123456789123"}}

索引.js

这是迄今为止的代码的稀松布:

如何安装 OpenAI 依赖项

您可以通过常规fetch请求访问 OpenAI API,但使用 OpenAI 依赖项要容易得多。如果你在本地工作,你可以使用 NPM 添加它:

$ npm install openai

终端

或者,如果您在 Scrimba 中工作,请将光标悬停在 DEPENDENCIES 上,然后单击出现的三点图标。

img依赖项旁边的三点菜单

从下拉列表中,选择添加模块。

img带有“添加模块”选项的下拉菜单

这将弹出一个对话框。输入openai,单击“添加”,Scrimba 将完成剩下的工作。

img添加NPM 包对话框

然后您将在侧边栏中看到 OpenAI 依赖项。

无论您是在本地工作还是在 Scrimba 中工作,您现在都安装了 OpenAI 依赖项。

如何使用 OpenAI 依赖项

您需要从依赖项导入两个构造函数。他们需要配置应用程序以使用 API。它们是Configuration并且OpenAIApi您可以通过添加以下代码行来导入它们index.js

import { Configuration, OpenAIApi } from 'openai'

索引.js

要与 API 交互,您需要使用构造函数设置您自己的configuration(注意小写“c”)对象Configuration

const configuration = new Configuration()

索引.js

接下来,向其传递一个带有键/值对的对象。键apiKey和值将是我们的 API 密钥,您已从该密钥导入process并可以使用 进行访问process.env.OPENAI_API_KEY

const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_KEY
})

索引.js

然后,您需要传递configurationOpenAIApi构造函数。将这个新实例保存OpenAIApi为 const openai(注意小写“o”)。

const openai = new OpenAIApi(configuration)

索引.js

要检查它是否正常工作,请注销openai

console.log(openai)
//OpenAIApi$1 {basePath: "<https://api.openai.com/v1>", configuration: {apiKey: "sk-12345678912345678912345678...", baseOptions: {headers: {User-Agent: "OpenAI/NodeJS/3.2.1", Authorization: "Bearer sk-1234567891234567891..."}}}}

索引.js

这是到目前为止所有代码的稀松布:

请记住,您可以单击齿轮图标 (⚙️) 将所有代码下载到一个压缩文件夹中。

现在您已经完成了 OpenAI API 依赖项的设置,您可以继续使用它了。但在您继续编写更多代码之前,让我们花点时间设想一下这个聊天机器人将如何工作。

这个应用程序的流程

使用 OpenAI 模型时的一个主要挑战是它们不会保留之前交互的查询或回复。事实上,他们根本不记得过去与你的谈话。这可能会导致脱节且令人困惑的对话,如下所示:

Human: Who was the first person to walk on the moon?
AI: Neil Armstrong.
Human: How old was he at the time?
AI: How old was who?
Human: ???

因此,为了创建一个能够进行连贯对话的聊天机器人,我们需要为 OpenAI 模型提供某种形式的内存。

幸运的是,有一种简单的方法可以做到这一点:我们将当前的整个对话包含在每个 API 调用中。这允许 API 在形成补全时利用对话的上下文来更好地理解所提出的问题。

所以应用程序是这样工作的:

img用户在输入字段中输入问题并点击发送。

硬编码消息“我能为您提供什么帮助?” 被展示。用户输入问题或请求,然后按回车键或按发送按钮。

img问题呈现给 DOM。

问题以绿色对话框呈现给 DOM,并且输入被清除。

img问题存储在数组中。该数组是对话的唯一事实来源。

问题存储在数组中。这是将保存整个对话并充当单一事实来源的数组。这允许应用程序拥有对话的“记忆”,因此它可以理解请求并将其响应上下文化。

img该数组被发送到 OpenAI API。

该数组被发送到 API。随着对话的增长,这个数组将包含越来越多的元素。

imgOpenAI API 发回带有答案的响应。(这称为完成。)

OpenAI API 发回响应。在该响应中是 AI 模型生成的实际语言。这称为完成

img完成存储在数组中并呈现给 DOM。

完成结果将添加到保存对话的数组中,以便它可用于将任何未来对 API 的请求置于上下文中。完成的内容也会呈现到 DOM 中,以便用户可以看到它。

img用户继续对话。

用户现在继续对话。他们输入的任何内容都会呈现到 DOM。

img用户的输入被添加到对话数组中,并且整个数组被发送到 API。

❗️第8步特别重要,因为这里的问题是有多少人住在那里?没有提及Paris,因此 API 仅当从我们随每个请求发送的数组中获取对话上下文时才能正确回答。

imgOpenAI API 的响应表明它理解问题的上下文。

从它的响应中,我们可以看到 API 确实具有数组中对话的上下文 - 它知道我们正在谈论巴黎,尽管问题中没有提到巴黎 有多少人住在那里?所以现在我们可以确定我们将能够与聊天机器人进行逻辑、流畅的对话。

现在您已经大致了解了该应用程序的工作原理,让我们深入了解人工智能的具体细节。

存储对话的数组

如前所述,每次 API 调用时都需要向 OpenAI API 提供当时存在的对话。对话应构建为对象数组,每个对象都遵循特定的格式。

首先,设置一个数组并调用它conversationArr

const conversationArr = []

索引.js

该数组中的每个元素都是一个具有两个键/值对的对象。第一个键是role,第二个键是content。在整个项目中,此结构对于存储在数组中的所有对象都是一致的。

数组中的第一个对象将包含聊天机器人的指令。该对象称为指令对象,允许您控制聊天机器人的个性并提供行为指令、指定响应长度等。

指令对象的role属性应包含字符串‘system',并且content应将您的指令保存在字符串中。

以下是一些示例说明:

‘You are a useful assistant'
‘You reply in French'
‘You translate whatever I say into Spanish'
‘You are a useful assistant that gives long, detailed answers'

所以conversationArr指令对象看起来像这样。

const conversationArr = [
    { 
        role: 'system',
        content: 'You are a useful assistant.' // this is the instruction
    }
]

索引.js

由于指令对象不会改变,所以我们对其进行硬编码并将其放入index.js.

到目前为止,我们的代码如下所示:

在继续之前,让我们看看您将存储在 中的其他两种类型的对象conversationArr。需要明确的是,您现在不会对它们进行硬编码index.js,而是根据需要以编程方式添加它们。

当用户提交一些文本时,该文本将存储在一个对象中conversationArr,它看起来像这样,包含用户提交的文本和rolebeing 。‘user'`content`

{ 
    role: 'user',
    content: 'What is the capital of France?' // your question
}

保存用户问题的对象的示例

API 的响应也将存储在一个对象中。这里的角色将是,‘assistant'并且content将是完成文本,例如:

{ 
    role: 'assistant',
    content: 'The capital of France is Paris.' // the completion
}

保存完成的对象的示例

随着其生长而最终形成的所有对象都conversationArr将遵循相同的模式,具有rolecontent属性。

现在让我们处理当用户输入一些文本并按下提交按钮时会发生什么。

如何处理用户的输入

您的下一个任务是获取用户的输入并将其呈现到 DOM。保存对话的 div 的index.htmlid 为chatbot-conversation。因此,index.js控制该 div 并将其保存到 const 中chatbotConversation

const chatbotConversation = document.getElementById('chatbot-conversation')

索引.js

现在您需要连接一个事件侦听器,该事件侦听器在用户提交一些文本时触发。快速查看一下index.html,确认该按钮位于表单元素内:

<form id="form" class="chatbot-input-container">
    <input name="user-input" type="text" id="user-input" required>
        <button id="submit-btn" class="submit-btn">
            <img 
            src="images/send-btn-icon.png" 
            class="send-btn-icon"
            >
    </button>
</form>

索引.html

所以点击按钮或敲回车会触发一个submit事件。这就是您需要事件监听器监听的内容。因为你想防止浏览器重新加载 URL 中的查询字符串,你需要添加e.preventDefault().

document.addEventListener('submit', (e) => {
    e.preventDefault()
})

索引.js

呈现用户的消息

当用户提交消息时,您需要呈现它。该过程分为五个阶段:

  1. 控制具有 id 的文本输入字段user-input
  2. 用于createElement创建一个新的 div。
  3. 添加 div 所需的 CSS 类:speech这是通用语音气泡类,speech-human它应用区分人类语音气泡和 AI 语音气泡的样式。
  4. 将该语音气泡附加到chatbotConversation
  5. 将对话气泡设置textContent为用户的输入,您可以从 获取该输入userInput.value
document.addEventListener('submit', (e) => {
    e.preventDefault()
    // 1. take control of the text input field
    const userInput = document.getElementById('user-input')  
    // 2. create the new element
    const newSpeechBubble = document.createElement('div')
    // 3. give it CSS classes
    newSpeechBubble.classList.add('speech', 'speech-human')
    // 4. append the speech bubble to the conversation
    chatbotConversation.appendChild(newSpeechBubble)
    // 5. add the user's inputted text to the speech bubble
    newSpeechBubble.textContent = userInput.value
})

索引.js

conversationArr根据用户的输入进行更新

将消息渲染到 DOM 后,您现在需要以conversationArr我们之前查看的格式推送对象。该对象将有一个roleof‘user’并且该content属性将保存用户在文本输入中键入的任何内容。

document.addEventListener('submit', (e) => {
    e.preventDefault()

    const userInput = document.getElementById('user-input')  
    const newSpeechBubble = document.createElement('div')
    newSpeechBubble.classList.add('speech', 'speech-human')
    chatbotConversation.appendChild(newSpeechBubble)
    newSpeechBubble.textContent = userInput.value
        
    // push object to conversationArr
    conversationArr.push({ 
        role: 'user',
        content: userInput.value
    })

})

索引.js

清除输入字段并滚动到底部

该事件侦听器函数需要完成两项最终工作。

首先,让我们通过将文本输入设置为空字符串来清除文本输入。其次,让我们将对话滚动到底部,这样用户就不必手动向下滚动。您可以使用scrollIntoView该方法来做到这一点,但因为我为迷你浏览器编写了此代码并scrollIntoView导致了问题,所以我使用了稍微不同的技术,如下所示:

document.addEventListener('submit', (e) => {
    e.preventDefault()

    const userInput = document.getElementById('user-input')  
    const newSpeechBubble = document.createElement('div')
    newSpeechBubble.classList.add('speech', 'speech-human')
    chatbotConversation.appendChild(newSpeechBubble)
    newSpeechBubble.textContent = userInput.value
        
    conversationArr.push({ 
        role: 'user',
        content: userInput.value
    })

    // empty the text input
    userInput.value = ''
    // scroll the conversation to the bottom
    chatbotConversation.scrollTop = chatbotConversation.scrollHeight
})

索引.js

所以我们的代码到目前为止看起来是这样的:

现在,如果你问法国的首都是什么?conversationArr并从事件侦听器的函数中注销,您会得到:

console.log(conversationArr)
//[{role: "system", content: "You are a useful assistant."}, {role: "user", content: "What is the capital of France?"}]

索引.js

人工智能时代来临

是时候使用 OpenAI API 实际生成一些文本了。依赖关系使它成为一个非常容易使用的 API——你只需要三个信息。

  1. 一个端点
  2. 一个模型
  3. 我们的对话在一个数组中

您已经设置好conversationArr处理该列表中的第 3 项,但在向 API 发出请求之前,让我们更详细地了解第 1 项和第 2 项。

端点

OpenAI API 有各种可用的端点。您使用哪一种取决于您希望 AI 执行什么操作(生成语言、生成代码、根据文本提示创建图像等)。

对于这个聊天机器人,我们将使用chat/completion端点,在撰写本文时,该端点是 OpenAI 稳定版中最先进的自然语言生成端点。

楷模

模型(有时称为引擎)是实际创建语言的东西。我们这个项目的模型是GPT-4GPT-4目前正在通过等待名单进行有限发布,因此如果您现在无法访问它,您可以使用它GPT-3.5-turbo。该项目中的所有代码都适用于这两种模型,并且功能GPT-3.5-turbo也非常强大。

好的,我们来调用 API。

fetchReply 函数

我们需要一个函数来承担向 API 发出请求的工作。我们称这个函数为fetchReply。该函数的基本原理如下所示:

async function fetchReply(){
    const response = await openai.createChatCompletion() 
}

索引.js

在函数体内,我们有一个 const response,并且等待对端点的调用,您可以通过获取之前存储在 const 中的构造函数chat/completion的实例并调用其上的方法来到达该端点。(是一种 OpenAI API 方法,可让我们访问端点。有关更多信息,请查看OpenAI API 文档。)OpenAiAPI`openaicreateChatCompletioncreateChatCompletion`chat/completion

由于依赖项正在发出获取请求,因此您需要使用await关键字并将其设为async函数。

接下来,您需要传递createChatCompletion一个对象,该对象需要两个属性:modelmessages

模型

我们的模型是 GPT-4。您可以通过将其放在键/值对中的小写字符串中来指定它:model: 'gpt-4'model: ’gpt-3.5-turbo'如果您还没有访问 GPT-4 的权限,也可以在这里使用。

留言

messages 属性只需要保存我们的对话,您已将其作为对象数组存储在 const 中conversationArr

现在,注销响应。所以完成的代码如下所示:

async function fetchReply(){
    const response = await openai.createChatCompletion({
        model: 'gpt-4', // or 'gpt-3.5-turbo'
        messages: conversationArr,
    })
    console.log(response)
} 

索引.js

现在,从事件侦听器的函数中调用 fetchReply。

document.addEventListener('submit', (e) => {
    e.preventDefault()
    const userInput = document.getElementById('user-input')   
    conversationArr.push({ 
        role: 'user',
        content: userInput.value
    })
    const newSpeechBubble = document.createElement('div')
    newSpeechBubble.classList.add('speech', 'speech-human')
    chatbotConversation.appendChild(newSpeechBubble)
    newSpeechBubble.textContent = userInput.value
    userInput.value = ''
    chatbotConversation.scrollTop = chatbotConversation.scrollHeight
    console.log(conversationArr)

    // call fetch reply to trigger the API call
    fetchReply()
})

索引.js

img聊天机器人回答用户的问题。

当你输入什么是法国的首都?然后点击发送,你会得到这个巨大的物体:(随意滚动浏览它,但不要被吓倒!)

{data: {id: "chatcmpl-7MuziItZYyiFpPG2KHQawd19rD54U", object: "chat.completion", created: 1685696658, model: "gpt-4-0314", usage: {prompt_tokens: 28, completion_tokens: 36, total_tokens: 64}, choices: [{message: {role: "assistant", content: "The capital of France is Paris."}, finish_reason: "stop", index: 0}]}, status: 200, statusText: "", headers: {cache-control: "no-cache, must-revalidate", content-type: "application/json"}, config: {transitional: {silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false}, adapter: xhrAdapter(e), transformRequest: [transformRequest(e,t)], transformResponse: [transformResponse(e)], timeout: 0, xsrfCookieName: "XSRF-TOKEN", xsrfHeaderName: "X-XSRF-TOKEN", maxContentLength: -1, maxBodyLength: -1, validateStatus: validateStatus(e), headers: {Accept: "application/json, text/plain, */*", Content-Type: "application/json", User-Agent: "OpenAI/NodeJS/3.2.1", Authorization: "Bearer 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"}, method: "post", data: "{"model":"gpt-4","messages":[{"role":"system","content":"You are a highly knowledgeable assistant that is always happy to help."},{"role":"user","content":"What is the capital of france?"}]}", url: "https://api.openai.com/v1/chat/completions"}, request: XMLHttpRequest {}}

OpenAI API 的响应

这里有很多有用的信息,但我们需要重点关注这一部分,为了便于阅读,我对其进行了格式化:

choices: [
    {
        message: {
            role: "assistant", 
            content: "The capital of France is Paris."
        }, 
        finish_reason: "stop", index: 0
    }
]

响应中的选择数组

这是我们可以看到完成的地方:法国的首都是巴黎。这就是您需要在对话气泡中渲染到 DOM 的内容。您可以使用点和括号表示法来获取该文本。

让我们把它记录下来。

console.log(response.data.choices[0].message.content)
//The capital of France is Paris.

索引.js

但在渲染任何内容之前,请记住您还需要将每段对话包含在conversationArr. 您需要的格式是一个具有两个键/值对的对象,其中一个键是并且role具有值’assistant’,另一个是content并且将完成作为其值。

而那个对象正是给你的response.data.choices[0].message——是的,你需要添加的对象conversationArr实际上是由 API 提供给你的!

您可以调整上面的内容console.log来证明这一点:

console.log(response.data.choices[0].message)
//{role: "assistant", content: "The capital of France is Paris."}

索引.js

现在您可以继续fetchReply将此对象推送到conversationArr.

让我们注销conversationArr来检查它是否有效:

async function fetchReply(){
    const response = await openai.createChatCompletion({
        model: 'gpt-4',
        messages: conversationArr,
    })
    conversationArr.push(response.data.choices[0].message)
    console.log(conversationArr)
}

// [{role: "system", content: "You are a useful assistant."}, {role: "user", content: "What is the capital of France?"}, {role: "assistant", content: "The capital of France is Paris."}]

索引.js

项目代码现在应如下所示:

现在剩下要做的就是渲染完成。

如何实现打字机效果

最后一个任务是让我们的聊天机器人输入它的响应。有成千上万种方法可以做到这一点,而且只用 CSS 是可能的。我们将使用 JavaScript 来完成它。

创建一个名为 的函数renderTypewriterText。此函数将接受一个参数,该参数将是您从响应中获得的文本字符串。

renderTypewriterText函数需要创建一个新的对话泡泡元素,为其提供 CSS 类,并将其附加到chatbotConversation. 这与您之前用于用户输入的代码几乎相同,但请注意,您还需要为语音气泡提供类,该类blinking-cursor使用 CSS 动画在渲染文本时创建光标效果。参见index.css上述 CSS 稀松布中第 151 行之后的内容。

function renderTypewriterText(text) {
    const newSpeechBubble = document.createElement('div')
    newSpeechBubble.classList.add('speech', 'speech-ai', 'blinking-cursor')
    chatbotConversation.appendChild(newSpeechBubble)
}

索引.js

现在添加一些逻辑来逐个渲染每个字符:

function renderTypewriterText(text) {
    const newSpeechBubble = document.createElement('div')
    newSpeechBubble.classList.add('speech', 'speech-ai', 'blinking-cursor')
    chatbotConversation.appendChild(newSpeechBubble)
    
    // render each character one by one 
    let i = 0
    const interval = setInterval(() => {
        newSpeechBubble.textContent += text.slice(i-1, i)
        if (text.length === i) {
            clearInterval(interval)
            newSpeechBubble.classList.remove('blinking-cursor')
        }
        i++
        chatbotConversation.scrollTop = chatbotConversation.scrollHeight
    }, 50)
}

索引.js

那是相当混乱的 JavaScript,所以让我们逐步完成它。

  1. let i = 0:这会初始化一个i值为 0 的变量。它将用于跟踪字符串的当前索引text
  2. const interval = setInterval(() => { ... }, 50):这会创建一个间隔,每 50 毫秒重复执行一次箭头函数。箭头函数包含将在每个时间间隔执行的代码。
  3. newSpeechBubble.textContent += text.slice(i-1, i):此行将字符串的一部分附加text到元素的内容中newSpeechBubble。它使用方法根据 的当前值slice从字符串中提取单个字符。text`i`
  4. if (text.length === i) { ... }:此条件检查整个text字符串是否已附加到对话泡泡。如果字符串的长度text等于i,则表示所有字符都已追加。
  5. clearInterval(interval):该行清除间隔,停止函数的执行。
  6. newSpeechBubble.classList.remove('blinking-cursor')`'blinking-cursor':这将从元素中删除 CSS 类 newSpeechBubbletext`一旦显示整个字符串,它就会消除闪烁的光标效果。您只需要在打字机运行时闪烁光标。
  7. i++:这会将 的值增加i1,移动到字符串中的下一个字符text以进行下一个间隔执行。
  8. chatbotConversation.scrollTop = chatbotConversation.scrollHeight:这会将对话容器滚动到底部,确保新内容始终可见。

要完成连接,请renderTypewriterText从 fetchReply 内部调用,记住传递从 API 返回的文本完成。

async function fetchReply(){
    const response = await openai.createChatCompletion({
        model: 'gpt-4',
        messages: conversationArr,
    }) 
    conversationArr.push(response.data.choices[0].message)

    // call renderTypewriterText passing in the completion
    renderTypewriterText(response.data.choices[0].message.content)
}

索引.js

你就完成了!

img完成的应用程序包含用户和 AI 聊天机器人之间的对话

我们现在拥有一个使用 GPT-4 API 的功能齐全的聊天机器人,您可以根据需要继续对话!

嗯,这并不完全正确。对话的长度在理论上是有限制的,但你必须继续聊天很长时间才能达到。我们将在整个课程中更多地讨论这一点。另外,请务必注意,在某些时候,您可能会达到信用额度。

这是完成的代码。和以前一样,您可以点击齿轮图标 ⚙️ 并下载它。

结论

祝贺您使用 GPT-4 API 成功构建了您自己的聊天机器人!借助 GPT-4,您已经开启了自然语言处理和对话生成的无限可能。

当您继续您的 AI 之旅时,请记住保持好奇心、不断学习并探索不断发展的人工智能领域。分享您的创作、与他人协作并成为 AI 社区的一员。编码愉快!

参考文档

视频教程: https://www.youtube.com/watch?v=jlogLBkPZ2A


用户bPc3wTz
1 声望0 粉丝