Jeden agent, trzy wersje: Interactions API kontra ADK kontra Antigravity SDK
Ten sam agent Gemini stworzył trzy wersje przy użyciu Interactions API, Google ADK oraz Antigravity SDK, porównując je pod kątem pętli, narzędzi, autoryzacji oraz implementacji w Cloud Run.
Źródła: I built the same agent three ways: Interactions API, ADK, and the Antigravity SDK
Stack Google oferuje obecnie trzy zupełnie różne ścieżki do stworzenia działającego agenta: Interactions API, który stanowi interfejs z okresu agentów w ramach Gemini API, ADK, pełny framework, oraz Antigravity SDK, narzędzie stanowiące podstawę Antigravity CLI. Sprawiedliwym sposobem na porównanie ich jest stworzenie jednego agenta trzy razy i sprawdzenie, co się zmienia: kto kontroluje pętlę agenta, w jaki sposób do niego dołączane są narzędzia oraz które modele działają. Każda wersja jest również dostarczana do Cloud Run.
Agent testowy
Każda budowa odpowiada na jeden typ pytania, a mianowicie na opinię publiczną na dany temat, jak pojawia się ona na Hacker News. Czyta ona z pliku bigquery-public-data.hacker_news.full, który jest publicznym zbiorem danych obejmującym 49 milionów artykułów i komentarzy, a który jest opóźniony o około dzień w stosunku do rzeczywistości. Wszystkie trzy wersje wymagają tych samych trzech umiejętności: pisania zapytań SQL na podstawie prostego pytania, ich wykonywania oraz sprowadzania do zwięzłości otrzymanych opinii.
BigQuery jest łączony w inny sposób za każdym razem. Interactions API korzysta z ręcznie napisanej funkcji, ADK używa własnego zestawu narzędzi, natomiast Antigravity SDK wykorzystuje MCP.
Udostępnienia
W grę wchodzą dwa rodzaje udostępnień:
export GOOGLE_API_KEY="..." # get this at aistudio.google.com
gcloud auth application-default login
Twoje dane uwierzytelniające istnieją, ponieważ API Interactions w tym ustawieniu opiera się na API Gemini, które wymaga klucza, podczas gdy ADK oraz Antigravity SDK kierują się bezpośrednio do projektu w chmurze i całkowicie pomijają klucze.
Przy bliższym przyjrzeniu się API Interactions: przyjmuje ono albo model=, czyli zwykły model, albo agent=, czyli agenta hostowanego przez Google, którego pętla oraz dostępne narzędzia działają na platformie. Narzędzie w tym rozwiązaniu to lokalna funkcja w Pythonie, co wyklucza agenta hostowanego, więc jest to model=, a pętla narzędzia pozostaje w kodzie lokalnym. Platforma korporacyjna Google (wcześniej Vertex AI) posiada własną, eksperymentalną wersję tego API, ale testowanie jej z kilkoma modelami skutkowało odrzuceniem każdej próby użycia model=.
Bezpłatny plan BigQuery umożliwiający 1 TB zapytań miesięcznie bez trudu obsługuje zapytania demonstracyjne, które zajmują od około 1 do 17 GB. Wersje użyte podczas testów to google-genai 2.17.0, google-adk 2.6.2 oraz google-antigravity 0.1.10, przy użyciu modelu gemini-3.6-flash.
Druga droga: Interactions API
Instaluj paczki za pomocą pip install google-genai google-cloud-bigquery. Narzędzie to składa się z zwykłej funkcji liczącej około dziesięciu linijek kodu:
def execute_sql(query: str) -> list[dict]:
client = bigquery.Client()
config = bigquery.QueryJobConfig(maximum_bytes_billed=20 * 10**9)
rows = client.query_and_wait(query, job_config=config, max_results=50)
return [{k: str(v) for k, v in dict(row).items()} for row in rows]
Wykonuje dowolny SQL wygenerowany przez model i zwraca do 50 wierszy w postaci zwykłych słowników. maximum_bytes_billed ogranicza jedno zapytanie do 20 GB danych do przeskanowania, dzięki czemu nic nie staje się kosztowne. Nie ma konieczności ręcznego obsługi danych uwierzytelniających, ponieważ bigquery.Client() korzysta z lokalnego logowania gcloud, a w Cloud Run ta sama funkcja cicho wykorzystuje konto usługowe.
Model nigdy nie widzi treści funkcji, tylko to, co zostało zadeklarowane, więc deklaracja zawiera schemat:
execute_sql_tool = {
"type": "function",
"name": "execute_sql",
"description": (
"Run a BigQuery Standard SQL SELECT query against "
"`bigquery-public-data.hacker_news.full`, the public Hacker News "
"dataset (stories and comments since 2006). Columns: id INT, "
"type STRING (story/comment/job/poll), title STRING (stories only), "
"text STRING (body, HTML-escaped), `by` STRING (username), score INT, "
"parent INT, descendants INT, timestamp TIMESTAMP, url STRING, "
"dead BOOL, deleted BOOL. Returns at most 50 rows."
),
"parameters": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
}
Blok parameters pozostaje niewielki: jedna obowiązkowa struna zawierająca zapytanie SQL. Opis ma większe znaczenie, ponieważ jest to jedyny kanał, przez który model poznaje nazwę tabeli oraz jej kolumny. Precyzyjniejsze sformułowania w tym miejscu przynoszą lepsze zapytania.
Pozostaje pętla narzędzia, składająca się z około tuzina linii:
while True:
calls = [s for s in interaction.steps if s.type == "function_call"]
if not calls:
break
results = [{
"type": "function_result",
"name": step.name,
"call_id": step.id,
"result": [{"type": "text", "text": json.dumps(execute_sql(**step.arguments))}],
} for step in calls]
interaction = client.interactions.create(
model=MODEL,
input=results,
system_instruction=INSTRUCTION,
tools=[execute_sql_tool],
previous_interaction_id=interaction.id,
)
Każdy cykl wykonywa każdy krok function_call wygenerowany przez model, przekazuje wyniki jako następny wprowadzenie i kontynuuje w pętli, aż odpowiedź nie będzie zawierać już żadnych wywołań. Jeden szczegół jest szczególnie istotny: historia interakcji nigdy nie jest przesyłana ponownie. Serwer ją przechowuje, a previous_interaction_id po prostu odnosi się do poprzedniej rundy, dzięki czemu każda prośba pozostaje niewielka. Obiekt client stanowi bramę SDK do API Gemini, a jego utworzenie bez argumentów pobiera GOOGLE_API_KEY z środowiska. Po zaimplementowaniu w Cloud Run ta sama wartość jest montowana jako zmienna środowiskowa z Secret Manager. Wszystko inne, w tym wybór SQL do wykonania i moment zatrzymania, jest decyzją modelu.
MCP na razie nie jest dostępne. Dokumentacja Interactions API wymienia to jako ograniczenie, stwierdzając, że Gemini 3 nie obsługuje zdalnego MCP i że ma ono zostać wkrótce dodane.
Werdykt: jak najwięcej kodu, jak najmniej zależności i pełna kontrola.
Druga droga: ADK
Zainstaluj za pomocą pip install google-adk google-cloud-dataplex google-cloud-bigquery.
import google.auth
from google.adk import Agent
from google.adk.integrations.bigquery import BigQueryCredentialsConfig, BigQueryToolset
from google.adk.integrations.bigquery.config import BigQueryToolConfig, WriteMode
credentials, _ = google.auth.default()
toolset = BigQueryToolset(
credentials_config=BigQueryCredentialsConfig(credentials=credentials),
bigquery_tool_config=BigQueryToolConfig(write_mode=WriteMode.BLOCKED),
)
root_agent = Agent(name="hn_opinion_agent", model=..., instruction=..., tools=[toolset])
ADK zawiera gotową integrację z BigQuery o nazwie BigQueryToolset. Oprócz funkcji execute_sql udostępnia również narzędzia do obsługi metadanych, takie jak get_table_info, które umożliwiają agentowi odczytanie samego schematu zamiast otrzymania go w formie promptu. Jedna z ustawień, WriteMode.BLOCKED, sprawia, że wszystko staje się tylko do odczytu.
Żaden klucz API nie pojawia się nigdzie. Narzędzie BigQuery wymaga wyraźnego obiektu z danymi uwierzytelniającymi, który google.auth.default() zwraca po zalogowaniu się lokalnie przez gcloud wraz z identyfikatorem projektu, który ta wersja odrzuca. Po stronie modelu całą pracę wykonuje jedna zmienna: GOOGLE_GENAI_USE_ENTERPRISE=TRUE kieruje ruch do modelu przez konto w chmurze. Po przeniesieniu na Cloud Run zarówno zapytania, jak i żądania dotyczące modeli są wysyłane pod nazwą konta usługowego.
Framework uruchamia pętlę i przechowuje sesje, w tym historię rozmów z różnych rund, w pamięci lokalnej oraz w bazie danych, gdy jest to konieczne ze względu na trwałość danych.
Werdykt: minimalny kod przy maksymalnych możliwościach, ponieważ gotowe narzędzia umożliwiają agentowi samodzielne przeglądanie danych.
Trzeci wariant: Antigravity SDK
Zainstaluj go za pomocą pip install google-antigravity.
from google.antigravity import Agent, LocalAgentConfig
from google.antigravity.types import McpStreamableHttpServer
bigquery_mcp = McpStreamableHttpServer(
name="bigquery",
type="http",
url="https://bigquery.googleapis.com/mcp",
headers={"Authorization": f"Bearer {token}",
"x-goog-user-project": project},
enabled_tools=["execute_sql_readonly", "get_table_info", ...],
)
config = LocalAgentConfig(system_instructions=..., mcp_servers=[bigquery_mcp])
async with Agent(config) as agent:
response = await agent.chat(question)
Do pasa bezpieczeństwa przekazywana jest instrukcja systemowa oraz jeden serwer MCP, a jedna wywołanie agent.chat() obejmuje planowanie, użycie narzędzi oraz podsumowanie końcowe. U podstaw znajduje się pętla, która steruje interfejsem Antigravity CLI, wraz z zawartymi w nim narzędziami do obsługi plików i wiersza poleceń.
Dostęp do BigQuery uzyskuje się przez MCP, za pośrednictwem adresu bigquery.googleapis.com/mcp – zarządzanego punktu końcowego obsługiwanego przez Google, który akceptuje wyłącznie tokeny OAuth (wygenerowane za pomocą gcloud auth print-access-token). Lista enabled_tools pełni rolę listy uprawnień narzędzi MCP, które agent może wywoływać. W tym punkcie końcowym dostępne są zarówno funkcje execute_sql, jak i execute_sql_readonly, przy czym aktywacja wyłącznie drugiej z nich zapobiega zapisywaniu danych przez tego agenta. Autoryzacja modelu odpowiada standardowi ADK, wykorzystując konto chmurowe na laptopie oraz konto usługowe w Cloud Run.
Przed wyborem tego rozwiązania należy wziąć pod uwagę dwie kwestie:
- Modele są ograniczone do Gemini. Antigravity IDE oferuje również Claude i GPT-OSS, których brakuje w SDK, chociaż lokalny serwer kompatybilny z OpenAI, taki jak Ollama, może pełnić tę funkcję.
- ID projektu powinno znajdować się w instrukcjach systemu. Każde narzędzie na hostowanym endpointzie wymaga argumentu
projectIdokreślającego projekt w chmurze, który przetwarza zapytanie, a model uzupełnia go podczas wywoływania narzędzia.
Werdykt: wygodne rozwiązanie umożliwiające korzystanie z agenta, który może również edytować pliki i wykonywać polecenia w shellu.
Rozwijanie w Cloud Run
Wszystkie trzy rozwiązania można zaimplementować w Cloud Run. Różnica polega na tym, ile kodu musi zostać napisane.
- Interfejs API do interakcji: wystarczy niewielki wrapper FastAPI wokół pętli. Ponieważ serwer przechowuje rozmowę, sam serwis nie przechowuje żadnego stanu, a wywołujące aplikacje zwracają jedynie
previous_interaction_id. Problem polega na tym, że ten interfejs API nadal nie może się autoryzować jako konto usługowe, co sprawia, że jest to jedyne rozwiązanie wymagające klucza API, który pochodzi z Secret Manager. - ADK: po stronie serwera nie ma nic do zapisania.
adk api_serveruruchamia go lokalnie, aadk deploy cloud_runtworzy konfigurację serwera, kontenera oraz procesu wdrażania. Należy uważać na dwa problemy. Po pierwsze, dodatkowe pakiety zestawu narzędzi (bigquery i dataplex) muszą być wymienione w pliku requirements.txt znajdującym się w folderze agenta. Po drugie, zmienne środowiskowe nie są przenoszone podczas wdrażania, więcGOOGLE_GENAI_USE_ENTERPRISEtrzeba dodać do usługi później. Dla tych, którzy nie chcą utrzymywać żadnej usługi, dostępna jest opcja w pełni zarządzana – Agent Runtime. - Antigravity SDK: trzeba ręcznie otoczyć funkcję
agent.chat()i zapakować ją jako obraz kontenera. Jedna zmiana dotyczy wyłącznie czasu serwowania: nagłówek MCP Authorization nie może już pochodzić z logowania gcloud na laptopie, więc token musi być wygenerowany i odnowiony z konta usługowego.
Ograniczenie dostępu nie wymaga dużo wysiłku. Użycie flagi --no-allow-unauthenticated ogranicza osoby wykonujące wywołania do tych, które mają uprawnienia IAM. Do testowego wywołania należy dołączyć token tożsamości za pomocą polecenia curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" lub uruchomić gcloud run services proxy; w przeglądarkach należy dodatkowo włączyć IAP.
Ustawienie tożsamości było praktycznie bezpłatne. Usługa Cloud Run zawsze działa pod określoną tożsamością, a jeśli nie zostanie inaczej określone, jest to domyślny konto usługi obliczeniowej projektu. Jedna tożsamość obsługiwała BigQuery we wszystkich trzech usługach oraz wywołania modeli w ADK i Antigravity. Jedynym ręcznym przyznaniem uprawnień było nadanie uprawnienia roles/secretmanager.secretAccessor do sekretu klucza API usługi Interactions, które jest przyłączone bezpośrednio do tego sekretu.
Nie kopiuj tego jednak ślepo. Konto domyślne ma szerokie uprawnienia i często posiada rolę Edytora na poziomie projektu. W przypadku zadań wykraczających poza demonstrację potrzebne jest dedykowane konto usługowe dla każdej usługi, ograniczone do ról wymaganych i określonych podczas wdrażania za pomocą --service-account.
Który wybrać
ADK na Cloud Run stanowi rozsądny punkt wyjścia dla większości zadań. Oferuje kompletny zestaw narzędzi oraz wsparcie MCP, proste zarządzanie sesjami i historią oraz swobodę wyboru dowolnego modelu, nie tylko Gemini i Gemma. Interactions API pokazuje, jak faktycznie działają agenci, ponieważ cały proces jest przejrzysty. Antigravity SDK nadaje się najlepiej, gdy agent musi edytować pliki i wykonywać polecenia w shellu.
Literatura pokrewna
- Gemini Spark wyjaśnione: zadania, umiejętności, harmonogramy, bezpieczeństwo i ceny — Co robi agent Gemini Spark dostępny cały czas od Google w Gmail, Kalendarzu i Dokumentach, jak działają jego mechanizmy bezpieczeństwa, ile kosztuje, gdzie jest zablokowany i kto powinien go przyjąć.
- Inżynieria agentowa i Outer Loop: Gdzie pasują Antigravity oraz Agents CLI — Specyfikacje, metody oceny i zasady bezpieczeństwa definiują inżynierię agentową. Przegląd narzędzia Agents CLI od Google, jego warstwy produkcyjnej w GCP oraz różnice między Antigravity a innymi narzędziami programistycznymi.