1. Przegląd
Współcześni podróżni oczekują interakcji konwersacyjnych. Zamiast korzystać ze skomplikowanych filtrów interfejsu, chcą zapytać: „Czy mogę zabrać psa na autobus do Bostonu o 9:00?”. Wymaga to agenta, który potrafi analizować dane nieuporządkowane (zasady w formacie PDF) i dane strukturalne (harmonogramy SQL).
W tym module utworzymy agenta Cymbal Transit, korzystając z tych narzędzi:
- LangChain4j: najlepsza platforma Java do orkiestracji AI.
- AlloyDB: baza danych o wysokiej wydajności zgodna z PostgreSQL.
- MCP Toolbox Java SDK: standardowy sposób łączenia agentów Java z narzędziami zewnętrznymi i źródłami danych.
Co utworzysz
Cymbal Bus Agent, aplikacja Java Spring Boot składająca się z:
- Baza danych AlloyDB i pakiet MCP Toolbox Java SDK do orkiestracji narzędzi za pomocą agentów.
- Cloud Run na potrzeby wdrożenia i aplikacji Toolbox (wdrożenie agenta).
- Biblioteka LangChain4J dla agenta i platformy LLM w aplikacji Spring Boot z Java 17.
Czego się nauczysz
- Jak używać LangChain4J do tworzenia wyspecjalizowanych agentów i podagentów, którymi zarządza MCP Toolbox for Databases Java SDK
- Jak skonfigurować i używać AlloyDB do danych i AI.
- Jak używać MCP Toolbox do łączenia agentów z narzędziami do danych AlloyDB.
- Jak wdrożyć rozwiązanie za pomocą Cloud Run lub uruchomić je lokalnie.
Architektura
- AlloyDB for PostgreSQL: wydajna operacyjna baza danych, w której przechowujemy rekordy dotyczące tras, zasad i rezerwacji. Umożliwia wyszukiwanie i pobieranie wektorowe.
- Pakiet MCP Toolbox for Databases Java SDK: pełni rolę „mistrza orkiestracji”, udostępniając dane AlloyDB jako wykonywalne narzędzia, które mogą wywoływać agenci.
Pakiet MCP Toolbox Java SDK umożliwia łatwe zarządzanie agentami za pomocą narzędzi do obsługi baz danych w aplikacjach klasy korporacyjnej.
- LangChain4J: biblioteka open source w języku Java, która upraszcza integrację dużych modeli językowych (LLM) z aplikacjami w tym języku. Zawiera narzędzia i abstrakcje do tworzenia aplikacji opartych na AI, w tym czatbotów, agentów i systemów generowania wspomaganego wyszukiwaniem (RAG).
- Cloud Run: w pełni zarządzana platforma BEZSERWEROWA, która umożliwia łatwe tworzenie i szybkie wdrażanie aplikacji lub stron internetowych w dowolnym języku, z dowolną biblioteką i dowolnym plikiem binarnym. Możesz pisać kod w ulubionym języku, frameworku i bibliotekach, spakować go jako kontener, uruchomić „gcloud run deploy” i udostępnić aplikację, która będzie miała wszystko, czego potrzebuje do działania w środowisku produkcyjnym. Tworzenie kontenera jest całkowicie opcjonalne. Jeśli używasz Go, Node.js, Pythona, Javy, .NET Core lub Ruby, możesz skorzystać z opcji wdrażania na podstawie kodu źródłowego, która tworzy kontener za Ciebie, korzystając z najlepszych praktyk dla używanego języka.
Wymagania
2. Zanim zaczniesz
Utwórz projekt
- W konsoli Google Cloud na stronie wyboru 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 włączone są płatności.
- Będziesz używać Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud. U góry konsoli Google Cloud kliknij Aktywuj Cloud Shell.

