Informacje o tym ćwiczeniu (w Codelabs)
1. Omówienie
W różnych branżach wyszukiwanie kontekstowe jest kluczową funkcją, która stanowi sedno aplikacji. Technologia Retrieval Augmented Generation (generowanie rozszerzone przez wyszukiwanie w zapisanych informacjach) od dawna jest kluczowym czynnikiem rozwoju tej ważnej technologii dzięki mechanizmom wyszukiwania opartym na generatywnej AI. Modele generatywne, które mają duże okna kontekstowe i zapewniają imponującą jakość danych wyjściowych, zmieniają oblicze AI. RAG zapewnia systematyczny sposób na wprowadzanie kontekstu do aplikacji i agentów AI, opierając je na uporządkowanych bazach danych lub informacjach z różnych mediów. Te dane kontekstowe są kluczowe dla przejrzystości i dokładności wyników, ale jak bardzo są dokładne? Czy Twoja firma w dużej mierze zależy od dokładności tych dopasowań kontekstowych i ich trafności? Ten projekt przypadnie Ci do gustu.
Wyobraź sobie, że moglibyśmy wykorzystać potencjał modeli generatywnych i tworzyć interaktywne agenty, które są w stanie podejmować autonomiczne decyzje na podstawie informacji o kontekście i oparte na prawdzie. To właśnie zamierzamy robić. Zamierzamy stworzyć kompleksową aplikację z usługą AI za pomocą pakietu Agent Development Kit, korzystając z zaawansowanego silnika RAG w AlloyDB do analizy patentów.
Agent analizy patentów pomaga użytkownikowi znaleźć patenty, które są kontekstualnie dopasowane do tekstu wyszukiwania. Gdy użytkownik poprosi o to, agent może podać przejrzyste i zwięzłe wyjaśnienie oraz dodatkowe informacje o wybranym patencie. Chcesz zobaczyć, jak to zrobić? Zaczynamy.
Cel
Cel jest prosty. Umożliw użytkownikowi wyszukiwanie patentów na podstawie opisu tekstowego, a potem wyświetlanie szczegółowych informacji o konkretnym patencie w wynikach wyszukiwania. Do tego celu można użyć agenta AI utworzonego za pomocą Java ADK, AlloyDB, wyszukiwania wektorowego (z zaawansowanymi indeksami), Gemini i całej aplikacji wdrożonej bez serwera w Cloud Run.
Co utworzysz
W ramach tego laboratorium wykonasz te czynności:
- Tworzenie instancji AlloyDB i wczytywanie danych z publicznego zbioru danych Patents
- Wdrożenie zaawansowanego wyszukiwania wektorowego w AlloyDB za pomocą funkcji oceny ScaNN i Recall
- Tworzenie agenta za pomocą Java ADK
- Implementacja logiki po stronie serwera bazy danych w bezserwerowych funkcjach Cloud Functions w Javie
- Wdrażanie i testowanie agenta w Cloud Run
Na diagramie poniżej przedstawiono przepływ danych i etapów wdrażania.
High level diagram representing the flow of the Patent Search Agent with AlloyDB & ADK
Wymagania
2. Zanim zaczniesz
Utwórz projekt
- W konsoli Google Cloud na stronie selektora projektu wybierz lub utwórz projekt Google Cloud.
- Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie są włączone płatności .
- Użyjesz Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud. Kliknij Aktywuj Cloud Shell u góry konsoli Google Cloud.
- Po połączeniu z Cloud Shell sprawdź, czy jesteś już uwierzytelniony i czy projekt jest ustawiony na identyfikator Twojego projektu, używając tego polecenia:
gcloud auth list
- Aby sprawdzić, czy polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project
- Jeśli projekt nie jest ustawiony, użyj tego polecenia:
gcloud config set project <YOUR_PROJECT_ID>
- Włącz wymagane interfejsy API. W terminalu Cloud Shell możesz użyć polecenia gcloud:
gcloud services enable alloydb.googleapis.com compute.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com run.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com aiplatform.googleapis.com
Alternatywą dla polecenia gcloud jest konsola, w której możesz wyszukać poszczególne usługi lub skorzystać z tego linku.
Informacje o poleceniach i użytkowaniu gcloud znajdziesz w dokumentacji.
3. Konfiguracja bazy danych
W tym module użyjemy bazy danych AlloyDB do przechowywania danych patentowych. Do przechowywania wszystkich zasobów, takich jak bazy danych i logi, używa klastrów. Każdy klaster ma instancję główną, która stanowi punkt dostępu do danych. W tabelach będą się znajdować rzeczywiste dane.
Utwórz klaster, instancję i tabelę AlloyDB, do której zostanie załadowany zbiór danych patentów.
Tworzenie klastra i instancji
- Otwórz stronę AlloyDB w konsoli Cloud. Najłatwiej znaleźć większość stron w Cloud Console jest za pomocą paska wyszukiwania w konsoli.
- Na tej stronie wybierz UTWÓRZ KLASTER:
- Zobaczysz ekran podobny do tego poniżej. Utwórz klaster i instancję z tymi wartościami (upewnij się, że wartości są takie same, jeśli klonujesz kod aplikacji z repozytorium):
- Identyfikator klastra: „
vector-cluster
” - password: "
alloydb
" - PostgreSQL 15 / najnowsza zalecana wersja
- Region: "
us-central1
" - Networking: „
default
”
- Po wybraniu sieci domyślnej zobaczysz ekran podobny do tego poniżej.
Kliknij SKONFIGUROWAĆ POŁĄCZENIE.
- Następnie wybierz „Użyj automatycznie przydzielonego zakresu adresów IP” i kliknij Dalej. Po sprawdzeniu informacji wybierz UTWÓRZ POŁĄCZENIE.
- Po skonfigurowaniu sieci możesz kontynuować tworzenie klastra. Kliknij UTWÓRZ KLASTER, aby zakończyć konfigurowanie klastra, jak pokazano poniżej:
Pamiętaj, aby zmienić identyfikator instancji (który możesz znaleźć w momencie konfigurowania klastra lub instancji) na
vector-instance
. Jeśli nie możesz go zmienić, pamiętaj, aby użyć identyfikatora instancji we wszystkich kolejnych odwołaniach.
Pamiętaj, że utworzenie klastra zajmie około 10 minut. Po zakończeniu procesu powinien wyświetlić się ekran z ogólnymi informacjami o kreatorzym utworzonym klastrze.
4. Pozyskiwanie danych
Teraz dodaj tabelę z danymi o sklepie. Przejdź do AlloyDB, wybierz klaster główny, a następnie AlloyDB Studio:
Możesz musieć poczekać na utworzenie instancji. Gdy to zrobisz, zaloguj się w AlloyDB, używając danych logowania utworzonych podczas tworzenia klastra. Do uwierzytelniania w PostgreSQL użyj tych danych:
- Nazwa użytkownika: „
postgres
” - Baza danych: „
postgres
” - Hasło: „
alloydb
”
Gdy uwierzytelnisz się w AlloyDB Studio, polecenia SQL są wpisywane w Edytorze. Możesz dodać większą liczbę okien Edytora, klikając plus po prawej stronie ostatniego okna.
Polecenia AlloyDB wpisujesz w oknach edytora, korzystając w razie potrzeby z opcji Uruchom, Formatuj i Wyczyść.
Włączanie rozszerzeń
Do tworzenia tej aplikacji użyjemy rozszerzeń pgvector
i google_ml_integration
. Rozszerzenie pgvector umożliwia przechowywanie wektorów dystrybucyjnych i wyszukiwanie ich. Rozszerzenie google_ml_integration udostępnia funkcje, których używasz do uzyskiwania dostępu do punktów końcowych prognozowania Vertex AI w celu uzyskiwania prognoz w SQL. Włącz te rozszerzenia, uruchamiając te DDL:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
Jeśli chcesz sprawdzić rozszerzenia włączone w bazie danych, uruchom to polecenie SQL:
select extname, extversion from pg_extension;
Tworzenie tabeli
W AlloyDB Studio możesz utworzyć tabelę za pomocą poniższego polecenia DDL:
CREATE TABLE patents_data ( id VARCHAR(25), type VARCHAR(25), number VARCHAR(20), country VARCHAR(2), date VARCHAR(20), abstract VARCHAR(300000), title VARCHAR(100000), kind VARCHAR(5), num_claims BIGINT, filename VARCHAR(100), withdrawn BIGINT, abstract_embeddings vector(768)) ;
Kolumna abstract_embeddings umożliwi przechowywanie wartości wektorowych tekstu.
Przyznaj uprawnienia
Uruchom poniższe polecenie, aby przyznać uprawnienia do wykonywania funkcji „embedding”:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
Przypisz rolę Vertex AI USER do konta usługi AlloyDB
W konsoli Google Cloud uprawnień przyznaj konto usługi AlloyDB (które wygląda tak: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) dostęp do roli „Użytkownik Vertex AI”. Zmienna PROJECT_NUMBER będzie zawierać numer Twojego projektu.
Możesz też uruchomić to polecenie w terminalu Cloud Shell:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Wczytywanie danych patentowych do bazy danych
Jako zbioru danych użyjemy publicznych zbiorów danych Patents Google w BigQuery. Do wykonywania zapytań użyjemy AlloyDB Studio. Dane pochodzą z pliku insert_scripts.sql
i będą wczytywane do niego, aby załadować dane patentowe.
- W konsoli Google Cloud otwórz stronę AlloyDB.
- Wybierz nowo utworzony klaster i kliknij instancję.
- W menu nawigacyjnym AlloyDB kliknij AlloyDB Studio. Zaloguj się, używając swoich danych logowania.
- Otwórz nową kartę, klikając ikonę Nowa karta po prawej stronie.
- Skopiuj do edytora zapytanie
insert
ze wspomnianego wcześniej skryptuinsert_scripts.sql
. Aby szybko przetestować ten przypadek użycia, możesz skopiować 10–50 instrukcji insert. - Kliknij Wykonaj. Wyniki zapytania pojawią się w tabeli Wyniki.
5. Tworzenie wektorów dla danych patentowych
Najpierw przetestuj funkcję umieszczania, wykonując tę przykładową kwerendę:
SELECT embedding('text-embedding-005', 'AlloyDB is a managed, cloud-hosted SQL database service.');
Powinien zwrócić wektor zagęszczenia, który wygląda jak tablica liczb zmiennoprzecinkowych, dla przykładowego tekstu w zapytaniu. Wygląda to tak:
Zaktualizuj pole wektora abstract_embeddings
Aby zaktualizować w tabeli streszczenia patentów odpowiednimi wektorami osadzania, uruchom DML:
UPDATE patents_data set abstract_embeddings = embedding( 'text-embedding-005', abstract);
6. Wykonywanie wyszukiwania wektorowego
Teraz, gdy tabela, dane i wektory są gotowe, wykonaj wyszukiwanie wektorowe w czasie rzeczywistym dla tekstu wyszukiwanego przez użytkownika. Możesz to sprawdzić, uruchamiając to zapytanie:
SELECT id || ' - ' || title as title FROM patents_data ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
W tym zapytaniu
- Użytkownik wyszukiwał tekst: „Analiza nastrojów”.
- W metodzie embedding() konwertujemy go na wektory w ramach modelu text-embedding-005.
- "<=>" oznacza użycie metody odległości podobieństwa cosinusowego.
- Przekształcamy wynik metody osadzania w typ wektora, aby był zgodny z wektorami zapisanymi w bazie danych.
- LIMIT 10 oznacza, że wybieramy 10 najbardziej pasujących do tekstu wyszukiwania elementów.
AlloyDB podnosi skuteczność wektorowego modelu uczenia się automatycznego na wyższy poziom:
Wprowadziliśmy sporo zmian. Oto 2 z nich, które są przeznaczone dla deweloperów:
- Filtrowanie w tekście
- Wycofanie oceny
Filtrowanie w tekście
Wcześniej deweloper musiał wykonać zapytanie wyszukiwania wektorowego i zadbać o odfiltrowanie i przywołanie. Optymalizator zapytań AlloyDB podejmuje decyzje dotyczące sposobu wykonywania zapytań z filtrami. Filtrowanie wbudowane to nowa technika optymalizacji zapytań, która umożliwia optymalizatorowi zapytań AlloyDB jednoczesne sprawdzanie warunków filtrowania metadanych i wyszukiwania wektorów, wykorzystując zarówno indeksy wektorów, jak i indeksy kolumn metadanych. Dzięki temu wzrosła skuteczność przywoływania, co pozwala deweloperom korzystać z domyślnych funkcji AlloyDB.
Filtrowanie w tekście jest najlepsze w przypadku średniej selektywności. Podczas wyszukiwania w indeksie wektorowym AlloyDB oblicza tylko odległości wektorów, które pasują do warunków filtrowania metadanych (filtry funkcyjne w zapytaniu są zwykle obsługiwane w klauzuli WHERE). Dzięki temu znacznie poprawia się wydajność tych zapytań, co uzupełnia zalety odfiltrowywania posortowanych danych lub przed ich sortowaniem.
- Zainstaluj lub zaktualizuj rozszerzenie pgvector
CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';
Jeśli rozszerzenie pgvector jest już zainstalowane, zaktualizuj je do wersji 0.8.0.google-3 lub nowszej, aby uzyskać możliwość korzystania z funkcjonalności weryfikatora przywołania.
ALTER EXTENSION vector UPDATE TO '0.8.0.google-3';
Ten krok musisz wykonać tylko wtedy, gdy rozszerzenie wektorowe ma wersję <0.8.0.google-3.
Ważna uwaga: jeśli liczba wierszy jest mniejsza niż 100, nie musisz tworzyć indeksu ScaNN, ponieważ nie będzie on potrzebny w przypadku mniejszej liczby wierszy. W takim przypadku pomiń te czynności.
- Aby tworzyć indeksy ScaNN, zainstaluj rozszerzenie alloydb_scann.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- Najpierw uruchom zapytanie wektorowe bez indeksu i bez włączonego filtra wbudowanego:
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
Wynik powinien być podobny do tego:
- Uruchom na nim narzędzie Explain Analyze (bez indeksu ani filtrowania wbudowanego).
Czas wykonywania to 2,4 ms
- Utwórzmy indeks zwykły pola num_claims, aby można było według niego filtrować:
CREATE INDEX idx_patents_data_num_claims ON patents_data (num_claims);
- Utwórzmy indeks ScaNN dla naszej aplikacji do wyszukiwania patentów. Wykonaj te czynności w AlloyDB Studio:
CREATE INDEX patent_index ON patents_data
USING scann (abstract_embeddings cosine)
WITH (num_leaves=32);
Ważna uwaga: (num_leaves=32)
dotyczy naszego całego zbioru danych zawierającego ponad 1000 wierszy. Jeśli liczba wierszy jest mniejsza niż 100, nie musisz tworzyć indeksu, ponieważ nie będzie on potrzebny w przypadku tak małej liczby wierszy.
- Ustaw filtrowanie wbudowane na indeksie ScaNN:
SET scann.enable_inline_filtering = on
- Teraz uruchom to samo zapytanie z filtrem i wyszukiwaniem wektorowym:
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
Jak widać, czas wykonania tej samej wyszukiwarki wektorów został znacznie skrócony. Umożliwiło to filtrowanie wbudowane w indeks ScaNN w wyszukiwarce wektorowej.
Teraz sprawdźmy odzyskiwanie danych w wyszukiwaniu wektorowym z włączoną funkcją ScaNN.
Wycofanie oceny
W przypadku wyszukiwania zbliżonego odwzorowania odwzorowanie to odsetek trafnych instancji wyodrębnionych z wyników wyszukiwania, czyli liczba wyników prawdziwie pozytywnych. Jest to najczęstszy sposób pomiaru jakości wyszukiwania. Jednym ze źródeł utraty przyrostu skuteczności jest różnica między przybliżonym wyszukiwaniem najbliższych sąsiadów (aNN) a wyszukiwaniem najbliższych sąsiadów (kNN). Indeksy wektorowe, takie jak ScaNN firmy AlloyDB, implementują algorytmy sieci neuronowych, co pozwala przyspieszyć wyszukiwanie wektorów w przypadku dużych zbiorów danych, ale w odwrocie wiąże się z niewielkim spadkiem czułości. Teraz AlloyDB umożliwia pomiar tego kompromisu bezpośrednio w bazie danych w przypadku poszczególnych zapytań i zapewnienie jego stabilności w czasie. Aby uzyskać lepsze wyniki i większą wydajność, możesz zaktualizować parametry zapytania i indeksów zgodnie z tymi informacjami.
Za pomocą funkcji evaluate_query_recall możesz znaleźć odzyskiwanie zapytania wektorowego w indeksie wektorowym dla danej konfiguracji. Ta funkcja umożliwia dostosowanie parametrów w celu uzyskania pożądanych wyników przywołania zapytania wektorowego. Odzyskiwanie to dane używane do oceny jakości wyszukiwania. Jest definiowane jako odsetek zwróconych wyników, które są obiektywnie najbliższe wektorom zapytań. Funkcja evaluate_query_recall jest domyślnie włączona.
Ważna uwaga:
Jeśli podczas wykonywania tych czynności pojawi się błąd odmowy uprawnień w przypadku indeksu HNSW, pomiń na razie całą sekcję oceny przywołań. Może to być związane z ograniczeniami dostępu, ponieważ w momencie tworzenia tego dokumentu funkcja ta została dopiero wydana.
- Ustaw flagę Włącz skanowanie indeksu na indeksie ScaNN i HNSW:
SET scann.enable_indexscan = on
SET hnsw.enable_index_scan = on
- Wykonaj to zapytanie w AlloyDB Studio:
SELECT
*
FROM
evaluate_query_recall($$
SELECT
id || ' - ' || title AS title,
abstract
FROM
patents_data
where num_claims >= 15
ORDER BY
abstract_embeddings <=> embedding('text-embedding-005',
'sentiment analysis')::vector
LIMIT 25 $$,
'{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10}',
ARRAY['scann']);
Funkcja evaluate_query_recall przyjmuje zapytanie jako parametr i zwraca jego wartość przywołania. Jako zapytanie wejściowe funkcji używam tego samego zapytania, którego użyłem do sprawdzenia wydajności. Dodano SCaNN jako metodę indeksowania. Więcej opcji parametrów znajdziesz w dokumentacji.
Współczynnik przyrostowy dla tego zapytania wyszukiwania wektorowego, którego używaliśmy:
Widzę, że odsetek przywołań to 70%. Teraz mogę użyć tych informacji, aby zmienić parametry indeksu, metody i parametry zapytania oraz poprawić odwzorowanie w wyszukiwarce wektorów.
Zmieniliśmy liczbę wierszy w zbiorze wyników na 7 (wcześniej było 10) i zauważyliśmy nieznacznie wyższą wartość RECALL, czyli 86%.
Oznacza to, że w czasie rzeczywistym mogę zmieniać liczbę dopasowań, które widzą użytkownicy, aby zwiększyć trafność dopasowań zgodnie z kontekstem wyszukiwania użytkowników.
Dobrze. Czas na wdrożenie logiki bazy danych i przejście do agenta.
7. Przenoszenie logiki bazy danych do sieci bez serwera
Czy chcesz udostępnić tę aplikację w internecie? Wykonaj te czynności:
- Aby UTWORZYĆ nową funkcję Cloud Run, otwórz funkcje Cloud Run w konsoli Google Cloud lub użyj tego linku: https://console.cloud.google.com/functions/add.
- Jako środowisko wybierz „funkcja Cloud Run”. Podaj nazwę funkcji „patent-search” i wybierz region „us-central1”. Ustaw uwierzytelnianie na „Zezwalaj na nieuwierzytelnione wywołania” i kliknij DALEJ. Wybierz Java 17 jako środowisko uruchomieniowe i Edytor wbudowany dla kodu źródłowego.
- Domyślnie punkt wejścia zostanie ustawiony na „gcfv2.HelloHttpFunction”. Zastąp kod zastępczy w pliku HelloHttpFunction.java i pom.xml funkcji Cloud Run kodem z pliku PatentSearch.java i z pliku pom.xml. Zmień nazwę pliku klasy na PatentSearch.java.
- Pamiętaj, aby w pliku Java zmienić obiekt zastępczy ************* i dane logowania do AlloyDB na swoje wartości. Dane logowania do AlloyDB to te, których użyliśmy na początku tego Codelab. Jeśli użyjesz innych wartości, zmień je w pliku Java.
- Kliknij Wdróż.
WAŻNY KROK:
Po wdrożeniu, aby umożliwić Cloud Functions dostęp do instancji bazy danych AlloyDB, utworzymy łącznik VPC.
Po wdrożeniu funkcje powinny być widoczne w konsoli Google Cloud Run Functions. Wyszukaj nowo utworzoną funkcję (patent-search), kliknij ją, a następnie kliknij EDYTUJ I WDROŻ NOWE WERSJE (oznaczone ikoną EDYTUJ (pisak) u góry konsoli funkcji Cloud Run) i zmień te ustawienia:
- Otwórz kartę Sieci:
- Kliknij „Łączyć się z siecią VPC w przypadku ruchu wychodzącego”, a następnie „Używaj oprogramowania sprzęgającego bezserwerowego dostępu do VPC”.
- W menu sieci kliknij menu sieci i wybierz opcję „Dodaj nowy łącznik VPC” (jeśli nie skonfigurowano jeszcze domyślnego), a następnie postępuj zgodnie z instrukcjami wyświetlanymi w wyskakującym okienku:
- Podaj nazwę oprogramowania sprzęgającego VPC i upewnij się, że region jest taki sam jak w przypadku instancji. Pozostaw wartość sieci jako domyślną, a podsieć ustaw jako niestandardowy zakres adresów IP z zakresem adresów 10.8.0.0 lub podobnym, który jest dostępny.
- Rozwiń opcję POKAZ USTAWIENIA SKALOWANIA i upewnij się, że konfiguracja jest ustawiona dokładnie tak:
- Kliknij UTWÓRZ. Ten sprzęgający program powinien teraz być widoczny w ustawieniach ruchu wychodzącego.
- Wybierz nowo utworzone złącze.
- Wybierz opcję kierowania całego ruchu przez to oprogramowanie sprzęgające VPC.
- Kliknij DALEJ, a potem WDRÓŻ.
- Po wdrożeniu zaktualizowanej funkcji w Cloud Functions powinien zostać wygenerowany punkt końcowy. Skopiuj to i wklej w następującym poleceniu:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST <<YOUR_ENDPOINT>> \
-H 'Content-Type: application/json' \
-d '{"search":"Sentiment Analysis"}'
Znakomicie. Tak łatwo można przeprowadzić zaawansowane wyszukiwanie wektorów podobieństwa w kontekście za pomocą modelu wektorów dystrybucyjnych na podstawie danych z AlloyDB.
8. Tworzenie agenta za pomocą Java ADK
Najpierw zacznijmy od projektu w języku Java w edytorze.
- Przechodzenie do terminala Cloud Shell
https://shell.cloud.google.com/?fromcloudshell=true&show=ide%2Cterminal
- Autoryzuj po wyświetleniu odpowiedniego komunikatu
- Przełącz na edytor Cloud Shell, klikając ikonę edytora u góry konsoli Cloud Shell.
- Na stronie głównej konsoli edytora Cloud Shell utwórz nowy folder o nazwie „adk-agents”.
W katalogu głównym powłoki chmurowej kliknij Utwórz nowy folder, jak pokazano na rysunku:
Nazwij go „adk-agents”:
- Utwórz tę strukturę folderów i puste pliki o odpowiednich nazwach:
adk-agents/
└—— pom.xml
└—— src/
└—— main/
└—— java/
└—— agents/
└—— App.java
- Otwórz repozytorium GitHub na osobnej karcie i skopiuj kod źródłowy plików App.java i pom.xml.
- Jeśli otworzyłeś edytor w nowej karcie, klikając ikonę „Otwórz w nowej karcie” w prawym górnym rogu, możesz otworzyć terminal na dole strony. Możesz otworzyć edytor i terminal równolegle, co pozwoli Ci swobodnie pracować.
- Po sklonowaniu projektu wróć do konsoli edytora Cloud Shell.
- Ponieważ funkcja Cloud Run została już utworzona, nie musisz kopiować plików funkcji Cloud Run z folderu repo.
Pierwsze kroki z pakietem ADK Java SDK
To dość proste. Podczas klonowania musisz przede wszystkim uwzględnić te elementy:
- Dodawanie zależności:
Uwzględnij artefakty google-adk i google-adk-dev (dla interfejsu internetowego) w pliku pom.xml.
<!-- The ADK core dependency -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk</artifactId>
<version>0.1.0</version>
</dependency>
<!-- The ADK dev web UI to debug your agent -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-dev</artifactId>
<version>0.1.0</version>
</dependency>
Pamiętaj, aby odwoływać się do pliku pom.xml z repozytorium źródłowego, ponieważ zawiera on inne zależności i konfiguracje, których aplikacja potrzebuje do działania.
- Konfigurowanie projektu:
Upewnij się, że wersja Java (zalecana 17+) i ustawienia kompilatora Maven są prawidłowo skonfigurowane w pliku pom.xml. Projekt możesz skonfigurować tak, aby miał taką strukturę:
adk-agents/
└—— pom.xml
└—— src/
└—— main/
└—— java/
└—— agents/
└—— App.java
- Definiowanie agenta i jego narzędzi (App.java):
Właśnie w tym tkwi magia pakietu ADK Java SDK. Określamy naszego agenta, jego możliwości (instrukcje) i narzędzia, których może używać.
Tutaj znajdziesz uproszczone wersje kilku fragmentów kodu klasy głównego agenta. Pełny projekt znajdziesz w repozytorium tutaj.
// App.java (Simplified Snippets)
package agents;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.InvocationContext;
import com.google.adk.tools.Annotations.Schema;
import com.google.adk.tools.FunctionTool;
// ... other imports
public class App {
static FunctionTool searchTool = FunctionTool.create(App.class, "getPatents");
static FunctionTool explainTool = FunctionTool.create(App.class, "explainPatent");
public static BaseAgent ROOT_AGENT = initAgent();
public static BaseAgent initAgent() {
return LlmAgent.builder()
.name("patent-search-agent")
.description("Patent Search agent")
.model("gemini-2.0-flash-001") // Specify your desired Gemini model
.instruction(
"""
You are a helpful patent search assistant capable of 2 things:
// ... complete instructions ...
""")
.tools(searchTool, explainTool)
.outputKey("patents") // Key to store tool output in session state
.build();
}
// --- Tool: Get Patents ---
public static Map<String, String> getPatents(
@Schema(name="searchText",description = "The search text for which the user wants to find matching patents")
String searchText) {
try {
String patentsJson = vectorSearch(searchText); // Calls our Cloud Run Function
return Map.of("status", "success", "report", patentsJson);
} catch (Exception e) {
// Log error
return Map.of("status", "error", "report", "Error fetching patents.");
}
}
// --- Tool: Explain Patent (Leveraging InvocationContext) ---
public static Map<String, String> explainPatent(
@Schema(name="patentId",description = "The patent id for which the user wants to get more explanation for, from the database")
String patentId,
@Schema(name="ctx",description = "The list of patent abstracts from the database from which the user can pick the one to get more explanation for")
InvocationContext ctx) { // Note the InvocationContext
try {
// Retrieve previous patent search results from session state
String previousResults = (String) ctx.session().state().get("patents");
if (previousResults != null && !previousResults.isEmpty()) {
// Logic to find the specific patent abstract from 'previousResults' by 'patentId'
String[] patentEntries = previousResults.split("\n\n\n\n");
for (String entry : patentEntries) {
if (entry.contains(patentId)) { // Simplified check
// The agent will then use its instructions to summarize this 'report'
return Map.of("status", "success", "report", entry);
}
}
}
return Map.of("status", "error", "report", "Patent ID not found in previous search.");
} catch (Exception e) {
// Log error
return Map.of("status", "error", "report", "Error explaining patent.");
}
}
public static void main(String[] args) throws Exception {
InMemoryRunner runner = new InMemoryRunner(ROOT_AGENT);
// ... (Session creation and main input loop - shown in your source)
}
}
Wyróżnione kluczowe komponenty kodu w języku Java w ADK:
- LlmAgent.builder(): interfejs Fluent API do konfigurowania agenta.
- .instruction(...): zawiera główne prompty i wskazówki dotyczące LLM, w tym informacje o tym, kiedy użyć danego narzędzia.
- FunctionTool.create(App.class, "methodName"): umożliwia łatwe rejestrowanie metod Javy jako narzędzi, które może wywołać agent. Ciąg znaków nazwy metody musi odpowiadać rzeczywistej publicznej metodzie statycznej.
- @Schema(description = ...): dołącza adnotacje do parametrów narzędzia, pomagając LLM w zrozumieniu, jakich danych wejściowych wymaga dane narzędzie. Opis jest kluczowy dla prawidłowego wyboru narzędzia i wypełnienia parametrów.
- InvocationContext ctx: przekazywany automatycznie do metod narzędzia, zapewniający dostęp do stanu sesji (ctx.session().state()), informacji o użytkowniku i innych danych.
- .outputKey("patents"): gdy narzędzie zwraca dane, ADK może automatycznie zapisać je w stanie sesji pod tym kluczem. W ten sposób usługa explainPatent może uzyskać dostęp do wyników usługi getPatents.
- VECTOR_SEARCH_ENDPOINT: to zmienna zawierająca podstawową logikę funkcjonalną kontekstowych pytań i odpowiedzi dla użytkownika w przypadku wyszukiwania patentów.
- Czynność: po wykonaniu kroku implementacji funkcji Java Cloud Run z poprzedniej sekcji musisz ustawić zaktualizowaną wartość wdrożonego punktu końcowego.
- searchTool: umożliwia użytkownikowi znalezienie w bazie danych patentów odpowiednich patentów w kontekście zapytania.
- explainTool: użytkownik musi podać konkretny patent, aby uzyskać szczegółowe informacje. Następnie podsumowuje streszczenie patentu i może odpowiadać na dodatkowe pytania użytkownika na podstawie posiadanych informacji o patencie.
Ważna uwaga: zmienną VECTOR_SEARCH_ENDPOINT zastąp punktem końcowym CRF.
Wykorzystanie InvocationContext w interakcjach ze stanem
Jedną z kluczowych funkcji umożliwiających tworzenie przydatnych agentów jest zarządzanie stanem w trakcie kolejnych etapów rozmowy. Dzięki parametrowi InvocationContext w ADK możesz to zrobić w prosty sposób.
W pliku App.java:
- Gdy zdefiniowana jest funkcja initAgent(), używamy .outputKey("patents"). Informuje to ADK, że gdy narzędzie (np. getPatents) zwraca dane w polu raportu, dane te powinny być przechowywane w stanie sesji pod kluczem „patents”.
- W metodzie narzędzia explainPatent wstrzykujemy kontekst wywołania:
public static Map<String, String> explainPatent(
@Schema(description = "...") String patentId, InvocationContext ctx) {
String previousResults = (String) ctx.session().state().get("patents");
// ... use previousResults ...
}
Dzięki temu narzędzie explainPatent ma dostęp do listy patentów pobranej przez narzędzie getPatents w poprzedniej turze, co sprawia, że rozmowa jest spójna i zachowuje stan.
9. Testowanie lokalnego interfejsu wiersza poleceń
Definiowanie zmiennych środowiskowych
Musisz wyeksportować 2 zmienne środowiskowe:
- klucz Gemini, który możesz uzyskać z AI Studio:
Aby to zrobić, otwórz stronę https://aistudio.google.com/apikey i pobierz klucz API dla aktywnego projektu Google Cloud, w którym wdrażasz tę aplikację. Zapisz klucz w bezpiecznym miejscu:
- Po uzyskaniu klucza otwórz terminal Cloud Shell i przejdź do nowego katalogu, który właśnie utworzyliśmy (adk-agents), uruchamiając to polecenie:
cd adk-agents
- Zmienna określająca, że tym razem nie używamy Vertex AI.
export GOOGLE_GENAI_USE_VERTEXAI=FALSE
export GOOGLE_API_KEY=AIzaSyDF...
- Uruchamianie pierwszego agenta w interfejsie wiersza poleceń
Aby uruchomić tego pierwszego agenta, w terminalu użyj tego polecenia Maven:
mvn compile exec:java -DmainClass="agents.App"
W terminalu zobaczysz interaktywną odpowiedź pracownika obsługi klienta.
10. Wdrażanie w Cloud Run
Wdrażanie agenta ADK Java w Cloud Run jest podobne do wdrażania dowolnej innej aplikacji w Javie:
- Dockerfile: utwórz plik Dockerfile, aby spakować aplikację w Javie.
- Tworzenie i przesyłanie obrazu Dockera: użyj Google Cloud Build i Artifact Registry.
- Możesz wykonać powyższy krok i wdrożyć usługę na platformie Cloud Run za pomocą jednego polecenia:
gcloud run deploy --source . --set-env-vars GOOGLE_API_KEY=<<Your_Gemini_Key>>
Podobnie wdróżysz funkcję Java Cloud Run (gcfv2.PatentSearch). Możesz też utworzyć i wdrożyć funkcję Java Cloud Run dla logiki bazy danych bezpośrednio w konsoli funkcji Cloud Run.
11. Testowanie za pomocą interfejsu internetowego
ADK zawiera poręczne interfejs internetowy do testowania i debugowania agenta lokalnie. Gdy uruchamiasz App.java lokalnie (np. mvn exec:java -Dexec.mainClass="agents.App", jeśli jest skonfigurowana, lub tylko uruchamiasz metodę main), ADK zwykle uruchamia lokalny serwer WWW.
Interfejs internetowy ADK umożliwia:
- Wysyłaj wiadomości do agenta.
- Sprawdź zdarzenia (wiadomość użytkownika, wywołanie narzędzia, odpowiedź narzędzia, odpowiedź LLM).
- Sprawdzanie stanu sesji.
- wyświetlać logi i ślady.
Jest to nieocenione podczas tworzenia, ponieważ pozwala zrozumieć, jak agent przetwarza żądania i korzysta z narzędzi. Zakładamy, że w pliku pom.xml wartość mainClass jest ustawiona na com.google.adk.web.AdkWebServer i że Twój agent jest zarejestrowany w tym module, albo że uruchamiasz lokalny test runner, który go udostępnia.
Uruchamiając App.java z InMemoryRunner i Scannerem na potrzeby danych wejściowych konsoli, testujesz główną logikę agenta. Interfejs internetowy to osobny komponent, który umożliwia bardziej wizualne debugowanie. Jest on często używany, gdy ADK udostępnia agenta za pomocą HTTP.
Aby uruchomić serwer lokalny SpringBoot, możesz użyć tego polecenia Maven w katalogu głównym:
mvn compile exec:java -Dexec.args="--adk.agents.source-dir=src/main/java/ --logging.level.com.google.adk.dev=TRACE --logging.level.com.google.adk.demo.agents=TRACE"
Interfejs jest często dostępny pod adresem URL z wynikiem powyższego polecenia. Jeśli jest to wdrożona usługa Cloud Run, możesz uzyskać do niej dostęp z linku do wdrożenia Cloud Run.
Wynik powinien być widoczny w interfejsie interaktywnym.
Poniżej znajdziesz film przedstawiający naszego agenta ds. patentów:
12. Czyszczenie danych
Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby wykorzystane w tym poście, wykonaj te czynności:
- W konsoli Google Cloud otwórz stronę https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog.
- https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog
- Na liście projektów wybierz projekt do usunięcia, a potem kliknij Usuń.
- W oknie wpisz identyfikator projektu i kliknij Wyłącz, aby usunąć projekt.
13. Gratulacje
Gratulacje! Udało Ci się utworzyć agenta Patent Analysis w języku Java, łącząc możliwości ADK, https://cloud.google.com/alloydb/docs?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog, Vertex AI i Vector Search. Ponadto zrobiliśmy ogromny krok naprzód w kwestii ulepszania wydajności i efektywności wyszukiwania podobieństw kontekstowych, aby były one naprawdę trafne.
Zacznij już dziś
Dokumentacja ADK: [Link do oficjalnej dokumentacji ADK w języku Java]
Kod źródłowy agenta do analizy patentowej: [link do repozytorium GitHub (teraz publicznego)]
Java Sample Agents: [link do repozytorium adk-samples]
Dołącz do społeczności ADK: https://www.reddit.com/r/agentdevelopmentkit/
Powodzenia w tworzeniu agentów