Nuxt3 × Vuetify3 × LangChain × OpenAI 创建聊天机器人

开发环境

  • Nuxt.js 3.8.0
  • Vuetify 3.4.0
  • npm 9.5.1
  • Node.js v18.16.0

创建项目

  • 创建nuxt3项目
npx nuxi@latest init nuxt3-chatbot
  • 切换到nuxt3项目
cd nuxt3-chatbot
  • 运行
yarn dev

看到如下所示的屏幕,则 Nuxt3 项目创建已完成

Nuxt3 × Vuetify3 × LangChain × OpenAI 创建聊天机器人
image.png

安装Vuetify3

  • 将Vuetify3引入到Nuxt3项目中

使用以下命令安装最新版本的Vuetify3以及应用样式所需的mdi和SASS,作为开发的依赖项。

npm install vuetify@next mdi @mdi/font sass --save-dev
  • 配置Vuetify3 直接在根目录下创建一个plugins目录,并在其中创建一个vuetify.ts文件,vuetify.ts 如下:
import { createVuetify } from "vuetify";
import * as components  from "vuetify/components";
import * as directives from "vuetify/directives";

export default defineNuxtPlugin((nuxtApp) => {
    const vuetify = createVuetify({
        components,
        directives
    });
    nuxtApp.vueApp.use(vuetify)
})

在上述代码中,我们安装了Vuetify所需的模块,并在defineNuxtPlugin中创建了Vuetify实例并进行了挂载。这样就可以使用Vuetify的组件和指令(如v-bindv-modelv-if等)。

  • nuxt.config.ts中的配置
export default defineNuxtConfig({
  typescript:{
      shim:false
  },
  ssr:false,
  css: [
      "vuetify/lib/styles/main.sass",
      "mdi/css/materialdesignicons.min.css",
      "@mdi/font/css/materialdesignicons.css"
  ],
   build:{
      transpile:["vuetify"]
  },
  vite:{
      define:{
          "process.env.DEBUG"false,
      }
  }
})

在上面的代码中,我们使用了Vuetify和MDI的样式,并在构建过程中包含了Vuetify。

安装Vercel AI SDK和LangChain

Vercel AI SDK是由Vercel提供的一个库,可以轻松创建AI聊天机器人。 LangChain是一个库,可用于高效开发基于LLM的应用程序。

npm install ai langchain

设置OpenAI的API密钥

在根目录下创建一个名为.env的文件,请将OpenAI的API密钥替换为自己的密钥。

  • 将 API 密钥设置添加到 nuxt.config.ts 文件中
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  typescript:{
      shim:false
  },
  ssr:false,
  css: [
      "vuetify/lib/styles/main.sass",
      "mdi/css/materialdesignicons.min.css",
      "@mdi/font/css/materialdesignicons.css"
  ],
  build:{
      transpile:["vuetify"]
  },
  vite:{
      define:{
          "process.env.DEBUG"false,
      }
  },
  runtimeConfig:{
      openaiApiKey:process.env.NUXT_OPENAI_API_KEY
  },
})

创建 API 端点

接下来,创建一个端点以启用聊天。在 server/api 路径中创建 chat.ts 文件并执行以下操作:

//server/api/chat.ts
import {ChatOpenAI} from "langchain/chat_models/openai";
import {LangChainStream, Message, StreamingTextResponse} from "ai";
import {AIMessage, HumanMessage} from "langchain/schema";
export const runtime = 'edge';
export default defineLazyEventHandler(()=>{
    const apiKey = useRuntimeConfig().openaiApiKey;
    if (!apiKey){
        throw createError('Missing OpenAI API key')
    }
    const llm = new ChatOpenAI({
        openAIApiKey:apiKey,
        streaming:true
    });

    return defineEventHandler(async event => {
        const { message } = await readBody(event);
        const { stream,handlers } = LangChainStream();
        llm.call((message as Message[]).map(message=>
            message.role === 'user'
            ? new HumanMessage(message.content)
                : new AIMessage(message.content)
        ),{},[handlers]);

        return new StreamingTextResponse(stream)
    })
})

我们来解释一下这段代码:

  • 导入:首先导入所需的模块和类。包括LangChainStreamMessageStreamingTextResponse(从AI流式传输消息)、ChatOpenAI(与OpenAI的聊天模型配合使用)、AIMessageHumanMessage(在人类和AI之间表达消息)。
  • 运行时设置:runtime变量被设置为’edge’。这表示该代码将在边缘计算环境中运行。
  • 定义事件处理程序:defineLazyEventHandler 函数定义事件发生时要执行的函数。在此函数内,检查 OpenAI API 密钥是否存在,如果不存在则返回错误。之后,创建一个新的 ChatOpenAI 实例。
  • 实现事件处理程序:defineEventHandler 函数定义特定事件发生时要执行的具体处理。在此函数内,我们从请求中提取消息,将其转换为适当的格式(人类或 AI),然后将它们传递给 ChatOpenAI 实例的调用方法。
  • 流响应:创建一个新的 StreamingTextResponse 实例。这会将来自 AI 的消息作为流发送。

前端UI和API的调用

直接在App.vue中写:

<template>
  <v-app>
    <v-container>
      <v-sheet v-for="message in messages" :key="message.id" class="my-16 d-flex" :style="{
        position: 'relative',
      }"
>

        <v-avatar :color="message.role === 'user' ? 'primary' : 'secondary'" class="mr-2">
          <v-icon>{{ message.role === 'user' ? 'mdi-account' : 'mdi-robot' }}</v-icon>
        </v-avatar>
        <v-card :class="message.role === 'user' ? 'user-message' : 'ai-message'" class="pa-4 mb-4" :color="message.role === 'user' ? 'primary' : 'secondary'" :style="{
          borderRadius: '10px',
        }"
>

          {{ message.role === 'user' ? '私: ' : 'AI: ' }}
          {{ message.content }}
        </v-card>
      </v-sheet>
      <v-form @submit="handleSubmit" :style="{ position: 'fixed', bottom: '20px', width: '80%' }">
        <v-text-field v-model="input" hide-details variant="solo" label="メッセージを送信">
          <template #append-inner>
            <v-icon :color="input ? 'primary' : ''" @click="handleSubmit" :disabled="!input">mdi-send</v-icon>
          </template>
        </v-text-field>
      </v-form>
    </v-container>
  </v-app>

</template>

<script setup>
import { useChat } from 'ai/
vue'

const { messages, input, handleSubmit } = useChat({
  headers: { '
Content-Type': 'application/json' },
})
</script>

useChat:这是一个自定义钩子,用于管理聊天机器人的状态和行为。该钩子返回一个对象,其中包含消息数组、当前输入值和发送处理程序。


原文始发于微信公众号(大前端编程教学):Nuxt3 × Vuetify3 × LangChain × OpenAI 创建聊天机器人

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/224461.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!