Lewati ke konten utama

Chainlit: Panduan dengan Contoh Praktis

Pelajari apa itu Chainlit, cara menginstalnya, dan cara menjalankannya untuk membangun antarmuka interaktif bagi aplikasi berbasis LLM.
· 8 mnt Baca

Jelajahi bersama AI

Chainlit adalah framework Python open-source yang andal untuk membangun antarmuka interaktif bagi aplikasi berbasis LLM Anda dengan sedikit kode dan tanpa repot urusan front-end.

Dalam tutorial ini, saya akan membahas:

  1. Instalasi dan penyiapan Chainlit.
  2. Memahami konsep intinya, seperti actions, siklus obrolan, dan konfigurasi.
  3. Membangun dua aplikasi contoh: 
    • Chatbot statis “Surprise Me” menggunakan tombol
    • Bot “Surprise Me” yang didukung oleh Ollama

Apa itu Chainlit?

Chainlit membantu Anda membuat frontend untuk chatbot AI, tool, dan alur kerja LLM. Ini menyederhanakan kompleksitas front-end dan memungkinkan Anda fokus pada logika Python sambil menyediakan dukungan untuk menambahkan tombol, slider, unggah file, atau bahkan menghubungkan ke tool menggunakan model context protocol (MCP).

Chainlit ideal untuk:

  • Membuat prototipe aplikasi berbasis LLM
  • Membuat tool internal
  • Membangun demo edukasi
  • Menghubungkan model Anda ke tool atau API eksternal

Komponen Chainlit

Setiap aplikasi Chainlit dibangun dari beberapa fitur penting:

  1. Hook siklus obrolan: Ini memungkinkan Anda mengontrol apa yang terjadi pada berbagai tahap obrolan. Contohnya:
    • @cl.on_chat_start berjalan saat obrolan dimulai.
    • @cl.on_message berjalan saat pengguna mengirim pesan.
    • @cl.on_chat_end berjalan saat obrolan berakhir.
  2. Aksi UI: Chainlit memungkinkan Anda menambahkan tombol dengan cl.Action dan menanganinya dengan @cl.action_callback. Ini sangat berguna untuk membangun UI interaktif yang rapi tanpa memerlukan input teks pengguna.
  3. Streaming pesan: Dengan LLM yang mendukung streaming token, Anda dapat melakukan streaming respons secara real time menggunakan stream=True, sehingga aplikasi terasa lebih dinamis dan responsif.
  4. Konfigurasi dengan config.toml: File ini memungkinkan Anda mengaktifkan fitur seperti persistensi obrolan, unggah file, penyesuaian tema, dan peningkatan kegunaan—semuanya tanpa mengubah kode Python Anda.

Saya akan menjelaskan setiap konsep dengan contoh kode praktis agar Anda dapat melihat cara kerjanya dan mengintegrasikannya ke aplikasi Chainlit Anda. Mari mulai dari langkah pertama.

Prasyarat

Pastikan Python 3.8+ sudah terpasang, lalu instal Chainlit menggunakan pip. Kita juga akan menggunakan Langchain untuk demo Ollama, jadi pastikan untuk memasangnya. Jalankan perintah berikut di terminal:

pip install chainlit langchain langchain-community

Memahami Dasar Chainlit Melalui Contoh

Pada bagian ini, kita akan membahas blok pembangun inti Chainlit, yang akan menjadi inti dari proyek apa pun.

Hook siklus obrolan

Setiap kali pengguna terhubung ke aplikasi Chainlit Anda, sebuah sesi obrolan dibuat. Anda dapat memanfaatkan berbagai tahap sesi tersebut menggunakan dekorator yang disediakan Chainlit. Ini mencakup:

Membangun dengan @cl.on_chat_start

Hook ini berjalan saat sesi obrolan baru dimulai. Anda dapat menggunakannya untuk menyapa pengguna, menampilkan pesan sambutan, atau menginisialisasi status sesi.

import chainlit as cl
@cl.on_chat_start
def on_chat_start():
    print("A new chat session has started!")

@cl.on_chat_start chainlit output

Membangun dengan @cl.on_message

Hook pesan ini berjalan saat pengguna mengirim pesan baru. Kita menggunakannya untuk memproses input pengguna, memanggil LLM, atau mengembalikan respons.

import chainlit as cl
@cl.on_message
async def on_message(msg: cl.Message):
    print("The user sent:", msg.content)
    await cl.Message(content=f"You said: {msg.content}").send()

