聊天机器人正在扭转咱们在线互动的形式。多亏了 OpenAI API,制作智能的、上下文感知的聊天机器人当初对任何老成持重的 Web 开发人员来说都是触手可及的。
在本教程中,我将教您应用 GPT-4 API 构建您本人的聊天机器人所需理解的所有。
目录
咱们正在构建的应用程序
您将构建的应用程序的屏幕截图
理解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 类 speech
和speech-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_KEY
API 密钥自身,值是 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 上,而后单击呈现的三点图标。
依赖项 旁边的三点菜单
从下拉列表中,抉择增加模块。
带有“增加模块”选项的下拉菜单
这将弹出一个对话框。输出openai
,单击“增加”,Scrimba 将实现剩下的工作。
增加 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
而后,您须要传递 configuration
给OpenAIApi
构造函数。将这个新实例保留 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 在造成补全时利用对话的上下文来更好地了解所提出的问题。
所以应用程序是这样工作的:
用户在输出字段中输出问题并点击发送。
硬编码音讯“我能为您提供什么帮忙?” 被展现。用户输出问题或申请,而后按 回车 键或按发送按钮。
问题出现给 DOM。
问题以绿色对话框出现给 DOM,并且输出被革除。
问题存储在数组中。该数组是对话的惟一事实起源。
问题存储在数组中。这是将保留整个对话并充当繁多事实起源的数组。这容许应用程序领有对话的“记忆”,因而它能够了解申请并将其响应高低文化。
该数组被发送到 OpenAI API。
该数组被发送到 API。随着对话的增长,这个数组将蕴含越来越多的元素。
OpenAI API 发回带有答案的响应。(这称为 实现。)
OpenAI API 发回响应。在该响应中是 AI 模型生成的理论语言。这称为 实现。
实现存储在数组中并出现给 DOM。
实现后果将增加到保留对话的数组中,以便它可用于将任何将来对 API 的申请置于上下文中。实现的内容也会出现到 DOM 中,以便用户能够看到它。
用户持续对话。
用户当初持续对话。他们输出的任何内容都会出现到 DOM。
用户的输出被增加到对话数组中,并且整个数组被发送到 API。
❗️第 8 步特地重要,因为这里的问题 是有多少人住在那里?没有提及Paris,因而 API 仅当从咱们随每个申请发送的数组中获取对话上下文时能力正确答复。
OpenAI 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
,它看起来像这样,蕴含用户提交的文本和role
being。‘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
将遵循雷同的模式,具备 role
和content
属性。
当初让咱们解决当用户输出一些文本并按下提交按钮时会产生什么。
如何解决用户的输出
您的下一个工作是获取用户的输出并将其出现到 DOM。保留对话的 div 的 index.html
id 为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
出现用户的音讯
当用户提交音讯时,您须要出现它。该过程分为五个阶段:
- 管制具备 id 的文本输出字段
user-input
。 - 用于
createElement
创立一个新的 div。 - 增加 div 所需的 CSS 类:
speech
这是通用语音气泡类,speech-human
它利用辨别人类语音气泡和 AI 语音气泡的款式。 - 将该语音气泡附加到
chatbotConversation
。 - 将对话气泡设置
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
咱们之前查看的格局推送对象。该对象将有一个 role
of‘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——你只须要三个信息。
- 一个端点
- 一个模型
- 咱们的对话在一个数组中
您曾经设置好 conversationArr
解决该列表中的第 3 项,但在向 API 发出请求之前,让咱们更具体地理解第 1 项和第 2 项。
端点
OpenAI API 有各种可用的端点。您应用哪一种取决于您心愿 AI 执行什么操作(生成语言、生成代码、依据文本提醒创立图像等)。
对于这个聊天机器人,咱们将应用 chat/completion
端点,在撰写本文时,该端点是 OpenAI 稳定版中最先进的自然语言生成端点。
楷模
模型(有时称为引擎)是理论创立语言的货色。咱们这个我的项目的模型是 GPT-4
。GPT-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
`openaicreateChatCompletion
createChatCompletion`chat/completion
因为依赖项正在收回获取申请,因而您须要应用 await
关键字并将其设为 async
函数。
接下来,您须要传递 createChatCompletion
一个对象,该对象须要两个属性:model
和messages
。
模型
咱们的模型是 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
聊天机器人答复用户的问题。
当你输出 什么是法国的首都?而后点击发送,你会失去这个微小的物体:(随便滚动浏览它,但不要被吓倒!)
{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,所以让咱们逐渐实现它。
let i = 0
:这会初始化一个i
值为 0 的变量。它将用于跟踪字符串的以后索引text
。const interval = setInterval(() => { ...}, 50)
:这会创立一个距离,每 50 毫秒反复执行一次箭头函数。箭头函数蕴含将在每个工夫距离执行的代码。newSpeechBubble.textContent += text.slice(i-1, i)
:此行将字符串的一部分附加text
到元素的内容中newSpeechBubble
。它应用办法依据 的以后值slice
从字符串中提取单个字符。text
`i`if (text.length === i) {...}
:此条件查看整个text
字符串是否已附加到对话泡泡。如果字符串的长度text
等于i
,则示意所有字符都已追加。clearInterval(interval)
:该行革除距离,进行函数的执行。newSpeechBubble.classList.remove('blinking-cursor')
`’blinking-cursor’:这将从元素中删除 CSS 类
newSpeechBubble。
text` 一旦显示整个字符串,它就会打消闪动的光标成果。您只须要在打字机运行时闪动光标。i++
:这会将 的值减少i
1,挪动到字符串中的下一个字符text
以进行下一个距离执行。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
你就实现了!
实现的应用程序蕴含用户和 AI 聊天机器人之间的对话
咱们当初领有一个应用 GPT-4 API 的功能齐全的聊天机器人,您能够依据须要持续对话!
嗯,这并不完全正确。对话的长度在实践上是有限度的,但你必须持续聊天很长时间能力达到。咱们将在整个课程中更多地探讨这一点。另外,请务必留神,在某些时候,您可能会达到信用额度。
这是实现的代码。和以前一样,您能够点击齿轮图标 ⚙️ 并下载它。
论断
恭喜您应用 GPT-4 API 胜利构建了您本人的聊天机器人!借助 GPT-4,您曾经开启了自然语言解决和对话生成的有限可能。
当您持续您的 AI 之旅时,请记住放弃好奇心、一直学习并摸索一直倒退的人工智能畛域。分享您的创作、与别人合作并成为 AI 社区的一员。编码欢快!
参考文档
视频教程:https://www.youtube.com/watch?v=jlogLBkPZ2A