برنامه نویسی

یک چت بابات هوش مصنوعی با NextJs ، Groq و Llama

این مستندات توضیح مفصلی درباره یک چت بابات AI ساخته شده با استفاده از آن ارائه می دهد بعد. jsبا گله، و للاما مدل زبان. Chatbot برای کمک به کاربران در حوزه های مختلف از جمله دانشگاهیان ، برنامه نویسی و یادگیری ماشین طراحی شده است.


فهرست مطالب

  1. مقدمه
  2. اجزای اصلی

  3. توضیح کد

  4. چگونه کار می کند
  5. راه اندازی و استقرار

مقدمه

AI chatbot قدرت از قدرت للاما (یک مدل زبان بزرگ) برای تولید پاسخ ها بر اساس ورودی کاربر. استفاده می کند گله به عنوان سرویس باطن برای مدیریت مدل Llama و بعد. js برای ساختن جلوی و پس زمینه با هم یکپارچه. Chatbot به گونه ای طراحی شده است که تعاملی ، پاسخگو و کاربر پسند باشد.

اجزای اصلی

API سمت سرور

API سمت سرور درخواست های دریافتی مشتری را انجام می دهد ، پیام ها را پردازش می کند ، با سرویس Groq تعامل دارد و پاسخ را به مشتری باز می گرداند.

رابط سمت مشتری

رابط سمت مشتری با استفاده از مؤلفه های React ساخته شده است و یک UI تمیز و بصری برای تعامل با chatbot فراهم می کند. این شامل ویژگی هایی مانند جریان واقعی پاسخ ها ، تاریخ پیام و طراحی براق است.

توضیح کد

کد سمت سرور

در زیر کد سمت سرور مسئول رسیدگی به درخواست های چت و تعامل با سرویس Groq است.

import Groq from 'groq-sdk';
const groq = new Groq({
  apiKey: process.env.NEXT_PUBLIC_GROQ_API_KEY
});

const systemPrompt = 
  "You are a friendly and knowledgeable academic assistant, " +
  "coding assistant and a teacher of anything related to AI and Machine Learning. " +
  "Your role is to help users with anything related to academics, " +
  "provide detailed explanations, and support learning across various domains.";

