1. Introduzione
In questo lab creerai un agente con Agent Development Kit (ADK). Imparerai a creare un agente assistente per i bug software utilizzando l'ADK e vari tipi di strumenti. Inizierai con un agente di base e aggiungerai progressivamente strumenti per migliorarne le funzionalità, tra cui strumenti di funzione, strumenti integrati, strumenti di terze parti e strumenti Model Context Protocol (MCP).
Obiettivi didattici
- Come configurare un progetto Python per lo sviluppo di ADK.
- Come creare un agente ADK di base.
- Come implementare e utilizzare gli strumenti di funzione.
- Come integrare gli strumenti integrati come la Ricerca Google.
- Come sfruttare gli strumenti di terze parti di framework come LangChain all'interno di ADK.
- Come utilizzare gli strumenti MCP per interagire con database (Cloud SQL) e API.
2. Panoramica
Immagina di essere un project manager di QuantumRoast, un'azienda globale di macchine da caffè.
Aiuti i tuoi colleghi a orientarsi in un mare di roadmap di ingegneria, improvvisi cambi di strategia (ora facciamo il matcha!) e ticket in arrivo dai clienti, da sistemi di fatturazione pieni di bug a una macchina del caffè che emette un suono acuto 24 ore su 24, 7 giorni su 7.
In una giornata normale, hai circa 50 schede del browser aperte: il sistema di ticket interno, email, chat, GitHub, Ricerca Google, StackOverflow e altro ancora. Ti piace il tuo lavoro e i tuoi colleghi, ma a volte ti senti sopraffatto.
E se potessimo creare un assistente per aiutarti a creare e assegnare priorità alle richieste software e a eseguire il debug dei problemi? Un agente AI lo rende possibile.
Agent Development Kit (ADK)
Agent Development Kit (ADK) è un framework flessibile e modulare per lo sviluppo e il deployment di agenti AI. Sebbene sia ottimizzato per Gemini e l'ecosistema Google, l'ADK è indipendente dal modello e dal deployment ed è progettato per la compatibilità con altri framework. ADK è stato progettato per rendere lo sviluppo di agenti più simile allo sviluppo di software, in modo che gli sviluppatori possano creare, eseguire il deployment e orchestrare più facilmente architetture di agenti che vanno da semplici attività a workflow complessi.
ADK è il framework che utilizzeremo per creare il nostro assistente per i bug del software QuantumRoast.
Strumenti 101
Gli agenti AI utilizzano modelli, non solo logica hardcoded, per ragionare su un problema. Ma oltre al ragionamento basato sugli LLM, gli agenti AI sono in grado di raccogliere dati esterni e poi intraprendere azioni per conto dell'utente. Anziché dirti come risolvere un problema, un agente AI può aiutarti a risolverlo. Come facciamo? Con gli strumenti.
Uno strumento è una funzionalità che aiuta un agente AI a interagire con il mondo. Uno strumento può essere quasi qualsiasi cosa: una funzione inline, un database ospitato, un'API di terze parti o persino un altro agente. I framework di AI Agent come Agent Development Kit (ADK) hanno un supporto integrato per gli strumenti, supportando una serie di tipi di strumenti che tratteremo tra poco.
Ma come fa un agente a sapere non solo quando chiamare un determinato strumento, ma anche come chiamarlo? Il modello dell'agente svolge alcuni ruoli chiave.
Il primo è la selezione dello strumento. Forniamo al nostro agente un elenco di strumenti e alcune istruzioni su come utilizzarli. Quando un utente richiede l'intervento dell'agente, il modello dell'agente aiuta a decidere quali strumenti chiamare e perché, per aiutare l'utente.
Il secondo passaggio chiave è la chiamata di funzioni. L'espressione "chiamata di funzione" è un po' fuorviante perché il modello non chiama effettivamente lo strumento, ma si prepara a chiamarlo formattando il corpo della richiesta che il framework utilizza poi per chiamare lo strumento.
Infine, il modello aiuta a interpretare la risposta dello strumento, ad esempio un elenco di bug aperti del database, e decide se intraprendere ulteriori azioni o rispondere all'utente con queste informazioni.
Per vedere tutto questo in azione, è il momento di creare l'agente di assistenza per i bug di QuantumRoast utilizzando ADK Python.
3. Prima di iniziare
Configurazione del progetto Google Cloud
- Se non hai ancora un Account Google, devi crearne uno.
- Utilizza un account personale anziché un account di lavoro o della scuola. Gli account di lavoro e della scuola potrebbero avere limitazioni che impediscono l'attivazione delle API necessarie per questo lab.
- Accedi a Google Cloud Console.
- Abilita la fatturazione in Cloud Console.
- Il completamento di questo lab dovrebbe costare meno di 1 $in risorse cloud.
- Per evitare ulteriori addebiti, puoi seguire i passaggi alla fine di questo lab per eliminare le risorse.
- I nuovi utenti hanno diritto alla prova senza costi di 300$.
- Crea un nuovo progetto o scegli di riutilizzarne uno esistente.
Apri editor di Cloud Shell
- Vai all'editor di Cloud Shell.
- Se il terminale non viene visualizzato nella parte inferiore dello schermo, aprilo:
- Fai clic sul menu a tre linee
.
- Fai clic su Terminale.
- Fai clic su Nuovo terminale
.
- Fai clic sul menu a tre linee
- Nel terminale, imposta il tuo progetto con questo comando (sostituendo
YOUR_PROJECT_ID
):- Formato:
gcloud config set project YOUR_PROJECT_ID
- Esempio:
gcloud config set project lab-project-id-example
- Se non ricordi l'ID progetto:
- Puoi elencare tutti gli ID progetto con:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- Puoi elencare tutti gli ID progetto con:
- Formato:
- Se ti viene richiesto di concedere l'autorizzazione, fai clic su Autorizza per continuare.
- Dovresti vedere questo messaggio:
Se visualizzi unUpdated property [core/project].
WARNING
e ti viene chiestoDo you want to continue (Y/N)?
, probabilmente hai inserito l'ID progetto in modo errato. PremiN
, premiEnter
e prova a eseguire di nuovo il comandogcloud config set project
. - Nel terminale, imposta la variabile di ambiente
PROJECT_ID
da utilizzare nei passaggi successivi.export PROJECT_ID=$(gcloud config get project)
Abilita API
Nel terminale, esegui questo comando per abilitare le API Google Cloud necessarie:
gcloud services enable sqladmin.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
secretmanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
Crea un'istanza Cloud SQL per PostgreSQL
QuantumRoast dispone di un database di richieste di bug che contiene tutte le richieste interne. Configuriamolo creando un'istanza Cloud SQL per PostgreSQL.
gcloud sql instances create software-assistant \
--database-version=POSTGRES_16 \
--tier=db-custom-1-3840 \
--region=us-central1 \
--edition=ENTERPRISE \
--enable-google-ml-integration \
--database-flags cloudsql.enable_google_ml_integration=on \
--root-password=admin
Attendi la creazione dell'istanza (potrebbe richiedere alcuni minuti).
Una volta creata, puoi visualizzare l'istanza nella console Cloud qui.
Crea un database Cloud SQL
Crea un database SQL (tickets-db
) e concedi all'account di servizio Cloud SQL l'accesso a Vertex AI (in modo da poter creare embedding per eseguire la ricerca di similarità).
gcloud sql databases create tickets-db --instance=software-assistant
SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe software-assistant --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL
gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" --role="roles/aiplatform.user"
Configurare la tabella tickets
Dalla console Google Cloud (Cloud SQL), apri Cloud SQL Studio per l'istanza software-assistant
.
Accedi al database tickets-db
utilizzando l'utente postgres
e admin
come password.
Apri una nuova scheda Editor
.
Quindi, incolla il seguente codice SQL per configurare la tabella e creare gli incorporamenti vettoriali. Premi il pulsante Run
per eseguire il comando.
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
GRANT EXECUTE ON FUNCTION embedding TO postgres;
CREATE TABLE tickets (
ticket_id SERIAL PRIMARY KEY, -- PostgreSQL's auto-incrementing integer type (SERIAL is equivalent to INT AUTO_INCREMENT)
title VARCHAR(255) NOT NULL, -- A concise summary or title of the bug/issue.
description TEXT, -- A detailed description of the bug.
assignee VARCHAR(100), -- The name or email of the person/team assigned to the ticket.
priority VARCHAR(50), -- The priority level (e.g., 'P0 - Critical', 'P1 - High').
status VARCHAR(50) DEFAULT 'Open', -- The current status of the ticket (e.g., 'Open', 'In Progress', 'Resolved'). Default is 'Open'.
creation_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the ticket was first created. 'WITH TIME ZONE' is recommended for clarity and compatibility.
updated_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- Timestamp when the ticket was last updated. Will be managed by a trigger.
);
È stata creata la tabella tickets
, fai clic su Clear
per cancellare la vecchia query.
Ora inserisci i dati di esempio e premi di nuovo il pulsante Run
.
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Login Page Freezes After Multiple Failed Attempts', 'Users are reporting that after 3 failed login attempts, the login page becomes unresponsive and requires a refresh. No specific error message is displayed.', 'samuel.green@example.com', 'P0 - Critical', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Dashboard Sales Widget Intermittent Data Loading Failure', 'The "Sales Overview" widget on the main dashboard intermittently shows a loading spinner but no data. Primarily affects Chrome browser users.', 'maria.rodriguez@example.com', 'P1 - High', 'In Progress');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Broken Link in Footer - Privacy Policy', 'The "Privacy Policy" hyperlink located in the website footer leads to a 404 "Page Not Found" error.', 'maria.rodriguez@example.com', 'P3 - Low', 'Resolved');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('UI Misalignment on Mobile Landscape View (iOS)', 'On specific iOS devices (e.g., iPhone 14 models), the top navigation bar shifts downwards when the device is viewed in landscape orientation, obscuring content.', 'maria.rodriguez@example.com', 'P2 - Medium', 'In Progress');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Critical XZ Utils Backdoor Detected in Core Dependency (CVE-2024-3094)', 'Urgent: A sophisticated supply chain compromise (CVE-2024-3094) has been identified in XZ Utils versions 5.6.0 and 5.6.1. This malicious code potentially allows unauthorized remote SSH access by modifying liblzma. Immediate investigation and action required for affected Linux/Unix systems and services relying on XZ Utils.', 'frank.white@example.com', 'P0 - Critical', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Database Connection Timeouts During Peak Usage', 'The application is experiencing frequent database connection timeouts, particularly during peak hours (10 AM - 12 PM EDT), affecting all users and causing service interruptions.', 'frank.white@example.com', 'P1 - High', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Export to PDF Truncates Long Text Fields in Reports', 'When generating PDF exports of reports containing extensive text fields, the text is abruptly cut off at the end of the page instead of wrapping or continuing to the next page.', 'samuel.green@example.com', 'P1 - High', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Search Filter "Date Range" Not Applying Correctly', 'The "Date Range" filter on the search results page does not filter records accurately; results outside the specified date range are still displayed.', 'samuel.green@example.com', 'P2 - Medium', 'Resolved');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Typo in Error Message: "Unathorized Access"', 'The error message displayed when a user attempts an unauthorized action reads "Unathorized Access" instead of "Unauthorized Access."', 'maria.rodriguez@example.com', 'P3 - Low', 'Resolved');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Intermittent File Upload Failures for Large Files', 'Users are intermittently reporting that file uploads fail without a clear error message or explanation, especially for files exceeding 10MB in size.', 'frank.white@example.com', 'P1 - High', 'Open');
In QuantumRoast, potremmo voler sapere quando è stato aggiornato l'ultima volta un bug/ticket.
Per farlo, possiamo creare un trigger per aggiornare il campo updated_time
ogni volta che un record viene aggiornato.
Fai clic su Clear
e poi incolla il seguente SQL per implementare un trigger.
Premi il pulsante Run
per eseguire l'azione.
CREATE OR REPLACE FUNCTION update_updated_time_tickets()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_time = NOW(); -- Set the updated_time to the current timestamp
RETURN NEW; -- Return the new row
END;
$$ language 'plpgsql';
CREATE TRIGGER update_tickets_updated_time
BEFORE UPDATE ON tickets
FOR EACH ROW -- This means the trigger fires for each row affected by the UPDATE statement
EXECUTE PROCEDURE update_updated_time_tickets();
Crea incorporamenti vettoriali dal campo description
. In questo modo, il nostro agente potrà eseguire una ricerca per similarità nel nostro database. Ad esempio, "Esistono problemi aperti relativi alla home page dei siti web?".
ALTER TABLE tickets ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005',description)) STORED;
Ora puoi eseguire query sul database per verificare che sia pronto.
SELECT * FROM tickets;
Dovresti visualizzare 10 righe restituite simili alle seguenti:
Ora puoi passare alla parte divertente, il codice.
4. Configurazione del progetto Python
Prima di poter iniziare a creare il nostro agente, dobbiamo assicurarci di aver configurato correttamente un progetto Python. Faremo tutto in Cloud Shell.
Innanzitutto, crea una cartella quantum-roast
e cd
al suo interno:
mkdir quantum-roast && cd quantum-roast
Ora che abbiamo una cartella per il nostro progetto, è il momento di inizializzarlo e creare i file corrispondenti di cui avremo bisogno.
Utilizzeremo uv
(il gestore di progetti e pacchetti estremamente veloce di Python), che viene preinstallato in Cloud Shell per gestire il nostro progetto e le dipendenze. Uv ci aiuterà a configurare alcuni dei nostri file e a gestire ambienti virtuali, dipendenze e così via. In questo modo non dovremo farlo noi.
Inizializza un nuovo progetto con uv init
:
uv init --description "QuantumRoast Software Bug Assistant with ADK" --bare --python 3.10
Dopo aver eseguito il comando, dovremmo avere un file pyproject.toml
per il nostro progetto. Per verificare, esegui cat pyproject.toml
nel terminale Cloud Shell:
cat pyproject.toml
Dovresti vedere l'output seguente:
[project] name = "quantum-roast" version = "0.1.0" description = "QuantumRoast Software Bug Assistant with ADK" requires-python = ">=3.10" dependencies = []
È il momento di aggiungere google-adk
(ADK) come dipendenza al nostro progetto utilizzando uv add
.
uv add google-adk==1.11.0
In questo modo, google-adk
viene aggiunto all'elenco dependencies
nel nostro pyproject.toml
.
ADK prevede una determinata struttura del progetto per ottenere risultati ottimali.
quantum-roast/ software_bug_assistant/ __init__.py agent.py .env
Crea la cartella software_bug_assistant
e i file al suo interno:
mkdir software_bug_assistant && touch software_bug_assistant/__init__.py \
software_bug_assistant/agent.py \
software_bug_assistant/tools.py \
software_bug_assistant/.env
Verifica la creazione dei file utilizzando ls
:
ls -a software_bug_assistant/
Dovresti visualizzare quanto segue:
__init__.py . .. .env agent.py tools.py
È il momento di compilare il file .env
con le variabili di ambiente necessarie ad ADK per chiamare correttamente i modelli Gemini. Accederemo a Gemini tramite l'API Vertex.
echo "GOOGLE_GENAI_USE_VERTEXAI=TRUE" >> software_bug_assistant/.env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> software_bug_assistant/.env \
&& echo "GOOGLE_CLOUD_LOCATION=us-central1" >> software_bug_assistant/.env
Per verificare che .env
sia stato compilato correttamente, esegui questo comando:
cat software_bug_assistant/.env
Dovresti visualizzare quanto segue, dove your-project-id
è l'ID progetto:
GOOGLE_GENAI_USE_VERTEXAI=TRUE GOOGLE_CLOUD_PROJECT=your-project-id GOOGLE_CLOUD_LOCATION=us-central1
Ora possiamo iniziare a creare il nostro agente ADK.
5. Base ADK Agent
Iniziamo con un agente ADK di base a cui possiamo aggiungere strumenti uno alla volta durante questo workshop per creare un potente assistente per i bug.
Apri agent.py
nell'editor di Cloud Shell:
cloudshell edit software_bug_assistant/agent.py
Incolla il seguente codice in agent.py
e salva il file Ctrl + s
:
from google.adk.agents import Agent
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[],
)
Esegui l'agente appena creato avviando l'interfaccia utente di sviluppo di ADK (adk web
). Se lo fai con uv run
, verrà creato automaticamente un ambiente virtuale con ADK installato.
uv run adk web --port 8080 --reload_agents
Nella console dovresti vedere l'avvio riuscito del server web ADK.
INFO: Started server process [1557] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://localhost:8080. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8080 (Press CTRL+C to quit)
Apri l'anteprima web di Cloud Shell per visualizzare la UI.
Dovresti visualizzare l'interfaccia utente web dell'ADK.
Prova a chattare con l'agente ADK.
Chiedi all'agente What day is it today?
.
Dalla risposta noterai che l'agente non è in grado di rispondere a questa domanda di base. Ricorda che gli LLM sono sistemi isolati, addestrati su dati passati. Non hanno il contesto in tempo reale degli eventi recenti o anche della data corrente, a meno che tu non fornisca loro degli strumenti.
È il momento di implementare il primo tipo di strumento di ADK, uno strumento funzione.
6. Strumento Funzione
Il primo e più semplice tipo di strumento ADK è lo strumento funzione. È esattamente come sembra: una funzione Python chiamata dall'agente.
Gli strumenti di funzione sono piuttosto potenti, in quanto ti consentono di scrivere codice personalizzato che l'agente può chiamare come strumento, ad esempio per eseguire un calcolo, chiamare un'API o eseguire query su un database. Possono essere funzioni semplici o complesse, la scelta è completamente tua.
In QuantumRoast vogliamo definire una funzione di base per ottenere la data del giorno corrente, in modo da gestire in un secondo momento query come "mostrami i bug dell'ultima settimana" o "che giorno è oggi?". (capita a tutti).
Il file tools.py
all'interno della cartella /software_bug_assistant
è il punto in cui organizzeremo tutti gli strumenti che creeremo in questo lab.
Apri un terminale NUOVO facendo clic sull'icona +
.
Ora, nel nuovo terminale, imposta PROJECT_ID
e apri tools.py
:
cd quantum-roast
export PROJECT_ID=$(gcloud config get project)
cloudshell edit software_bug_assistant/tools.py
Ora definisci la funzione get_current_date
che verrà utilizzata come strumento Funzione.
from datetime import datetime
# ----- Example of a Function tool -----
def get_current_date() -> dict:
"""
Get the current date in the format YYYY-MM-DD
"""
return {"current_date": datetime.now().strftime("%Y-%m-%d")}
La funzione è ora definita. È il momento di passarlo all'agente come strumento.
Apri agent.py
nell'editor di Cloud Shell:
cloudshell edit software_bug_assistant/agent.py
Vogliamo importare la funzione get_current_date
da tools.py
e trasmetterla all'argomento tools
dell'agente.
L'agent.py
aggiornato ha il seguente aspetto:
from google.adk.agents import Agent
from .tools import get_current_date
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date],
)
Ora, se torni alla scheda Anteprima web in cui è in esecuzione la GUI web ADK e chiedi di nuovo What day is it today?
…
L'agente può indicare correttamente la data chiamando lo strumento Funzione get_current_date
. 🎉
È il momento di esplorare il prossimo tipo di strumento ADK.
7. Strumento integrato
Un altro tipo di strumento ADK è uno strumento integrato. Si tratta di strumenti che funzionano con le funzionalità del modello di punta di Google, come l'esecuzione di codice all'interno del modello stesso. Possiamo collegare lo strumento integrato Ricerca Google al nostro agente di assistenza per i bug per fornire all'agente un contesto pertinente, consentendogli di accedere alla ricerca sul web. In questo modo, l'agente può raccogliere informazioni più aggiornate su un bug o una vulnerabilità nota.
Apri il file tools.py
per aggiungere il supporto dello strumento integrato Ricerca Google.
cloudshell edit software_bug_assistant/tools.py
Aggiungi quanto segue in fondo a tools.py
:
# ----- Built-in Tool Imports -----
from google.adk.agents import Agent
from google.adk.tools import google_search
from google.adk.tools.agent_tool import AgentTool
# ----- Example of a Built-in Tool -----
search_agent = Agent(
model="gemini-2.5-flash",
name="search_agent",
description="A specialist in Google Search.",
instruction="""
You're a specialist in Google Search.
""",
tools=[google_search],
)
search_tool = AgentTool(search_agent)
In questo caso, stiamo inserendo lo strumento di Ricerca Google nel proprio agente con istruzioni di sistema specifiche, utilizzando di fatto un agente come strumento.
Ora possiamo importare e passare search_tool
all'agente principale in agent.py
:
cloudshell edit software_bug_assistant/agent.py
Puoi sostituire agent.py
con il seguente codice per includere search_tool
:
from google.adk.agents import Agent
from .tools import get_current_date, search_tool
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool],
)
Salva il file e torna alla finestra in cui è in esecuzione l'interfaccia utente web dell'ADK.
In QuantumRoast vogliamo assicurarci che il nostro sito web e il nostro software siano protetti da vulnerabilità ed esposizioni comuni (CVE), ovvero vulnerabilità di cybersecurity pubbliche. Possiamo utilizzare il nuovo strumento di Ricerca Google del nostro agente per cercare sul web i CVE scoperti più di recente.
Esegui la seguente query: Do a web search for 5 of the most recent CVEs?
.
Il nostro agente deve chiamare il search_agent
per eseguire ricerche sul web.
Il nostro agente ha ora sbloccato la possibilità di cercare sul web tramite lo strumento integrato dell'ADK per la Ricerca Google. 🎉
Passiamo al tipo di strumento ADK successivo.
8. Strumento di terze parti
L'ADK è progettato per essere altamente estensibile, consentendoti di integrare facilmente strumenti di altri framework di agenti AI di terze parti come CrewAI e LangChain. Questa interoperabilità è fondamentale perché consente di ridurre i tempi di sviluppo e di riutilizzare gli strumenti esistenti.
Per integrare il nostro agente di bug nei potenti dati di domande e risposte di Stack Overflow, possiamo estrarre dati dalla vasta libreria di strumenti di LangChain, in particolare dallo strumento wrapper API StackExchange. ADK supporta strumenti di terze parti come LangChain, quindi l'aggiunta di questo strumento al nostro agente ADK richiede solo poche righe di codice.
Innanzitutto, dobbiamo aggiungere nuove dipendenze per LangChain e Stack Overflow (langchain-community
e stackapi
) al nostro progetto:
uv add langchain-community==0.3.27 stackapi==0.3.1
Apri il file tools.py
per aggiungere il supporto per lo strumento LangChain StackExchange.
cloudshell edit software_bug_assistant/tools.py
Aggiungi quanto segue in fondo a tools.py
:
# ----- Example of a Third-Party Tool -----
from google.adk.tools.langchain_tool import LangchainTool
from langchain_community.tools import StackExchangeTool
from langchain_community.utilities import StackExchangeAPIWrapper
stack_exchange_tool = StackExchangeTool(api_wrapper=StackExchangeAPIWrapper())
langchain_tool = LangchainTool(stack_exchange_tool)
Ora possiamo importare e passare langchain_tool
all'agente principale in agent.py
:
cloudshell edit software_bug_assistant/agent.py
Puoi sostituire agent.py
con il seguente codice per includere langchain_tool
:
from google.adk.agents import Agent
from .tools import get_current_date, langchain_tool, search_tool
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool, langchain_tool],
)
Salva il file e torna alla scheda aperta con la UI web dell'ADK.
Prova a chiedere all'agente informazioni sulle CVE precedenti, "Are there similar issues on stack exchange?"
o su qualcosa di nuovo come "Our database queries with SQLAlchemy seem to be timing out, is there anything on StackExchange relevant to this?"
.
Il nostro agente ha utilizzato correttamente uno strumento LangChain in ADK per eseguire query su Stack Overflow. 🥳
È il momento di passare al tipo di strumento ADK successivo… Strumenti MCP.
9. Strumento MCP (database)
MCP è l'acronimo di Model Context Protocol. Si tratta di un protocollo aperto introdotto da Anthropic nel 2024. MCP fornisce un livello di astrazione tra l'agente AI e i "backend" (API, database) dello strumento.
MCP ha alcune specifiche uniche. A differenza di HTTP standard, MCP fornisce una connessione stateful bidirezionale tra il client e il server. Ha un proprio modo di definire gli strumenti e i messaggi di errore specifici per gli strumenti. Un fornitore di strumenti può quindi creare server MCP sulle proprie API, esponendo uno o più strumenti predefiniti per sviluppatori e utenti. Quindi, i framework degli agenti possono inizializzare i client MCP all'interno di un'applicazione agente per scoprire e chiamare questi strumenti.
In QuantumRoast abbiamo un database Cloud SQL per PostgreSQL per i bug del software interno. Vogliamo creare strumenti ADK in modo che il nostro agente possa eseguire determinate query sul nostro database.
Il modo più semplice per farlo è utilizzare MCP Toolbox for Databases , un server MCP open source per i database. Toolbox supporta più di 15 database, uno dei quali è Cloud SQL.
Toolbox fornisce:
- Sviluppo semplificato: integra gli strumenti nel tuo agente con meno di 10 righe di codice, riutilizza gli strumenti tra più agenti o framework e implementa più facilmente nuove versioni degli strumenti.
- Rendimento migliore: best practice come il pooling delle connessioni, l'autenticazione e altro ancora.
- Maggiore sicurezza: autenticazione integrata per un accesso più sicuro ai tuoi dati
- Osservabilità end-to-end: metriche e tracciamento predefiniti con supporto integrato per OpenTelemetry.
L'ADK supporta MCP Toolbox for Database tools, il che rende l'integrazione rapida.
Esegui il deployment di MCP Toolbox for Databases Server su Cloud Run
Innanzitutto, eseguiremo il deployment di MCP Toolbox for Databases Server in Cloud Run e lo indirizzeremo alla nostra istanza Cloud SQL.
Toolbox richiede un file YAML per la configurazione, in cui delinei l'origine del database e gli strumenti da configurare.
Crea un file tools.yaml
per il deployment.
cloudshell edit tools.yaml
Incolla i seguenti contenuti in tools.yaml
:
sources:
postgresql:
kind: cloud-sql-postgres
project: ${PROJECT_ID}
region: us-central1
instance: software-assistant
database: tickets-db
user: postgres
password: admin
tools:
search-tickets:
kind: postgres-sql
source: postgresql
description: Search for similar tickets based on their descriptions.
parameters:
- name: query
type: string
description: The query to perform vector search with.
statement: |
SELECT ticket_id, title, description, assignee, priority, status, (embedding <=> embedding('text-embedding-005', $1)::vector) as distance
FROM tickets
ORDER BY distance ASC
LIMIT 3;
get-ticket-by-id:
kind: postgres-sql
source: postgresql
description: Retrieve a ticket's details using its unique ID.
parameters:
- name: ticket_id
type: string
description: The unique ID of the ticket.
statement: SELECT * FROM tickets WHERE ticket_id = $1;
get-tickets-by-assignee:
kind: postgres-sql
source: postgresql
description: Search for tickets based on assignee (email).
parameters:
- name: assignee
type: string
description: The email of the assignee.
statement: SELECT * FROM tickets WHERE assignee ILIKE '%' || $1 || '%';
update-ticket-priority:
kind: postgres-sql
source: postgresql
description: Update the priority of a ticket based on its ID.
parameters:
- name: priority
type: string
description: The priority of the ticket. Can be one of 'P0 - Critical', 'P1 - High', 'P2 - Medium', or 'P3 - Low'.
- name: ticket_id
type: string
description: The ID of the ticket.
statement: UPDATE tickets SET priority = $1 WHERE ticket_id = $2;
update-ticket-status:
kind: postgres-sql
source: postgresql
description: Update the status of a ticket based on its ID.
parameters:
- name: status
type: string
description: The new status of the ticket (e.g., 'Open', 'In Progress', 'Closed', 'Resolved').
- name: ticket_id
type: string
description: The ID of the ticket.
statement: UPDATE tickets SET status = $1 WHERE ticket_id = $2;
get-tickets-by-status:
kind: postgres-sql
source: postgresql
description: Search for tickets based on their current status.
parameters:
- name: status
type: string
description: The status of the tickets to retrieve (e.g., 'Open', 'In Progress', 'Closed', 'Resolved').
statement: SELECT * FROM tickets WHERE status ILIKE '%' || $1 || '%';
get-tickets-by-priority:
kind: postgres-sql
source: postgresql
description: Search for tickets based on their priority.
parameters:
- name: priority
type: string
description: The priority of the tickets to retrieve (e.g., 'P0 - Critical', 'P1 - High', 'P2 - Medium', 'P3 - Low').
statement: SELECT * FROM tickets WHERE priority ILIKE '%' || $1 || '%';
create-new-ticket:
kind: postgres-sql
source: postgresql
description: Create a new software ticket.
parameters:
- name: title
type: string
description: The title of the new ticket.
- name: description
type: string
description: A detailed description of the bug or issue.
- name: assignee
type: string
description: (Optional) The email of the person to whom the ticket should be assigned.
- name: priority
type: string
description: (Optional) The priority of the ticket. Can be 'P0 - Critical', 'P1 - High', 'P2 - Medium', or 'P3 - Low'. Default is 'P3 - Low'.
- name: status
type: string
description: (Optional) The initial status of the ticket. Default is 'Open'.
statement: INSERT INTO tickets (title, description, assignee, priority, status) VALUES ($1, $2, $3, COALESCE($4, 'P3 - Low'), COALESCE($5, 'Open')) RETURNING ticket_id;
get-tickets-by-date-range:
kind: postgres-sql
source: postgresql
description: Retrieve tickets created or updated within a specific date range.
parameters:
- name: start_date
type: string
description: The start date (inclusive) for the range (e.g., 'YYYY-MM-DD').
- name: end_date
type: string
description: The end date (inclusive) for the range (e.g., 'YYYY-MM-DD').
- name: date_field
type: string
description: The date field to filter by ('creation_time' or 'updated_time').
statement: SELECT * FROM tickets WHERE CASE WHEN $3 = 'creation_time' THEN creation_time ELSE updated_time END BETWEEN $1::timestamp AND $2::timestamp;
toolsets:
tickets_toolset:
- search-tickets
- get-ticket-by-id
- get-tickets-by-assignee
- get-tickets-by-status
- get-tickets-by-priority
- get-tickets-by-date-range
- update-ticket-priority
- update-ticket-status
- create-new-ticket
Il file YAML definisce 9 strumenti correlati al database dei ticket QuantumRoast.
È il momento di configurare un service account per il servizio Cloud Run di Toolbox, concedergli l'autorizzazione ad accedere a Cloud SQL e Secret Manager e creare un secret Secret Manager per il nostro file tools.yaml
.
Secret Manager è il servizio in cui archivieremo il nostro file tools.yaml
perché contiene credenziali Cloud SQL sensibili.
gcloud iam service-accounts create toolbox-identity
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/secretmanager.secretAccessor
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/cloudsql.client
gcloud secrets create tools --data-file=tools.yaml
È il momento di eseguire il deployment di MCP Toolbox for Databases in Cloud Run. Utilizzeremo l'ultima versione di rilascio dell'immagine container di MCP Toolbox.
gcloud run deploy toolbox \
--image us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest \
--service-account toolbox-identity \
--region us-central1 \
--set-secrets "/app/tools.yaml=tools:latest" \
--set-env-vars="PROJECT_ID=$PROJECT_ID" \
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
--allow-unauthenticated
Attendi il completamento del deployment…
Verifica che Toolbox sia in esecuzione eseguendo una query sui log di Cloud Run:
gcloud run services logs read toolbox --region us-central1 --limit 10
Dovresti vedere:
2025-08-20 18:03:55 2025-08-20T18:03:55.465847801Z INFO "Initialized 1 sources." 2025-08-20 18:03:55 2025-08-20T18:03:55.466152914Z INFO "Initialized 0 authServices." 2025-08-20 18:03:55 2025-08-20T18:03:55.466374245Z INFO "Initialized 9 tools." 2025-08-20 18:03:55 2025-08-20T18:03:55.466477938Z INFO "Initialized 2 toolsets." 2025-08-20 18:03:55 2025-08-20T18:03:55.467492303Z INFO "Server ready to serve!"
Salva l'URL Cloud Run per il servizio Toolbox come variabile di ambiente in modo che l'agente ADK sappia dove trovarlo.
export MCP_TOOLBOX_URL=$(gcloud run services describe toolbox --region us-central1 --format "value(status.url)")
echo MCP_TOOLBOX_URL=$MCP_TOOLBOX_URL >> software_bug_assistant/.env
Aggiorna l'agente QuantumRoast
In secondo luogo, dobbiamo aggiungere la dipendenza per l'SDK MCP Toolbox for Databases (toolbox-core
) al nostro progetto:
uv add toolbox-core==0.5.0
Apri il file tools.py
per aggiungere il supporto per gli strumenti di MCP Toolbox.
cloudshell edit software_bug_assistant/tools.py
Aggiungi quanto segue in fondo a tools.py
:
# ----- Example MCP Toolbox for Databases tools -----
import os
from toolbox_core import ToolboxSyncClient
TOOLBOX_URL = os.getenv("MCP_TOOLBOX_URL", "http://127.0.0.1:5000")
# Initialize Toolbox client
toolbox = ToolboxSyncClient(TOOLBOX_URL)
# Load all the tools from toolset
toolbox_tools = toolbox.load_toolset("tickets_toolset")
Ora possiamo importare e passare toolbox_tools
all'agente principale in agent.py
:
cloudshell edit software_bug_assistant/agent.py
Puoi sostituire agent.py
con il seguente codice per includere toolbox_tools
:
from google.adk.agents import Agent
from .tools import get_current_date, langchain_tool, search_tool, toolbox_tools
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool, langchain_tool, *toolbox_tools],
)
Salva il file e torna alla scheda aperta con la UI web dell'ADK.
Ora puoi porre domande sui ticket archiviati nel nostro database interno dei ticket Cloud SQL.
Fai una domanda come una delle seguenti:
I am seeing an issue with database timeouts, has anyone else seen a similar issue?
How many bugs are assigned to samuel.green@example.com? Show a table.
Can you bump the priority of ticket with ID 6 to to P0 - Critical priority
Create a new ticket
(lascia che l'agente ti guidi nella creazione del bug)
Il nostro agente ADK ha eseguito correttamente la query sul nostro database tramite gli strumenti MCP Toolbox for Databases.🚀
10. (Facoltativo) Strumento MCP (API)
Che dire della connessione del nostro agente ADK agli strumenti MCP che non hanno un proprio SDK, come MCP Toolbox for Database?
ADK supporta gli strumenti MCP generici tramite la classe MCPToolset
. La classe MCPToolset
è il meccanismo principale dell'ADK per l'integrazione di strumenti da un server MCP.
MCPToolset
può essere utilizzato per connettersi a server MCP locali o remoti. In QuantumRoast vogliamo connettere il nostro agente al server MCP remoto di GitHub per chiamare facilmente le API di GitHub. In questo modo, il nostro agente potrà estrarre informazioni sui problemi dai repository di software pubblici o persino dai nostri codebase. Il server GitHub MCP espone diverse parti della funzionalità di GitHub, dai problemi e dalle richieste di pull alle notifiche e alla sicurezza del codice.
Token di accesso personale (PAT) di GitHub
Per l'autenticazione con il server GitHub MCP, è necessario un token di accesso personale GitHub.
Per ottenerne uno, segui questi passaggi:
- Vai alle impostazioni per sviluppatori di GitHub.
- Fai clic su "Token di accesso personale" -> "Token (classico)".
- Fai clic su "Genera nuovo token" -> "Genera nuovo token (classico)".
- Assegna un nome descrittivo al token.
- Imposta una data di scadenza per il token.
- Importante: per motivi di sicurezza, concedi al token gli ambiti più limitati necessari. Per l'accesso di sola lettura ai repository, spesso sono sufficienti gli ambiti
repo:status
,public_repo
eread:user
. Evita di concedere autorizzazioni di amministratore o di repository complete, a meno che non sia assolutamente necessario. - Fai clic su
Generate token
. - Copia il token generato.
Nel terminale Cloud Shell, esegui questo comando per impostare il PAT GitHub che l'agente potrà utilizzare. Sostituisci YOUR_GITHUB_PAT
con il PAT generato.
export GITHUB_PAT=YOUR_GITHUB_PAT
Aggiorna l'agente QuantumRoast
Per il nostro assistente per i bug, esporremo solo alcuni strumenti GitHub di sola lettura, per consentire ai dipendenti di QuantumRoast di trovare problemi relativi alle dipendenze open source e verificare se ciò può aiutare a trovare la causa principale dei bug visualizzati nel sistema di gestione dei ticket interno. Per configurare questa impostazione, utilizzeremo MCPToolset
dell'ADK con un tool_filter
. tool-filter
espone solo gli strumenti GitHub di cui abbiamo bisogno, il che non solo nasconde gli strumenti a cui non vogliamo che gli utenti accedano (ad esempio, azioni sensibili del repository), ma protegge anche il modello dell'agente dall'essere sopraffatto quando cerca di scegliere lo strumento giusto per il lavoro.
Apri il file tools.py
per aggiungere il supporto per gli strumenti GitHub.
cloudshell edit software_bug_assistant/tools.py
Aggiungi quanto segue in fondo a tools.py
:
# ----- Example MCP Tools with MCPToolset (GitHub) -----
from google.adk.tools.mcp_tool import MCPToolset, StreamableHTTPConnectionParams
mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url="https://api.githubcopilot.com/mcp/",
headers={
"Authorization": "Bearer " + os.getenv("GITHUB_PAT"),
},
),
# Read only tools
tool_filter=[
"search_repositories",
"search_issues",
"list_issues",
"get_issue",
"list_pull_requests",
"get_pull_request",
],
)
Tieni presente che dobbiamo fornire anche il token di accesso personale (PAT) di GitHub alla nostra definizione MCPToolset
, proprio come faresti con un token di autenticazione quando configuri un client API standard nel tuo codice. Questo PAT è limitato all'accesso ai dati del repository pubblico, senza ambiti relativi a azioni sensibili dell'utente o del repository.
Ora possiamo importare e passare mcp_tools
all'agente principale in agent.py
:
cloudshell edit software_bug_assistant/agent.py
Puoi sostituire agent.py
con il seguente codice per includere mcp_tools
:
from google.adk.agents import Agent
from .tools import get_current_date, langchain_tool, mcp_tools, search_tool, toolbox_tools
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool, langchain_tool, *toolbox_tools, mcp_tools],
)
Salva il file e torna alla scheda aperta con la UI web dell'ADK.
Ora abbiamo un insieme di strumenti MCP di GitHub che il nostro agente può chiamare. I servizi di QuantumRoast si basano su XZ utils, uno strumento di compressione dei dati. Il nostro sistema interno di gestione delle richieste di bug tiene traccia di una CVE (vulnerabilità di sicurezza) dell'anno scorso, che possiamo ricondurre al repository GitHub di XZ Utils utilizzando gli strumenti StackOverflow e Ricerca Google. Possiamo quindi utilizzare uno degli strumenti MCP di GitHub, search_issues
, per determinare quando e come è stata applicata la patch alla CVE:
Chiedi all'agente quanto segue:
Find the official XZ Utils GitHub repository
Search the repository for issues related to CVE-2024-3094
Dovresti vedere gli strumenti GitHub chiamati dall'agente.
L'agente ADK QuantumRoast ora è in grado di interagire con gli strumenti del server GitHub MCP. 🤩
11. Complimenti
Complimenti! Hai creato correttamente l'agente assistente per i bug QuantumRoast utilizzando l'Agent Development Kit (ADK) e hai integrato vari tipi di strumenti per migliorarne le funzionalità. Hai iniziato con un agente di base e hai aggiunto progressivamente strumenti di funzioni, strumenti integrati, strumenti di terze parti e strumenti MCP.
Argomenti trattati
- Come configurare un progetto Python per lo sviluppo di ADK.
- Come creare un agente ADK di base.
- Come implementare e utilizzare gli strumenti di funzione.
- Come integrare gli strumenti integrati come la Ricerca Google.
- Come sfruttare gli strumenti di terze parti di framework come LangChain all'interno di ADK.
- Come utilizzare gli strumenti MCP per interagire con database (Cloud SQL) e API.
Esegui la pulizia
Puoi eliminare il tuo progetto Cloud per evitare addebiti aggiuntivi.
Sebbene non siano previsti addebiti per Cloud Run quando il servizio non è in uso, ti potrebbero comunque essere addebitati i costi di archiviazione dell'immagine container in Artifact Registry. L'eliminazione del progetto Cloud interrompe la fatturazione per tutte le risorse utilizzate al suo interno.
Se vuoi, elimina il progetto:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Potresti anche voler eliminare le risorse non necessarie dal disco Cloud Shell. Puoi:
- Elimina la directory del progetto codelab:
rm -rf ~/quantum-roast
- Attenzione. La prossima azione non può essere annullata. Se vuoi eliminare tutto ciò che è presente in Cloud Shell per liberare spazio, puoi eliminare l'intera home directory. Fai attenzione che tutto ciò che vuoi conservare sia salvato altrove.
sudo rm -rf $HOME