Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

ในบทความนี้ ผมจะเล่าเกี่ยวกับการสร้าง Custom Content RAG Chatbot แบบโอเพนซอร์ส ด้วย Upstash Vector, Upstash Redis, Hugging Face Inference API, Replicate LLAMA-2-70B Chat model และ Vercel Upstash Vector ช่วย insert และ query vectors สร้าง context ที่เกี่ยวข้องแบบไดนามิกสำหรับแต่ละข้อความของผู้ใช้ ส่วน Upstash Redis ช่วยเก็บประวัติการสนทนาของ chatbot

ข้อกำหนดเบื้องต้น

  • Node.js 18 หรือใหม่กว่า
  • บัญชี Upstash
  • บัญชี Hugging Face
  • บัญชี Replicate
  • บัญชี Vercel

เทคโนโลยีที่ใช้

เทคโนโลยีคำอธิบาย
Upstashแพลตฟอร์มฐานข้อมูล Serverless ใช้ Upstash Vector และ Upstash Redis สำหรับเก็บ vectors และ conversations ตามลำดับ
Next.jsเฟรมเวิร์ก React สำหรับเว็บ ใช้ shadcn/ui สำหรับ prototyping รวดเร็ว
Replicateรันและ fine-tune โมเดลโอเพนซอร์ส ใช้โมเดล LLAMA-2-70B Chat
Hugging Faceแพลตฟอร์มชุมชน ML ใช้ Hugging Face Inference API สร้าง embeddings
LangChainเฟรมเวิร์กพัฒนาแอปขับเคลื่อนด้วย language models
TailwindCSSเฟรมเวิร์ก CSS สำหรับออกแบบที่ปรับแต่งได้
Vercelแพลตฟอร์มคลาวด์ปรับใช้และปรับขนาดแอปเว็บ

ตั้งค่า Upstash Redis

สร้างบัญชี Upstash เข้าสู่ระบบ ไปที่แท็บ Redis สร้างฐานข้อมูล

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

หลังสร้างเสร็จ ไปที่แท็บ Details เลื่อนลงหาส่วน Connect your database คัดลอกเก็บไว้

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

เลื่อนลงหาส่วน REST API กดปุ่ม .env คัดลอกเก็บไว้

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

ตั้งค่า Upstash Vector

ไปที่แท็บ Vector สร้าง Index

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

เลื่อนลงหาส่วน Connect กดปุ่ม .env คัดลอกเก็บไว้

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

ตั้งค่าโปรเจกต์

โคลน repo และติดตามคู่มือ:

git clone https://github.com/rishi-raj-jain/custom-rag-chatbot-upstash-vector
cd custom-rag-chatbot-upstash-vector
pnpm install

สร้างไฟล์ .env ใส่ค่าจากขั้นตอนก่อนหน้า:

# .env
# Upstash Redis URL and Token
UPSTASH_REDIS_REST_URL="https://....upstash.io"
UPSTASH_REDIS_REST_TOKEN="..."
# Upstash Vector URL and Token
UPSTASH_VECTOR_REST_URL="https://...-vector.upstash.io"
UPSTASH_VECTOR_REST_TOKEN="..."
# Replicate API Key
REPLICATE_API_TOKEN="r8_..."
# Hugging Face Inference API Key
HUGGINGFACEHUB_API_KEY="hf_..."

รัน local environment:

pnpm dev

โครงสร้าง Repository

โครงสร้างโฟลเดอร์หลัก (ไฟล์ที่ติดสีแดงจะอธิบายต่อไป)

สร้าง RAG Chatbot อันทรงพลังด้วย Upstash: คู่มือทีละขั้นตอน

ตั้งค่า Chat Route ใน Next.js App Router

ส่วนนี้อธิบาย route app/api/chat/route.js สำหรับ sync conversation ใน serverless database สร้าง embeddings แบบไดนามิก query vectors ที่เกี่ยวข้อง และ request predictions จาก LLAMA-2-70B Chat model

เก็บ Conversations

ใช้ Redis Lists เก็บการสนทนา เมื่อมีข้อความจากผู้ใช้ ให้ push คำตอบของ chatbot (ครั้งก่อน) เข้า list แล้ว push ข้อความล่าสุดของผู้ใช้เข้า list ด้วย

// File: app/api/chat/route.js
import { Redis } from '@upstash/redis'

const upstashRedis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL,
  token: process.env.UPSTASH_REDIS_REST_TOKEN,
})

export async function POST(req) {
  try {
    const { messages } = await req.json()
    
    if (messages.length > 1) {
      await upstashRedis.lpush('unique_conversation_id', JSON.stringify(messages[messages.length - 2]))
    }
    await upstashRedis.lpush('unique_conversation_id', JSON.stringify(messages[messages.length - 1]))
    
    // สร้างคำตอบต่อไป...
  }
}

สร้าง embedding ของข้อความล่าสุด

ใช้ Hugging Face Inference API กับ LangChain สร้าง embeddings บน edge ตัด vector ให้ยาวตามที่ตั้งค่าไว้ (256)