export async function POST(request) {
  try {
    const { messages, msg } = await request.json();

    // Safely handle undefined or null messages
    const processedMessages = messages && Array.isArray(messages) 
      ? messages.reduce((acc, m) => {
          if (m && m.parts && m.parts[0] && m.parts[0].text) {
            acc.push({
              role: m.role === "model" ? "assistant" : "user",
              content: m.parts[0].text
            });
          }
          return acc;
        }, [])
      : [];

    const enhancedMessages = [
      { role: "system", content: systemPrompt },
      ...processedMessages,
      { role: "user", content: msg }
    ];

    const stream = await groq.chat.completions.create({
      messages: enhancedMessages,
      model: "llama3-8b-8192", // Choose your preferred model
      stream: true,
      max_tokens: 1024,
      temperature: 0.7,
    });

    // Create a custom readable stream to parse the chunks
    const responseStream = new ReadableStream({
      async start(controller) {
        const encoder = new TextEncoder();

        try {
          for await (const chunk of stream) {
            const content = chunk.choices[0]?.delta?.content;

            if (content) {
              controller.enqueue(encoder.encode(content));
            }
          }
        } catch (error) {
          console.error("Streaming error:", error);
          controller.error(error);
        } finally {
          controller.close();
        }
      }
    });

    return new Response(responseStream);
  } catch (error) {
    console.error("Error in chat API:", error);
    return new Response(JSON.stringify({ 
      error: "An error occurred processing your request",
      details: error.message 
    }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' }
    });
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

توضیح:

  1. وابستگی های وارداتی:

    • Groq از groq-sdk بسته بندی برای تعامل با سرویس Groq.
    • در POST عملکرد برای رسیدگی به درخواست های ورودی HTTP ورودی تعریف شده است.
  2. فوری سیستم:

    • یک سریع سیستم از پیش تعریف شده برای هدایت رفتار مدل Llama تنظیم شده است. این تضمین می کند که chatbot مفید و آگاه است.
  3. پردازش پیام ها:

    • در messages آرایه از درخواست برای استخراج محتوای مربوطه پردازش می شود. هر پیام به یک قالب سازگار با API GRAC تبدیل می شود.
  4. افزایش پیام ها:

    • سریع سیستم به لیست پیام ها اضافه می شود و به دنبال آن آخرین پیام کاربر است.
  5. ایجاد جریان تکمیل:

    • در groq.chat.completions.create روش برای تولید پاسخ از مدل Llama استفاده می شود. پاسخ در زمان واقعی به مشتری باز می گردد.
  6. جریان قابل خواندن:

    • یک عرف ReadableStream برای تجزیه و تحلیل پاسخ پخش شده و ارسال آن به صورت تدریجی به مشتری ایجاد شده است.
  7. رسیدگی به خطا:

    • خطاها در طی فرآیند گرفتار و ورود به سیستم می شوند و پاسخ خطای مناسبی به مشتری ارسال می شود.

کد سمت مشتری

در زیر کد سمت مشتری برای رابط چت قرار دارد.

'use client'
import React, { useEffect, useRef, useState } from 'react';
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Send, Bot, User, Zap } from "lucide-react";
import ReactMarkdown from 'react-markdown';

const ChatInterface = () => {
  const [messages, setMessages] = useState([
    {
      role: "model",
      parts: [{ text: "Hello! I'm ready to assist you. What would you like to explore today?" }],
    },
  ]);
  const [message, setMessage] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const messagesEndRef = useRef(null);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  };

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  const sendMessage = async () => {
    if (!message.trim() || isLoading) return;
    setIsLoading(true);
    setMessage("");

    setMessages((messages) => [
      ...messages,
      { role: "user", parts: [{ text: message }] },
      { role: "model", parts: [{ text: "" }] },
    ]);

    try {
      const response = await fetch("/api/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          history: [...messages],
          msg: message,
        }),
      });

      if (!response.ok) throw new Error("Network response was not ok");

      if (response.body) {
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let fullResponse = "";

        while (true) {
          const { done, value } = await reader.read();
          if (done) break;

          const text = decoder.decode(value || new Uint8Array(), { stream: true });
          fullResponse += text;

          setMessages((messages) => {
            const lastMessage = messages[messages.length - 1];
            const otherMessages = messages.slice(0, messages.length - 1);
            return [
              ...otherMessages,
              {
                ...lastMessage,
                parts: [{ text: fullResponse }],
              },
            ];
          });
        }
      }
    } catch (error) {
      console.error("Error:", error);
      setMessages((messages) => [
        ...messages,
        {
          role: "model",
          parts: [{ text: "Apologies, an unexpected error occurred. Please try again." }],
        },
      ]);
    }

    setIsLoading(false);
  };

  const handleKeyPress = (e) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }
  };

  return (
    <div className="min-h-screen bg-[#1C1C1E] flex items-center justify-center p-4">
      <div className="w-full max-w-4xl bg-[#2C2C2E] rounded-2xl shadow-2xl border border-[#3A3A3C] overflow-hidden">
        {/* Header */}
        <div className="bg-[#3A3A3C] p-4 md:p-6 flex justify-between items-center">
          <div className="flex items-center gap-3">
            <div className="bg-[#4A4A4C] p-2 rounded-full">
              <Zap className="w-6 h-6 text-[#5E5CE6]" />
            </div>
            <h1 className="text-xl md:text-2xl font-bold text-white">AI Companion</h1>
          </div>
        </div>

        {/* Chat Area */}
        <div className="p-4 md:p-6 flex flex-col h-[75vh]">
          <ScrollArea className="flex-grow mb-4 pr-4">
            <div className="space-y-4">
              {messages.map((message, index) => (
                <div
                  key={index}
                  className={`flex items-start ${
                    message.role === "user" ? "justify-end" : "justify-start"
                  }`}
                >
                  <div
                    className={`flex gap-3 max-w-[85%] md:max-w-[75%] ${
                      message.role === "user" ? "flex-row-reverse" : "flex-row"
                    }`}
                  >
                    <div className="flex h-10 w-10 shrink-0 select-none items-center justify-center rounded-full bg-[#3A3A3C]">
                      {message.role === "user" ? (
                        <User className="h-5 w-5 text-[#5E5CE6]" />
                      ) : (
                        <Bot className="h-5 w-5 text-[#5E5CE6]" />
                      )}
                    </div>
                    <div
                      className={`rounded-2xl px-4 py-3 shadow-lg ${
                        message.role === "user"
                          ? "bg-[#5E5CE6] text-white"
                          : "bg-[#3A3A3C] text-white"
                      }`}
                    >
                      <div className="prose prose-invert max-w-none">
                        <ReactMarkdown>{message.parts[0].text}</ReactMarkdown>
                      </div>
                    </div>
                  </div>
                </div>
              ))}
              {isLoading && (
                <div className="flex justify-center">
                  <div className="animate-pulse rounded-full h-8 w-8 bg-[#5E5CE6]" />
                </div>
              )}
              <div ref={messagesEndRef} />
            </div>
          </ScrollArea>

          {/* Input Area */}
          <div className="flex gap-3 mt-auto">
            <Textarea
              value={message}
              onChange={(e) => setMessage(e.target.value)}
              onKeyDown={handleKeyPress}
              placeholder="Type your message..."
              className="h-[40px] text-white bg-[#3A3A3C] border-gray-100 focus:border-blue-200 resize-none rounded-xl"
              disabled={isLoading}
            />
            <Button
              size="icon"
              className="h-[60px] w-[60px] bg-[#5E5CE6] hover:bg-[#4B3FD6] rounded-xl transition-all duration-300 ease-in-out transform hover:scale-105"
              onClick={sendMessage}
              disabled={!message.trim() || isLoading}
            >
              <Send className="h-5 w-5 text-white" />
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default ChatInterface;
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

توضیح:

  1. مدیریت دولت:

    • messages: تاریخچه مکالمه را بین کاربر و chatbot ذخیره می کند.
    • message: ورودی کاربر فعلی را نگه می دارد.
    • isLoading: نشان می دهد که آیا chatbot پاسخی ایجاد می کند یا خیر.
  2. رفتار پیمایش:

    • در scrollToBottom عملکرد تضمین می کند که هر زمان که پیام جدیدی اضافه شود ، منطقه چت به پایین می رود.
  3. ارسال پیام:

    • در sendMessage عملکرد پیام کاربر را از طریق تماس API به سرور ارسال می کند و تاریخچه مکالمه را با پاسخ ربات به روز می کند.
  4. جریان در زمان واقعی:

    • پاسخ از سرور به صورت تدریجی پخش می شود و رابط چت در زمان واقعی به روز می شود زیرا ربات پاسخ خود را ایجاد می کند.
  5. اجزای UI:

    • رابط گپ شامل یک هدر ، یک منطقه چت قابل پیمایش و یک منطقه ورودی برای ارسال پیام است.
    • نمادها (Userبا Botبا Zapبا Send) برای تقویت جذابیت بصری و ارائه شاخص های روشنی از صحبت کردن چه کسی استفاده می شود.
  6. رسیدگی به خطا:

    • اگر خطایی در هنگام تماس API رخ دهد ، chatbot یک پیام خطای مناسب را نشان می دهد.

چگونه کار می کند

  1. تعامل کاربر:

    • کاربر یک پیام را در قسمت ورودی تایپ می کند و یا با فشار دادن دکمه “ارسال” یا ضربه زدن به کلید Enter ، آن را ارسال می کند.
  2. پردازش سرور:

    • سرور پیام را دریافت می کند ، آن را پردازش می کند و آن را برای تولید تکمیل به سرویس Groq می فرستد.
  3. جریان پاسخ:

    • پاسخ تولید شده در زمان واقعی به مشتری باز می گردد و رابط چت را به صورت پویا به روز می کند.
  4. نمایش:

    • رابط چت تاریخ مکالمه را نشان می دهد و با استفاده از رنگ ها و نمادهای مختلف بین پیام های کاربر و ربات تمایز قائل می شود.

راه اندازی و استقرار

پیش نیازهای

  • Node.js و NPM روی دستگاه شما نصب شده اند.
  • یک کلید API Groq با دسترسی به مدل Llama.

گام

  1. کلون مخزن:
   git clone https://github.com/Minty-cyber/AI-Chatbot
   cd chatbot
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

  1. وابستگی ها را نصب کنید:
   npm install
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

  1. متغیرهای محیط را تنظیم کنید:

     NEXT_PUBLIC_GROQ_API_KEY=your-groq-api-key
    
  2. برنامه را اجرا کنید:

   npm run dev
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

  1. مستقر کردن:

    • برای استقرار برنامه از سیستم عامل هایی مانند Vercel یا NetLify استفاده کنید.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا