Usługa semantycznego wyszukiwania wykorzystująca bazę danych wektorową Pinecone za serwerem MCP.
Usługa semantycznego wyszukiwania wielokrotnego użytku: dzielenie plików PDF na fragmenty, przechowywanie wektorów w bazie danych Pinecone oraz umożliwianie dowolnemu agentowi wyszukiwania ich za pośrednictwem serwera FastMCP.
Źródła: Building a Semantic Search Pipeline with Pinecone and MCP
Model językowy może odpowiadać tylko na podstawie tego, co widział podczas szkolenia. Standardy inżynieryjne, podręczniki polityk, specyfikacje produktów oraz wewnętrzne wiki są dla niego niewidoczne, chyba że te materiały zostaną dostarczone w momencie zadania pytania. Opisany tutaj proces zajmuje się tym w przypadku zbiorów w formacie PDF: dokumenty są raz umieszczane w Pinecone, a każdy agent AI może do nich uzyskiwać dostęp za pośrednictwem serwera MCP stworzonego przy użyciu SDK FastMCP.
Dlaczego wyszukiwanie według słów kluczowych jest niewystarczające
Proste wyszukiwanie według słów kluczowych wydaje się oczywistym rozwiązaniem, ale ludzie rzadko formułują pytania dokładnie tak, jak to robi dokumentacja, przez co istotne fragmenty umykają uwadze. Słowniki synonimów i rozszerzanie zapytań pomagają, jednak oba te podejścia opierają się na relacjach między słowami zdefiniowanych ręcznie. Żadne z nich nie rozumie znaczenia tych słów.
Poszukiwanie semantyczne obiera inną drogę. Zarówno dokumenty, jak i zapytania są przekształcane w wektorowe embeddingi, które kodują znaczenie, a trafność oceniana jest poprzez porównanie tych wektorów za pomocą podobieństwa kosinowego – miary tego, jak blisko dwa wektory w przestrzeni embeddingów wskazują w tym samym kierunku. Wyższy wynik oznacza silniejszy związek semantyczny, dzięki czemu powiązane fragmenty pojawiają się nawet wtedy, gdy słownictwo jest zupełnie inne. Pytanie takie jak „Jak rośliny przekształcają światło słoneczne w energię?” może ujawnić teksty o chloroplastach i fotosyntezie, mimo że żaden z tych terminów się w nich nie pojawia.
Dwa komponenty: baza danych wektorowych i serwer MCP
System składa się z dwóch części, które mogą zmieniać się niezależnie: pipeline’u do pobierania danych oraz serwera MCP. Proces pobierania danych odbywa się raz na dokument. Następnie każdy połączony agent może wielokrotnie wysyłać zapytania do tej samej zindeksowanej wiedzy przez serwer.
Proces przetwarzania przekształca surowe pliki PDF w wektory nadające się do wyszukiwania. Wyodrębnia z nich tekst, dzieli go na nakładające się fragmenty, tworzy embeddingi za pomocą Pinecone Inference i zapisuje wektory do indeksu Pinecone. Tworzenie embeddingów dla dużej liczby plików wymaga znacznych zasobów obliczeniowych, dlatego prosty rejestr zapobiega powtarzaniu tych działań. Dla każdego zindeksowanego pliku przechowuje czas ostatniego utworzenia embeddingu. Podczas kolejnego uruchomienia proces porównuje aktualny czas modyfikacji pliku z zapisanym. Zmieniony dokument otrzymuje nowe embeddingi, natomiast niezmieniony zachowuje swoje istniejące wektory. Baza danych pozostaje zgodna z aktualizacjami dokumentów, dzięki czemu nie dochodzi do zbędnych wywołań funkcji tworzenia embeddingów.
Serwer MCP, zbudowany na FastMCP, otrzymuje pytanie w języku naturalnym od agenta, wstawia je, przeprowadza wyszukiwanie podobieństw w Pinecone i zwraca fragmenty o najwyższych wynikach. Ponieważ interfejsem jest MCP, kilka aplikacji AI może korzystać z tego samego usługi wyszukiwania bez konieczności znajomości bazy danych wektorowych ani modelu wstawiania za nią stojącego.
Rozdzielenie tych dwóch części było celowe. Zamiana modeli wstawiania, dostosowanie metody dzielenia na fragmenty lub odbudowa indeksu wektorowego może odbywać się bez ingerencji w interfejs MCP ani w żaden agent, który od niego zależy.
Budowa pipeline'u do tworzenia embeddingów i dzielenia na fragmenty
Pliki PDF są tworzone dla ludzkich oczu, a nie dla maszyn do wyszukiwania, dlatego muszą najpierw zostać przekształcone w formę oddającą ich znaczenie. Proces rozpoczyna się od pobierania tekstu z każdego pliku za pomocą biblioteki pypdf w Pythonie – strony są czytane pojedynczo, a uzyskane wyniki łączone w jedną ciągłą sekwencję, aby ułatwić późniejszą obróbkę. Może on obsługiwać zarówno pojedyncze pliki, jak i całe katalogi, dzięki czemu nowe zbiory dokumentów mogą być indeksowane bez konieczności zmian w mechanizmie wyszukiwania.
Wybór sposobu dzielenia na fragmenty
Po wyekstrakowaniu tekstu dokument jest dzielony na mniejsze fragmenty zwane kawałkami, a ta decyzja okazała się jedną z najważniejszych w całym procesie. Modele embeddingowe mają ustalone okna kontekstowe, co wyklucza umieszczenie całego dokumentu jako jednego wektora. Nawet gdy dokument mieści się w tych ograniczeniach, pojedynczy embedding całego pliku daje szerokie, niewyraźne przedstawienie, ponieważ kilka niespowiązanych tematów zostaje ze sobą połączonych, co obniża dokładność wyszukiwania.
Każdy dokument jest więc dzielony na kawałki o stałej wielkości, które się nakładają, co umożliwia temu, by każde embedding reprezentowało krótszy, bardziej precyzyjny fragment tekstu. Wybór tej wielkości to balans między kontekstem a specyfiką. Małe kawałki zazwyczaj dostarczają dokładniejszych wyników, ponieważ każdy embedding oddaje węższe pojęcie, choć generują one więcej wektorów i zwiększają czas indeksowania oraz potrzeby przechowywania. Duże kawałki zachowują więcej otaczającego kontekstu i zmniejszają liczbę wektorów, ale każdy embedding obejmuje szerszy zakres informacji, co może obniżyć precyzję. Dzielenie tekstu na kawałki z uwzględnieniem semantyki lub struktury zdania stanowi bardziej zaawansowaną opcję, jednak proste dzielenie na kawałki o stałej wielkości okazało się prostym i skutecznym rozwiązaniem podstawowym do ogólnego wyszukiwania.
chunks = [
text[i:i+500]
for i in range(0, len(text), 450)
]
/*
Fixed-size overlapping chunk generation used during document ingestion.
A chunk length of 500 characters and a stride of 450 characters preserve
contextual continuity while maintaining semantic specificity.
*/
Embeddingi z Pinecone
Następnie fragmenty tekstu przekształcają się w embeddingi. Embedding to gęsta liczbowa reprezentacja tekstu, która koduje jego znaczenie. Zamiast porównywać słowa kluczowe, wyszukiwanie semantyczne porównuje wektory, dzięki czemu powiązane fragmenty tekstowe pasują do siebie pomimo różnego słownictwa. Wektory dla „kota” i „psa” znajdują się blisko siebie w przestrzeni embeddingów, natomiast „kot” i „samolot” są od siebie daleko, co umożliwia obliczanie podobieństwa w sposób matematyczny, a nie poprzez dokładne dopasowanie słów.
Modelem embeddingowym jest tutaj hostowany przez Pinecone model multilingual-e5-large, dostępny za pośrednictwem API Pinecone Inference. Usługa hostowana oznacza, że nie ma konieczności wdrażania ani utrzymywania oddzielnego modelu sztucznej inteligencji, dzięki czemu kod służący do przetwarzania danych może skupić się wyłącznie na obsłudze dokumentów, a architektura pozostaje prostsza.
Wybrano ten model, ponieważ jest zoptymalizowany pod kątem semantycznego wyszukiwania i obsługuje ponad sto języków. Rodzina E5 traktuje również zapytania oraz fragmenty dokumentów jako różne typy danych wejściowych, co dobrze odpowiada potrzebom wyszukiwania. Podczas tworzenia indeksu fragmenty są umieszczane jako teksty do wyszukiwania, ponieważ to one stanowią treść, którą można przeszukiwać. Podczas wysyłania zapytania pytanie użytkownika jest traktowane jako zapytanie. Oba elementy znajdują się w tym samym przestrzeni semantycznej, co zwiększa szanse na znalezienie odpowiedniego materiału, nawet gdy sformułowanie różni się znacznie.
Pod względem przepustowości, fragmenty są wysyłane do API w partiach po 96 elementach – to największa liczba elementów w jednej partii, jaką obecnie obsługuje Pinecone Inference dla modelu multilingual-e5-large. Wysyłanie wielu fragmentów w jednej prośbie zmniejsza liczbę wywołań API, lepiej wykorzystuje zasoby i skraca czas indeksowania w porównaniu z wysyłaniem fragmentów pojedynczo. Gotowe embeddingi wraz z ich metadanymi są następnie przechowywane w bazie danych wektorowej Pinecone, gotowe do wyszukiwania.
embeddings = pc.inference.embed(
model="multilingual-e5-large",
inputs=batch,
parameters={"input_type": "passage"}
)
Server MCP do wyszukiwania semantycznego
Gdy dokumenty są już zindeksowane, agenci potrzebują sposobu na dostęp do nich. Zamiast bezpośrednio udostępniać bazę danych wektorowych aplikacjom, server Model Context Protocol zbudowany przy użyciu FastMCP pełni tę rolę. MCP zapewnia aplikacjom AI jeden standardowy sposób na wywoływanie narzędzi, dzięki czemu każdy kompatybilny klient może korzystać z funkcji wyszukiwania bez konieczności znajomości bazy danych czy modelu embeddingu, który ją obsługuje. Dodatkowa warstwa umożliwia ponowne wykorzystanie kodu wyszukiwania, ułatwia jego utrzymanie oraz zapewnia oddzielenie od aplikacji, które go wykorzystują.
Głównym zadaniem servera jest wyszukiwanie. Gdy agent wysyła pytanie, server embeduje je za pomocą tego samego modelu multilingual-e5-large używanego podczas indeksowania, przeprowadza wyszukiwanie podobieństw w indeksie Pinecone i zwraca najbardziej relevantne fragmenty. Użycie tego samego modelu po obu stronach sprawia, że fragmenty i zapytania pozostają w tym samym przestrzeni semantycznej, co umożliwia ich sensowne porównywanie.
Aby poprawić jakość wyników, narzędzie wyszukiwania zwraca tylko te wyniki, których podobieństwo kosinowe przekracza 0,82. W eksperymentach wyniki powyżej tej wartości zazwyczaj wskazywały na silne dopasowanie semantyczne pomiędzy zapytaniem a fragmentem tekstu, natomiast niższe wyniki oznaczały co najwyżej słabe powiązanie. Usunięcie słabszych wyników zapewnia modelom językowym bardziej istotny kontekst. Pytanie takie jak „Jak złożyć raport wydatkowy?” może trafić na właściwą stronę z zasadami, nawet jeśli dokument formułuje je inaczej. Oprócz funkcji wyszukiwania, serwer udostępnia narzędzia do zarządzania bazą wektorową: dodawanie wektorów, ich usuwanie oraz wyświetlanie dostępnych indeksów.
Ponieważ system jest przeznaczony do wdrożenia w przedsiębiorstwach, bezpieczeństwo stanowi integralną część jego projektu. Dane uwierzytelniające pochodzą z Azure Key Vault, a każda prośba wymaga ważnego klucza API przed przeprowadzeniem jakiejkolwiek operacji pobierania. Sensitive informacje dotyczące infrastruktury nie trafiają do aplikacji klienckich, a dostęp do zindeksowanych dokumentów jest zabezpieczony.
results = index.query(
vector=query_embedding,
top_k=5,
include_metadata=True
)
Co pokazuje projekt dotyczący RAG w przypadku dokumentów wewnętrznych
Skuteczny system wyszukiwania semantycznego zależy równie mocno od decyzji inżynieryjnych, jak i od modeli językowych, które stanowią jego podstawę. Strategia dzielenia na fragmenty, model embeddingów, podejście do grupowania zapytań oraz architektura wyszukiwania bezpośrednio wpływają na jakość, skalowalność i łatwość konserwacji systemu. Umieszczenie procesów pobierania i wyszukiwania za serwerem MCP daje modułowy system, który można ponownie wykorzystać, który jest prosty w utrzymaniu i łatwy do rozszerzania wraz ze zmianami potrzeb.
Obecna wersja stanowi solidną podstawę z wyraźną możliwością dalszego rozwoju. Semantic chunking, modeli do ponownego rankowania, wyszukiwanie hybrydowe oraz bogatsze metadane mogą jeszcze bardziej poprawić efektywność wyszukiwania, zachowując przy tym niezmienioną strukturę modułową. W miarę jak generowanie wzbogacone o funkcje wyszukiwania staje się standardem w korporacyjnej sztucznej inteligencji, niezawodne wyszukiwanie semantyczne przekształca się w podstawowy element systemów produkcyjnych, a łączenie Pinecone Inference z warstwą wyszukiwania MCP to praktyczny i skalowalny sposób na tworzenie wielokrotnie używalnego systemu wyszukiwania semantycznego.