W tym samouczku budujemy agenta z wywołaniem funkcji, w przypadku którego narzędzie udostępnione modelowi nigdy nie wykonuje dowolnego kodu SQL. Łączy w sobie dwa mechanizmy już zweryfikowane w kodzie Aurabase: walidator NL2SQL i transakcję Postgres tylko do odczytu, dwie cegły natywnej sztucznej inteligencjizintegrowanej z backendem. Wymagania wstępne: projekt Aurabase, jego klucz service_rolei konto u jednego z trzech natywnych dostawców LLM (OpenAI, Anthropic, Gemini).
Najważniejsze
- Prawdziwym ryzykiem nie jest samo wywołanie funkcji, ale narzędzie narażone na model: surowy
execute_sql(query)zapewnia pełny dostęp do SQL. - Bezpieczna architektura udostępnia narzędzie
query_database(question), które deleguje do modułu sprawdzania poprawności drzewa składni (tylko SELECT, ograniczony LIMIT, izolowany schemat), a nie do bezpośredniego wykonania. - Aurabase udostępnia ten walidator natywnie (
/nl2sql): ponowne użycie go jako implementacji narzędzia pozwala uniknąć konieczności samodzielnego przekodowania walidacji SQL. - Zatwierdzony kod SQL jest następnie wykonywany poprzez
aura.db.sql()w trybiereadOnly: true, co jest rzeczywistą transakcją Postgres tylko do odczytu, a nie prostym filtrem tekstowym. - Natywny punkt końcowy
/chatAurabase nie akceptuje jeszcze rolitoolani parametrutools(zweryfikowanego w kodzie): pętla agenta działa obecnie za pośrednictwem pakietu SDK dostawcy LLM, a nie za pośrednictwem serwera proxy Aurabase. - Klucz
service_rolez założenia omija RLS: nie może nigdy opuścić backendu, a agent dziedziczy szerszy dostęp niż typowy uwierzytelniony użytkownik.
Co zbudujesz
Stworzysz agenta, który odpowiada na pytania w języku naturalnym dotyczące danych w projekcie Postgres, nigdy nie pozwalając modelowi na zapisanie kodu SQL, który będzie wykonywany w niezmienionej postaci. Model wywołuje narzędzie o nazwie query_database, narzędzie to tłumaczy pytanie na język SQL zweryfikowany przez NL2SQL, następnie wykonuje ten kod SQL tylko do odczytu i zwraca linie do modelu, aby sformułował odpowiedź.
W tym samouczku zastosowano zestaw SDK JavaScript @aurabase/aurabase-js po stronie serwera (nigdy po stronie przeglądarki, klucz service_role nie może być widoczny dla klienta) oraz funkcję OpenAI wywołującą API dla pętli agenta. Ta sama zasada dotyczy pakietu Anthropic lub Gemini SDK.
Dlaczego narzędzie „uruchom ten SQL” jest niebezpieczne
Większość samouczków dotyczących agentów Postgres, w tym niektóre oficjalne przewodniki, definiuje jedno narzędzie: funkcję execute_sql, która przyjmuje ciąg SQL jako argument i wykonuje go w niezmienionej postaci. Model sam zapisuje ten ciąg na podstawie pytania użytkownika i schematu podanego mu w kontekście.
Wybór ten przenosi na model odpowiedzialność, której nie jest w stanie rzetelnie spełnić. Natychmiastowy zastrzyk włożony w pytanie może spowodować destrukcyjny kod SQL, który narzędzie wykonuje bezkrytycznie, ponieważ nie ma pojęcia, jak powinno wyglądać „uprawnione” zapytanie. W naszym dedykowanym artykule szczegółowo opisano ten wektor ataku: zabezpieczanie NL2SQL przed wstrzyknięciem SQL.
Alternatywa wbudowana w tym samouczku udostępnia węższe narzędzie, query_database(question). Model nie może już bezpośrednio pisać kodu SQL: może jedynie zadawać pytania w ramach własnego wywołania narzędzia. To silnik Aurabase NL2SQL tłumaczy to pytanie na SQL przed przekazaniem go przez walidator drzewa syntaktycznego (sam SELECT, bez podzapytań, autoryzowanych dziesięć funkcji, ograniczony LIMIT).
Narzędzie execute_sql(query: string) zapewnia modelowi pełny dostęp do SQL, niezależnie od tego, jak dobry jest znak zachęty systemu. Instrukcja („wykonuje tylko SELECT”) pozostaje instrukcją, którą model może wykonać, błędnie zinterpretować lub którą można obejść poprzez wstrzyknięcie w pytanie użytkownika.
Zdefiniuj schemat narzędzia wystawionego na model
Trzej natywni dostawcy LLM Aurabase (OpenAI, Anthropic, Gemini) akceptują tabelę definicji narzędzi w formacie schematu JSON. Dla tego agenta wystarczy jedno narzędzie: query_database, które zadaje pytanie w języku naturalnym i nic więcej. Model nie widzi schematu SQL ani pola query, które mógłby sam wypełnić.
Zaimplementuj narzędzie: NL2SQL następnie tylko do odczytu
Moduł obsługi narzędzi działa na Twoim backendzie, nigdy w przeglądarce. Zawiera klucz projektu service_role, który z założenia omija RLS i dlatego nigdy nie powinien być udostępniany klientowi. Wykonuje dwa wywołania pakietu Aurabase SDK.
Pierwsze wywołanie tłumaczy pytanie na język SQL sprawdzany za pomocą aura.ai.nl2sql(): tylko SELECT, ograniczenie LIMIT, brak dostępu do katalogu systemowego. Drugi wykonuje ten SQL już zweryfikowany przez aura.db.sql(), z opcją readOnly: true: sam Postgres następnie odmawia jakiegokolwiek zapisu w tej transakcji, niezależnie od sprawdzania poprawności tekstu zastosowanego już przez NL2SQL wyższego szczebla.
readOnly: true wyzwala prawdziwą transakcję Postgres tylko do odczytu: silnik odmawia zapisu, nie jest to filtr zastosowany do tekstu żądania. W połączeniu z walidacją NL2SQL obejmującą tylko SELECT, agent ma dwie niezależne warstwy: jeśli jedna ma wadę, druga nadal działa.
Pętla agenta: wywołanie funkcji po stronie SDK dostawcy
Aurabase udostępnia trzech natywnych dostawców LLM, ale jego punkt końcowy /chat nie przekazuje jeszcze parametru tools ani roli tool. ChatOptions przenosi tylko temperature, max_tokens i model, a akceptowane role są ograniczone do system, user i assistant (zweryfikowane w llm/mod.rs i handlers/chat.rs). Dlatego pętla wywoływania funkcji działa obecnie bezpośrednio za pośrednictwem pakietu SDK dostawcy, a nie za pośrednictwem serwera proxy Aurabase.
Dopóki Aurabase nie koordynuje natywnie wywołań narzędzi, Twój backend musi sam zarządzać pętlą za pomocą OpenAI, Anthropic lub Gemini SDK. Wykonywanie NL2SQL i SQL pozostaje klasycznymi wywołaniami Aurabase w tej pętli.
Zasada pozostaje taka sama, jeśli koordynujesz agenta za pomocą LangChain lub usługi takiej jak Azure AI Agent: narzędzie zadeklarowane w strukturze musi pozostać takie samo query_database, nigdy surowy moduł wykonujący SQL. Nasze szczegóły porównania, gdzie LangChain i LlamaIndex zapewniają prawdziwą wartość w Postgres i gdzie szczególnie zwiększają złożoność: Agenci Postgres z LangChain lub LlamaIndex.
Test z prawdziwym pytaniem
Pytanie wysłane do agenta: „Ilu klientów premium złożyło zamówienie w tym miesiącu?” ". Szablon wywołuje query_database z tym pytaniem w niezmienionej postaci, nigdy nie wyświetlając ani nie zapisując żadnego kodu SQL. Oto wynik dwóch wewnętrznych wywołań wywołanych przez narzędzie.
Ostateczna odpowiedź modelu opiera się na tych rzeczywistych liniach, a nie na domysłach. Jeśli narzędzie zwróci zero wierszy, halucynacja liczbowa stanie się znacznie mniej prawdopodobna niż w przypadku modelu, który odpowiedziałby bez zweryfikowanych danych.
Zabezpiecz agenta przed wejściem do produkcji
- Klucz
service_rolenigdy nie opuszcza Twojego backendu: ani w podpowiedzi wysyłanej do modelu, ani w dzienniku, ani w zmiennej środowiskowej po stronie klienta. readOnly: truepozostaje aktywny naaura.db.sql()dla tego konkretnego narzędzia, nawet jeśli projekt wymaga napisania w innym miejscu aplikacji.service_rolezgodnie z projektem omija RLS. Jeśli agent powinien reagować inaczej w zależności od użytkownika zadającego pytanie, jawnie odfiltruj kod SQL lub wróć do klasycznych punktów końcowych PostgREST, które uwzględniają RLS. Zobacz izolacja RLS dla wielu dzierżawców.- Rejestruj każde wywołanie narzędzia (zadane pytanie, walidacja SQL, liczba wierszy): jest to jedyny użyteczny ślad, jeśli pytanie daje nieoczekiwany wynik.
- Limity stawek i miesięczny limit Aurabase obowiązują już dla każdego projektu w dniu
/nl2sql: gadatliwy agent nie może po cichu przekroczyć budżetu AI.
Aktualne ograniczenia, o których należy pamiętać
Narzędzie query_database dziedziczy wszystkie ograniczenia walidatora NL2SQL: brak podzapytań, brak CTE/WITH, brak UNION i zamkniętą listę dziesięciu funkcji SQL. Pytanie, które w naturalny sposób wymaga zapytania dodatkowego („klienci, którzy nigdy nie zamawiali”), należy przeformułować lub przetworzyć za pomocą drugiego dedykowanego narzędzia, a nie wtłaczać do NL2SQL.
Obecnie w serwerze proxy Aurabase /chat nie istnieje żadna orkiestracja wywołań narzędzi: opisana tutaj pętla agenta znajduje się w kodzie aplikacji, a nie w usłudze zarządzanej. Jeśli agent musi połączyć kilka narzędzi (na przykład bazę danych i dokument RAG), to Twój backend koordynuje te dwa połączenia.
RAG i wywołanie funkcji połączone
W tym samouczku opisano pytania strukturalne dotyczące danych relacyjnych. W przypadku pytań dotyczących zawartości nieustrukturyzowanej (dokumenty, bilety, notatki) ten sam agent może udostępnić drugie narzędzie połączone z natywnym RAG Aurabase (pgvector, wyszukiwanie HNSW). Obie możliwości i ich artykulacja są szczegółowo opisane na stronie Natywna sztuczna inteligencja w Postgres.