Tüm yazılara dön

myaihub.ai: Elasticsearch ile Hybrid Search ve eland

myaihub.ai, eland ile yüklenen multilingual-e5-small modelini kNN semantic search ve English analyzer'lı lexical filtreyle birleştirip alakasız sonuçları temizledi.

myaihub.ai: Elasticsearch ile Hybrid Search ve eland

Bir AI araçları dizininde "find an ai tool for web design" yazıyorsunuz; ilk sayfada Typli.AI çıkıyor—bir AI yazı aracı. Üstelik sayaç ne yazarsanız yazın "100+ Results found" diyor. myaihub.ai'daki arama deneyimi buydu: Elasticsearch üzerinde 10.000+ AI aracı barındıran bir dizin, ama sonuçlar kullanıcının niyetini ıskalıyordu.

Katalogda sorun yoktu; sorun query'deydi. AI araçları indeksindeki her doküman "AI" ve "tool" kelimelerini içerir; boost'lu ve fuzzy bir multi_match tam olarak yanlış şeyi ödüllendirir. Aşağıda bunu hybrid search'e—semantic kNN + lexical filtre—nasıl dönüştürdüğümüz ve altyapı tarafında nelerin gerektiği var.

Kısa cevap: myaihub.ai, keyword-only multi_match query'den Elasticsearch üzerinde hybrid search'e geçti: eland_import_hub_model ile 4GB'lık dedicated ML node'a deploy edilen .multilingual-e5-small embedding modeli, description alanından üretilen dense vector'lar ve boost'lu match_phrase ile knn'i (query_vector_builder) birleştiren bir bool query. Lexical taraf name, slug, tags, category, tagline üzerinde English analyzer'lı multi_match filtresi olarak çalışıyor. Anlamı semantic buluyor, keyword filtresi dürüst tutuyor.

Sorun

myaihub.ai kataloğu tools indeksinde: 1 primary shard, 1 replica; name, description, slug, tagline, tags, category alanları text + .keyword multifield. Uygulama tarafındaki query klasik birinci nesildi:

{
  "bool": {
    "must": [{
      "multi_match": {
        "query": "find an ai tool for web design",
        "fields": ["name^10", "description^2", "slug^8", "category^4", "tags^3"],
        "type": "best_fields",
        "fuzziness": "AUTO"
      }
    }],
    "should": [
      { "match_phrase": { "name": { "query": "...", "boost": 3 } } },
      { "match_phrase": { "description": { "query": "...", "boost": 2 } } }
    ]
  }
}

Toplantı notları ve ekran görüntüsünden üç sorun net çıktı:

  • Alakasız sonuçlar. "find an ai tool for web design" sorgusu Typli.AI'ı getirdi—çünkü "ai" ve "tool" her şeyle eşleşiyor, fuzziness: AUTO ağı daha da genişletiyor.
  • "Her zaman 100 sonuç var." Sonuç sayısı sinyal taşımıyordu; arayüz sürekli "100+ Results found" gösteriyordu.
  • Generic token'lar skoru domine ediyordu. Notlar açıktı: ai, an, find, tool kelimeleri ML modeline gitmeden önce temizlenmeli.

Controller kodundan küçük bir detay daha: "most popular" ve "most recent" sıralaması aramadan sonra, JavaScript içinde ve yalnızca çekilen sayfa üzerinde yapılıyordu—relevance'ın query'de değil downstream'de yamalandığının işareti.

Teşhis

Lexical scoring bozuk değildi; kendisine söyleneni yapıyordu. Her dokümanın bir AI aracı olduğu bir korpusta "ai tool" kelimeleri üzerinden tf-idf tarzı sıralama gürültüdür. Kullanıcının "web design" ile kastettiği şey description alanının anlamında yaşar, fuzzy token örtüşmesinde değil.

Ekip erken ve doğru bir ürün kararı verdi: bunu num_candidates'ı küçülterek çözmeyeceğiz. "design" gibi geniş bir sorgu meşru olarak 100+ araçla eşleşir; candidate sayısını kısmak gerçek sonuçları saklardı. Yani çözüm recall'dan çalmak değil, anlama katmanı eklemek olmalıydı.

Bu da hybrid search'e işaret etti: anlam için dense vector semantic retrieval, hassasiyet için lexical filtre. Elastic'in search relevance yazısı aynı dengeyi anlatır.

Çözüm

Cluster'ı ML'e hazırla

Query çalışmasından önce iki ön koşul: 4GB RAM'li dedicated machine learning node ve en az 8.13 hedefli Elasticsearch upgrade (indeks 8.5.x'te yaratılmıştı). ML node yoksa model deployment da yok—ekiplerin en sık atladığı adım bu.

Modeli eland ile yükle

Model import işlemi resmi Docker image'ındaki eland_import_hub_model ile yapıldı. İlk çalışan koşu bir Hugging Face text-embedding modelini deploy etti:

docker run -it --rm elastic/eland \
  eland_import_hub_model \
    --url https://<elasticsearch-endpoint>:443 \
    -u <kullanici> -p <sifre> \
    --hub-model-id sentence-transformers/msmarco-MiniLM-L-12-v3 \
    --task-type text_embedding \
    --start

