Przejdź do treści
Architektura 8 min czytania

AI w wyszukiwarce sklepu - semantic search i NLP dla katalogów B2B

Klient B2B wpisuje w wyszukiwarce "śruba do silnika Forda 2.0 TDI" i klasyczny Elasticsearch zwraca mu 3000 wyników, bo łapie wszystkie produkty zawierające słowo "śruba". Klient nie znajduje, czego szukał, idzie do konkurencji albo dzwoni na infolinię z prośbą o pomoc handlowca. Semantic search z embeddingami z OpenAI albo modelami lokalnymi rozumie zapytanie jako koncept, nie tylko jako worek słów kluczowych. W konkretnym wdrożeniu na katalogu 60 tys. SKU widziałem skok search conversion o 30-60%. Cena za to są realne koszty - API embeddingów, baza wektorowa, zespół, który to ogarnie - oraz komplikacja architektoniczna: hybrid search jest niemal zawsze lepszy niż czysty semantic. Mit "AI rozwiąże wszystko" boleśnie się weryfikuje na pierwszym audycie po wdrożeniu.

Jakub Owsianka Autor
Zaktualizowano:
Okladka artykulu: AI w wyszukiwarce sklepu - semantic search i NLP dla katalogów B2B
Okladka artykulu: AI w wyszukiwarce sklepu - semantic search i NLP dla katalogów B2B
Spis treści (6)

Elasticsearch, OpenSearch i Algolia są świetne i nie próbuję ich tutaj dyskredytować - 90% sklepów B2B z dobrze ustawionym Elastykiem ma porządną wyszukiwarkę. Pozostałe 10% to przypadki, w których klasyczny search ma fundamentalne ograniczenia, których nie da się obejść tuningiem.

Pierwszy problem to synonimy bez kontekstu. "Wkręt" i "śruba" mogą znaczyć to samo (w stolarstwie często tak) albo zupełnie co innego (w elektronice precyzyjnej to dwie różne klasy elementów). Klasyczny search wymaga ręcznej listy synonimów - dodajesz synonim, robisz reindex. Sklep z 50 tys. SKU ma tysiące potencjalnych par synonimów, ich ręczne ułożenie i utrzymanie to praca, której nikt nigdy nie skończy.

Drugi problem to brak rozumienia intencji. Query "świder do betonu 8 mm" w klasycznym search matchuje produkty zawierające słowa "świder" plus "beton" plus "8 mm", ale często pokazuje świdry do drewna 8 mm, bo TF-IDF dla "drewno" wypada podobnie do "beton". Klient widzi nieadekwatne wyniki i odchodzi.

Trzeci - long-tail jest całkowicie niewydolny. "Element pasujący do silnika Forda Mondeo 2.0 TDI rok 2018" - klasyczny search nie wie, co z tym zrobić. Brak exact match, słowa kluczowe są zbyt specyficzne. Klient porzuca wyszukiwarkę, idzie do konkurenta.

Czwarty - branżowo specyficzny słownik. Każda branża ma swój dialekt: motoryzacja, budowlanka, chemia. Klasyczny search nie odróżnia "duńskiej" od "polskiej" terminologii bez ręcznego wskazania.

Piąty - multi-language. Klient z Niemiec szuka "Schraube M8x20", chce dokładnie tego samego, co "śruba M8x20" w polskiej części katalogu. Klasyczny search wymaga osobnych indeksów per język i odpowiednich tłumaczeń każdego produktu, co przy 50 tys. SKU jest projektem osobnym.

Semantic search rozwiązuje cztery z tych pięciu problemów out of the box. Rozumie koncept "świder" jako narzędzie plus materiał docelowy plus rozmiar. Synonimy "uczy się" automatycznie z embeddingów. Long-tail łapie bez ręcznej pracy. Multi-language działa naturalnie, bo modele embeddingów są multilingual. Branżowa terminologia wymaga jeszcze fine-tuningu na własnych danych, ale to inny rząd wielkości problemu.

Search w sklepie B2B - klasyczne opcje wyszukiwarki, na które semantic warto nakładać, nie zastępować.

Mechanika rozbija się na cztery kroki, które warto rozumieć przed wdrożeniem.

Pierwszy to embeddings, czyli wektorowanie. Tekst (nazwa produktu plus opis plus atrybuty) jest zamieniany na wektor o stałym wymiarze - typowo 1536, choć modele różnią się szczegółami. Model embeddingów (na przykład OpenAI text-embedding-3-small) został wytrenowany na ogromnym korpusie tekstów i nauczył się reprezentować podobne koncepty jako podobne wektory:

embeddings_model = OpenAIEmbeddings(model="text-embedding-3-small")

vec_screw = embeddings_model.embed("Śruba M8x20 stal nierdzewna")
# [0.12, -0.45, 0.78, ..., 0.23]