- Po połączeniu z Cloud Shell sprawdź, czy uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu, używając tego polecenia:
gcloud auth list
- Aby potwierdzić, że 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, aby go ustawić:
gcloud config set project <YOUR_PROJECT_ID>
- Włącz wymagane interfejsy API: kliknij link i włącz interfejsy API.
Możesz też użyć polecenia gcloud. Informacje o poleceniach gcloud i ich użyciu znajdziesz w dokumentacji.
Pułapki i rozwiązywanie problemów
Syndrom „projektu widma” | Uruchomiono polecenie |
Bariera rozliczeniowa | Projekt został włączony, ale zapomniano o koncie rozliczeniowym. AlloyDB to wydajny mechanizm, który nie uruchomi się, jeśli „zbiornik paliwa” (płatności) jest pusty. |
Opóźnienie propagacji interfejsu API | Kliknięto „Włącz interfejsy API”, ale w wierszu poleceń nadal wyświetla się |
Limit Quags | Jeśli korzystasz z nowego konta próbnego, możesz osiągnąć regionalny limit instancji AlloyDB. Jeśli |
„Ukryty” agent usługi | Czasami agentowi usługi AlloyDB nie jest automatycznie przyznawana rola |
3. Konfiguracja bazy danych
W centrum naszej aplikacji znajduje się AlloyDB for PostgreSQL. Wykorzystaliśmy jego zaawansowane funkcje wektorowe i zintegrowany silnik kolumnowy do wygenerowania osadzeń dla ponad 50 tys. rekordów SCM. Umożliwia to analizę wektorową w czasie zbliżonym do rzeczywistego, dzięki czemu nasi agenci mogą w ciągu milisekund wykrywać anomalie w asortymencie lub ryzyko logistyczne w ogromnych zbiorach danych.
W tym module użyjemy AlloyDB jako bazy danych do przechowywania danych testowych. Używa klastrów do przechowywania wszystkich zasobów, takich jak bazy danych i logi. Każdy klaster ma instancję podstawową, która zapewnia punkt dostępu do danych. Tabele będą zawierać rzeczywiste dane.
Utwórzmy klaster, instancję i tabelę AlloyDB, do których zostanie załadowany testowy zbiór danych.
- Kliknij przycisk lub skopiuj poniższy link do przeglądarki, w której zalogowany jest użytkownik konsoli Google Cloud.
Możesz też otworzyć terminal Cloud Shell w projekcie, w którym zostało wykorzystane konto rozliczeniowe, sklonować repozytorium GitHub i przejść do projektu, używając tych poleceń:
git clone https://github.com/AbiramiSukumaran/easy-alloydb-setup
cd easy-alloydb-setup
- Po wykonaniu tego kroku repozytorium zostanie sklonowane do lokalnego edytora Cloud Shell i będziesz mieć możliwość uruchomienia poniższego polecenia z folderu projektu (ważne jest, aby upewnić się, że jesteś w katalogu projektu):
sh run.sh
- Teraz użyj interfejsu (kliknij link w terminalu lub link „Podgląd w internecie” w terminalu).
- Aby rozpocząć, wpisz szczegóły identyfikatora projektu, klastra i nazw instancji.
- Idź po kawę, podczas gdy dzienniki będą się przewijać. Tutaj możesz przeczytać, jak to działa za kulisami.
Pułapki i rozwiązywanie problemów
Problem z „cierpliwością” | Klastry baz danych to rozbudowana infrastruktura. Jeśli odświeżysz stronę lub zakończysz sesję Cloud Shell, ponieważ „utknęła”, możesz skończyć z „duchem” instancji, która jest częściowo udostępniona i nie można jej usunąć bez ręcznej interwencji. |
Niezgodny region | Jeśli interfejsy API zostały włączone w regionie |
Zombie Clusters | Jeśli nazwa klastra była już wcześniej używana i nie została usunięta, skrypt może wyświetlić komunikat, że nazwa klastra już istnieje. Nazwy klastrów muszą być unikalne w projekcie. |
Limit czasu Cloud Shell | Jeśli przerwa na kawę trwa 30 minut, Cloud Shell może przejść w stan uśpienia i odłączyć proces |
4. Obsługa administracyjna schematu
Gdy klaster i instancja AlloyDB będą działać, przejdź do edytora SQL w AlloyDB Studio, aby włączyć rozszerzenia AI i udostępnić schemat.

Może być konieczne poczekanie na zakończenie tworzenia 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” (lub inne hasło ustawione podczas tworzenia)
Po pomyślnym uwierzytelnieniu w AlloyDB Studio polecenia SQL są wpisywane w Edytorze. Możesz dodać wiele okien Edytora, klikając znak plusa po prawej stronie ostatniego okna.

