Bir crawler sayfaları çeker; onları bulunabilir kılan şey ise dizindir (index). Her arama motoru, her web arama API'si ve erişimle güçlendirilmiş üretim (RAG) sistemlerinin çoğu bir dizinin üzerinde durur. Ajanınız herhangi bir şeyde arama yapıyorsa, neyi bulabileceğine, bulduğunun ne kadar güncel olduğuna ve neyi hiç göremeyeceğine dizin karar verir. Bu yazıda bir dizinin nasıl kurulduğunu, modern dizinlerin içindeki iki temel yapıyı ve güveneceğiniz her dizini şekillendiren ödünleşimleri anlatıyoruz.
Çekilen sayfalardan aranabilir kayıtlara
Ham bir tarama, bir yığın HTML'den ibarettir. Onu dizine çevirmek bir işlem hattı gerektirir ve her aşama, içeriğin kaybolabileceği ya da bozulabileceği bir noktadır:
- Ayrıştırma ve temizlik. Ana metni çıkarmak; menüleri, çerez uyarılarını, alt bilgileri ve tekrarlanan kalıp metinleri atmak.
- Tekilleştirme ve kanonik adres. Aynı ya da neredeyse aynı sayfaları birleştirmek; böylece tek bir belge farklı URL'ler altında defalarca dizine girmez.
- Zenginleştirme. Dili tespit etmek; başlığı, ara başlıkları, yayın ipuçlarını ve yapılandırılmış veriyi çıkarmak; çekme zamanını kaydetmek.
- Metin çözümleme. Metni sözcük birimlerine (token) bölmek, büyük-küçük harfi eşitlemek ve kök bulma gibi dile özgü kuralları uygulamak. Türkçe gibi eklemeli bir dilde bu adım çok önemlidir: sözleşme, sözleşmeler ve sözleşmelerimizin genellikle birbiriyle eşleşmelidir.
- Dizin yapılarını oluşturma. Ters dizini, vektör dizinini ya da ikisini birden yazmak.
- Sıralama sinyallerini ekleme. Sayfalar arası bağlantılar, bağlantı metinleri, tazelik, kalite ve spam sinyalleri; hepsi daha sonra sonuçları sıralamak için kullanılır.
Çıktı, her biri bir URL'ye ve bir çekme zamanına bağlı kayıtlardan oluşur. Bu son alanı aklınızda tutun; tazelikten söz ederken yeniden karşımıza çıkacak.
Ters dizin
Klasik yapı, her terimi onu içeren belgelerin listesine eşler. Bu listeye kayıt listesi (posting list) denir ve genellikle terimin konumunu ve kaç kez geçtiğini de içerir. Çözümlemeden sonra küçük bir örnek:
belge 1 "Tedarikçi sözleşmeleri için yenileme bildirimi" belge 2 "Tedarikçi kayıt kontrol listesi" belge 3 "Sözleşme yenileme tarihleri ve bildirim süreleri" terim kayıt listesi yenileme 1, 3 bildirim 1, 3 (bildirimi -> bildirim) tedarikçi 1, 2 sözleşme 1, 3 (sözleşmeleri -> sözleşme) kayıt 2 süre 3 (süreleri -> süre)
tedarikçi yenileme sorgusu, her belgeyi baştan sona taramak yerine iki kısa listeye bakar. Belge 1 iki terimi de içerdiği için ilk sıraya çıkar; belge 3 ve belge 2 birer terimle eşleşir. BM25 gibi sıralama fonksiyonları bunu inceltir: koleksiyonda nadir geçen terimleri ödüllendirir ve uzun bir belgenin bir sözcüğü çok tekrar ettiği için öne geçmesini engeller.
Ters dizinler hızlıdır, parça parça güncellenmeleri ucuzdur ve açıklamaları kolaydır: hangi sözcüğün eşleştiğini her zaman söyleyebilirsiniz. Özel adlarda, ürün kodlarında, hata mesajlarında, mevzuat atıflarında ve nadir terimlerde çok başarılıdırlar. Zayıf noktaları sözcük dağarcığıdır: aboneliğimi iptal et sorgusu, yalnızca üyeliğinizi sonlandırın diyen bir sayfayı bulamaz.
Vektör dizini
Vektör dizini her belge ya da pasaj için bir embedding saklar: bir modelin ürettiği ve anlamca benzer metinleri birbirine yakın konumlandıran bir sayı listesi. Sorgu anında soru da aynı şekilde vektöre çevrilir ve dizin en yakın komşuları döndürür. Büyük ölçekte sorguyu saklanan her vektörle tek tek karşılaştırmak çok yavaş kalır; bu yüzden vektör dizinleri yaklaşık en yakın komşu yapılarına dayanır. HNSW gibi grafik tabanlı ya da kümeleme tabanlı bu yapılar, biraz doğruluktan vazgeçerek büyük bir hız kazanır.
| Ters dizin | Vektör dizini | |
|---|---|---|
| Ne saklanır | Belgelere eşlenmiş terimler | Belge ya da pasajların embedding'leri |
| Ne eşleşir | Çözümlemeden sonra ortak sözcükler | Ortak sözcük olmasa bile benzer anlam |
| Güçlü olduğu yer | Adlar, kodlar, kesin ifadeler, nadir terimler | Yeniden ifadeler, doğal dildeki sorular, diller arası eşleşmeler |
| Zayıf olduğu yer | Eş anlamlılar ve farklı ifade biçimleri | Kesin kimlikler, olumsuzluk, bir sonucun neden eşleştiğini açıklamak |
| Değişikliğin maliyeti | Belgeler parça parça eklenip silinebilir | Embedding modelini değiştirmek her şeyi yeniden vektörleştirmek demektir |
Ciddi sistemlerin çoğu artık ikisini birlikte tutar ve sonuçlarını birleştirir; bu yaklaşıma hibrit arama denir. Embedding'lerin nasıl çalıştığını ve iki sıralamanın nasıl birleştirildiğini anlamsal arama yazısında bulabilirsiniz.
Dizini taze tutmak
Dizin bir anlık görüntüdür; web ise durmadan değişir. Sayfaların değişme hızı birbirinden çok farklıdır: bir haber sitesinin ana sayfası günde defalarca değişir, bir ürün sayfası fiyatı değiştiğinde değişir, eski bir akademik makale hiç değişmeyebilir. İyi crawler'lar her sayfanın ritmini geçmişinden öğrenir ve ziyaretlerini buna göre planlar; sık değişen ya da daha önemli sayfalara öncelik verir. Son değişiklik ipucu taşıyan site haritaları, akışlar ve yayıncılardan gelen anlık bildirimler, ziyaretlerin işe yarayacağı yere harcanmasına yardım eder.
Dizin tarafında motorların çoğu her şeyi baştan kurmaktan kaçınır. Yeni ve değişen belgeler arka planda birleştirilen yeni segmentlere yazılır; silmeler ise sonraki bir birleştirme onları kaldırana kadar işaret olarak tutulur. Kaldırma başlı başına bir tazelik sorunudur: artık 404 döndüren, noindex taşıyan ya da hukuki nedenle yayından kaldırılan bir sayfa dizinden hızla çıkmalıdır; yoksa dizin artık hiçbir yerde var olmayan yanıtlar sunmaya devam eder.
Tazelik görünür de olmalıdır. Her kayıt çekildiği zamanı taşımalı ve bu bilgi sonucu kullanan kişiye ya da ajana ulaşmalıdır. Güncel fiyatları ya da yürürlükteki bir düzenlemeyi soran bir ajanın, bir pasajın yalnızca eşleştiğini değil, bir hafta önce alındığını da görmesi gerekir.
Kapsam, tazelik ve maliyet
Her dizin bir çekme, depolama ve işlem bütçesiyle çalışır ve bu bütçe tercih yapmaya zorlar:
- Genişlik mi güncellik mi. Daha çok sayfayı daha seyrek mi, daha az sayfayı daha sık mı ziyaret edeceksiniz?
- Uzun kuyruk. Küçük siteler, niş forumlar ve daha az yaygın dillerdeki belgeler, ne sıklıkla sorulduklarına oranla kapsanması pahalı içeriklerdir.
- Gizli web. Giriş ekranlarının, formların, arama kutularının ve ödeme duvarlarının arkasındaki içerik büyük ölçüde dizinde yoktur; içeriğini betiklerle oluşturan sayfalar da ancak kısmen dizine girebilir.
- Saklama derinliği. Bazı dizinler tam metni tutar, bazıları yalnızca bir kesit ve bağlantı; bu da sonraki aşamadaki bir ajanın neyi alıntılayabileceğini sınırlar.
Ajan geliştirenler için pratik ders şu: "Sonuç yok" genellikle "bu dizinde yok" demektir, "hiç yok" değil. Geçici olarak erişilemeyen bir dizin ise bambaşka bir durumdur; kesintiyi boş sonuç gibi raporlayan bir sistem, kendisinden sonra gelen herkesi yanıltır. Aynı şekilde sonuç sayısı da bir koleksiyonun eksiksiz olduğunun kanıtı değildir.
Başkasının dizini üzerine kurmak
Bir web arama API'sini çağırdığınızda aslında bir dizin kiralıyorsunuz. Her sağlayıcıya sorulmaya değer sorular: sizin alanınızdaki kapsam ne kadar taze, her sonuç alındığı tarihi taşıyor mu, tam metin mi yoksa yalnızca kesit mi geliyor, API kesilmiş ya da kısmi sonuçları nasıl bildiriyor, kaldırılan sayfalar nasıl ele alınıyor? Yanıtları olduğu gibi kabul etmeyin; kendi sorgularınızla değerlendirin. Bazı kullanımlarda kalıcı bir vektör deposuna hiç ihtiyacınız olmayabilir: arama tabanlı RAG, güncel sonuçları soru anında getirir.
GoCux'ta proje dizinleri
GoCux açık web'in dizinini tutmaz. Bilgi arama, tek bir projeye ait dokümanlar üzerinde çalışır. Bir doküman içeri aktarıldıktan sonra tam metin arama onun üzerinde çalışır; anlamsal erişim de kullanılabilir olduğunda sonuçlara katkı verir. Yanıtlar atıflı pasajlar olarak gelir; kaynağı açıp bakabilirsiniz. Boş sonuç geçerli bir yanıt sayılır ve "arama kullanılamıyor" durumu "hiçbir şey bulunamadı" durumundan ayrı bildirilir. Bir projenin içeri aktardığı web malzemesi, geldiği sayfanın referansını ve alındığı tarihi korur; böylece yaşı her zaman görünür kalır. Bellek de canlı bir veri akışı olmadığından, güncel bir bilgiye ulaşmanın yolu eski bir özete güvenmek değil, kaynağı yenilemektir. Ayrıntılar için Bilgi arama sayfasına ve aramayı değerlendirme rehberine bakın.
Her dizin için sorulacak sorular
- İçinde tam olarak ne var: hangi siteler, diller ve belge türleri; bilinçli olarak dışarıda bırakılan ne?
- Her sonuç çekildiği zamanı taşıyor mu ve bu zamanı ajana ya da kullanıcıya iletiyor musunuz?
- Anahtar kelime eşleşmesi mi, vektörler mi, ikisi birden mi kullanılıyor; tipik sorgunuzda hangisi başarısız oluyor?
- İlgilendiğiniz her dil için metin çözümleme ve kök bulma nasıl ele alınıyor?
- Kaldırılan ya da değişen sayfalar ne kadar hızlı yansıyor ve bunu nasıl fark edersiniz?
- Boş bir sonucu erişilemeyen bir dizinden, kesilmiş bir listeyi eksiksiz bir listeden ayırt edebiliyor musunuz?
- Dizin ya da ayarları her değiştiğinde yeniden çalıştırdığınız sabit bir test sorgusu setiniz var mı?
Bu iş akışını çalışma alanınıza taşıyın.
Kapsamı belirleyin. Kanıtları inceleyin. Gereken adımları onaylayın.