欢迎回到我们正在学习如何将人工智能产品集成到 Web 应用程序中的系列:

  1. 简介和设置
  2. 您的第一个 AI 提示
  3. 流式响应
  4. 人工智能如何运作
  5. 快速工程
  6. 人工智能生成的图像
  7. 安全性和可靠性
  8. 正在部署

上次,我们解决了所有样板工作。

在这篇文章中,我们将学习如何使用 获取。我们希望通过从后端执行这些 HTTP 请求来确保我们不会泄漏 API 密钥。

在本文结束时,我们将拥有一个基本但有效的人工智能应用程序。

生成 OpenAI API 密钥

在我们开始构建任何内容之前,您需要访问 platform.openai.com/account /api-keys 并生成一个 API 密钥以在您的应用程序中使用。

<图>
生成 API 密钥的步骤

请确保在某处保存一份副本,因为您只能看到它一次。

使用您的 API 密钥,您将能够向 OpenAI 发出经过身份验证的 HTTP 请求。因此,熟悉 API 本身是个好主意。我鼓励您简要浏览一下 OpenAI 文档 并熟悉一些概念。 模型特别容易理解,因为它们具有不同的功能。

如果您想熟悉 API 端点、预期负载和返回值,请查看 OpenAI API 参考。它还包含有用的示例。

您可能会注意到 NPM 上提供的 JavaScript 包名为 openai。我们将不会使用这个,因为它不太支持我们想要做的一些事情,而fetch可以。

发出您的第一个 HTTP 请求

我们要构建的应用程序将根据用户输入进行人工智能生成的文本补全。为此,我们需要使用 聊天端点(请注意,完成端点已弃用)。

我们需要使用 'Authorization' 设置为 'Bearer OPENAI_API_KEY'(您需要将 OPENAI_API_KEY 替换为您的 API 密钥),并且 body< /code> 设置为包含要使用的 GPT 模型的 JSON 字符串(我们将使用 gpt-3.5-turbo)和一组消息:

JavaScript

 

fetch('https://api.openai.com/v1/chat/completions', {
  方法:'POST',
  标题:{
    '内容类型':'应用程序/json',
    '授权': '承载 OPENAI_API_KEY'
  },
  正文:JSON.stringify({
    '型号': 'gpt-3.5-turbo',
    “消息”:[
      {
        '角色':'用户',
        'content': '给我讲一个有趣的笑话'
      }
    ]
  })
})

您可以直接从浏览器控制台运行此命令,并在开发工具的“网络”选项卡中查看请求。

响应应该是一个带有一堆属性的 JSON 对象,但我们最感兴趣的是“choices”。它将是文本完成对象的数组。第一个应该是一个带有 "message" 对象的对象,该对象具有带有聊天完成信息的 "content" 属性。

JSON

 

{
  “id”:“chatcmpl-7q63Hd9pCPxY3H4pW67f1BPSmJs2u”,
  "object": "聊天完成",
  “创建”:1692650675,
  “型号”:“gpt-3.5-turbo-0613”,
  “选择”:[
    {
      “索引”:0,
      “信息”: {
        “角色”:“助理”,
        "content": "为什么科学家不相信原子?\n\n因为它们构成了一切!"
      },
      "finish_reason": "停止"
    }
  ],
  “用法”: {
    “提示令牌”:12,
    “完成令牌”:13,
    “total_tokens”:25
  }
}

恭喜!现在您可以随时请求一个平庸的笑话。

构建表单

上面的fetch请求很好,但它不完全是一个应用程序。我们想要的是用户可以与之交互以生成像上面这样的 HTTP 请求。

为此,我们可能需要某种形式的 HTML

包含

<按钮>告诉我

' data-lang="text/html">

<表单>
  
  

  <按钮>告诉我


我们可以将此表单复制并粘贴到 Qwik 组件的 JSX 模板中。如果您过去使用过 JSX,则可能习惯于替换 for 属性 htmlFor,但 Qwik 的编译器不需要我们这样做就可以了。

接下来,我们要替换默认的表单提交行为。默认情况下,提交 HTML 表单时,浏览器将通过加载表单的 action 属性中提供的 URL 来创建 HTTP 请求。如果未提供,它将使用当前 URL。我们希望避免此页面加载并使用 JavaScript。

如果您以前做过此操作,您可能会熟悉 preventDefault 方法rel="noopener noreferrer" target="_blank">事件接口。顾名思义,它会阻止事件的默认行为。

由于Qwik 处理事件的方式,这里存在一个挑战处理程序。与其他框架不同,Qwik 不会在首页加载时下载应用程序的所有 JavaScript 逻辑。相反,它有一个非常瘦的客户端,可以拦截用户交互并按需下载 JavaScript 事件处理程序。

这种异步特性使得 Qwik 应用程序的加载速度更快,但也带来了异步处理事件处理程序的挑战。它使得不可能像在用户交互之前下载和解析的同步事件处理程序一样阻止默认行为。

幸运的是,Qwik 提供了一种通过将 preventdefault:{eventName} 添加到 HTML 标记来防止默认行为的方法。一个非常基本的表单示例可能如下所示:

JavaScript
 
从 '@builder.io/qwik' 导入 { component$ };
 
导出默认组件$(() => {
  返回 (
    <表格
      防止默认:提交
      onSubmit$={(事件) => {
        控制台.日志(事件)
      }}
    >
      
    
  )
})

您是否注意到 onSubmit$ 处理程序末尾的那个小 $ ?请留意这些内容,因为它们通常向开发人员暗示 Qwik 的编译器将做一些有趣的事情并转换代码。在这种情况下,这是由于我上面提到的延迟加载事件处理系统造成的。

合并获取请求

现在我们已经有了工具,可以用我们上面创建的获取请求替换默认的表单提交。

接下来我们要做的是将数据从