MemoDokümantasyon
TR

Vektör Arama Mantığı

Memo'nun vektör arama motoru, sqlite-vec uzantılı SQLite desteğiyle tamamen süreç içinde çalışır. 768 boyutlu float32 gömüler üzerinde kosinüs benzerliği kullanır.

Temel Algoritma: Kosinüs Benzerliği

q sorgu vektörü ve d₁, d₂, ..., dₙ belge vektörleri için:

benzerlik(q, d) = (q · d) / (||q|| × ||d||)

Burada:

  • q · d nokta çarpımıdır
  • ||q|| ve ||d|| L2 normlarıdır

Sonuç -1.0 (zıt) ile 1.0 (özdeş) arasında bir değerdir.

func CosineSimilarity(a, b []float32) float64 {
    var dot, normA, normB float64
    for i := range a {
        dot += float64(a[i]) * float64(b[i])
        normA += float64(a[i]) * float64(a[i])
        normB += float64(b[i]) * float64(b[i])
    }
    if normA == 0 || normB == 0 {
        return 0
    }
    return dot / (math.Sqrt(normA) * math.Sqrt(normB))
}

İlk-K Arama

Arama hattı en benzer K parçayı döndürür:

  1. ANN Ön Filtre: vec0 yaklaşık en yakın komşu indeksi, arama alanını hızla ~100 adaya daraltır
  2. Tam Kosinüs Puanlama: Her aday sorgu vektörüne karşı puanlanır
  3. Sırala & Kes: Sonuçlar azalan benzerliğe göre sıralanır, ilk K korunur
  4. Eşik Filtresi: min_similarity altındaki tüm sonuçlar atılır
type SearchResult struct {
    Content    string  `json:"content"`
    Source     string  `json:"source"`
    Similarity float64 `json:"similarity"`
    ChunkIndex int     `json:"chunk_index"`
}

func (s *Store) Search(ctx context.Context, queryVector []float32, topK int, minSimilarity float64) ([]SearchResult, error) {
    // 1. vec0 ile ANN ön filtre
    // 2. Tam kosinüs puanlama
    // 3. Sırala, kes, eşikle
}

Paralel İşçi Havuzu

Büyük arama alanları, goroutine işçi havuzu kullanılarak paralel olarak işlenir:

Sorgu Vektörü
    │
    ├─▶ İşçi 1 ── Parçalar 0–999   ──▶ Sonuç Kümesi A
    ├─▶ İşçi 2 ── Parçalar 1000–1999 ──▶ Sonuç Kümesi B
    ├─▶ İşçi 3 ── Parçalar 2000–2999 ──▶ Sonuç Kümesi C
    └─▶ İşçi 4 ── Parçalar 3000–3999 ──▶ Sonuç Kümesi D
                                               │
                                         Birleştir + İlk-K
                                               │
                                         Nihai Sonuçlar
  • İşçi sayısı: Varsayılan olarak runtime.NumCPU()
  • İş dağıtımı: Kanal üzerinden atanan eşit boyutlu parçalar
  • Sonuç toplama: Her işçi sync.Mutex ile korunan paylaşımlı sonuç dilimine yazar
  • İptal: Bağlam iptali tüm işçileri anında durdurur

Parçalı Arama Alanı

Arama alanı, aktarılan belgeler ve geçmiş sohbetlerle büyür. Veri ölçeklendikçe hızlı aramayı sürdürmek için:

Toplam Parça Strateji
< 1,000 Kaba kuvvet kosinüs (tek geçiş)
1,000 – 100,000 vec0 ANN indeksi + tam yeniden puanlama
> 100,000 Yalnızca ANN indeksi, yeniden puanlama öncesi ilk 200 aday

Parça Üst Verisi

Her parça, filtreleme ve atıf sağlamak için üst veri taşır:

SELECT content, source, chunk_index, created_at
FROM vec_memory
WHERE embedding MATCH ?  -- vec0 ile KNN arama
ORDER BY distance
LIMIT ?;

Benzerlik Eşiği

min_similarity eşiği (varsayılan 0.7) iki amaca hizmet eder:

  1. Gürültüyü önler: Düşük benzerlikli parçalar değer katmaz ve bağlam penceresini seyreltir
  2. Token tasarrufu: Daha az parça enjeksiyonu, gerçek sohbet için daha fazla alan demektir

Kullanıcılar eşiği Ayarlar'dan ayarlayabilir:

Ayar Etki
0.9 Yalnızca neredeyse özdeş eşleşmeler (dar hatırlama)
0.7 Varsayılan — iyi kesinlik ve hatırlama dengesi
0.5 Geniş hatırlama, teğetsel ilgili içerik içerebilir
0.3 Çok geniş — yalnızca kapsamlı arama için kullan

Performans Ayarı

Parametre Varsayılan Ne Zaman Artırılmalı Ne Zaman Azaltılmalı
top_k 5 Daha geniş bağlam gerektiğinde Bağlam penceresi dolduğunda
min_similarity 0.7 İlgisiz sonuçlar geliyorsa İlgili sonuçlar kaçıyorsa
chunk_size 512 Belgeler uzun tutarlı bölümlere sahipse Kısa soru-cevap tarzı içerikte
chunk_overlap %10 İçerik yoğun ve süreklilik gerekiyorsa İçerik zaten kendi kendine yeterliyse


Kosinüs benzerliği hesaplaması karşılaştırma başına O(n)'dir. 768 boyutlu vektörlerle tek bir karşılaştırma yaklaşık 3 mikrosaniye sürer. İşçi havuzu bunu mevcut tüm CPU çekirdeklerine paralelleştirir.