vec_bolt = embeddings_model.embed("Bolt M8x20 stainless steel")
# [0.15, -0.43, 0.76, ..., 0.21]  bardzo podobny do śruby

vec_drill = embeddings_model.embed("Świder do drewna 8mm")
# [0.45, 0.12, -0.34, ..., 0.67]  zupełnie inny

Drugi krok to baza wektorowa. Każdy produkt w katalogu ma swój wektor, 60 tys. SKU razy 1536 floatów to około 370 MB danych. Baza wektorowa (Qdrant, Weaviate, Pinecone, pgvector) potrafi w 10-50 ms znaleźć najbliższe wektory dla zapytania - to jest jej core competency.

Trzeci to runtime obsługi zapytań. Klient wpisuje "śruba do silnika 8 mm". Sklep wektoruje zapytanie (sam jeden call do API embeddingów), szuka top 100 najbliższych produktów w bazie wektorowej (cosine similarity), zwraca posortowane wyniki.

Czwarty i najważniejszy to hybrid search, czyli kombinacja klasycznego Elastica i semantic. Klasyczny full-text plus semantic vector search, reranking po obu scoring, klient dostaje dokładne matche na górze listy plus podobne koncepty niżej. Hybrid wygrywa nad czystym semantic w każdym wdrożeniu, jakie widziałem - bo zapytanie typu "ABC-123" nie potrzebuje wektorów, potrzebuje exact match.

W praktyce wygląda to tak. Klient szuka "element łączący do drewna miękkiego 6 mm". Klasyczny search zwraca produkty z dosłownymi słowami "element", "łączący", "drewno", "miękki", "6 mm" - niewiele. Semantic zwraca śruby do drewna, wkręty, kołki, kotwy - wszystkie sensowne kandydaty. Hybrid pokazuje dokładne matche (jeśli istnieją) na górze, sensowne podobieństwa poniżej. Klient zostaje na sklepie.

Stos: embeddings, vector DB, hybrid search

Wybór komponentów dla typowego sklepu B2B z 60 tys. SKU. Cztery decyzje, każda z własnym profilem.

Model embeddingów. OpenAI text-embedding-3-small kosztuje 0.020 USD za milion tokenów, jakość w polskim bardzo dobra, mój domyślny wybór do startu. OpenAI text-embedding-3-large to 0.130 USD za milion - lepsza jakość, ale dla większości sklepów różnica niewidoczna. Cohere embed-multilingual-v3 to alternatywa, lepsza dla polskiego w niszach, ale ekosystem mniejszy. Open-source (bge-large-pl, multilingual-e5) hostowane lokalnie eliminują koszt API, ale dorzucają koszt GPU - sensowne dopiero powyżej miliona zapytań miesięcznie.

Baza wektorowa. Qdrant to open-source w Rust, świetny dla self-hosted, szybki, mój default. Weaviate ma większy ekosystem i GraphQL API, ale jest cięższy w utrzymaniu. Pinecone managed jest najwygodniejszy, ale kosztowny (0.10 USD za godzinę za każdy pod). Postgres z rozszerzeniem pgvector to prosty start, jeśli już masz Postgresa w stosie - bez dodatkowej infrastruktury. Elasticsearch z dense_vector zostawia cię w jednym silniku, ale wydajność wektorowa słabsza niż dedykowanych baz.

Hybrid search wymaga warstwy aplikacyjnej, która łączy klasyczny full-text z wektorowym. Reranking po stronie aplikacji w PHP albo Pythonie, kalkulujący kombinowany score: na przykład 0.6 razy semantic score plus 0.4 razy full-text score, z wagami dobranymi eksperymentalnie.

Rekomendacja dla typowego sklepu B2B 60 tys. SKU:

Komponent Wybór
Embeddings OpenAI text-embedding-3-small na start, własny model po MVP
Vector DB Qdrant self-hosted
Hybrid search Elasticsearch plus Qdrant, reranking w warstwie aplikacji

Architektura wdrożenia:

Sklep front
  ↓ query "śruba do drewna 6mm"
Search service
  ├── Elasticsearch (klasyczny full-text)  → top 100 wyników
  ├── OpenAI embedding API → wektor query  →
  └── Qdrant vector search                  → top 100 podobnych
         ↓
Reranker (kombinacja scoringu obu źródeł)
         ↓
Top 50 wyników → odpowiedź do klienta

Czasy poszczególnych kroków: klasyczny Elasticsearch 20-50 ms, embedding API 100-300 ms (latency do OpenAI to największy koszt), vector search 10-30 ms, reranking 1-5 ms. Razem 150-400 ms, akceptowalne dla większości zapytań.

