Semua artikel
#ai#chatbot#rag#ai-sdk

Tutorial: Membuat Chatbot AI untuk Brand Sendiri (dengan RAG)

Arif5 menit baca tayangan
Ilustrasi sampul: Tutorial: Membuat Chatbot AI untuk Brand Sendiri (dengan RAG)

Setiap brand kini ingin asisten AI yang paham produk dan kebijakannya — bukan chatbot generik. Rahasianya adalah RAG (Retrieval-Augmented Generation): AI menjawab berdasarkan dokumenmu sendiri, bukan tebakan. Tutorial ini membangunnya langkah demi langkah dengan AI SDK.

Untuk siapa tutorial ini?

  • Tingkat: Pemula–Menengah (paham dasar React/Next.js akan membantu)
  • Perkiraan waktu: 60–90 menit
  • Hasil akhir: chatbot di halaman web yang menjawab berdasarkan dokumen yang kamu beri

Istilah penting dulu:

  • Embedding = mengubah teks menjadi deretan angka (vektor) agar komputer bisa mengukur "kemiripan makna".
  • Chunk = potongan kecil dokumen.
  • RAG = teknik mencari potongan dokumen yang relevan lalu menyuapkannya ke AI sebagai bahan jawaban.
  • Halusinasi = saat AI mengarang jawaban yang terdengar yakin padahal salah.

Prasyarat

  1. Node.js 18+ (cek node -v di Terminal).

  2. Proyek Next.js. Belum punya? npx create-next-app@latest chatbot-brand lalu cd chatbot-brand.

  3. Database dengan dukungan vektor — gunakan Neon atau Supabase (keduanya mendukung ekstensi pgvector untuk menyimpan embedding).

  4. Paket yang diperlukan, instal lewat Terminal:

    npm install ai @ai-sdk/react
  5. Kunci API AI di file .env.local (lihat tutorial AI Workflow untuk caranya).

Cara kerja RAG (gambaran besar)

Baca ini sekali agar paham alurnya sebelum koding:

  1. Dokumenmu dipecah jadi potongan kecil (chunks).
  2. Tiap chunk diubah jadi embedding dan disimpan ke database.
  3. Saat user bertanya, pertanyaan juga diubah jadi embedding lalu dicari chunk paling mirip.
  4. Chunk relevan diselipkan ke prompt AI sebagai konteks, lalu AI menjawab.

Langkah 1: Siapkan embedding dokumen

Buat file lib/siapkan-dokumen.ts. Kode ini mengubah potongan teks menjadi embedding lalu menyimpannya.

// lib/siapkan-dokumen.ts
import { embedMany } from 'ai'
 
export async function siapkanDokumen(chunks: string[]) {
  // ubah banyak teks sekaligus menjadi embedding
  const { embeddings } = await embedMany({
    model: 'openai/text-embedding-3-small',
    values: chunks, // contoh: ["Jam buka kami 09.00-17.00", "Garansi 30 hari", ...]
  })
 
  // simpan pasangan { teks, embedding } ke database vektor milikmu
  await simpanKeDatabase(chunks, embeddings)
}

Tips memecah dokumen: potong tiap 300–500 kata, atau per paragraf. Chunk terlalu besar membuat pencarian kurang tepat; terlalu kecil membuat konteks hilang.

Langkah 2: Cari konteks relevan

Buat file lib/cari-konteks.ts:

// lib/cari-konteks.ts
import { embed } from 'ai'
 
export async function cariKonteks(pertanyaan: string) {
  // ubah pertanyaan user menjadi embedding
  const { embedding } = await embed({
    model: 'openai/text-embedding-3-small',
    value: pertanyaan,
  })
 
  // ambil 4 chunk paling mirip (cosine similarity) dari database
  return cariChunkTerdekat(embedding, 4) // mengembalikan array string
}

Istilah: Cosine similarity adalah cara mengukur seberapa "searah" dua vektor — makin searah, makin mirip maknanya.

Langkah 3: Buat route API chat

