Python ile Dil Modeli Uygulamasına Sohbet Arayüzü Yapmak
Beceri rehberi

Python ile Dil Modeli Uygulamasına Sohbet Arayüzü Yapmak

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Streamlit, saf Python betiğini web arayüzüne çevirir; bir dil modeli uygulamasına sohbet kutusu, mesaj geçmişi ve akışlı yanıt eklemek için ayrı bir ön yüz bilgisi gerekmez. Burada çalışan bir iskeleti ve sık düşülen tuzakları bulacaksınız.

Bir bakışta

  1. Streamlit'te her etkileşim betiği baştan çalıştırır. Bu yüzden sohbet geçmişi sıradan bir değişkende değil, oturum durumunda (session_state) tutulmalıdır.
  2. Sohbet arayüzü hazır bileşenlerle kurulur. st.chat_input mesajı alır, st.chat_message baloncuğu çizer, st.write_stream yanıtı akıtarak gösterir.
  3. Model çağrısını arayüzden ayrı bir fonksiyona koyun. Sağlayıcıyı ya da yerel modeli değiştirdiğinizde arayüz kodu dokunulmadan kalır.
  4. Anahtar ve ağır model yüklemesi sahnenin dışında tutulur. API anahtarı st.secrets ile okunur, yerel model st.cache_resource ile yalnızca bir kez yüklenir.
  5. Streamlit prototip ve kurum içi araçlar için uygundur. Müşteriye açık, çok kullanıcılı ürünlerde kimlik doğrulama ve ölçekleme için ayrı bir mimari gerekir.

Streamlit dil modeli uygulamasında neyi çözer

Dil modeliyle çalışan bir prototip genellikle bir not defterinde başlar: istemi yazarsınız, yanıtı hücrenin altında okursunuz. Ekibin geri kalanı ise bu denemeyi tarayıcıda, bir sohbet kutusuyla görmek ister. Streamlit tam bu boşluğu doldurur: Python dosyanızdaki st ile başlayan çağrılar sayfadaki bileşenlere dönüşür, HTML, JavaScript ya da ayrı bir arka uç yazmanız gerekmez.

Bu kolaylığın bir bedeli vardır ve her şeyi belirleyen özellik odur: kullanıcı sayfada bir şey yaptığında, örneğin mesaj gönderdiğinde, betik yukarıdan aşağıya yeniden çalışır. Sıradan bir Python değişkeni her çalıştırmada sıfırlanır; sohbet geçmişi gibi kalıcı olması gereken her şey oturum durumuna konmalıdır. Arayüzü bu döngüye göre tasarlamak, hataların çoğunu baştan önler.

Şekil 1

Her mesaj betiği baştan çalıştırır, geçmiş oturum durumundan geri çizilir

Streamlit etkileşim döngüsü

  1. Kullanıcı mesaj yazarSohbet kutusu yeni metni döndürür.
  2. Betik baştan çalışırBütün sayfa kodu yeniden yürütülür.
  3. Geçmiş yeniden çizilirEski mesajlar oturum durumundaki listeden okunur.
  4. Model çağrılırYeni soru ve geçmiş modele gönderilir.
  5. Yanıt listeye eklenirBir sonraki çalıştırmada bu yanıt da ekranda olur.
Kaynak: Streamlit sohbet uygulaması eğitim belgelerindeki yaklaşımMindset Institute

Uygulamanın katmanları

Sağlam bir dil modeli arayüzü, kodu baştan ayrı sorumluluklara böler. En üstte kullanıcının gördüğü arayüz durur: başlık, mesaj baloncukları, giriş kutusu. Ortada durum vardır: sohbet geçmişi, seçilen ayarlar, kullanıcının yüklediği dosya. En altta ise modeli çağıran ve metin döndüren işlev bulunur.

Bu ayrım ilk bakışta gereksiz görünebilir, fakat ilk sağlayıcı değişikliğinde karşılığını verir. Model çağrısı tek bir fonksiyonda toplandığında, hizmet sağlayıcıyı değiştirmek ya da yerel bir açık kaynak modele geçmek yalnızca o fonksiyonu etkiler. Arayüz, aldığı mesaj listesinin arkasında hangi modelin çalıştığını bilmez.

Şekil 2

Arayüz, durum ve model ayrı tutulursa her biri bağımsız değişir