Optymalizacja, którą warto wdrożyć od pierwszego dnia: cache embeddingów dla popularnych zapytań (90%+ wyszukiwań to wspólne terminy), opcjonalnie lokalny model embeddingów dla samego zapytania (eliminuje latency do OpenAI, ale dorzuca GPU).

Wdrożenie - od POC do produkcji

Realny plan wdrożenia, którego trzymam się w projektach, ma cztery fazy.

Faza POC zajmuje 2-4 tygodnie. Wybierasz 5 tys. produktów (subset katalogu), generujesz embeddingi przez OpenAI API, ładujesz do Qdranta. Budujesz proste REST API: query, embedding, vector search, results. Manualnie testujesz 100 typowych zapytań od klientów, porównujesz wyniki z aktualnym search. Cel: udowodnić, że semantic daje wartość. Bez tego kroku zaczynasz większą inwestycję na ślepo.

Faza MVP produkcyjnego zajmuje 4-8 tygodni. Pełny katalog (60 tys. SKU) w bazie wektorowej. Integracja z istniejącym frontendem wyszukiwarki (UI bez zmian dla klienta). Hybrid search z reranking. Monitoring czasów odpowiedzi i konwersji z wyników wyszukiwania. A/B test: połowa userów dostaje klasyczny search, połowa hybrid. Cel: porównać metryki na realnym ruchu, nie na próbce testowej.

Faza optymalizacji to kolejne 4-6 tygodni. Tuning wagi klasycznego do semantic w hybrydzie. Ewentualnie fine-tuning embeddingów na własnych danych branżowych, jeśli sklep ma niszową terminologię. Cache layer dla popularnych zapytań. Internacjonalizacja, jeśli sklep wielojęzyczny.

Faza continuous improvement nigdy się nie kończy. Logowanie zapytań i wyników, trenowanie własnego modelu z czasem. Click-through analysis - co klient klika po pierwszym wyświetleniu wyników. Feedback loop - jeśli klient regularnie klika wynik na 5 pozycji w wynikach, podbijasz ten typ rankingu.

Total time dla pełnego wdrożenia w średnim sklepie: 3-6 miesięcy. Pierwsze efekty widoczne po fazie MVP, czyli po 6-12 tygodniach.

Akeneo PIM w sklepie B2B - dane z PIM zasilają embeddingi i decydują o ich jakości.

Koszty - OpenAI vs własny model

Kalkulacja kosztu OpenAI dla typowego sklepu jest często szokująco niska - tańsza, niż ludzie myślą.

Pozycja Wartość
Liczba produktów 60 000
Średni opis plus atrybuty 200 tokenów per produkt
Tokeny dla initial indexing 12 mln
Koszt indexing (text-embedding-3-small) 12 mln × 0.020 USD/mln = 0.24 USD (około 1 zł)
Re-indexing miesięczny (10% katalogu się zmienia) około 0.1 zł
Zapytania miesięcznie 100 000
Średni token query 5
Tokeny zapytań miesięcznie 500 tys.
Koszt zapytań 500 tys. × 0.020 USD/mln = 0.01 USD/mc (grosze)
Łączny koszt OpenAI około 1-2 zł/mc dla typowego sklepu

Baza wektorowa Qdrant self-hosted: maszyna z 8 GB RAM dla 60 tys. wektorów to około 50 USD miesięcznie na AWS. Alternatywnie lokalna instancja na istniejącym serwerze - zero ekstra kosztu.

Razem cały stack semantic search to około 50-60 USD miesięcznie. Dla średniego sklepu B2B to żaden koszt - dla porównania jedna kampania Google Ads w tej skali to dziesiątki tysięcy złotych miesięcznie.

Własny model embeddingów (bge-large-pl albo multilingual-e5) hostowany lokalnie wymaga GPU dla embeddingu zapytań w real-time - Tesla T4 na AWS to około 200 USD miesięcznie. Alternatywnie CPU inference, wolniejsze ale akceptowalne dla mniejszej skali. Plus jednorazowe koszty fine-tuningu na własnych danych (500-2000 USD).

Break-even OpenAI versus własny model: OpenAI tańszy poniżej miliona zapytań miesięcznie. Własny model opłaca się powyżej 5 mln zapytań miesięcznie. Dla średniego B2B w Polsce OpenAI jest tańsze i nie warto bawić się we własny model, chyba że istnieją szczególne wymagania prywatności danych (nie chcemy wysyłać polskich opisów produktów do USA).

Czy warto - kiedy AI search się opłaca

Realna analiza ROI, którą stosuję na audytach przed projektem.