Buat file app/api/chat/route.ts. Gunakan streamText agar jawaban muncul mengalir seperti ChatGPT.

// app/api/chat/route.ts
import { streamText, convertToModelMessages } from 'ai'
import { cariKonteks } from '@/lib/cari-konteks'
 
export async function POST(req: Request) {
  const { messages } = await req.json()
  // ambil teks pertanyaan terakhir dari user
  const pertanyaan = messages[messages.length - 1].content
  const konteks = await cariKonteks(pertanyaan)
 
  const result = streamText({
    model: 'openai/gpt-5-mini',
    system: `Kamu asisten resmi brand. Jawab HANYA berdasarkan konteks berikut.
    Jika informasinya tidak ada di konteks, katakan kamu tidak tahu.
 
    Konteks:
    ${konteks.join('\n')}`,
    messages: convertToModelMessages(messages),
  })
 
  return result.toUIMessageStreamResponse()
}

Instruksi "jawab HANYA berdasarkan konteks" sangat penting untuk mencegah AI berhalusinasi.

Langkah 4: Buat UI chat dengan useChat

Buat file components/chat.tsx:

// components/chat.tsx
'use client'
import { useChat } from '@ai-sdk/react'
import { useState } from 'react'
 
export function Chat() {
  const { messages, sendMessage, status } = useChat()
  const [input, setInput] = useState('')
 
  return (
    <div className="mx-auto flex max-w-lg flex-col gap-3 p-4">
      {messages.map((m) => (
        <div key={m.id} className="rounded-md bg-card p-3">
          <strong>{m.role === 'user' ? 'Kamu' : 'Asisten'}:</strong>{' '}
          {m.parts.map((p, i) => (p.type === 'text' ? <span key={i}>{p.text}</span> : null))}
        </div>
      ))}
 
      <form
        onSubmit={(e) => {
          e.preventDefault()
          sendMessage({ text: input })
          setInput('')
        }}
        className="flex gap-2"
      >
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Tanya sesuatu..."
          className="flex-1 rounded-md border bg-background px-3 py-2"
        />
        <button
          disabled={status !== 'ready'}
          className="rounded-md bg-primary px-4 py-2 text-primary-foreground"
        >
          Kirim
        </button>
      </form>
    </div>
  )
}

Tampilkan di app/page.tsx:

import { Chat } from "@/components/chat"
 
export default function Home() {
  return <Chat />
}

Yang harus kamu lihat: jalankan npm run dev, buka http://localhost:3000, ketik pertanyaan tentang isi dokumenmu. Jawaban muncul mengalir dan hanya berdasarkan dokumen yang kamu beri.

Langkah 5: Beri batasan dan kepribadian

Atur nada bicara dan batasan di system prompt (Langkah 3): bahasa, panjang jawaban, dan kapan harus mengarahkan ke manusia. Inilah yang membuat chatbot terasa "milik brand", bukan generik.

Troubleshooting

  • Jawaban selalu "saya tidak tahu" → kemungkinan pencarian konteks kosong. Pastikan dokumen sudah di-embed (Langkah 1) dan database terisi.
  • Error koneksi database → cek variabel lingkungan database di .env.local.
  • Jawaban mengarang di luar dokumen → perkuat instruksi "jawab HANYA berdasarkan konteks" di system.
  • UI tidak mengirim pesan → pastikan file route ada di app/api/chat/route.ts (nama folder harus persis chat).

Tips produksi

  • Cantumkan sumber (chunk mana yang dipakai) agar jawaban bisa diverifikasi.
  • Batasi rate dan simpan riwayat untuk evaluasi.
  • Perbarui embedding tiap kali dokumen berubah.

Dengan pola ini kamu bisa membuat asisten untuk FAQ, dokumentasi produk, atau onboarding. Untuk menjalankannya di servermu sendiri, lihat Panduan Deploy.

Suka dengan artikel ini?

Beri dukunganmu dengan menekan tombol suka — bantu pembaca lain menemukan konten terbaik.

Diskusi(0)

0/1000
Memuat komentar…

/ Baca juga