Natywne wyszukiwanie wektorów w Aurabase (RAG, pgvector, osadzanie) opiera się na tym samym mechanizmie indeksowania, opisanym szczegółowo na stronie Native AI na stronie Postgres. W tym przewodniku założono tabelę Postgres z już zainstalowanym pgvectorem, kolumną typu vectori co najmniej kilkoma tysiącami wierszy. Poniżej proste skanowanie sekwencyjne jest często szybsze niż przybliżony indeks.
Najważniejsze
- HNSW nie wymaga żadnej fazy szkoleniowej, w przeciwieństwie do IVFFlat: indeks zbudowany jest na wstawkach, dostępnych w pgvector od wersji 0.5.0.
- Dwa parametry określają jakość indeksu podczas konstruowania:
m(połączenia na węzeł, domyślnie 16) ief_construction(szerokość wyszukiwania podczas konstruowania, domyślnie 64). - Trzeci parametr,
hnsw.ef_search(domyślnie pgvector: 40), jest dostosowywany dla każdego żądania bez przebudowy indeksu, aby rozstrzygnąć przywołanie i opóźnienie. - pgvector caps Indeksowanie HNSW typu
vectordo 2000 wymiarów. Poza tym (na przykład osadzenie z 3072 wymiarami) do indeksowania konieczne jest rzutowanie nahalfvec. - pgvector 0.8.6 to wersja osadzona w obrazie dzierżawcy Aurabase Postgres, zweryfikowana bezpośrednio w pliku Dockerfile 24 sierpnia 2026 r.
Co to jest indeks HNSW w pgvector?
HNSW oznacza Hierarchiczny Żeglowny Mały Świat. Jest to indeks grafowy: każdy wektor staje się węzłem połączonym z najbliższymi sąsiadami, zorganizowanymi w kilku nałożonych na siebie warstwach. Wyszukiwanie rozpoczyna się od góry wykresu, w najrzadszej warstwie, a następnie przechodzi w dół, warstwa po warstwie, do najbardziej odpowiednich sąsiadów. Czas wyszukiwania staje się zatem prawie logarytmiczny, a nie liniowy w zależności od liczby linii.
IVFFlat, drugi indeks pgvector, działa inaczej: dzieli przestrzeń wektorową na listy określone w trakcie szkolenia na istniejącej próbce, zanim będzie można cokolwiek zaindeksować. HNSW nie ma tego ograniczenia, każde wstawienie bezpośrednio wzbogaca wykres, co ułatwia operowanie na tabeli, która stale rośnie. Z drugiej strony indeks HNSW zużywa więcej pamięci i jego zbudowanie zajmuje więcej czasu niż równoważny indeks IVFFlat na tym samym woluminie.
pgvector wprowadza obsługę HNSW w wersji 0.5.0. Późniejsze wersje dodają przydatne funkcje do tego przewodnika: typ halfvec (0.7.0) do indeksowania ponad 2000 wymiarów oraz parametr hnsw.iterative_scan (0.8.0) do poprawy przypominania filtrowanych zapytań. Jeśli przed podjęciem decyzji porównasz pgvector z dedykowaną bazą wektorów, nasze porównanie pgvector z Pinecone, Weaviate i Qdrant szczegółowo opisuje kompromisy.
Przed utworzeniem indeksu sprawdź swoją wersję pgvector
Najpierw potwierdź zainstalowaną wersję pgvector. Rozszerzenie, które jest zbyt stare, powoduje, że niektóre funkcje tego przewodnika po cichu nie działają, szczególnie halfvec i hnsw.iterative_scan.
HNSW istnieje od wersji pgvector 0.5.0. Typ halfvecniezbędny do indeksowania osadzania powyżej 2000 wymiarów wymaga wersji co najmniej 0.7.0. Parametr hnsw.iterative_scan żąda wersji 0.8.0.
W projektach Aurabase pytanie nie pojawia się: obraz Postgres osadza pgvector 0.8.6, zarówno we współdzielonym klastrze Postgres (docker/Postgres.Dockerfile, zbudowany bezpośrednio na pgvector/pgvector:0.8.6-pg16-bookworm), jak i w 16 instancjach CNPG Postgres dedykowanych dla każdego projektu (docker/Postgres.CNPG.Dockerfile, który dziedziczy pgvector 0.8.6 z oficjalny obraz CloudNativePG). Zweryfikowano w obu plikach Dockerfile 24 sierpnia 2026 r.
Wybierz odpowiedni typ kolumny w zależności od rozmiaru osadzonych elementów
Typ kolumny zależy od rozmiaru osadzonych elementów, a nie tylko od modelu, który je generuje. pgvector przechowuje w pamięci klasyczny wektor typu vectorz ograniczeniem do 16 000 wymiarów. Ale indeksowanie HNSW tego typu jest ograniczone do 2000 wymiarów: poza tym CREATE INDEX kończy się niepowodzeniem.
Typowe modele osadzania często przekraczają ten próg: text-embedding-3-large z OpenAI lub gemini-embedding-2 z Google natywnie generują do 3072 wymiarów. Aby zindeksować te wektory za pomocą HNSW, rzuć kolumnę na halfvec (precyzja przechowywania zmniejszona o połowę), co przesuwa limit indeksowania znacznie poza 2000 wymiarów.
| Wymiary | Kolumna | HNSW na wektorze | Wymaga odlewania |
|---|---|---|---|
| 768 | osadzanie_768 | Tak | NIE |
| 1536 | osadzanie_1536 | Tak | NIE |
| 3072 | osadzanie_3072 | Nie (> 2000 przyciemnień) | Tak, obsada::halfvec(3072) |
Silnik Aurabase RAG ilustruje ten kompromis w produkcji: obsługiwane są trzy klasy wymiarów (768, 1536, 3072), przechowywane w trzech odrębnych kolumnach tej samej tabeli embeddings. Kolumny 768 i 1536 są indeksowane bezpośrednio w HNSW na typie vector. Kolumna 3072 jest indeksowana za pomocą rzutowania ::halfvec(3072), dokładnie w celu obejścia ograniczenia wymiaru 2000.
Aby uzyskać szczegółowe informacje na temat pozyskiwania (porcjowanie, wywoływanie dostawcy osadzania, wstawianie), zobacz samouczek potoku RAG na pgvector.
Utwórz indeks z parametrami m i ef_construction
Minimalna składnia jest wystarczająca dla pierwszego indeksu, z domyślnymi wartościami pgvector.
pgvector następnie stosuje m = 16 i ef_construction = 64. Aby jawnie dostosować te wartości, użyj klauzuli WITH:
Przed zbudowaniem indeksu HNSW na dużym stole tymczasowo zwiększ maintenance_work_mem dla sesji: jest to, zgodnie z samą dokumentacją pgvector, najbardziej bezpośrednią dźwignią skracającą czas budowy.
Co zmienia parametr m?
m ustawia maksymalną liczbę połączeń utrzymywanych przez każdy węzeł na wykresie w każdej warstwie. Wyższa wartość zagęszcza wykres: wzrasta przywoływanie, ale zużycie pamięci i czas konstrukcji również rosną, w przybliżeniu liniowo. Wartość domyślna (16) jest odpowiednia w większości przypadków. Zwiększenie liczby do 24 lub 32 jest szczególnie uzasadnione w przypadku dużych osadów, gdzie rozróżnienie między bliskimi i odległymi sąsiadami staje się dokładniejsze.
Co zmienia ef_construction?
ef_construction ustawia rozmiar listy kandydatów badanej podczas konstruowania indeksu dla każdego wstawionego węzła. Wyższa wartość poprawia jakość końcowego wykresu, a tym samym potencjalne wycofanie, kosztem dłuższego czasu konstrukcji. W przeciwieństwie do m, ten parametr nie ma żadnych kosztów w momencie zapytania: jest to jednorazowa inwestycja, płacona tylko raz w momencie utworzenia indeksu.
Częściowe indeksy dla kilku klas wymiarów w tej samej tabeli
Gdy tabela przechowuje wiele kolumn wektorowych (po jednej na klasę wymiaru, tak jak robi to Aurabase), indeksuj każdą kolumnę osobno za pomocą klauzuli WHERE colonne IS NOT NULL. Ten częściowy indeks pozwala uniknąć indeksowania pustych linii dla klas, które nie są używane w danej linii, co zmniejsza rozmiar indeksu i przyspiesza jego budowę, nie ponosząc żadnych kosztów przywołania.
Wybór klasy operatora (vector_cosine_ops, vector_l2_ops lub vector_ip_ops) musi odpowiadać metryce, na podstawie której uczono modelu osadzania. Najnowsze modele osadzania tekstu są szkolone pod kątem podobieństwa cosinus: vector_cosine_ops (lub halfvec_cosine_ops w kolumnie rzutowanej) jest zatem najbezpieczniejszym wyborem domyślnym.
Ustaw ef_search w czasie zapytania
Wartość ef_search jest ustawiana przy każdym zapytaniu, a nie podczas budowania indeksu. Określa rozmiar listy kandydatów sprawdzanych podczas wyszukiwania: im jest ona większa, tym lepsze przypominanie, kosztem dłuższego opóźnienia. pgvector ustawia wartość domyślną na 40.
Wartość 40 rzadko wystarcza, gdy tylko zapytanie łączy wyszukiwanie wektorowe z filtrem WHERE zastosowanym po przeskanowaniu indeksu (w przestrzeni nazw, dzierżawie lub innym kryterium metadanych). Skan HNSW przywraca surowych kandydatów ef_search, a następnie filtr odrzuca ich część. Jeśli zbyt mało kandydatów przeżyje, ostateczny LIMIT okaże się niedopełniony.
Dlatego silnik Aurabase RAG rozszerza ef_search dynamicznie zgodnie z żądanym top_k, zamiast utrzymywać stałą wartość 40: ef = max(top_k × 4, 64). Do wyszukiwania 5 najbliższych wyników używa się ef_search = 64; wyszukiwanie 50 najpopularniejszych zastosowań ef_search = 200. Tę formułę można dostosować do zmiennej środowiskowej w przypadku wdrożeń, które wymagają innego kompromisu w zakresie przypominania/opóźnienia.
pgvector 0.8 dodaje drugą dźwignię dla tego samego problemu: hnsw.iterative_scan. W trybie strict_order lub relaxed_orderwyszukiwanie stopniowo rozszerza swoje wyszukiwanie, aż po przefiltrowaniu zgromadzi wystarczającą liczbę wyników, zamiast zatrzymywać się na ustalonej liście kandydatów. Aurabase aktywuje go domyślnie w strict_order, ale chroni połączenie w punkcie zapisu. W wersji pgvector wcześniejszej niż 0.8, gdzie ten parametr nie istnieje, zapytanie jest kontynuowane w trybie pogorszonym, a nie kończy się niepowodzeniem.
Zbuduj kompletny rurociąg RAG
Ten indeks HNSW to tylko jeden element kompletnego potoku RAG: fragmentacja, generowanie osadzania, przetwarzanie, a następnie wyszukiwanie. Nasz samouczek krok po kroku buduje ten potok od początku do końca na pgvector, od pierwszego wstawienia do zapytania o podobieństwo. Dokumentacja techniczna zawiera również szczegółowe informacje na temat wszystkich natywnych możliwości sztucznej inteligencji Aurabase zbudowanych na Postgres.