Kod sorumlulukları

  1. ArayüzBaşlık, mesaj baloncukları ve giriş kutusu.
  2. DurumSohbet geçmişi ve kullanıcının seçtiği ayarlar.
  3. Model çağrısıMesaj listesini alıp metin döndüren tek işlev.
Kaynak: sayfa içeriğiMindset Institute

En küçük çalışan sohbet iskeleti

Aşağıdaki satırlar bir sohbet uygulamasının omurgasıdır. Model çağrısı yerine kendi sağlayıcınızın ya da yerel modelinizin çağrısını koyacağınız bir işlev bırakılmıştır.

  • import streamlit as st: kütüphaneyi içeri alır.
  • def yanit_uret(mesajlar): bu işlevin içinde seçtiğiniz modeli çağırır ve yanıt metnini döndürürsünüz.
  • if "mesajlar" not in st.session_state: st.session_state.mesajlar = [] ile geçmiş listesini yalnızca ilk çalıştırmada oluşturursunuz.
  • for m in st.session_state.mesajlar: with st.chat_message(m["rol"]): st.markdown(m["metin"]) ile eski mesajları her çalıştırmada yeniden çizersiniz.
  • if soru := st.chat_input("Sorunuzu yazın"): kutu boşken None döner, mesaj gönderilince metni verir.
  • Bu blokta soruyu listeye ekler, kullanıcı baloncuğunda gösterir, yanit_uret işlevini çağırır, yanıtı asistan baloncuğunda gösterir ve listeye ekler.

Betiği streamlit run komutuyla başlattığınızda tarayıcıda çalışan bir sohbet ekranı elde edersiniz. Rol adı olarak "user" ve "assistant" kullanırsanız baloncuklar hazır biçimlendirmeyle gelir.

Akışlı yanıt, sistem istemi ve ayarlar

Uzun yanıtlarda kullanıcıyı boş bir ekranla bekletmek, uygulamanın bozuk olduğu izlenimini verir. Çoğu sağlayıcı yanıtı parça parça döndürebilir; st.write_stream bu parçaları bir üretici (generator) olarak alır, ekrana akıtır ve sonunda tam metni geri verir. O metni geçmiş listesine eklemeyi unutmayın, yoksa bir sonraki çalıştırmada yanıt ekrandan kaybolur.

Modelin davranışını belirleyen sistem istemini kod içinde sabit bir metin olarak tutabilir, ya da yan çubukta kullanıcıya düzenletebilirsiniz. Sıcaklık gibi üretim ayarlarını yan çubuğa koymak, prototipi gösterirken farklı davranışları canlı denemenizi sağlar. Bu ayarlar da oturum durumunda durmalıdır ki her çalıştırmada varsayılana dönmesin.

Yanıtın doğruluğu arayüzün değil istemin ve verinin işidir. Kurum belgelerinden yanıt vermesini istiyorsanız arayüzün arkasına bir getirme (RAG) katmanı eklemek gerekir; arayüz bunu fark etmez, yalnızca daha iyi yanıt gösterir.

Anahtar, model yükleme ve maliyet

API anahtarını kod dosyasına yazmak, uygulamayı bir depoya koyduğunuz anda sızıntıya dönüşür. Streamlit anahtarlar için st.secrets mekanizmasını sunar; anahtar depoya girmeyen ayrı bir yapılandırma dosyasında durur ve kodda yalnızca ada göre okunur.

Yerel çalışan bir açık kaynak model kullanıyorsanız, model her etkileşimde yeniden yüklenmemelidir. Betik baştan çalıştığı için bu kolayca olur ve uygulama dakikalarca takılır. st.cache_resource, model gibi paylaşılan ağır nesneleri bir kez oluşturup sonraki çalıştırmalarda yeniden kullanır.

Son olarak maliyeti hatırlayın: sohbet geçmişinin tamamını her istekte göndermek, konuşma uzadıkça hem maliyeti hem yanıt süresini büyütür. Geçmişin yalnızca son bölümünü göndermek ya da eski kısmı özetleyip eklemek yaygın çözümlerdir.

Sık yapılan hatalar

Durum hataları, durumla ilgilidir. Geçmişi sıradan bir liste değişkeninde tutmak, her mesajdan sonra sohbetin silinmesine yol açar. Düzeltmesi geçmişi oturum durumunda tutmak ve her çalıştırmada oradan çizmektir.

