Retrywal semantyczny przy użyciu ChromaDB i embeddingów dla platformy wielu agentów
Przeniesienie platformy wieloagentowej dla przedsiębiorstw na rzeczywiste wyszukiwanie semantyczne: dzielenie tekstu z uwzględnieniem słów, odległość kosinowa w ChromaDB, warstwy testowe oraz następny krok RetrievalAgent.
Źródła: Building Real Semantic Retrieval for an Enterprise Multi-Agent AI Platform
W projekcie Enterprise Multi-Agent AI Platform osiągnięto nowy kamień milowy: pipeline wyszukiwania realizuje teraz prawdziwe wyszukiwanie semantyczne, wykorzystując embeddingi przechowywane w ChromaDB. Architektura ewoluowała od prostego przygotowywania dokumentów do pełnowartościowego procesu wyszukiwania, który obejmuje kolejno SourceDocument, DocumentChunker, EmbeddingService, OpenAI Embeddings, ChromaDB, wyszukiwanie semantyczne i wreszcie RetrievedDocument.
To znacząca zmiana na tym etapie. Platforma nie tylko przygotowuje dokumenty i generuje embeddingi – może również przechowywać wektorowe dane firmowe, wyszukiwać je według znaczenia, sortować istotne fragmenty i zwracać ustrukturyzowane wyniki. Budowa platformy ujawniła również kilka problemów związanych z jakością wyszukiwania, które trzeba było naprawić, zanim pipeline mógł zostać podłączony do RetrievalAgent.
Pipeline nabiera kształtu
Architektura wyszukiwania jest zorganizowana w następujący sposób:
Enterprise Documents
│
▼
SourceDocument
│
▼
DocumentChunker
│
▼
DocumentChunk[]
│
▼
EmbeddingService
│
▼
OpenAI Embeddings
│
▼
ChromaDB
│
▼
Semantic Search
│
▼
RetrievedDocument[]
│
▼
RetrievalAgent
Każda warstwa ma jedną odpowiedzialność, i to jest celowe. Celem nie było stworzenie jednej dużej funkcji RAG, która ładuje pliki, dzieli tekst, tworzy embeddingi, zarządza bazą wektorową, przeprowadza wyszukiwanie i generuje odpowiedź. Zamiast tego system składa się z wyraźnych granic architektonicznych.
Etap 1: dokumenty źródłowe
Wszystko zaczyna się od wiedzy przedsiębiorstwa. Z biegiem czasu ta treść może pochodzić z plików PDF, DOCX i TXT, raportów finansowych, polityk wewnętrznych, dokumentacji technicznej, materiałów badawczych oraz baz wiedzy przedsiębiorstwa. Model SourceDocument nadaje temu materiałowi jednolity kształt przed wpuszczeniem go do procesu. Koncepcyjnie wygląda to tak:
SourceDocument
├── document_id
├── content
├── source
└── metadata
Zasadą kluczową w tym przypadku jest możliwość śledzenia. Wszystko, co zostanie później odzyskane, musi nadal łączyć się z źródłem, z którego pochodzi.
Etap 2: dzielenie na fragmenty
Dokumenty dużej objętości zazwyczaj nie powinny być umieszczane jako jeden blok. DocumentChunker przekształca każdy SourceDocument w mniejsze fragmenty gotowe do odzyskania:
SourceDocument
│
▼
DocumentChunker
│
├── Chunk 0
├── Chunk 1
├── Chunk 2
└── Chunk N
Każdy fragment zachowuje swoje chunk_id, document_id, content, source, chunk_index oraz metadane. Dzięki temu wyszukiwanie semantyczne może funkcjonować na małych jednostkach informacji bez utraty powiązania z oryginalnym dokumentem.
Poprawa jakości fragmentów
Rozpoczęcie rzeczywistego procesu wyszukiwania ujawniło pewien problem. Dzielenie tekstu na fragmenty według znaków może przerwać zwykłą prozę w nieodpowiednich miejscach, czasami nawet w środku słowa. Granica może teoretycznie stworzyć fragment, który kończy się w następujący sposób:
...important financial risks for
następuje fragment, który zaczyna się w ten sposób:
the upcoming quarter...
lub, w gorszych przypadkach, rozdzielenie w środku słowa. Takie fragmenty są technicznie poprawne, jednak jakość wydobywania informacji zależy od czegoś więcej niż tylko od poprawnych struktur danych. Granice wpływają na jakość semantyczną tego, co jest w nich umieszczane.
Dlatego strategia dzielenia tekstu została zmieniona tak, aby w przypadku zwykłego prozy preferować granice słów, zachowując jednocześnie opcję opartą na granicach znaków dla tekstu bez użytecznych przerw. Narzędzie do dzielenia tekstu ma teraz dwa tryby działania:
Normal prose
↓
Prefer word-aware boundaries
Text without whitespace
↓
Fallback to character boundaries
To mały szczegół implementacji, który niesie ze sobą ważną lekcję architektoniczną: przejście testów nie oznacza, że jakość wydobywanych danych jest dobra, a rzeczywiste dane ujawniają problemy, których izolowane testy jednostkowe nie zawsze są w stanie pokazać.
Etap 3: embeddingi
Gdy fragmenty będą gotowe, EmbeddingService przekształca ich tekst na wektory liczbowe.
DocumentChunk
│
▼
EmbeddingService
│
▼
Embedding Model
│
▼
Vector Representation
Sługa obsługuje embeddingi pojedynczych tekstów dla zapytań oraz embeddingi zbiorcze dla fragmentów dokumentów. Wcześniejszy rzeczywisty test integracji lokalnej potwierdził wymiar wektora na poziomie 1 536. Sama liczba ma mniejsze znaczenie niż fakt, że implementacja embeddingów znajduje się poza granicami usługi, dzięki czemu Retrieval Agent nie musi wiedzieć, w jaki sposób są generowane wektory.
Etap 4: Przechowywanie wektorów w ChromaDB
Kolejnym elementem jest trwałe przechowywanie wektorów. Każdy fragment może teraz być przechowywany wraz ze swoim wektorem i metadanymi. Koncepcyjnie:
DocumentChunk
+
Embedding
+
Metadata
│
▼
ChromaDB
│
▼
Persistent Vector Collection
Zapis wektorowy może przechowywać informacje takie jak:
Vector Record
├── chunk_id
├── embedding
├── content
├── document_id
├── source
├── chunk_index
└── metadata
Pusty wektor nie jest przydatny dla reszty aplikacji. Platforma potrzebuje rzeczywistej treści oraz informacji o tym, skąd pochodzi.
Etap 5: wyszukiwanie semantyczne
Dzięki wbudowanym fragmentom przechowywanym w ChromaDB system może przeprowadzać wyszukiwanie semantyczne. Ścieżka zapytania wygląda następująco:
User Query
│
▼
EmbeddingService
│
▼
Query Embedding
│
▼
ChromaDB
│
▼
Similarity Search
│
▼
Top-K Relevant Chunks
│
▼
RetrievedDocument[]
Zdobywanie informacji zmienia się z wyszukiwania dokumentów zawierających dokładnie te słowa na znajdowanie fragmentów, których znaczenie najlepiej odpowiada zapytaniu. To jedna z kluczowych możliwości leżących u podstaw RAG.
Korekta metryki podobieństwa
Rzeczywiste testy ujawniły drugi problem. Bazy danych wektorowych obsługują różne metryki odległości lub podobieństwa, a jeśli kolekcja używa jednej metryki, podczas gdy aplikacja interpretuje zwróconą odległość jako inną, ocena istotności staje się myląca. W tym przypadku kolekcja ChromaDB została wyraźnie skonfigurowana pod kątem odległości kosinusowej, dzięki czemu warstwa pozyskiwania danych może spójnie interpretować wyniki jako podobieństwo oparte na kosinusie.
Query Embedding
│
▼
ChromaDB
│
▼
Cosine Distance
│
▼
Similarity Score
│
▼
Ranked Results
Retrywalizacja semantyczna nie polega tylko na zwracaniu dokumentów. Chodzi również o zrozumienie, jak istotne one są.
Prawdziwe wyniki retrywalizacji
Po podziale na fragmenty i korekcie wskaźników podobieństwa pipeline został przetestowany przy użyciu rzeczywistego zapytania dotyczącego ryzyka finansowego. Wyniki uporządkowane wykazały wskaźniki podobieństwa wynoszące mniej więcej 0,6181, 0,5520 i 0,4198, a odzyskany kontekst zawierał istotne informacje o ryzyku płynnościowym i zmienności rynkowej. Dlatego pipeline przeszedł przez całą tę ścieżkę:
Question
↓
Query Embedding
↓
ChromaDB
↓
Semantic Similarity
↓
Relevant Chunks
↓
Financial Risk Context
W tym momencie infrastruktura wyszukiwania przestała być zwykłą pracą konfiguracyjną i zaczęła pokazywać rzeczywiste wykorzystanie wiedzy semantycznej do wyszukiwania.
Dlaczego ważne są rzeczywiste testy wyszukiwania
Testy jednostkowe symulowane pozostają niezwykle cenne. Zapewniają szybkość, determinizm, bezpieczeństwo w procesach CI, brak kosztów związanych z zewnętrznymi API, kontrolowane scenariusze awarii oraz izolację logiki aplikacji. Nie mogą jednak odpowiedzieć na każde pytanie. Test symulowany może potwierdzić, że coś funkcjonuje poprawnie pod względem strukturalnym:
EmbeddingService
↓
Expected Vector
ale nie może w pełni pokazać, że następujący łańcuch zapewnia dobre zachowanie przy wyszukiwaniu:
Real Document
↓
Real Chunking
↓
Real Embedding
↓
Real Vector Database
↓
Real Semantic Query
↓
Useful Context
Zatem strategia testowania oddziela kilka poziomów weryfikacji.
Strategia testowania
Pliatforma zmierza w kierunku trzech uzupełniających się warstw testowania.
Testy jednostkowe są szybkie i deterministyczne, więc należą do standardowego procesu CI:
Application Logic
↓
Mock External Dependencies
↓
Controlled Results
↓
Assertions
Testy integracyjne weryfikują rzeczywistą infrastrukturę i mogą być wykonywane oddzielnie od szybkiego zestawu CI:
Application
↓
Real Embedding Provider
↓
Real ChromaDB
↓
End-to-End Retrieval
Testy wydajności i odporności stają się konieczne w miarę dojrzewania platformy:
Realistic Workload
↓
Concurrent Requests
↓
Latency
Throughput
Rate Limits
Failures
Cost
Scalability
System AI gotowy do produkcji wymaga wszystkich trzech elementów. Symulowanie usług zewnętrznych w testach jednostkowych nie zastępuje testów integracyjnych, a te z kolei nie zastępują testów wydajnościowych. Każda warstwa odpowiada na inne pytania inżynieryjne.
CI pozostaje sprawny
Po ulepszeniach w procesie pobierania danych szybki zestaw testów funkcjonuje prawidłowo – 17 testów przeszło pomyślnie, a 2 testy integracyjne zostały wykluczone. Jest to istotne, ponieważ pipeline RAG staje się coraz bardziej zaawansowany, bez rezygnacji z deterministycznej weryfikacji w ramach CI. Cykl rozwoju przebiega następująco:
Code Change
↓
Fast Unit Tests
↓
Commit
↓
Push
↓
GitHub Actions
↓
CI Validation
↓
Keep Green
Testy z rzeczywistymi usługami pozostają dostępne jako oddzielna sesja.
Łączenie RAG z platformą wieloagentową
Infrastruktura pozyskiwania informacji nie istnieje w izolacji. Ma służyć jako warstwa wiedzy dla większego systemu wieloagentowego, a szersza architektura zmierza w tym kierunku:
User
│
▼
Supervisor Agent
│
▼
Planning Agent
│
▼
Execution Plan
│
▼
Agent Registry
│
┌────────────┼────────────┐
▼ ▼ ▼
RetrievalAgent ResearchAgent AnalysisAgent
│
▼
RetrievalService
│
▼
EmbeddingService
│
▼
ChromaDB
│
▼
Semantic Search
│
▼
Relevant Context
│
▼
Downstream Agents
To jest moment, w którym RAG i orkiestracja wielu agentów zaczynają się łączyć.
Zachowanie prostoty agenta pobierania
Kluczowym celem jest utrzymanie RetrievalAgent skupionego na swojej własnej zadaniu. Nie powinien on znać się na algorytmach dzielenia na fragmenty, implementacji embeddingów, wymiarach wektorów, wewnętrznej strukturze ChromaDB, obliczeniach podobieństwa ani konfiguracji przechowywania. Zamiast tego:
RetrievalAgent
↓
RetrievalService
↓
VectorStoreService
↓
EmbeddingService + ChromaDB
Agent żąda odpowiednich informacji, a infrastruktura wyszukiwania decyduje o sposobie ich znalezienia. To rozdzielenie umożliwia rozwój podstawowej implementacji bez konieczności przepisywania agenta.
Kolejny etap: zastąpienie tymczasowej infrastruktury wyszukiwania
Kolejny krok jest jasny. Agent wyszukiwania nadal musi być połączony bezpośrednio z rzeczywistą infrastrukturą wyszukiwania. Obecnie wygląda to tak:
BEFORE
RetrievalAgent
↓
Temporary Local Documents
a celem jest to:
NEXT
RetrievalAgent
↓
RetrievalService
↓
VectorStoreService
↓
EmbeddingService
↓
ChromaDB
↓
Semantic Search
↓
Enterprise Knowledge
Po tej integracji agent przestaje zwracać tymczasowe, sztywno zdefiniowane wyniki i pobiera wiedzę z rzeczywistej, skatalogowanej kolekcji dokumentów.
Od infrastruktury do wykonywania z udziałem wielu agentów
Ta integracja oznacza kolejną przemianę. Do tej pory większość pracy skupiła się na budowie infrastruktury do wyszukiwania. Gdy RetrievalAgent zacznie korzystać z rzeczywistego, semantycznego procesu przetwarzania, architektura będzie mogła obsługiwać takie schematy pracy:
User Request
↓
Supervisor
↓
Planning Agent
↓
Execution Plan
↓
Retrieval Agent
↓
Enterprise Knowledge
↓
Analysis Agent
↓
Report Agent
↓
Quality Review
↓
Final Response
RAG staje się zatem funkcjonalnością w ramach szerszego systemu wykonywania zadań przez wiele agentów, a nie już samodzielną funkcją wyszukiwania.
Droga naprzód
Plan rozwoju funkcji wyszukiwania przechodzi od podstawowych komponentów ku funkcjonalnościom skierowanym na produkcję:
Document Contracts ✅
↓
Chunking ✅
↓
Embeddings ✅
↓
ChromaDB Vector Storage ✅
↓
Semantic Search ✅
↓
RetrievalAgent Integration ← NEXT
↓
Reranking
↓
Caching & Cost Controls
↓
Observability & Metrics
↓
Multi-Tenant Isolation
↓
Production Hardening
Późniejsze etapy nabierają coraz większego znaczenia, w miarę jak platforma przechodzi od architektury funkcjonalnej do operacji przedsiębiorstwa.
Produkcyjny RAG wymaga czegoś więcej niż tylko wyszukiwania
Pobranie istotnych fragmentów z ChromaDB to ważny krok, ale nie koniec architektury. Platforma produkcyjna do wyszukiwania musi ostatecznie radzić sobie z:
- Ponownym sortowaniem, ponieważ początkowa podobieństwo wektorów nie zawsze zapewnia najlepszy porządek.
- Cachingiem, ponieważ powtarzane embeddingi i wyszukiwania zwiększają opóźnienia i koszty.
- Zdolnością do obserwacji, aby można było mierzyć opóźnienia w wyszukiwaniu, embeddingach, liczbę dokumentów, wyniki, błędy oraz koszty.
- Ewolucją modeli i przestrzeni wektorowej, ponieważ zmiana modeli embeddingów może wymagać wersjonowanych indeksów oraz kontrolowanego ponownego embeddingowania.
- Zarządzaniem ograniczeniami szybkości, ponieważ zewnętrzni dostawcy AI narzucają ograniczenia operacyjne, które nie są deterministyczne.
To elementy, które powinny znaleźć się w planie rozwoju, ale należy je dodawać stopniowo, przy ustalonych granicach, a nie łączyć od razu w jedną dużą implementację.
Zasada inżynieryjna
Najważniejsza lekcja z tej fazy: najpierw zaprojektować abstrakcję, sprawdzić jej działanie na rzeczywistych danych, a następnie udoskonalać cechy produkcyjne w miarę rozwoju architektury. Ten proces był celowy:
Data Contract
↓
Chunking
↓
Unit Testing
↓
Embeddings
↓
Mocked Provider Testing
↓
Real Integration Validation
↓
Vector Storage
↓
Semantic Retrieval
↓
Retrieval Quality Improvements
↓
Agent Integration
Każdy etap dotyczy innej kategorii problemów, i to właśnie dlatego architektura stopniowa jest tak skuteczna.
Od dokumentów do wykonywania z udziałem wielu agentów
Bardziej szeroka wizja zaczyna stawać się wyraźna:
Enterprise Knowledge
↓
Document Processing
↓
Chunking
↓
Embeddings
↓
Vector Storage
↓
Semantic Retrieval
↓
Retrieval Agent
↓
Multi-Agent Orchestration
↓
Analysis + Research + Reporting
↓
Quality Review
↓
Grounded Enterprise Response
RAG to nie cała platforma. Jest to infrastruktura wiedzy, która umożliwia specjalistycznym agentom pracę w oparciu o konkretny kontekst przedsiębiorstwa.
Bieżący etap
To, co istnieje obecnie: jednolite modele dokumentów, dzielenie tekstu na fragmenty zarówno w sposób prosty, jak i z uwzględnieniem granic słów, usługa embeddingów z symulowanymi testami jednostkowymi oraz rzeczywistym testem walidacyjnym, trwałe przechowywanie w ChromaDB z wyraźnie ustawioną podobieństwem kosinowym, wyszukiwanie semantyczne zwracające wyniki uszeregowane według priorytetu oraz szybki zestaw 17 przeprowadzonych z powodzeniem testów. Kolejnym etapem jest połączenie RetrievalAgent z rzeczywistym procesem wyszukiwania semantycznego, co oznacza, że system przestanie być jedynie podsystemem RAG i zacznie realizować wieloagentową ekzekucję opartą na RAG.
Enterprise AI nie oznacza po prostu podłączenia modelu językowego do bazy danych wektorowej i ogłaszania zwycięstwa. Warstwy wymagają umów, umowy wymagają testów, integracje potrzebują rzeczywistej weryfikacji, a system musi mieć możliwość rozwoju. Proces przeszedł ewolucję od dokumentów, fragmentów tekstu, embeddingów i wektorów do dokumentów, fragmentów, embeddingów, ChromaDB, wyszukiwania semantycznego oraz istotnego kontekstu przedsiębiorstwa. Kolejnym krokiem jest wprowadzenie tego kontekstu do RetrievalAgent, a następnie do realizacji z udziałem wielu agentów. Podstawowy cykl pracy pozostaje niezmienny: budowanie, testowanie, mierzenie, ulepszanie, integracja i skalowanie.