Semantic search ma sens, gdy spełniasz przynajmniej trzy z pięciu warunków. Katalog ma powyżej 20 tys. SKU z bogatymi opisami (sklep z 500 SKU i krótkimi nazwami nie ma dla semantic dość paliwa). Klienci często szukają long-tail - specyficzne aplikacje, wymagania techniczne, parametry kombinacyjne. Dropoff w wyszukiwarce jest wysoki - powyżej 30% klientów opuszcza sklep po wyszukiwaniu bez kliknięcia w wyniki. Branża ma bogaty słownik - synonimy, terminy techniczne, wieloznaczność. Zespół jest zdolny to wdrożyć i utrzymać - bo bez tego, nawet najlepszy stos technologiczny się sypie.

Semantic search nie ma sensu w czterech przypadkach. Mały katalog (poniżej 5 tys. SKU) - klasyczny search z dobrze ustawionymi synonimami wystarcza, semantic nie da realnej różnicy. Sklep silnie transakcyjny, w którym klienci znają SKU i nie szukają - tu quick order jest ważniejszy niż search. Brak zespołu, który obsłuży utrzymanie. Inne problemy w sklepie są pilniejsze - jeśli sklep ma LCP 5 sekund, semantic search ratuje 0.5% konwersji, podczas gdy LCP ratowałby 10%.

Realne wzrosty z wdrożeń, które prowadziłem albo audytowałem:

Metryka Bez semantic Z hybrid search
Search-to-click 35-50% 55-75%
Search-to-purchase 5-12% 8-18%
Średnia liczba relewantnych wyników per zapytanie 3-8 8-20
"Zero results" queries 15-25% 3-10%

Wartość biznesowa dla sklepu z 100 tys. organic visits miesięcznie, gdzie 30% używa wyszukiwarki: poprawa search-to-purchase z 8% do 14% to 6% × 30 tys. = 1800 dodatkowych zamówień miesięcznie. Średnia wartość zamówienia 500 zł, czyli 900 tys. zł obrotu miesięcznie ekstra. Koszt całego stacku 200-300 zł miesięcznie. ROI tysiącokrotny.

Optymalizacja PLP - po dobrym search ważna jest też lista produktów, która utrzymuje klienta na stronie.

FAQ

Czy semantic search zastąpi klasyczne Elasticsearch? Nie. Hybrid jest zawsze najlepszy: klasyczny exact-match dla precyzyjnych zapytań plus semantic dla long-tail. Klasyczny Elasticsearch wciąż jest tańszy i szybszy, gdy klient szuka SKU "ABC-123" - tu embeddingów nie potrzebujesz. Semantic dodajesz nad Elasticem, nie zamiast.

Ile kosztuje wdrożenie wektorowej wyszukiwarki dla 50 tys. SKU? POC zajmuje 2-4 tygodnie pracy seniora, czyli 15-30 tys. zł. Pełne wdrożenie hybrid z monitoringiem i A/B testingiem to 3-6 miesięcy, czyli 100-250 tys. zł. Plus infrastruktura (50-100 USD miesięcznie) i API embeddingów (1-5 USD miesięcznie dla typowego ruchu).

Jak obsłużyć long-tail zapytania typu "śruba do silnika Forda 2.0 TDI"? To dokładnie zadanie dla semantic search. Wektor zapytania trafia blisko produktów z opisami w stylu "Element łączący silnik Ford" albo "Cylinder head bolt Ford TDI 2.0" - nawet jeśli słowa się nie pokrywają wprost. Hybrid system pokazuje najpierw exact matches (jeśli istnieją), potem semantic kandydatów.

Czy mogę używać własnych modeli embeddingów lokalnie? Tak. Modele jak bge-large-pl, mxbai-embed-large są open-source. Wymaga GPU albo akceptacji wolniejszego CPU inference. Sensowne, gdy koszty OpenAI rosną powyżej 500 zł miesięcznie albo gdy masz szczególne wymagania prywatności danych (sektor publiczny, dane medyczne, klauzule SCC).

Czy semantic search działa po polsku tak dobrze jak po angielsku? OpenAI text-embedding-3 jest multilingual, ale jakość dla polskiego jest niższa niż dla angielskiego - różnica 5-15% w accuracy w testach branżowych. Cohere embed-multilingual-v3 ma lepszy support polskiego. Dla naprawdę polskiego rynku z niszową terminologią - fine-tuned model na polskim korpusie daje najlepsze wyniki, ale wymaga zespołu i danych.

Co dalej

O autorze

Jakub Owsianka

Architekt rozwiązania silnika platform B2B. Zaczynał po stronie biznesu (własne sklepy), potem deweloper, dziś projektuje wdrożenia dla sklepów z katalogami w dziesiątkach tysięcy SKU. W ostatnich latach wdrożył AI-development w zespole i funkcjonalności oparte o AI bezpośrednio w silniku sklepu.

Masz pytanie do tego artykułu?

Dodatkowy kontekst, problem z własnym wdrożeniem, druga opinia - napisz wprost. Odpowiadam osobiście w 1-2 dni robocze.