@cl.on_message Output

Membangun dengan @cl.on_stop

Hook on_stop berjalan saat pengguna mengeklik tombol stop (⏹) selama sebuah tugas berjalan. Ini berguna untuk membatalkan operasi yang berjalan lama atau membersihkan sesi yang terputus.

import chainlit as cl
import asyncio
@cl.on_chat_start
async def start():
    await cl.Message("Type anything and I'll pretend to work on it.").send()
@cl.on_message
async def on_message(msg: cl.Message):
    await cl.Message("Working on it... you can press Stop").send()
    try:
        # Simulate a long task
        await asyncio.sleep(10)
        await cl.Message("Task complete!").send()
    except asyncio.CancelledError:
        print("Task was interrupted!")
        # This is optional, just logs in the server
        raise
@cl.on_stop
async def on_stop():
    print("The user clicked Stop!")

Saat pengguna mengirim pesan, Chainlit mensimulasikan tugas dengan asyncio.sleep(10). Jika pengguna mengeklik tombol stop (⏹), tugas dibatalkan, dan @cl.on_stop dipicu untuk mencatat interupsi.

@cl.on_stop output

Membangun dengan @cl.on_chat_end

Hook ini dipicu saat sesi berakhir—baik pengguna menyegarkan, menutup tab, atau memulai sesi baru. Biasanya digunakan untuk mencatat pemutusan koneksi atau menyimpan status.

import chainlit as cl
@cl.on_chat_start
async def on_chat_start():
    await cl.Message("Welcome! Feel free to leave anytime").send()
@cl.on_chat_end
async def on_chat_end():
    print("The user disconnected!")

Setelah localhost terbuka, Anda dapat bekerja dengannya. Saat Anda menutup tab atau jendela localhost, terminal akan menampilkan hal berikut:

on_chat_end() chainlit output

Aksi UI (tombol)

Chainlit memungkinkan Anda menambahkan tombol interaktif langsung ke antarmuka chatbot. Setiap tombol didefinisikan sebagai sebuah action dan dihubungkan ke fungsi callback Python. Anda mengirim tombol sebagai bagian dari Message menggunakan argumen actions:

import chainlit as cl
@cl.on_chat_start
async def start():
    actions = [
        cl.Action(
            name="hello",
            label="👋 Say Hello",
            icon="smile",
            payload={"value": "hi"}
        )
    ]
    await cl.Message("Click a button!", actions=actions).send()

Berikut cara menangani klik tombol:

@cl.action_callback("hello")
async def on_hello(action: cl.Action):
    await cl.Message("Hello there! 👋").send()

Dekorator @cl.action_callback("hello") memberi tahu Chainlit untuk mendengarkan klik pada tombol bernama "hello". Saat diklik, tombol tersebut mengirim pesan ramah ke pengguna di antarmuka obrolan.

@cl.action_callback chainlit output

Tip: Anda dapat menyesuaikan payload dengan data apa pun yang ingin dikirim kembali ke server.

Streaming pesan 

Chainlit mendukung streaming respons LLM secara real time. Artinya, Anda dapat mengirim konten ke pengguna secara bertahap seiring konten tersebut dihasilkan.

@cl.on_message
async def on_message(message: cl.Message):
    await cl.Message(content="Thinking...").send()
    async for chunk in llm.astream(message.content):
        await cl.Message(content=chunk, author="LLM", stream=True).send()

Mari kita uraikan:

  • Pertama, segera menampilkan pesan "Thinking..." agar pengguna tahu aplikasi sedang bekerja.
  • Lalu, mengirim pesan pengguna ke LLM yang kompatibel dengan streaming.
  • Saat model menghasilkan keluaran, setiap potongan (chunk) di-stream kembali ke UI secara real time.
  • Parameter stream=True memastikan setiap chunk muncul secara bertahap alih-alih menunggu respons penuh.

Catatan: Ini bekerja paling baik dengan model yang mendukung streaming.

Konfigurasi Chainlit (config.toml)

Untuk membuka fitur andal seperti persistensi obrolan, unggah file, tema, dan lainnya, Anda dapat menyesuaikan aplikasi Chainlit menggunakan file config.toml. File ini berada di root direktori proyek Anda (di bawah folder .chainlit) dan memungkinkan Anda menyesuaikan perilaku runtime tanpa mengubah kode.

Persistensi