Yapı hataları, yapıyla ilgilidir. Model çağrısını arayüz koduna gömmek, bir sağlayıcı sorunu çıktığında bütün betiği kırar. Çağrıyı işleve ayırın ve hata yakalamayı orada yapın; kullanıcıya "yanıt alınamadı, tekrar deneyin" gibi anlaşılır bir mesaj gösterin.

Gizlilik hataları, gizlilikle ilgilidir. Kullanıcının yazdığı metin bir dış sağlayıcıya gider. Kurum içi bir araçta kişisel veri ya da gizli belge paylaşılabileceğini önceden düşünün; hangi verinin modele gönderilemeyeceğini kullanıcıya arayüzde açıkça yazın. Son olarak, prototipin kimlik doğrulaması yoktur: adresi bilen herkes araca girer, bu yüzden erişimi ağ düzeyinde sınırlamadan kurum verisiyle çalışan bir sürümü paylaşmayın.

Prototipten ürüne ve öğrenme yolu

Pratik bir yol şudur: önce yukarıdaki iskeleti bir sağlayıcıyla çalıştırın, sonra akışlı yanıtı ve sistem istemini ekleyin, ardından kendi belgelerinizle getirme katmanını bağlayın. Streamlit bu aşamalarda hızlı geri bildirim aracıdır; kullanıcılar ürünün gerçekten işe yarayıp yaramadığını görmeden ağır bir ön yüz projesine girmemek akıllıca olur.

Uygulama çok kullanıcıya, kimlik yönetimine ya da özel tasarıma ihtiyaç duyduğunda, model mantığını bir API arkasına alıp ön yüzü ayrı bir teknolojiyle yazmak gerekir. Bu geçiş, model çağrısını baştan ayrı bir işlevde tuttuysanız kolaydır.

Python ile ajan ve dil modeli uygulaması geliştirmek isteyen bir yazılımcı ya da veri uzmanı için Mindset'in Python ile yapay zeka ajanları programı, dil modellerine pratik giriş, araç kullanan ajanlar ve bir uygulama projesi içerir; Generative NLP programı ise açık kaynak modelleri yerelde ya da bulutta çalıştırmaya odaklanır.

İlgili Mindset programı

Python ile Yapay Zekâ Ajanları (AI Agent) Geliştirme Eğitimi

Sık sorulanlar

Sık sorulan sorular

Streamlit ile sohbet geçmişi neden kayboluyor?

Betik her etkileşimde baştan çalıştığı için sıradan değişkenler sıfırlanır. Geçmişi st.session_state içindeki bir listede tutun, ilk çalıştırmada boş liste oluşturun ve her çalıştırmada eski mesajları bu listeden yeniden çizin. Yeni soruyu ve yanıtı da çizdikten sonra aynı listeye ekleyin.

Streamlit yerel bir açık kaynak modelle de çalışır mı?

Çalışır; arayüz modelin nerede çalıştığını bilmez. Model çağrısını tek bir işleve koyun, yerel modeli st.cache_resource ile bir kez yükleyin. Aksi hâlde model her mesajda yeniden yüklenir ve uygulama kullanılamayacak kadar yavaşlar. Donanım gereksinimi seçtiğiniz modele bağlıdır.

Gradio ya da başka bir arayüz kütüphanesi mi seçmeliyim?

Karar ihtiyaca bağlıdır. Streamlit, sayfa düzeni ve birden çok bileşenle esnek paneller kurmak için rahattır. Yalnızca bir modelin giriş ve çıkışını hızla göstermek istiyorsanız model odaklı kütüphaneler de uygundur. Her ikisinde de model çağrısını arayüzden ayırmak aynı biçimde geçerlidir.

Uygulamayı kurum dışına açabilir miyim?

Teknik olarak yayına alınabilir, ancak prototipin kimlik doğrulaması, kullanım sınırı ve veri koruma önlemleri hazır gelmez. Müşteriye açık bir ürün için erişim kontrolü, istek sınırlama, günlük tutma ve gizlilik metni ekleyin ya da model mantığını ayrı bir API arkasına alıp ön yüzü ürün düzeyinde yeniden yazın.

API anahtarımı nereye koymalıyım?

Kod dosyasına ya da depoya hiç yazmayın. Streamlit'in st.secrets mekanizması anahtarları ayrı bir yapılandırmadan okur; yayın ortamında da platformun gizli değer ayarlarını kullanın. Anahtar bir kez sızdıysa onu hemen yenileyin, çünkü depo geçmişinde kalır.

Streamlit ile LLM Arayüzü Nasıl Yapılır? Adımlar