Multilingual ve image-similarity planları için özel bir image kurduk (python:3.11, eland[pytorch], transformers, sentence-transformers, PYTORCH_ENABLE_MPS_FALLBACK=1) ve clip-ViT-B-32-multilingual-v1 modelini cluster'a göndermeden önce Apple silicon üzerinde lokal test ettik. Production text search, Elastic'in hazır sunduğu multilingual-e5-small modelinde karar kıldı (.multilingual-e5-small_linux-x86_64); dense vector'lar hem indexing hem search anında description alanından üretiliyor.

Hybrid query

{
  "query": {
    "bool": {
      "should": [
        { "match_phrase": {
            "name": { "query": "find an ai tool for web design",
                      "boost": 10, "_name": "exact_match" } } },
        { "knn": {
            "field": "ai.predicted_value",
            "num_candidates": 100,
            "query_vector_builder": {
              "text_embedding": {
                "model_id": ".multilingual-e5-small_linux-x86_64",
                "model_text": "find an ai tool for web design" } },
            "_name": "semantic_search" } }
      ],
      "minimum_should_match": 1,
      "filter": [
        { "multi_match": {
            "query": "web design",
            "fields": ["name", "slug", "tags", "category", "tagline"] } },
        { "knn": {
            "field": "ai.predicted_value",
            "num_candidates": 100,
            "query_vector_builder": {
              "text_embedding": {
                "model_id": ".multilingual-e5-small_linux-x86_64",
                "model_text": "web design" } } } }
      ]
    }
  }
}

Notlara işlenen iş bölümü:

  • Semantic taraf: ai.predicted_value üzerinde kNN, embedding benzerliğiyle en alakalı ürünleri buluyor (pratikte ~20); _score evet/hayır değil, olasılık benzeri bir sinyal.
  • Lexical taraf: English analyzer (stemmer, stop words, lowercase) hem index hem search anında çalışıyor; query kelimelerinin en az %50'si name, slug, tags, category, tagline, description alanlarında eşleşmeli.
  • Filtrele, kısma: lexical multi_match filter içinde durur ve semantic candidate setini keyword'lerle budar—geniş sorgular 100+ meşru sonucunu korur, "web design için Typli" kazaları kaybolur.
  • Query hijyeni: generic token'lar (ai, an, find, tool) metin embedding modeline ulaşmadan temizlenir.

name üzerindeki boost: 10'lu exact match_phrase, navigasyonel sorguları ("Foundr AI") tepede sabit tutar.

Sonuçlar

Yalnızca evidence pack'in desteklediği kadarı:

Sonuç Kanıt
Hybrid query (kNN + lexical filtre) production formunda Notlardaki kayıtlı query
Embedding modeli eland ile deploy edildi, text_embedding, started "looks working fine" notlu eland koşusu
4GB ML node ve ≥8.13 upgrade ön koşul olarak tanımlı Notlardaki aksiyon maddeleri
Katalog ölçeği: tools indeksinde 10.000+ doküman (1 shard / 1 replica) Search response başlığı, index settings
Bilinen kötü örnek tespit edilip hedeflendi (Typli.AI / "web design") Toplantı notları + UI ekran görüntüsü
Recall korundu: num_candidates relevance yaması olarak kısılmadı Notlardaki açık karar

İddia etmediklerimiz: relevance artış yüzdesi, CTR değişimi veya latency rakamları. Kaynak pakette yoklar; bu yazıda da yoklar.

Öğrendiklerimiz

  1. Tek domain'li korpusta generic token zehirdir. Her doküman "AI tool" diyorsa, bu kelimeleri scoring ve embedding'den önce temizleyin.
  2. Hybrid, ikisinden de iyidir. Anlamı kNN bulur; filter içindeki lexical multi_match recall'ı kısmadan hassasiyeti korur.
  3. Kötü relevance'ı num_candidates ile saklamayın. Geniş sorgu geniş sonucu hak eder; sayıyı değil ranking'i düzeltin.
  4. eland + Docker, model deployment'ın en kısa yolu. Tek eland_import_hub_model komutu Hugging Face modelini yükleyip başlatır.
  5. Önce ML node bütçesi. 4GB ML node ve güncel bir 8.x sürümü sonradan akla gelen şeyler değil, ön koşuldur.
  6. Exact-match kaçış kapısı bırakın. name üzerinde boost'lu match_phrase, navigasyonel sorguları semantic kaymadan korur.

Ürün aramanız hâlâ "100+ sonuç" diye gevşek alakalı gürültü döndürüyorsa uyguladığım desen bu: eland ile embedding, hybrid bool query, lexical disiplin. Model canlıya çıktıktan sonra ML node'u da her production iş yükü gibi izleyin—bkz. searchali.com/tr/monitoring.

Kataloğunuzu anlayan bir arama mı istiyorsunuz?searchali.com

Arama altyapınızı sınırların ötesine taşıyalım.

Yüksek performanslı ve hatasız bir arama deneyimi için hemen iletişime geçin.