Parameter ini memungkinkan Chainlit menyimpan riwayat obrolan dan status sesi. Ini mengaktifkan hook @cl.on_chat_resume, sehingga ideal untuk aplikasi tempat pengguna mungkin terputus dan kembali lagi.

[persistence]
enabled = true

Pengunggahan file

Pengaturan ini memungkinkan pengguna mengunggah file di antarmuka obrolan. Anda dapat membatasi jenis dan ukuran file yang diizinkan untuk memastikan keamanan dan kinerja.

[features.spontaneous_file_upload]
enabled = true
accept = ["*/*"] 
max_files = 5
max_size_mb = 500

Berikut beberapa jenis file yang diterima oleh Chainlit.

# 1. For specific file types:
    # accept = ["image/jpeg", "image/png", "application/pdf"]
# 2. For all files of a certain type:
    #    accept = ["image/*", "audio/*", "video/*"]
# 3. For specific file extensions:
    #    accept = { "application/octet-stream" = [".xyz", ".pdb"] }

Ini memungkinkan Anda menyesuaikan unggahan demi keamanan, kinerja, atau kasus penggunaan spesifik domain.

Kustomisasi UI

Penyesuaian ini mengubah nama asisten di bawah parameter UI dan mengaktifkan Chain of Thought (CoT) dalam mode rendering, yang berguna untuk penalaran bertahap atau debug.

[UI]
name = "Assistant"
cot = "full"

Penyempurnaan kegunaan

Ini meningkatkan pengalaman pengguna dengan menggulir otomatis pesan baru ke tampilan dan memungkinkan penyuntingan pesan.

[features]
user_message_autoscroll = true
edit_message = true

Penyempurnaan kegunaan di atas memungkinkan pengguna mengaktifkan fitur autoscroll dan penyuntingan pesan di dalam UI.

Proyek: Surprise Me Bot (Tanpa LLM)

Sekarang setelah kita mengetahui komponen dasar Chainlit, mari buat aplikasi berbasis UI sederhana yang menggunakan tombol untuk menampilkan fakta menarik atau pesan motivasi untuk pengembang yang sudah ditentukan sebelumnya.

import chainlit as cl
import random
FUN_FACTS = [
    "💡 Did you know? Chainlit supports file uploads and custom themes!",
    "💡 You can add buttons, sliders, and images directly in your chatbot UI!",
    "💡 Chainlit supports real-time tool execution with LangChain and LLMs!",
    "💡 You can customize the look of your chatbot with just a CSS file!",
    "💡 Chainlit lets you connect to tools using Model Context Protocol (MCP)!"
]
SUPRISES = [
    "🎉 Surprise! You're doing great!",
    "🚀 Keep it up, you're making awesome progress!",
    "🌟 Fun fact: Someone out there just smiled because of you. Why not make it two?",
    "👏 Bravo! You just unlocked +10 imaginary developer XP!",
    "💪 Remember: Even bugs fear your debugging skills!"
]
@cl.on_chat_start
async def start():
    actions = [
        cl.Action(
            name="surprise_button",
            label="🎁 Surprise Me",
            icon="gift",
            payload={"value": "surprise"}
        ),
        cl.Action(
            name="fact_button",
            label="💡 Did You Know?",
            icon="lightbulb",
            payload={"value": "fact"}
        )
    ]
    await cl.Message(content="Choose an action:", actions=actions).send()
@cl.action_callback("surprise_button")
async def on_surprise(action: cl.Action):
    suprise = random.choice(SUPRISES)
    await cl.Message(content=suprise).send()
@cl.action_callback("fact_button")
async def on_fact(action: cl.Action):
    fact = random.choice(FUN_FACTS)
    await cl.Message(content=fact).send()