Polecenia dla AlloyDB będziesz wpisywać w oknach edytora, w razie potrzeby korzystając z opcji Uruchom, Formatuj i Wyczyść.
Włączanie rozszerzeń
Do utworzenia 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 możesz używać 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;
Przyznaj uprawnienia
Aby przyznać uprawnienia do wykonywania funkcji „embedding”, uruchom to polecenie:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
Przyznawanie roli Użytkownik Vertex AI kontu usługi AlloyDB
W konsoli IAM Google Cloud przyznaj kontu 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"
Tworzenie tabeli
Tabelę możesz utworzyć za pomocą instrukcji DDL poniżej w AlloyDB Studio:
DROP TABLE IF EXISTS transit_policies;
DROP TABLE IF EXISTS bus_schedules;
DROP TABLE IF EXISTS bookings;
-- Table 1: Transit Policies (Unstructured Data for RAG)
CREATE TABLE transit_policies (
policy_id SERIAL PRIMARY KEY,
category VARCHAR(50),
policy_text TEXT,
policy_embedding vector(768)
);
-- Table 2: Intercity Bus Schedules (Structured Data)
CREATE TABLE bus_schedules (
trip_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
origin_city VARCHAR(100),
destination_city VARCHAR(100),
departure_time TIMESTAMP,
arrival_time TIMESTAMP,
available_seats INT DEFAULT 50,
ticket_price DECIMAL(6,2)
);
-- Table 3: Booking Ledger (Transactional Action Data)
CREATE TABLE bookings (
booking_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
trip_id UUID REFERENCES bus_schedules(trip_id),
passenger_id VARCHAR(100),
status VARCHAR(20) DEFAULT 'CONFIRMED',
booking_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Kolumna policy_embedding będzie umożliwiać przechowywanie wartości wektorowych niektórych pól tekstowych.
Pozyskiwanie danych
Uruchom poniższy zestaw instrukcji SQL, aby zbiorczo wstawić rekordy do odpowiednich tabel:
- Wstawianie nieustrukturyzowanych zasad i NATIVE GENERATE REAL EMBEDDINGS w AlloyDB
-- 1. Insert Unstructured Policies and GENERATE REAL EMBEDDINGS natively in AlloyDB
INSERT INTO transit_policies (category, policy_text, policy_embedding)
VALUES
('Pets', 'Service animals are always welcome. Small pets (under 25 lbs) are allowed in secure carriers for a $25 fee. Large dogs are not permitted on standard coaches.', embedding('text-embedding-005', 'Service animals are always welcome. Small pets (under 25 lbs) are allowed in secure carriers for a $25 fee. Large dogs are not permitted on standard coaches.')),
('Luggage', 'Each passenger is allowed one carry-on (up to 15 lbs) and two stowed bags (up to 50 lbs each) free of charge. Additional bags cost $15 each.', embedding('text-embedding-005', 'Each passenger is allowed one carry-on (up to 15 lbs) and two stowed bags (up to 50 lbs each) free of charge. Additional bags cost $15 each.')),
('Refunds', 'Tickets are fully refundable up to 24 hours before departure. Within 24 hours, tickets can be exchanged for travel credit only.', embedding('text-embedding-005', 'Tickets are fully refundable up to 24 hours before departure. Within 24 hours, tickets can be exchanged for travel credit only.'));
- Generowanie ponad 200 realistycznych harmonogramów na 7 dni za pomocą funkcji generate_series
-- 2. Generate 200+ Realistic Schedules for the Next 7 Days using generate_series
INSERT INTO bus_schedules (origin_city, destination_city, departure_time, arrival_time, ticket_price, available_seats)
SELECT
origin,
destination,
-- Generate departures every 4 hours starting from tomorrow
(CURRENT_DATE + 1) + (interval '4 hours' * seq) AS dep_time,
(CURRENT_DATE + 1) + (interval '4 hours' * seq) + interval '4.5 hours' AS arr_time,
ROUND((RANDOM() * 30 + 25)::numeric, 2) AS price, -- Random price between $25 and $55
FLOOR(RANDOM() * 50 + 1) AS seats -- Random seats between 1 and 50
FROM
(VALUES
('New York', 'Boston'), ('Boston', 'New York'),
('Philadelphia', 'Washington DC'), ('Washington DC', 'Philadelphia'),
('Seattle', 'Portland'), ('Portland', 'Seattle')
) AS routes(origin, destination)
CROSS JOIN generate_series(1, 40) AS seq; -- 6 routes * 40 time slots = 240 distinct trips ingested!
Generowanie wektorów dystrybucyjnych
Osadzanie jest automatycznie uwzględniane w instrukcji wstawiania do tabeli transit_policies za pomocą funkcji „embedding('text-embedding-005', '<<policytext>>')”.
Pułapki i rozwiązywanie problemów
Pętla „amnezji hasła” | Jeśli używasz konfiguracji „Jedno kliknięcie” i nie pamiętasz hasła, otwórz stronę podstawowych informacji o instancji w konsoli i kliknij „Edytuj”, aby zresetować hasło |
Błąd „Nie znaleziono rozszerzenia” | Jeśli |
Problemy z propagacją uprawnień | Uruchomiono polecenie
|
Niezgodność wymiarów wektora | Kolumna |
Błąd w identyfikatorze projektu | Jeśli w wywołaniu |
5. Narzędzia i konfiguracja zestawu narzędzi
MCP Toolbox for Databases to serwer MCP typu open source przeznaczony do baz danych. Umożliwia łatwiejsze, szybsze i bezpieczniejsze tworzenie narzędzi dzięki obsłudze złożonych procesów, takich jak pula połączeń, uwierzytelnianie i inne. Zestaw narzędzi pomaga tworzyć narzędzia generatywnej AI, które umożliwiają agentom dostęp do danych w bazie danych.
Jako „dyrygenta” używamy zestawu narzędzi Model Context Protocol (MCP) do baz danych. Działa jako standardowe oprogramowanie pośredniczące między naszymi agentami a AlloyDB. Dzięki zdefiniowaniu tools.yaml konfiguracji zestaw narzędzi automatycznie udostępnia złożone operacje na bazie danych jako proste, wykonywalne narzędzia, takie jak find-bus-schedules and routes lub query-schedules for specific routes, i wykonuje autonomiczne działania, takie jak book-ticket. Eliminuje to konieczność ręcznego tworzenia puli połączeń lub standardowego kodu SQL w logice agenta.
Instalowanie serwera Toolbox
W terminalu Cloud Shell utwórz folder, w którym zapiszesz nowy plik YAML narzędzi i binarny plik przybornika:
mkdir cymbal-bus-toolbox
cd cymbal-bus-toolbox
W tym nowym folderze uruchom te polecenia:
# see releases page for other versions
export VERSION=0.27.0
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
chmod +x toolbox
Następnie utwórz w tym nowym folderze plik tools.yaml. W tym celu otwórz edytor Cloud Shell i skopiuj zawartość tego pliku z repozytorium do pliku tools.yaml.
... (Refer to entire file in the repo)
tools:
find-bus-schedules:
kind: postgres-sql
source: alloydb
description: Find all available bus schedules.
statement: |
SELECT CAST(trip_id AS TEXT) trip_id, departure_time, arrival_time, ticket_price, available_seats , origin_city, destination_city
FROM bus_schedules;
query-schedules:
kind: postgres-sql
source: alloydb
description: Find available bus schedules between an origin and destination city.
parameters:
- name: origin
type: string
description: The departure city name.
- name: destination
type: string
description: The arrival city name.
statement: |
SELECT CAST(trip_id AS TEXT) trip_id, departure_time, arrival_time, ticket_price, available_seats
FROM bus_schedules
WHERE lower(origin_city) = lower($1)
AND lower(destination_city) = lower($2)
AND available_seats > 0
ORDER BY departure_time ASC
LIMIT 5;
book-ticket:
kind: postgres-sql
source: alloydb
description: Books a ticket for a specific trip, decrementing available seats and generating a confirmed booking record.
parameters:
- name: trip_id
type: string
description: The UUID of the trip schedule to book.
- name: passenger_name
type: string
description: Name or ID of the passenger (Bound securely via backend or AuthToken).
authServices:
- name: google_auth
field: sub
statement: |
WITH updated_schedule AS (
UPDATE bus_schedules
SET available_seats = available_seats - 1
WHERE trip_id = CAST($1 AS UUID) AND available_seats > 0
RETURNING trip_id
)
INSERT INTO bookings (trip_id, passenger_id)
SELECT trip_id, $2
FROM updated_schedule
RETURNING CAST(booking_id as TEXT) as booking_id, trip_id, passenger_id, status, booking_time;
search-policies:
kind: postgres-sql
source: alloydb
description: Semantic search for transit policies regarding luggage, pets, refunds, and general rules.
parameters:
- name: search_query
type: string
description: The user's question about transit policies to be embedded and searched.
statement: |
SELECT category, policy_text
FROM transit_policies
ORDER BY policy_embedding <=> CAST(embedding('text-embedding-005', $1) AS vector(768))
LIMIT 2;
Uwaga:
- W konfiguracji tools.yaml nie zapomnij uwzględnić ipType: "private" w konfiguracji źródła AlloyDB.
- Pamiętaj też, aby w parametrze clientId konfiguracji authServices uwzględnić adres URL usługi MCP Toolbox. Link możesz otrzymać dopiero po pierwszym wdrożeniu, więc musisz wykonać kroki wdrażania 2 razy, aby mieć pewność, że narzędzia uwierzytelnione działają prawidłowo.
- Poniższe opcje testowania zestawu narzędzi lokalnie nie będą działać, jeśli połączenie z AlloyDB jest prywatne. Aby przetestować je lokalnie, musisz ustawić je jako publiczne lub użyć serwera proxy do połączenia. Ale nie musisz się tym przejmować. W naszym przypadku wdrożymy go bezpośrednio w Cloud Run, a potem przetestujemy.
Aby przetestować plik tools.yaml na serwerze lokalnym:
./toolbox --tools-file "tools.yaml"
Możesz też przetestować ją w interfejsie:
./toolbox --ui
Wdróżmy go w Cloud Run w ten sposób:
Wdrożenie Cloud Run
- Ustaw zmienną środowiskową PROJECT_ID:
export PROJECT_ID="my-project-id"
- Zainicjuj gcloud CLI:
gcloud init
gcloud config set project $PROJECT_ID
- Musisz mieć włączone te interfejsy API:
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
iam.googleapis.com \
secretmanager.googleapis.com
- Jeśli nie masz jeszcze konta usługi backendu, utwórz je:
gcloud iam service-accounts create toolbox-identity
- Przyznaj uprawnienia do korzystania z usługi Secret Manager:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/secretmanager.secretAccessor
- Przyznaj kontu usługi dodatkowe uprawnienia specyficzne dla naszego źródła AlloyDB (role/alloydb.client i roles/serviceusage.serviceUsageConsumer).
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/alloydb.client
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/serviceusage.serviceUsageConsumer
- Prześlij plik tools.yaml jako tajny token:
gcloud secrets create tools-cymbal-transit --data-file=tools.yaml
- Jeśli masz już obiekt tajny i chcesz zaktualizować jego wersję, wykonaj te czynności:
gcloud secrets versions add tools-cymbal-transit --data-file=tools.yaml
- Ustaw zmienną środowiskową na obraz kontenera, którego chcesz użyć w Cloud Run:
export IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest
- Wdróż Toolbox w Cloud Run za pomocą tego polecenia:
Jeśli masz włączony publiczny dostęp do instancji AlloyDB, wykonaj to polecenie, aby wdrożyć ją w Cloud Run:
gcloud run deploy toolbox-cymbal-transit \
--image $IMAGE \
--service-account toolbox-identity \
--region us-central1 \
--set-secrets "/app/tools.yaml=tools-cymbal-transit:latest" \
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
--allow-unauthenticated
Jeśli używasz sieci VPC, użyj tego polecenia:
gcloud run deploy toolbox-cymbal-transit \
--image $IMAGE \
--service-account toolbox-identity \
--region us-central1 \
--set-secrets "/app/tools.yaml=tools-cymbal-transit:latest" \
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
--network <<YOUR_NETWORK_NAME>> \
--subnet <<YOUR_SUBNET_NAME>> \
--allow-unauthenticated
Uwaga: po wdrożeniu otwórz listę usług Cloud Run i upewnij się, że na karcie bezpieczeństwa tej usługi jest zaznaczona opcja „Zezwalaj na dostęp publiczny”.
6. Konfiguracja aplikacji agenta
Sklonuj to repozytorium do swojego projektu i przejdźmy przez nie.
Aby sklonować ten projekt, uruchom to polecenie w terminalu Cloud Shell (w katalogu głównym lub w dowolnym miejscu, w którym chcesz utworzyć ten projekt):
git clone https://github.com/googleapis/mcp-toolbox-sdk-java
Powyższe polecenie klonuje cały pakiet mcp-toolbox-sdk-java. Potrzebujemy tylko projektu próbnego. Przejdź do katalogu głównego projektu w repozytorium:
cd mcp-toolbox-sdk-java/demo-applications/cymbal-transit
- Powinno to spowodować utworzenie projektu, co możesz sprawdzić w edytorze Cloud Shell.

- Otwórz plik CymbalTransitController.java i ustaw zmienne środowiskowe:
- GCP_PROJECT_ID
- GCP_REGION
- GEMINI_MODEL_NAME
- MCP_TOOLBOX_URL
Możesz też (tylko na potrzeby programowania) zastąpić odpowiednie symbole zastępcze wartości rezerwowych.
7. Instrukcja dotycząca kodu
Symbol CymbalTransitController działa jako punkt wejścia dla naszej usługi Cloud Run. Zarządza ona przebiegiem rozmowy i zapewnia agentowi dostęp do bieżącego żądania użytkownika.
Implementacja ma architekturę warstwową, która rozdziela orkiestrację AI, łączenie narzędzi i komunikację MCP niskiego poziomu.
1. Konfiguracja agenta AI (AgentConfiguration)
Ta klasa używa @Configuration Springa do uruchamiania komponentów AI. Inicjuje VertexAiGeminiChatModel i wiąże go z naszym interfejsem agenta.
@Bean
ChatLanguageModel geminiChatModel() {
return VertexAiGeminiChatModel.builder()
.project(projectId)
.location(region)
.modelName(modelName)
.build();
}
@Bean
TransitAgent transitAgent(ChatLanguageModel chatLanguageModel, TransitAgentTools tools) {
return AiServices.builder(TransitAgent.class)
.chatLanguageModel(chatLanguageModel)
.chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(20))
.tools(tools)
.build();
}
Znaczenie: AiServices wiąże interfejs z LLM. MessageWindowChatMemory zapewnia, że agent zapamięta preferencje użytkownika (np. wspomnianą wcześniej torbę dla zwierząt) w przypadku maksymalnie 20 wiadomości w ramach jednej sesji.
2. Interfejs agenta AI (TransitAgent)
Adnotacja @SystemMessage określa „Personę” i ograniczenia operacyjne, w szczególności strategię routingu.
@SystemMessage({
"You are the Cymbal Transit Concierge.",
"CRITICAL INSTRUCTION: On your very first interaction, you MUST use the 'findAllSchedules' tool to fetch and memorize the broad bus routes.",
"ONLY if the user asks a specifically narrowed-down question... should you route to the specific tools like 'querySchedules', 'bookTicket', 'searchPolicies'.",
"Don't show any asterisks while listing results. Keep it formatted and numbered or bulleted."
})
String chat(@MemoryId String sessionId, @UserMessage String userMessage);
Znaczenie: ta strategia minimalizuje opóźnienie. Pobierając najpierw ogólne dane, agent może odpowiadać na ogólne pytania dotyczące routingu, korzystając z kontekstu wewnętrznego, bez wykonywania zbędnych wywołań backendu.
3. Toolbox Bridge (TransitAgentTools)
Ta usługa działa jak „ręce” agenta, tłumacząc wywołania narzędzi LangChain4j na logikę wykonania.
@Tool("Fetches the initial, broad dataset of all available bus schedules and routes.")
public String findAllSchedules() {
return mcpService.findAllSchedules().join();
}
@Tool("Book a ticket for a passenger using a specific trip ID.")
public String bookTicket(String tripId, String passengerName) {
return mcpService.bookTicket(tripId, passengerName).join();
}
Wykonanie synchroniczne: wywołania MCP są asynchroniczne (zwracają CompletableFuture), ale LLM wymaga wyniku, zanim będzie mógł kontynuować proces „myślenia”. Używamy .join(), aby synchronicznie przekazywać wyniki do agenta.
4. Usługa MCP Toolbox (McpToolboxService)
Jest to warstwa komunikacyjna, która używa pakietu MCP Toolbox Java SDK do interakcji z backendem AlloyDB.
// Identity Management: Fetching OIDC ID Token for Auth
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
this.idToken = ((IdTokenProvider) credentials)
.idTokenWithAudience(targetUrl, Collections.emptyList())
.getTokenValue();
// Dynamic Invocation: Executing a tool by name
public CompletableFuture<String> findAllSchedules() {
return mcpClient.invokeTool("find-bus-schedules", Collections.emptyMap()).thenApply(result -> {
return result.content().stream()
.map(content -> content.text())
.collect(Collectors.joining(", ", "[", "]"));
});
}
Znaczenie: McpToolboxClient zajmuje się obsługą komunikacji JSON-RPC. Metoda bookTicket pokazuje, że pakiet SDK może dynamicznie wiązać złożone parametry.
5. Kontroler REST (TransitAgentController)
Końcowy punkt końcowy jest znacznie uproszczony, ponieważ LangChain4j zarządza stanem i logiką.
@PostMapping("/chat")
public ResponseEntity<String> handleUserChat(@RequestBody String userMessage, HttpSession session) {
String sessionId = session.getId();
String agentResponse = transitAgent.chat(sessionId, userMessage);
return ResponseEntity.ok(agentResponse);
}
Znaczenie: przypisując identyfikator HttpSession do @MemoryId, dbamy o to, aby plany podróży różnych użytkowników nie były ze sobą mylone, a kod kontrolera był przejrzysty i czytelny.
8. MCP Toolbox: znaczenie i pakiet SDK Javy
Co to jest MCP?
Protokół Model Context Protocol (MCP) to uniwersalny tłumacz dla AI. Protokół MCP został stworzony, aby ujednolicić sposób, w jaki modele AI łączą się z narzędziami i zbiorami danych zewnętrznych. Zastępuje on niestandardowe, rozproszone skrypty integracyjne bezpiecznym, uniwersalnym protokołem. Niezależnie od tego, czy agent musi wykonać transakcyjne zapytanie SQL, przeszukać tysiące dokumentów dotyczących zasad czy wywołać interfejs API REST, MCP zapewnia jeden ujednolicony interfejs.
Zestaw narzędzi MCP do baz danych
Zespoły inżynierów wykraczają poza proste chatboty i tworzą systemy agentowe, które wchodzą w bezpośrednią interakcję z bazami danych o kluczowym znaczeniu. Jednak tworzenie takich agentów klasy korporacyjnej często wiąże się z koniecznością pokonania bariery integracji, która polega na użyciu niestandardowego kodu łączącego, niestabilnych interfejsów API i złożonej logiki bazy danych.
Aby zastąpić te zakodowane na stałe wąskie gardła bezpieczną, ujednoliconą platformą sterującą, z przyjemnością ogłaszamy wprowadzenie pakietu SDK w języku Java do zestawu narzędzi Model Context Protocol (MCP) dla baz danych. Ta wersja wprowadza do najpopularniejszego ekosystemu dla przedsiębiorstw najwyższej klasy, bezpieczną pod względem typów orkiestrację agentów. Dojrzała architektura Javy została stworzona z myślą o tych rygorystycznych wymaganiach. Zapewnia wysoką współbieżność, ścisłą integralność transakcyjną i solidne zarządzanie stanem, które są niezbędne do bezpiecznego skalowania w środowisku produkcyjnym kluczowych agentów AI.
Dlaczego warto używać pakietu SDK Java?
Pakiet MCP Toolbox Java SDK umożliwia programistom Java:
- Narzędzia do wykorzystania: połącz się z serwerem MCP (np. MCP Toolbox for AlloyDB) i automatycznie przekształć jego możliwości w metody Java, które rozumie LangChain4j.
- Bezpieczeństwo typów: wykorzystaj silne typowanie w języku Java w przypadku parametrów narzędzia, aby ograniczyć błędy „halucynacji” w wywołaniach narzędzia.
- Gotowość do użycia w firmie: łatwa integracja z Spring Boot, Quarkus, Micronaut itp.
- Łatwe łączenie: nie musisz pisać powtarzalnego kodu JSON-RPC.
- Ujednolicone uwierzytelnianie: natywna obsługa tokenów OIDC Google Cloud zapewnia bezpieczne wykonywanie narzędzi.
i wiele innych.
Zależności: konfiguracja pliku pom.xml
Aby dodać najnowszy pakiet MCP Toolbox SDK w języku Java, dodaj do projektu Maven tę zależność:
<dependency>
<groupId>com.google.cloud.mcp</groupId>
<artifactId>mcp-toolbox-sdk-java</artifactId>
<version>0.2.0</version>
</dependency>
Aby uwzględnić artefakt LangChain4j, dodaj do projektu Maven tę zależność:
<!-- LangChain4j Core & Gemini -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>0.35.0</version>
</dependency>
To wszystko!!! Udało Ci się sklonować projekt i zapoznać się ze szczegółami agenta, pakietu MCP Toolbox Java SDK i kontekstu.
9. Uruchamianie lokalne
Aby przetestować agenta na swoim komputerze, musisz skierować go na wdrożony serwer MCP Toolbox.
- Ustaw zmienne środowiskowe:
export GCP_PROJECT_ID="<<YOUR_PROJECT_ID>>"
export GCP_REGION="us-central1"
export GEMINI_MODEL_NAME="gemini-2.5-flash"
export MCP_TOOLBOX_URL="<<YOUR_TOOLBOX_ENDPOINT_URL>>/mcp"
- Uruchom za pomocą narzędzia Maven:
mvn compile
mvn spring-boot:run
Spowoduje to uruchomienie agenta lokalnie i umożliwi jego przetestowanie.
10. Wdróżmy go w Cloud Run
Wdróż go w Cloud Run, uruchamiając to polecenie w terminalu Cloud Shell, w którym projekt jest sklonowany. Upewnij się, że jesteś w folderze głównym projektu.
JEŚLI NIE ZNAJDUJESZ SIĘ W FOLDERZE GŁÓWNYM AKTUALNEGO PROJEKTU, uruchom to polecenie w terminalu Cloud Shell:
cd cymbal-transit
Jeśli jesteś już w katalogu głównym cymbal-transit, uruchom to polecenie, aby bezpośrednio wdrożyć aplikację w Cloud Run:
gcloud run deploy cymbal-transit --source . --set-env-vars GCP_PROJECT_ID=<<YOUR_PROJECT_ID>>,GCP_REGION=us-central1,GEMINI_MODEL_NAME=gemini-2.5-flash,MCP_TOOLBOX_URL=<<YOUR_MCP_TOOLBOX_URL>> --allow-unauthenticated
Zastąp wartości symboli zastępczych <<YOUR_PROJECT>> and <<YOUR_MCP_TOOLBOX_URL>>
Po zakończeniu polecenia wyświetli się URL usługi. Skopiuj go.
Przyznaj kontu usługi Cloud Run rolę Klient AlloyDB.Umożliwi to aplikacji bezserwerowej bezpieczne tunelowanie do bazy danych.
Uruchom to polecenie w terminalu Cloud Shell:
# 1. Get your Project ID and Project Number
PROJECT_ID=$(gcloud config get-value project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
# 2. Grant the AlloyDB Client role
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/alloydb.client"
Uwaga: po wdrożeniu otwórz listę usług Cloud Run i upewnij się, że na karcie bezpieczeństwa tej usługi jest zaznaczona opcja „Zezwalaj na dostęp publiczny”.
Teraz użyj adresu URL usługi (skopiowanego wcześniej punktu końcowego Cloud Run) i przetestuj aplikację.
Uwaga: jeśli napotkasz problem z usługą, a jako przyczynę podano pamięć, spróbuj zwiększyć przydzielony limit pamięci do 1 GiB, aby to sprawdzić.
11. Prezentacja
Zapytaj agenta: „Muszę jutro rano dostać się z Nowego Jorku do Bostonu. Czy mogę zabrać ze sobą golden retrievera? Obserwuj, jak agent:
- Wyszukuje zasady dotyczące dużych psów.
- znajdować konkretne harmonogramy;
- Podsumowuje najszybszą podróż za pomocą identyfikatora podróży.
- Rezerwuje też bilet, jeśli wykonasz to działanie.

12. Czyszczenie danych
Po ukończeniu tego modułu nie zapomnij usunąć klastra i instancji AlloyDB.
Powinien on wyczyścić klaster wraz z instancjami.
13. Gratulacje
Udało Ci się utworzyć zaawansowanego agenta transportu opartego na Javie. Dzięki wykorzystaniu LangChain4j do orkiestracji i pakietu MCP Toolbox Java SDK do łączności z danymi udało Ci się utworzyć system, który może wnioskować na podstawie agentów, narzędzi i źródeł danych. Jeśli chcesz zacząć koordynować aplikacje oparte na agentach za pomocą MCP Toolbox for Databases w wielu bazach danych, nawet na różnych platformach, już dziś zacznij korzystać z pakietu Java SDK. Więcej informacji o bibliotece znajdziesz w tym poście na blogu z ogłoszeniem o jej uruchomieniu. Jeśli chcesz samodzielnie tworzyć więcej takich aplikacji, bezpłatnie, we własnym tempie i pod okiem instruktora, zarejestruj się na Code Vipassana na stronie https://codevipassana.dev.