// File: app/api/chat/route.js
import { HuggingFaceInferenceEmbeddings } from '@langchain/community/embeddings/hf'

const embeddings = new HuggingFaceInferenceEmbeddings()

export async function POST(req) {
  try {
    // ...
    const userMessages = messages.filter(i => i.role === 'user')
    const lastMessage = userMessages[userMessages.length - 1].content
    const queryVector = (await embeddings.embedQuery(lastMessage)).slice(0, 256)
    // สร้างคำตอบต่อไป...
  }
}

ดึง context vectors ที่เกี่ยวข้องจากข้อความล่าสุด

Query vectors ที่มีอยู่ หา top 2 ที่เกี่ยวข้องที่สุด รวม metadata กรองเฉพาะ confidence score > 70%

// File: app/api/chat/route.js
import { Index } from '@upstash/vector'

const upstashVectorIndex = new Index()

export async function POST(req) {
  try {
    // ...
    const queryResult = await upstashVectorIndex.query({
      vector: queryVector,
      topK: 2,
      includeVectors: false,
      includeMetadata: true,
    })
    
    const queryPrompt = queryResult
      .filter(match => match.score && match.score > 0.7)
      .map(match => match.metadata.description)
      .join('\n')
    // สร้างคำตอบต่อไป...
  }
}

Prompt LLAMA-2-70B Chat model ด้วย context เพื่อทำนาย

ใช้ Vercel AI SDK experimental_buildLlama2Prompt สร้าง prompt format ที่เหมาะสม

// File: app/api/chat/route.js
import Replicate from 'replicate'
import { experimental_buildLlama2Prompt } from 'ai/prompts'
import { ReplicateStream, StreamingTextResponse } from 'ai'

const replicate = new Replicate({ auth: process.env.REPLICATE_API_TOKEN })

export async function POST(req) {
  try {
    // ...
    const response = await replicate.predictions.create({
      stream: true,
      version: '2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1',
      input: {
        prompt: experimental_buildLlama2Prompt([
          {
            role: 'system',
            content: queryPrompt.substring(0, Math.min(queryPrompt.length, 2000)),
          },
          ...messages,
        ]),
      },
    })
    
    const stream = await ReplicateStream(response)
    return new StreamingTextResponse(stream)
  }
}

ตั้งค่า Train Route ใน Next.js App Router

Route app/api/train/route.js สร้าง embeddings ของ strings ที่ส่งมา และ upsert เข้า Upstash Vector Index

สร้าง embeddings ของ strings

// File: app/api/train/route.js
import { HuggingFaceInferenceEmbeddings } from '@langchain/community/embeddings/hf'

const embeddings = new HuggingFaceInferenceEmbeddings()

export async function POST(req) {
  try {
    let messagesToVectorize = [
      'Rishi is pretty much active on Twitter nowadays.',
      'Rishi loves writing for Upstash',
      "Rishi's recent article on building chatbot using Upstash went viral",
      'Rishi is enjoying building launchfa.st.',
    ]
    
    if (req.headers.get('Content-Type') === 'application/json') {
      const { messages } = await req.json()
      if (typeof messages !== 'string' && messages.length > 0) {
        messagesToVectorize = messages
      }
    }
    
    const generatedEmbeddings = await Promise.all(messagesToVectorize.map(i => embeddings.embedQuery(i)))
    // ...
  }
}

เก็บ vectors สำหรับ relevance search

Slice vectors ให้ยาว 256 ใช้ upsert ใส่ embedding พร้อม metadata (คือ strings เอง) เพื่อดึงกลับมาได้เมื่อค้นหา vectors ที่คล้ายกัน

// File: app/api/train/route.js
import { Index } from '@upstash/vector'

const upstashVectorIndex = new Index()

export async function POST(req) {
  try {
    // ...
    await Promise.all(
      generatedEmbeddings
        .map(i => i.slice(0, 256))
        .map((vector, index) => 
          upstashVectorIndex.upsert({
            vector,
            id: index.toString(),
            metadata: { description: messagesToVectorize[index] },
          })
        ),
    )
    
    return new Response(JSON.stringify({ code: 1 }), {
      status: 200,
      headers: { 'Content-Type': 'application/json' }
    })
  }
}

ปรับใช้งานบน Vercel

  • สร้าง GitHub repository
  • ไป Vercel Dashboard สร้าง New Project
  • เชื่อมกับ GitHub repo
  • ใน Settings อัปเดต Environment Variables ให้ตรง .env local
  • Deploy! 🚀

ข้อมูลเพิ่มเติม

สำหรับรายละเอียดเพิ่มเติม โปรดดู references ในบทความนี้

สรุป

โปรเจกต์นี้ให้ประสบการณ์มีค่าในการสร้าง embeddings query จาก vectors ที่มีอยู่ และใช้ context สร้าง predictions ที่เกี่ยวข้องด้วย LLAMA-2-70B Chat model พร้อมใช้บริการที่ปรับขนาดได้ตามความต้องการ คือ Upstash