Developing an AI-Powered Chatbot with Vercel AI SDK

Developing an AI-Powered Chatbot with Vercel AI SDK

Prerequisites

  • GROQ API key

Step 1: Install the Required npm Packages

Run the following commands to install necessary packages:

npm install groq-sdk

npm install ai

npm install react-markdown        

Setting Up the Environment Variables

Then, we need to setup environment variable in .env file. You can get GROQ API Key from here

GROQ_API_KEY="GROQ_API_KEY"        

Step 2: Create the Chatbot Components

1. ChatHeader Component

Create a chat-header.tsx file with the following code:

import React from "react";

const ChatHeader = () => {
  return (
    <div className="h-[70px] p-3 border">
      <h3>AI ChatBot</h3>
      <h4>Basic chatbot example with Vercel AI SDK</h4>
    </div>
  );
};

export default ChatHeader;        

2. ChatInput Component

Create a chat-input.tsx file.

The ChatInput component is used to renders a input from for user text input and handles input changes and form submission through provided handler functions.

import React, { ChangeEvent, FormEvent } from "react";

type ChatInputProps = {
  handleInputChange: (e: ChangeEvent<HTMLInputElement>) => void;
  input: string;
  className?: string;
  handleSubmit: (e: FormEvent<HTMLFormElement>) => void;
};

const ChatInput = ({
  handleInputChange,
  handleSubmit,
  input,
}: ChatInputProps) => {
  return (
    <div className="p-3 flex justify-center items-center border">
      <form className="w-full" onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={handleInputChange}
          className="p-2 rounded-md outline-none border-none w-full text-foreground"
          placeholder="write here..."
        />
      </form>
    </div>
  );
};

export default ChatInput;        

3. ChatMessage Component

Create a chat-message.tsx file.

The ChatMessage component is used to displays a chat message with conditional formatting based on whether the message is from the user or assistant and also using react-markdown for message content rendering.

import React from "react";
import Markdown from "react-markdown";

type ChatMessageProps = {
  message: Message;
  isUserMessage: boolean;
};

const ChatMessage = ({ message, isUserMessage }: ChatMessageProps) => {
  return (
    <div className="chat-message" key={`${message.id}-${message.id}`}>
      <div className={`flex items-end ${isUserMessage ? "justify-end" : ""}`}>
        <div className={`flex flex-col space-y-3 text-sm max-w-xs mx-3 overflow-x-hidden ${isUserMessage ? "order-1 items-end" : "order-2 items-start"}`}>
          <div className={`px-4 py-3 rounded-lg ${isUserMessage ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-900"}`}>
            <Markdown>{message.content}</Markdown>
          </div>
        </div>
      </div>
    </div>
  );
};

export default ChatMessage;        

4. ChatMessages Component

Create a chat-messages.tsx file.

This component will display a list of chat messages. The Vercel AI SDK will handle user messages by synchronizing with the input component.

"use client";

import React from "react";
import ChatMessage from "@/components/chat-message";

type ChatMessagesProps = {
  messages: Message[];
  className?: string;
};

const ChatMessages = ({ messages, className }: ChatMessagesProps) => {
  const inverseMessages = [...messages].reverse();

  return (
    <div className={`flex flex-col-reverse gap-3 overflow-y-auto flex-grow py-3 no-scrollbar ${className}`}>
      <div className="flex-1 flex-grow" />
      {inverseMessages.map((message) => (
        <ChatMessage key={message.id} message={message} isUserMessage={message.role === "user"} />
      ))}
    </div>
  );
};

export default ChatMessages;        

5. ChatWidget Component

Create a chat-widget.tsx file.

This component will integrate all previously defined components and handle the chatbot's logic.

"use client";
import React, { useState } from "react";
import ChatHeader from "@/components/chat-header";
import ChatInput from "@/components/chat-input";
import ChatMessages from "@/components/chat-messages";
import { useChat } from "ai/react";
import Image from "next/image";

const ChatWidget = () => {
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    api: "/api/chat",
  });

  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);

  return (
    <div className="fixed bottom-10 right-10">
      <div className="flex flex-col items-end">
        {isOpen && (
          <div className="w-[350px] flex flex-col shadow-md rounded-lg h-[600px] max-h-[70vh]">
            <ChatHeader />
            <div className="flex-1 border overflow-auto no-scrollbar">
              <ChatMessages messages={messages} />
            </div>
            <ChatInput handleInputChange={handleInputChange} input={input} handleSubmit={handleSubmit} />
          </div>
        )}
        <button onClick={toggle} className="mt-6 flex justify-center items-center cursor-pointer hover:scale-95 animate-in">
          <Image src="/chatbot.svg" alt="chatbot icon" height={60} width={60} />
        </button>
      </div>
    </div>
  );
};

export default ChatWidget;        

6. Add ChatWidget into Layout

After creating the ChatWidget component we need to set it on layout.tsx file in root directory for ensuring it that will appears on every page of your application:. Here is an example of it.

<body className={inter.className}>
  <ChatWidget />
        <main>
               {children}
        </main>
</body>        

Step 3: Create the Route for the Chat API

Create a route.ts file in the app/api/chat folder:

This file sets up an API route that takes user messages, sends them to a GROQ AI model and returns a stream response.

import { streamText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";

const groq = createOpenAI({
  baseURL: "<https://api.groq.com/openai/v1>",
  apiKey: process.env.GROQ_API_KEY,
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await streamText({
    model: groq("llama3-8b-8192"),
    system: "You are a helpful assistant. Give all your responses in markdown format.",
    messages,
  });

  return result.toAIStreamResponse();
}        

We can update the system message to modify how the LLM respond.

system: "You are a helpful assistant. Give all your responses in markdown format.",        

I hope you've successfully built the simple AI-powered chatbot using the Vercel AI SDK, React Markdown, and GROQ API. Check out my portfolio website at shubhamkashyap.in for more articles and code snippets.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了