Kode di atas mendefinisikan dua daftar: “FUN_FACTS” untuk tips Chainlit yang menarik dan “SUPRISES” untuk pesan motivasi.

  • Saat obrolan baru dimulai, dua tombol ditampilkan: "Surprise Me" dan "Did You Know?"—menggunakan cl.Action. '
  • Mengklik "Surprise Me" memicu @cl.action_callback("surprise_button"), yang mengirim pesan kejutan acak.
  • Mengklik "Did You Know?" memicu @cl.action_callback("fact_button")`, yang mengirim fakta menarik acak.

Ini menghasilkan chatbot interaktif sederhana menggunakan tombol tanpa memerlukan LLM dan sangat cocok untuk mempelajari cara kerja actions dan callback di Chainlit.

Untuk menjalankan aplikasi ini, cukup jalankan perintah berikut di terminal:

chainlit run main.py

Anda akan melihat tombol interaktif di UI yang memicu fakta atau pesan seru!

Surprise Me Bot (no LLM)

Proyek: Surprise Me Bot Didukung oleh Ollama

Sekarang, mari otomatisasi proses ini dan hasilkan pesan kejutan serta fakta menggunakan LLM lokal melalui Ollama.

import chainlit as cl
from langchain_community.llms import Ollama
import random
llm = Ollama(model="mistral", temperature=0.7)  # Use any lightweight local model
# Reusable action buttons
def get_action_buttons():
    return [
        cl.Action(
            name="surprise_button",
            label="🎁 Surprise Me",
            icon="gift",
            payload={"value": "surprise"}
        ),
        cl.Action(
            name="fact_button",
            label="💡 Did You Know?",
            icon="lightbulb",
            payload={"value": "fact"}
        )
    ]

@cl.on_chat_start
async def start():
    await cl.Message(content="Choose an action below to see something fun:").send()
    await cl.Message(content="", actions=get_action_buttons()).send()
@cl.action_callback("surprise_button")
async def on_surprise(action: cl.Action):
    prompt = "Give a short, uplifting surprise message to a developer. Make it fun."
    try:
        surprise = llm.invoke(prompt).strip()
    except Exception:
        surprise = "🎉 Surprise! You're doing great!"
    await cl.Message(content=surprise).send()
    await cl.Message(content="", actions=get_action_buttons()).send()  
@cl.action_callback("fact_button")
async def on_fact(action: cl.Action):
    prompt = "Give a fun and helpful fact about LLMs or Chainlit."
    try:
        fact = llm.invoke(prompt).strip()
    except Exception:
        fact = "💡 Did you know? You can add sliders and buttons to Chainlit with just a few lines of code!"
    await cl.Message(content=fact).send()
    await cl.Message(content="", actions=get_action_buttons()).send()  

Aplikasi Chainlit ini mengintegrasikan LLM lokal (melalui Ollama dengan model Mistral) untuk menghasilkan respons secara dinamis berdasarkan interaksi pengguna.

  • Mendefinisikan dua tombol cl.Action—"Surprise Me" dan "Did You Know?" menggunakan fungsi get_action_buttons() yang dapat digunakan ulang.
  • Pada inisialisasi obrolan (@cl.on_chat_start) mengirim pesan dengan tombol interaktif ini.
  • Saat pengguna mengeklik tombol "Surprise Me", handler @cl.action_callback mengirim prompt ke LLM untuk meminta pesan singkat yang membangkitkan semangat bagi pengembang. Respons dibersihkan dengan fungsi .strip() dan dikirim kembali ke obrolan.
  • Demikian juga, mengeklik "Did You Know?" memanggil LLM dengan prompt yang meminta fakta informatif tentang Chainlit atau LLM.
  • Jika LLM gagal, maka respons statis cadangan akan dikembalikan.
  • Setelah setiap interaksi, tombol dikirim ulang untuk menjaga loop percakapan.

Ini menunjukkan cara menggabungkan UI Chainlit dengan pembuatan konten berbasis LLM, menawarkan fondasi modular dan mudah dikembangkan untuk aplikasi chat AI lokal.

Jalankan perintah berikut di terminal:

ollama run mistral
chainlit run main.py

Sekarang Anda telah memiliki asisten AI lokal yang aktif dan menghasilkan pesan otomatis.

Surprise Me Bot Powered by Ollama

Kesimpulan

Chainlit memiliki potensi kuat untuk membuat prototipe tool berbasis obrolan, membangun asisten, dan mengintegrasikan keluaran LLM real time—semuanya tanpa menyentuh JavaScript. Untuk kasus lanjutan, lihat Chainlit Cookbook.

Untuk memperluas pembelajaran Anda dengan tool AI baru, lihat blog berikut:

Aashi Dutt

Penulis

Aashi Dutt

Saya adalah Google Developers Expert di ML (Gen AI), Kaggle 3x Expert, dan Women Techmakers Ambassador dengan pengalaman lebih dari 3 tahun di bidang teknologi. Saya ikut mendirikan startup health-tech pada 2020 dan sedang menempuh studi magister ilmu komputer di Georgia Tech dengan spesialisasi machine learning.

Topik

Terkait

blogs

Tutorial Korelasi di R

blogs

Spaghetti Plot dan Jalur Badai