RAG w praktyce, czyli samo wyszukiwanie wektorowe to za mało
Utworzono: 12 czerwca 2025 Zaktualizowano: 1 października 2026
Robię czatbota do obsługi urządzeń medycznych. Na demo działał świetnie, gorzej przy prawdziwych pytaniach.
Założenie było proste, ktoś pyta o konkretne urządzenie, bot szuka w dokumentacji i odpowiada. Klasyczny RAG, dzielimy dokumenty na kawałki, liczymy embeddingi, wrzucamy do Azure AI Search i przy pytaniu dociągamy najbliższe fragmenty do promptu.
Urządzeń jest kilka tysięcy i sporo z nich ma prawie takie same nazwy, różnią się jedną literą albo numerem wersji, a dla wyszukiwania wektorowego to prawie to samo. Bot potrafił odpowiedzieć bardzo pewnie, tylko że na podstawie instrukcji od innego modelu, a pomylona instrukcja urządzenia medycznego to już poważna sprawa.
Rozwiązanie wyszło dość przyziemne, zanim w ogóle zaczniemy szukać w dokumentacji, najpierw ustalamy, o jakie urządzenie chodzi. Najpierw dokładne dopasowanie po kodzie i nazwie, potem przybliżone, embeddingi dopiero na końcu, a jak się nie da jednoznacznie ustalić produktu, to bot dopytuje, zamiast zgadywać.
def resolve_product(question: str) -> Product | None: candidates = exact_match(question) or fuzzy_match(question) if not candidates: candidates = vector_match(question, top_k=5) if len(candidates) == 1: return candidates[0] return None # bot dopytuje, o które urządzenie chodzi
Dopiero z ustalonym produktem szukamy fragmentów i to tylko w jego dokumentacji. Pomyłek od razu wyraźnie mniej, a odpowiedzi krótsze i konkretniejsze.
Potem doszły narzędzia, z których model sam wybiera: rozwiązywanie problemów krok po kroku, szukanie w dokumentacji, zaglądanie do systemu z katalogiem produktów i do systemu ze zgłoszeniami od użytkowników, dane z bazy Postgres, wszystko na LangChain i LangGraph. Działa, ale każde nowe narzędzie to kolejne miejsce, gdzie model może skręcić nie tam, gdzie trzeba.
Pytania przychodzą w wielu językach, a dokumentacja jest głównie po angielsku. Z samym językiem embeddingi sobie radzą, gorzej z nazwami produktów, bo te trzeba trafić dokładnie, niezależnie od języka pytania, i to kolejny powód, żeby rozpoznawanie produktu było osobnym krokiem.
Co bym zrobił od razu
Zbiór testowy od pierwszego dnia, prawdziwe pytania z oczekiwanym urządzeniem i dokumentem, puszczane w CI przy każdej zmianie promptu albo dzielenia dokumentów. Bez tego każda poprawka to trochę zgadywanie, czy przy okazji czegoś nie zepsuliśmy.