Metni çıkarıyoruz ve yapamadığımızda bunu açıkça söylüyoruz
Düz metinden, markdown’dan, günlüklerden, CSV’den, JSON’dan, DOCX ve PDF’den. DOCX bir arşiv gibi açılır ve içindeki XML belgesi okunur; PDF, sayfa yerleşimini koruyan standart çıkarıcıdan geçer ve bu yoksa, metin operatörlerini doğrudan dosyadan okuyan bir yedek vardır. Önemli durum, çalışmadığı zamandır: taranmış bir PDF, yani bir görüntü, seçilebilir metin içermez ve sistem açık bir mesaj döndürür — DOCX veya metin yükleyin, ya da dosyayı önce optik tanımadan geçirin. Optik tanıma uygulamamız yok ve varmış gibi davranmıyoruz.
Parçaları örtüşmeyle bölüyoruz, cümlelerin arasından keserek, içlerinden değil
Kullandığımız varsayılan değerler: sesli pipeline için 50 örtüşmeyle 500 sözcüksel birim, metin için 150 örtüşmeyle 1.200 karakter; sesli sağlayıcı tarafında 100 örtüşmeyle 500. Örtüşme vardır çünkü iki parça arasında ortadan kesilen bir cümle her ikisi için de kullanılamaz hale gelir. Cümle ayırıcı, çalıştığımız diller için yazılmıştır: cümle sonunu, Romence diakritikler dahil, Latin **veya Kiril** büyük harfi izlediğinde tanır. İngilizce için yazılmış bir ayırıcı Romence’de kötü, Rusça’da daha da kötü keser.
Vektörlerle orada indexliyoruz, bunu nerede yapmadığımızı da söylüyoruz
Varsayılan temsil modeli `text-embedding-3-small`dır, 1.536 boyutludur ve doğrudan sağlayıcıdan değil, modeller kapımız üzerinden istenir — böylece bilgi tabanı koduna dokunmadan sağlayıcı değiştirilebilir. Veritabanında sütun, kosinüs mesafesi üzerinde `ivfflat` indexine sahip bir vector türündedir. Migration’da yazılmış bir yedek strateji vardır: vektör uzantısı mevcut değilse, şema her zaman metin üzerinde trigram indexiyle oluşturulur ve geri getirme leksikal benzerliğe geçer. Bu varsayımsal değildir — tam da uzantı haklarının her kurululumda garanti olmaması nedeniyle yazılmıştır.
Hibrit geri getirme, ağırlıklar görünür halde
Son puan 0,7 vektörel benzerlikten artı 0,3 kelime eşleşmesinden, sözlüksel kısım normalleştirilmiş olarak hesaplanır. Bir aday kümesi puanlanır ve ilk parçalar tutulur; modele gönderilen bağlam, her parçayı bir azami uzunlukta keser, böylece tek bir uzun belge tüm alanı kaplamaz. Yapılandırma, asistan başına temeldedir: geri getirme açık ya da kapalı, soru başına azami parça sayısı (varsayılan 5, 1 ile 20 arasında sınırlı), benzerlik eşiği, arama türü — semantik, sözcüksel veya hibrit — ve sözcüksel kısmın ağırlığı.
Onay kapısı: bilgi eksiklerden büyür, zincirde bir insanla
Asistan bilginin olmadığını yanıtladığında, soru “beklemede” durumuyla bir tabloda yazılır, geldiği kanal ile işaretlenir — ses veya widget. Bir insan bildirim alır ve doğrudan mesaja yanıt verir; bir webhook yanıtı alır, girişi “onaylandı” durumuna geçirir ve oradan asistanın bağlamına girer. Olası durumlar dörttür: beklemede, onaylandı, yok sayıldı, yinelendi — ve yinelenenler, aynı eksikliğin on farklı ifadesi birikmesin diye, özgün soruya bir referansla bağlanır. Asistana teslim, onaylanan her giriş için bir kez yapılır.
Yenileme: kaynak değiştiğinde ne olur
Eklemede içeriğin SHA-256 fingerprint’i hesaplanır; metin zaten indekslenmiş bir şeyle aynıysa yeniden kullanılır ve yeni bir vektör temsili ödenmez. Belge değiştiğinde, parçaları bütünüyle silinir ve yeniden yazılır — kaynak bazında tam değiştirme, kısmi güncelleme değil; çünkü kısmi güncelleme eski sürümden yetim parçalar bırakır ve bunlar sitenin çelişen yanıtlar üretmesine yol açar. Kaynağın görünür bir durum döngüsü vardır: beklemede, işleniyor, yeniden işleniyor, hazır veya başarısız; yeniden indeksleme kaynağa özel olarak noktasal istenebilir.
Değişmeyeni yeniden indekslemiyoruz
Sadece büyüyen bir liste üzerinde her otuz dakikada bir çalışan bir döngüde, dokunulmamış bir öğe için temsilin yeniden hesaplanması, kıpırdayamayacak bir vektör için tekrarlanan bir ödemedir. Döngümüz son dokunulma anını son indeksleme anıyla karşılaştırır ve değişmemiş olanı atlar. Temsiller toplu halde istenir, tek tek değil. Bunlar maliyet ayrıntılarıdır, ama bir bilgi tabanının aylık maliyeti neredeyse tamamen burada belirlenir.
Bağlı bir katalog, yüklenmiş bir liste değildir
Fark biçimde değil, zamanda. Yüklenmiş bir liste, yükleme anında doğrudur: fiyat, stok ve yeni ürünler, biri yeniden yüklemeyi hatırlayana kadar donmuş kalır — ve genelde, bir müşteri üç aylık eski bir fiyatı sorunca, kimsenin hatırlamadığı anlaşılır. Bağlı bir katalog soru anında, kaydı tutan kaynaktan okunur. Bu yönde yaptığımız şey: olağan anahtarlar üzerinden bir JSON veya CSV’de ürün koleksiyonlarını tanıyan bir çıkarıcı ve yapı alışılmadık olduğunda, kesin olarak verilen bir biçimde yanıt verme yükümlülüğüyle bir modelden yardım isteyen bir araç; ve mağazanın canlı sayfasından fiyatı okuyan bir tarayıcı. En iyi yol, varsa, mağazanın kendi yapılandırılmış arayüzü olmaya devam eder — ama bu mağaza bazında doğrulanır, varsayılmaz.
Bir siteyi tarama: önce harita, sonra keşif
Önce, yaygın adlandırma varyantlarında site haritası aranır ve iç içe haritalar iki düzey boyunca açılır. Yalnızca harita yoksa, aynı kaynak üzerinde katı biçimde genişlik öncelikli keşfe geçilir; sayfa limiti yapılandırılabilir (varsayılan 50, 200 ile sınırlandırılmış). Fiilen kullanılan strateji geri raporlanır — harita veya keşif — çünkü zayıf bir sonucun siteden mi yöntemden mi geldiği ondan okunur. Sitenin hariç tutma dosyası uygulanır.