כלים ליצירת סוכן: מאפס לעוזר עם ADK

1. מבוא

בשיעור ה-Lab הזה תלמדו לבנות סוכן באמצעות ערכה לפיתוח סוכנים (ADK). תלמדו איך לבנות סוכן שיעזור לכם לפתור באגים בתוכנה באמצעות ADK וסוגים שונים של כלים. תתחילו עם סוכן בסיסי ותוסיפו לו בהדרגה כלים כדי לשפר את היכולות שלו, כולל כלים של פונקציות, כלים מובנים, כלים של צד שלישי וכלים של Model Context Protocol‏ (MCP).

כלים ליצירת סוכן

מה תלמדו

  • איך מגדירים פרויקט Python לפיתוח ADK.
  • איך יוצרים סוכן ADK בסיסי.
  • איך מטמיעים ומשתמשים בכלי הפונקציות.
  • איך משלבים כלים מובנים כמו חיפוש Google.
  • איך משתמשים בכלים של צד שלישי מתוך מסגרות כמו LangChain ב-ADK.
  • איך משתמשים בכלי MCP כדי ליצור אינטראקציה עם מסדי נתונים (Cloud SQL) וממשקי API.

2. סקירה כללית

נניח שאתם מנהלי פרויקטים בחברת QuantumRoast, חברה גלובלית לייצור מכונות קפה.

Quantum Roast

אתם עוזרים לחברי הצוות להתמודד עם מגוון רחב של תוכניות עבודה הנדסיות, שינויים פתאומיים באסטרטגיה (עכשיו אנחנו מכינים מאצ'ה!), וכרטיסים נכנסים מלקוחות – החל ממערכות חשבוניות עם באגים ועד למכונת קפה שמשמיעה רעש בתדר גבוה מסביב לשעון.

ביום רגיל, יש לך כחמישים כרטיסיות פתוחות בדפדפן: מערכת פנימית לכרטיסי תמיכה, אימייל, צ'אט, GitHub, חיפוש Google,‏ StackOverflow ועוד. אתם אוהבים את העבודה ואת חברי הצוות, אבל לפעמים אתם מרגישים מוצפים.

מנהל פרויקטים מוצף

מה אם נוכל ליצור כלי שיעזור לכם ליצור כרטיסי תמיכה לתוכנה, לתעדף אותם ולנפות באגים? סוכן AI מאפשר לעשות את זה.

נציג תמיכה מבוסס-AI

ערכת פיתוח לנציגים (ADK)

ערכת פיתוח סוכנים (ADK) היא מסגרת גמישה ומודולרית לפיתוח ולפריסה של סוכני AI. ה-ADK מותאם ל-Gemini ולסביבת Google, אבל הוא לא תלוי במודל או בפריסה, והוא בנוי כך שיהיה תואם למסגרות אחרות. ה-ADK נועד להפוך את פיתוח הסוכנים לתהליך שדומה יותר לפיתוח תוכנה, כדי להקל על מפתחים ליצור, לפרוס ולתזמר ארכיטקטורות של סוכנים שמבצעות משימות פשוטות ועד תהליכי עבודה מורכבים.

‫ADK הוא המסגרת שבה נשתמש כדי לבנות את הכלי שלנו לזיהוי באגים בתוכנה QuantumRoast.

דיאגרמת נציג

כלים למתחילים

סוכני AI משתמשים במודלים, ולא רק בלוגיקה שמוגדרת בקוד, כדי להגיע לפתרון של בעיה. אבל מעבר לנימוקים שמבוססים על LLM, לסוכני AI יש יכולת ייחודית לאסוף נתונים חיצוניים ואז לפעול בשם המשתמש. במקום להסביר לכם איך לפתור בעיה, נציג AI יכול לעזור לכם לפתור אותה בפועל. איך עושים את זה? עם כלים!

כלי הוא יכולת שעוזרת לסוכן AI ליצור אינטראקציה עם העולם. כלי יכול להיות כמעט כל דבר: פונקציה מוטבעת, מסד נתונים מתארח, API של צד שלישי או אפילו סוכן אחר. מסגרות של סוכני AI כמו ערכת פיתוח הסוכנים (ADK) כוללות תמיכה מובנית בכלים, ותומכות במגוון סוגי כלים שנסביר עליהם בהמשך.

אבל איך סוכן יודע לא רק מתי להתקשר לכלי מסוים, אלא גם איך להתקשר אליו? למודל של הסוכן יש כמה תפקידים חשובים בתהליך הזה.

איך הכלים פועלים

הראשונה היא בחירת כלי. אנחנו מספקים לסוכן שלנו רשימה של כלים והוראות לשימוש בהם. כשמשתמש מזין הנחיה לסוכן, המודל של הסוכן עוזר להחליט אילו כלים להפעיל ולמה, כדי לעזור למשתמש.

השלב השני והחשוב הוא הפעלת פונקציות. המונח 'הפעלת פונקציות' קצת מטעה כי המודל לא באמת מפעיל את הכלי, אלא מתכונן להפעיל אותו על ידי עיצוב גוף הבקשה שהמסגרת משתמשת בו כדי להפעיל את הכלי.

לבסוף, המודל עוזר לפרש את התשובה מהכלי הזה – למשל, רשימה של באגים פתוחים ממסד הנתונים – ומחליט אם לבצע פעולה נוספת או להשיב למשתמש עם המידע הזה.

כדי לראות את כל זה בפעולה, הגיע הזמן ליצור את הסוכן QuantumRoast לזיהוי באגים באמצעות ADK Python.

QuantumRoast Bug Assistant

3. לפני שמתחילים

הגדרת פרויקט ב-Google Cloud

  1. אם אין לכם חשבון Google, אתם צריכים ליצור חשבון Google.
    • משתמשים בחשבון לשימוש אישי במקום בחשבון לצורכי עבודה או בחשבון בית ספרי. יכול להיות שבחשבונות לצורכי עבודה או בחשבונות בית ספריים יש הגבלות שלא מאפשרות להפעיל את ממשקי ה-API שנדרשים למעבדה הזו.
  2. נכנסים למסוף Google Cloud.
  3. מפעילים את החיוב במסוף Cloud.
    • העלות של השלמת שיעור ה-Lab הזה צריכה להיות פחות מ-1 $‎ על משאבי Cloud.
    • כדי למחוק משאבים ולמנוע חיובים נוספים, אפשר לפעול לפי השלבים בסוף שיעור ה-Lab הזה.
    • משתמשים חדשים זכאים לתקופת ניסיון בחינם בשווי 300$.
  4. יוצרים פרויקט חדש או בוחרים להשתמש בפרויקט קיים.

פתיחת Cloud Shell Editor

  1. עוברים אל Cloud Shell Editor.
  2. אם הטרמינל לא מופיע בחלק התחתון של המסך, פותחים אותו:
    • לוחצים על סמל האפשרויות הנוספות (3 קווים) סמל של תפריט שלושת הקווים.
    • לוחצים על Terminal (מסוף).
    • לוחצים על New Terminal (מסוף חדש)פתיחת טרמינל חדש ב-Cloud Shell Editor.
  3. בטרמינל, מגדירים את הפרויקט באמצעות הפקודה הבאה (מחליפים את YOUR_PROJECT_ID):
    • פורמט:
      gcloud config set project YOUR_PROJECT_ID
      
    • דוגמה:
      gcloud config set project lab-project-id-example
      
    • אם אתם לא זוכרים את מזהה הפרויקט:
      • כדי להציג את כל מזהי הפרויקטים:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      הגדרת מזהה הפרויקט בטרמינל של Cloud Shell Editor
  4. אם מתבקשים לאשר, לוחצים על אישור כדי להמשיך. לוחצים כדי לתת הרשאה ל-Cloud Shell
  5. תוצג ההודעה:
    Updated property [core/project].
    
    אם מופיע WARNING ומוצגת השאלה Do you want to continue (Y/N)?, כנראה שהזנתם את מזהה הפרויקט בצורה שגויה. לוחצים על N, לוחצים על Enter ומנסים להריץ שוב את הפקודה gcloud config set project.
  6. במסוף, מגדירים את משתנה הסביבה PROJECT_ID לשימוש בשלבים הבאים.
    export PROJECT_ID=$(gcloud config get project)
    

הפעלת ממשקי API

בטרמינל, מריצים את הפקודה הבאה כדי להפעיל את ממשקי Google Cloud API הנדרשים:

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

יצירת מכונות של Cloud SQL ל-PostgreSQL

ל-QuantumRoast יש מסד נתונים של כרטיסי באגים שמכיל את כל הכרטיסים הפנימיים. בוא נגדיר אותו על ידי יצירת מופע של Cloud SQL ל-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

מחכים עד שהמופע ייווצר (יכול להיות שייקח כמה דקות).

אחרי שיוצרים את המופע, אפשר לראות אותו במסוף Cloud כאן.

יצירת מסד נתונים ב-Cloud SQL

יוצרים מסד נתונים של SQL‏ (tickets-db) ומעניקים לחשבון השירות של Cloud SQL גישה ל-Vertex AI (כדי שנוכל ליצור הטמעות ולבצע חיפוש דמיון).

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"

הגדרת הטבלה tickets

ממסוף Cloud (Cloud SQL), פותחים את Cloud SQL Studio עבור מופע software-assistant.

מתחברים למסד הנתונים tickets-db באמצעות המשתמש postgres והסיסמה admin.

Cloud SQL Studio

פותחים כרטיסייה חדשה של Editor.

עורך ב-Cloud SQL Studio

לאחר מכן, מדביקים את קוד ה-SQL הבא כדי להגדיר את הטבלה וליצור הטמעות וקטוריות. לוחצים על הלחצן Run כדי להריץ את הפקודה.

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.
);

טבלת tickets נוצרה. לוחצים על Clear כדי למחוק את השאילתה הישנה.

עכשיו מוסיפים את הנתונים לדוגמה ולוחצים שוב על הלחצן 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');

ב-QuantumRoast, יכול להיות שנרצה לדעת מתי באג או כרטיס עודכנו לאחרונה.

כדי לעשות את זה, אפשר ליצור טריגר לעדכון השדה updated_time בכל פעם שרשומה מתעדכנת.

לוחצים על Clear ומדביקים את ה-SQL הבא כדי להטמיע טריגר.

לוחצים על הלחצן Run כדי להפעיל את הפקודה.

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();

יצירת הטמעות וקטוריות מהשדה description. כך הסוכן יוכל לבצע חיפוש דמיון במסד הנתונים שלנו. לדוגמה, "Are there any open issues related to the websites homepage?" (האם יש בעיות פתוחות שקשורות לדף הבית של האתר?).

ALTER TABLE tickets ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005',description)) STORED;

עכשיו אפשר לשלוח שאילתה למסד הנתונים כדי לוודא שהוא מוכן.

SELECT * FROM tickets;

אמורים לראות 10 שורות שדומות לאלה:

אימות מסד נתונים של Cloud SQL

עכשיו אפשר לעבור לחלק הכיפי – הקוד!

4. הגדרת פרויקט Python

לפני שנתחיל לבנות את הנציג, נצטרך לוודא שהגדרנו פרויקט Python בצורה נכונה. אנחנו נעשה את הכול ב-Cloud Shell.

קודם יוצרים תיקייה quantum-roast ומעבירים אליה את cd:

mkdir quantum-roast && cd quantum-roast

עכשיו שיש לנו תיקייה לפרויקט, הגיע הזמן לאתחל את הפרויקט וליצור את הקבצים המתאימים שנצטרך.

נשתמש ב-uv (מנהל הפרויקטים והחבילות המהיר במיוחד של Python) שמותקן מראש ב-Cloud Shell כדי לנהל את הפרויקט ואת יחסי התלות. הכלי Uv יעזור לנו להגדיר חלק מהקבצים שלנו וגם לנהל סביבות וירטואליות, יחסי תלות וכו'. כך שלא נצטרך לעשות זאת בעצמנו.

מאתחלים פרויקט חדש באמצעות uv init:

uv init --description "QuantumRoast Software Bug Assistant with ADK" --bare --python 3.10

אחרי הפעלת הפקודה, אמור להיות קובץ pyproject.toml לפרויקט. כדי לוודא, מריצים את הפקודה cat pyproject.toml בטרמינל של Cloud Shell:

cat pyproject.toml

הפלט הבא אמור להתקבל:

[project]
name = "quantum-roast"
version = "0.1.0"
description = "QuantumRoast Software Bug Assistant with ADK"
requires-python = ">=3.10"
dependencies = []

הגיע הזמן להוסיף את google-adk (ADK) כתלות לפרויקט שלנו באמצעות uv add.

uv add google-adk==1.11.0

הפעולה הזו מוסיפה את google-adk לרשימה dependencies בpyproject.toml שלנו.

כדי להשיג את התוצאות הטובות ביותר, ב-ADK מצפים למבנה פרויקט מסוים.

quantum-roast/
    software_bug_assistant/
        __init__.py
        agent.py
        .env

יוצרים את התיקייה software_bug_assistant ואת הקבצים בתוכה:

mkdir software_bug_assistant && touch software_bug_assistant/__init__.py \
software_bug_assistant/agent.py \
software_bug_assistant/tools.py \
software_bug_assistant/.env

מאמתים את יצירת הקבצים באמצעות ls:

ls -a software_bug_assistant/

אתם אמורים לראות את הנתונים הבאים:

__init__.py	 .  ..	 .env	 agent.py    tools.py

עכשיו צריך לאכלס את הקובץ .env במשתני הסביבה שנדרשים ל-ADK כדי להפעיל בצורה תקינה מודלים של Gemini. אנחנו ניגש ל-Gemini דרך Vertex API.

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

כדי לוודא שהטבלה .env אוכלסה בצורה נכונה, מריצים את הפקודה הבאה:

cat software_bug_assistant/.env

אתם אמורים לראות את הפלט הבא, כאשר your-project-id הוא מזהה הפרויקט:

GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=us-central1

עכשיו אנחנו מוכנים להתחיל ליצור את סוכן ה-ADK.

5. סוכן ADK בסיסי

בסדנה הזו נגדיר סוכן ADK בסיסי שאליו נוסיף כלים בזה אחר זה כדי ליצור עוזר חזק לזיהוי באגים.

פותחים את agent.py ב-Cloud Shell Editor:

cloudshell edit software_bug_assistant/agent.py

מדביקים את הקוד הבא בקובץ agent.py ושומרים את הקובץ 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=[],
)

מריצים את הסוכן החדש שיצרתם על ידי הפעלת ממשק המשתמש למפתחים של ADK ‏ (adk web). אם תעשו את זה באמצעות uv run, תיווצר באופן אוטומטי סביבה וירטואלית עם ADK מותקן.

uv run adk web --port 8080 --reload_agents

במסוף אמור להופיע שהשרת של ADK Web Server הופעל בהצלחה.

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)

פותחים את התצוגה המקדימה באינטרנט של Cloud Shell כדי לראות את ממשק המשתמש.

תצוגה מקדימה באינטרנט של Cloud Shell

ממשק האינטרנט של ADK אמור להופיע.

ממשק משתמש באינטרנט של ADK

אפשר לנסות לשוחח עם סוכן ה-ADK.

שואלים את הנציג What day is it today?.

דוגמה לשימוש ב-ADK Web

אפשר לראות מהתשובה שהנציג לא יכול לענות על השאלה הבסיסית הזו. חשוב לזכור שמודלים מסוג LLM הם מערכות מבודדות שאומנו על נתונים מהעבר. אין להם הקשר בזמן אמת לגבי אירועים מהזמן האחרון או אפילו התאריך הנוכחי... אלא אם נותנים להם כלים!

הגיע הזמן להטמיע את סוג הכלי הראשון של ADK, שהוא כלי פונקציה.

6. Function Tool

סוג הכלי הראשון והפשוט ביותר ב-ADK הוא כלי הפונקציה. הכלי הזה הוא בדיוק מה ששמו מרמז – פונקציית Python שהסוכן מפעיל.

כלי פונקציה

הכלים של הפונקציות הם עוצמתיים מאוד, כי הם מאפשרים לכם לכתוב קוד בהתאמה אישית כדי שהסוכן יפעיל אותו ככלי, למשל כדי לבצע חישוב, להפעיל API או לשלוח שאילתה למסד נתונים. אלה יכולות להיות פונקציות פשוטות או מורכבות, הבחירה היא שלכם.

ב-QuantumRoast אנחנו רוצים להגדיר פונקציה בסיסית שתקבל את התאריך של היום, כדי שבהמשך המעבדה נוכל לטפל בשאילתות כמו 'הצגת באגים מהשבוע האחרון' או 'מה התאריך היום?'. (זה קורה לכולנו).

בקובץ tools.py שבתיקייה /software_bug_assistant נאחסן את כל הכלים שנבנה במהלך שיעור ה-Lab הזה.

פותחים טרמינל חדש בלחיצה על הסמל +.

טרמינל חדש

עכשיו בטרמינל החדש, מגדירים את PROJECT_ID ופותחים את tools.py:

cd quantum-roast
export PROJECT_ID=$(gcloud config get project)
cloudshell edit software_bug_assistant/tools.py

עכשיו מגדירים את הפונקציה get_current_date שתשמש ככלי פונקציה.

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")}

הפונקציה מוגדרת עכשיו. הגיע הזמן להעביר את הכלי לסוכן.

פותחים את agent.py ב-Cloud Shell Editor:

cloudshell edit software_bug_assistant/agent.py

אנחנו רוצים לייבא את הפונקציה get_current_date מ-tools.py ולהעביר את הפונקציה לארגומנט tools של הסוכן.

הנוסח המעודכן של agent.py הוא:

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],
)

עכשיו, אם תחזרו לכרטיסייה Web Preview (תצוגה מקדימה של אתר) שבה פועל ממשק המשתמש של ADK Web ותשאלו את What day is it today? שוב...

ADK Web Function Tool

הנציג יכול להגיד את התאריך באמצעות קריאה לכלי הפונקציות get_current_date. 🎉

הגיע הזמן להכיר את סוג הכלי הבא ב-ADK.

7. כלי מובנה

סוג נוסף של כלי ADK הוא כלי מובנה. אלה כלים שפועלים עם תכונות של המודל המוביל של Google, כמו הרצת קוד בתוך המודל עצמו. אנחנו יכולים לצרף את הכלי המובנה חיפוש Google לסוכן שלנו לטיפול בבאגים, כדי לספק לסוכן הקשר הרלוונטי על ידי מתן גישה לחיפוש באינטרנט. כך הסוכן יוכל לאסוף מידע עדכני יותר על באג או על פגיעות ידועה.

כלי מובנה

פותחים את הקובץ tools.py כדי להוסיף תמיכה בכלי המובנה של חיפוש Google.

cloudshell edit software_bug_assistant/tools.py

מוסיפים את הטקסט הבא לתחתית הקובץ 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)

כאן אנחנו למעשה עוטפים את כלי חיפוש Google בסוכן משלו עם הוראות מערכת משלו, ומשתמשים למעשה בסוכן ככלי.

עכשיו אפשר לייבא את search_tool ולהעביר אותו לסוכן הבסיסי ב-agent.py:

cloudshell edit software_bug_assistant/agent.py

אפשר להחליף את agent.py בקוד הבא כדי לכלול את 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],
)

שומרים את הקובץ וחוזרים לכרטיסייה הפתוחה שבה מופעל ממשק המשתמש האינטרנטי של ADK.

אנחנו ב-QuantumRoast רוצים לוודא שהאתר והתוכנה שלנו מוגנים מפני פרצות אבטחה נפוצות וחשיפות (CVE) שהן פרצות אבטחה ציבוריות בסייבר. אנחנו יכולים להשתמש בכלי החדש של הסוכן לחיפוש Google כדי לחפש באינטרנט את ה-CVEs שהתגלו לאחרונה.

מריצים את השאילתה הבאה: Do a web search for 5 of the most recent CVEs?.

הנציג שלנו צריך להתקשר למספר search_agent כדי לבצע חיפוש באינטרנט.

דוגמה לכלי מובנה ב-ADK Web

הסוכן שלנו הצליח לבטל את הנעילה של האפשרות לחיפוש באינטרנט באמצעות הכלי המובנה של ADK לחיפוש Google. 🎉

נעבור לסוג הבא של כלי ADK.

8. כלי של צד שלישי

ה-ADK מתוכנן להיות ניתן להרחבה בקלות, כך שתוכלו לשלב בצורה חלקה כלים ממסגרות אחרות של סוכני AI מצד שלישי, כמו CrewAI ו-LangChain. יכולת הפעולה ההדדית הזו היא קריטית, כי היא מאפשרת לקצר את זמן הפיתוח ולעשות שימוש חוזר בכלים קיימים.

כלי של צד שלישי

כדי לחבר את סוכן הבאגים שלנו לנתוני השאלות והתשובות העוצמתיים של StackOverflow, אנחנו יכולים לשלוף נתונים מספריית הכלים הנרחבת של LangChain, ובאופן ספציפי מכלי ה-API Wrapper של StackExchange. ‫ADK תומך בכלים של צד שלישי כמו LangChain, כך שנדרשות רק כמה שורות קוד כדי להוסיף את הכלי הזה לסוכן ADK שלנו.

קודם כל, צריך להוסיף לפרויקט יחסי תלות חדשים עבור LangChain ו-StackOverflow (langchain-community ו-stackapi):

uv add langchain-community==0.3.27 stackapi==0.3.1

פותחים את הקובץ tools.py כדי להוסיף תמיכה בכלי LangChain StackExchange.

cloudshell edit software_bug_assistant/tools.py

מוסיפים את הטקסט הבא לתחתית הקובץ 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)

עכשיו אפשר לייבא את langchain_tool ולהעביר אותו לסוכן הבסיסי ב-agent.py:

cloudshell edit software_bug_assistant/agent.py

אפשר להחליף את agent.py בקוד הבא כדי לכלול את 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],
)

שומרים את הקובץ וחוזרים לכרטיסייה הפתוחה עם ממשק האינטרנט של ADK.

אפשר לנסות לשאול את הסוכן על ה-CVE הקודמים, "Are there similar issues on stack exchange?" או על משהו חדש כמו "Our database queries with SQLAlchemy seem to be timing out, is there anything on StackExchange relevant to this?".

דוגמה לכלי של צד שלישי ב-ADK Web

הסוכן שלנו השתמש בהצלחה בכלי LangChain ב-ADK כדי לשלוח שאילתה ל-StackOverflow. 🥳

הגיע הזמן לסוג הבא של כלי ADK... MCP Tools!

9. כלי MCP (מסד נתונים)

‫MCP הוא ראשי תיבות של Model Context Protocol (פרוטוקול הקשר של המודל). זהו פרוטוקול פתוח שהוצג על ידי Anthropic בשנת 2024. ‫MCP מספק שכבת הפשטה בין סוכן ה-AI לבין ה'קצה העורפי' של הכלי (ממשקי API, מסדי נתונים).

איך MCP עובד

ל-MCP יש מפרטים ייחודיים. בשונה מ-HTTP רגיל, פרוטוקול MCP מספק חיבור דו-כיווני עם שמירת מצב בין הלקוח לשרת. יש לו דרך משלו להגדיר כלים והודעות שגיאה ספציפיות לכלים. ספק כלים יכול ליצור שרתי MCP על בסיס ממשקי ה-API שלו, ולחשוף כלי אחד או יותר שנוצרו מראש למפתחים ולמשתמשים. לאחר מכן, מסגרות של סוכנים יכולות לאתחל לקוחות MCP בתוך אפליקציית סוכן, כדי לגלות את הכלים האלה ולהפעיל אותם.

ב-QuantumRoast, יש לנו מסד נתונים של Cloud SQL ל-PostgreSQL לזיהוי באגים בתוכנה פנימית. אנחנו רוצים ליצור כלים ל-ADK כדי שהסוכן שלנו יוכל לבצע שאילתות מסוימות במסד הנתונים שלנו.

מסד הנתונים של כלי ה-MCP

הדרך הכי קלה לעשות את זה היא באמצעות MCP Toolbox for Databases , שרת MCP בקוד פתוח למסדי נתונים. ערכת הכלים תומכת ביותר מ-15 מסדי נתונים, כולל Cloud SQL.

ארגז הכלים כולל:

  • פיתוח פשוט יותר: אפשר לשלב כלים בסוכן בפחות מ-10 שורות קוד, להשתמש מחדש בכלים בין כמה סוכנים או מסגרות, ולפרוס גרסאות חדשות של כלים בקלות רבה יותר.
  • ביצועים משופרים: שיטות מומלצות כמו איגום חיבורים, אימות ועוד.
  • אבטחה משופרת: אימות משולב לגישה מאובטחת יותר לנתונים
  • יכולת מעקב מקצה לקצה: מדדים ומעקב מוכנים לשימוש עם תמיכה מובנית ב-OpenTelemetry.

ערכת ה-ADK תומכת בערכת הכלים של MCP לכלי מסד נתונים, ולכן השילוב מהיר.

ערכת הכלים של MCP למסדי נתונים

פריסת MCP Toolbox for Databases Server ב-Cloud Run

קודם נבצע פריסה של MCP Toolbox for Databases Server ב-Cloud Run ונפנה אותו למכונה של Cloud SQL.

כדי להגדיר את Toolbox, צריך קובץ YAML שבו מציינים את מקור הנתונים ואת הכלים להגדרה.

יוצרים קובץ tools.yaml לפריסה.

cloudshell edit tools.yaml

מדביקים את התוכן הבא ב-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

קובץ ה-YAML מגדיר 9 כלים שקשורים למסד הנתונים של כרטיסי QuantumRoast.

הגיע הזמן להגדיר חשבון שירות בשביל שירות Cloud Run של ערכת הכלים, לתת לו הרשאה לגשת ל-Cloud SQL ול-Secret Manager, וליצור סוד ב-Secret Manager בשביל קובץ tools.yaml.

נאחסן את קובץ tools.yaml ב-Secret Manager כי הוא מכיל פרטי כניסה רגישים ל-Cloud SQL.

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

הגיע הזמן לפרוס את MCP Toolbox for Databases ב-Cloud Run. נשתמש בגרסת ההפצה האחרונה של קובץ האימג' של הקונטיינר של 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

ממתינים לסיום הפריסה…

כדי לוודא ש-Toolbox פועל, שולחים שאילתה ליומנים של Cloud Run:

gcloud run services logs read toolbox --region us-central1 --limit 10

הפרטים שמוצגים הם:

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!"

שומרים את כתובת ה-URL של Cloud Run בשביל שירות Toolbox כמשתנה סביבה, כדי שסוכן ADK יידע איפה למצוא אותה.

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

עדכון של QuantumRoast Agent

בשלב השני, צריך להוסיף לפרויקט את התלות ב-SDK של ארגז הכלים של MCP למסדי נתונים (toolbox-core):

uv add toolbox-core==0.5.0

פותחים את קובץ tools.py כדי להוסיף תמיכה בכלים של MCP Toolbox.

cloudshell edit software_bug_assistant/tools.py

מוסיפים את הטקסט הבא לתחתית הקובץ 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")

עכשיו אפשר לייבא את toolbox_tools ולהעביר אותו לסוכן הבסיסי ב-agent.py:

cloudshell edit software_bug_assistant/agent.py

אפשר להחליף את agent.py בקוד הבא כדי לכלול את 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],
)

שומרים את הקובץ וחוזרים לכרטיסייה הפתוחה עם ממשק האינטרנט של ADK.

עכשיו אפשר לשאול שאלות לגבי הכרטיסים שמאוחסנים במסד הנתונים הפנימי של כרטיסים ב-Cloud SQL.

שואלים שאלה כמו אחת מהשאלות הבאות:

  • 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 (הנציג ינחה אותך בתהליך יצירת הבאג)

דוגמה לכלי מסד נתונים של MCP

הסוכן ADK שלנו ביצע עכשיו שאילתה במסד הנתונים באמצעות MCP Toolbox for Databases tools!🚀

10. אופציונלי: כלי MCP‏ (API)

מה לגבי חיבור סוכן ADK לכלים של MCP שאין להם SDK משלהם, כמו MCP Toolbox for Database?

‫ADK תומך בכלים גנריים של MCP דרך המחלקה MCPToolset. המחלקות MCPToolset הן המנגנון העיקרי של ADK לשילוב כלים משרת MCP.

כלי MCP‏ (API)

MCPToolset יכול לשמש לחיבור לשרתי MCP מקומיים או מרוחקים. ב-QuantumRoast אנחנו רוצים לחבר את הסוכן שלנו לשרת ה-MCP המרוחק של GitHub כדי להפעיל בקלות את ממשקי ה-API של GitHub. כך הסוכן יוכל לשלוף מידע על בעיות ממאגרי תוכנה ציבוריים או אפילו מבסיסי הקוד שלנו. שרת ה-MCP של GitHub חושף חלקים שונים מהפונקציונליות של GitHub, מבעיות ובקשות משיכה, ועד התראות ואבטחת קוד.

כלי MCP ב-GitHub

טוקן גישה אישי (PAT) ב-GitHub

כדי לבצע אימות בשרת GitHub MCP, צריך אסימון גישה אישי של GitHub.

כדי לקבל אחד, צריך לבצע את השלבים הבאים:

  1. עוברים להגדרות המפתחים ב-GitHub.
  2. לוחצים על Personal access tokens (אסימוני גישה אישיים) -> Tokens (classic) (אסימונים (קלאסי)).
  3. לוחצים על 'יצירת טוקן חדש' -> 'יצירת טוקן חדש (קלאסי)'.
  4. נותנים לטוקן שם תיאורי.
  5. מגדירים תאריך תפוגה לטוקן.
  6. חשוב: מטעמי אבטחה, צריך להעניק לאסימון את ההיקפים המוגבלים ביותר שנדרשים. לגישה לקריאה בלבד למאגרים, היקפי ההרשאות repo:status, public_repo ו-read:user לרוב מספיקים. מומלץ להימנע מהענקת הרשאות מלאות למאגר או הרשאות אדמין, אלא אם הדבר נחוץ לחלוטין.
  7. לוחצים על Generate token.
  8. מעתיקים את הטוקן שנוצר.

בטרמינל של Cloud Shell, מריצים את הפקודה הבאה כדי להגדיר את ה-PAT של GitHub שהסוכן יוכל להשתמש בו. מחליפים את YOUR_GITHUB_PAT ב-PAT שנוצר.

export GITHUB_PAT=YOUR_GITHUB_PAT

עדכון של QuantumRoast Agent

כדי לעזור לעובדי QuantumRoast למצוא בעיות שקשורות לתלות בקוד פתוח, אנחנו נחשוף רק חלק מכלי GitHub לקריאה בלבד. כך הם יוכלו לבדוק אם זה יעזור להם למצוא את שורש הבעיה בבאגים שהם רואים במערכת הפנימית לטיפול בפניות. נשתמש ב-MCPToolset של ADK עם tool_filter כדי להגדיר את זה. הכלי tool-filter חושף רק את הכלים של GitHub שאנחנו צריכים, וכך לא רק מסתיר את הכלים שאנחנו לא רוצים שהמשתמשים יגשו אליהם (למשל: פעולות רגישות במאגר), אלא גם מגן על המודל של הסוכן מפני עומס יתר בניסיון לבחור את הכלי הנכון למשימה.

פותחים את הקובץ tools.py כדי להוסיף תמיכה בכלים של GitHub.

cloudshell edit software_bug_assistant/tools.py

מוסיפים את הטקסט הבא לתחתית הקובץ 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",
    ],
)

שימו לב שאנחנו צריכים לספק את אסימון הגישה האישית (PAT) של GitHub להגדרה MCPToolset שלנו, בדיוק כמו שמספקים אסימון אימות כשמגדירים לקוח API רגיל בקוד. ה-PAT הזה מוגבל לגישה לנתונים של מאגרים ציבוריים בלבד, ללא היקפי הרשאות שקשורים לפעולות רגישות של משתמשים או מאגרים.

עכשיו אפשר לייבא את mcp_tools ולהעביר אותו לסוכן הבסיסי ב-agent.py:

cloudshell edit software_bug_assistant/agent.py

אפשר להחליף את agent.py בקוד הבא כדי לכלול את 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],
)

שומרים את הקובץ וחוזרים לכרטיסייה הפתוחה עם ממשק האינטרנט של ADK.

עכשיו יש לנו קבוצה של כלים של GitHub MCP שהסוכן יכול להשתמש בהם. השירותים של QuantumRoast מסתמכים על XZ utils, כלי לדחיסת נתונים. במערכת הפנימית שלנו לכרטיסי באגים מתבצע מעקב אחרי CVE (פגיעות אבטחה) מהשנה שעברה, שאפשר לאתר את המקור שלה במאגר XZ Utils ב-GitHub באמצעות הכלים של StackOverflow וחיפוש Google. לאחר מכן, אנחנו יכולים להשתמש באחד מכלי ה-MCP של GitHub,‏ search_issues, כדי לקבוע מתי ואיך בוצע התיקון של ה-CVE:

אפשר לשאול את הנציג את השאלות הבאות:

  • Find the official XZ Utils GitHub repository
  • Search the repository for issues related to CVE-2024-3094

אפשר לראות שהסוכן קורא לכלים של GitHub.

דוגמה ל-GitHub של כלי MCP

הסוכן של QuantumRoast ADK יכול עכשיו ליצור אינטראקציה עם כלי השרת של GitHub MCP. 🤩

11. מזל טוב

מעולה! בנית בהצלחה את סוכן העזרה לתיקון באגים QuantumRoast באמצעות ערכה לפיתוח סוכנים (ADK) ושילבת סוגים שונים של כלים כדי לשפר את היכולות שלו. התחלתם עם סוכן בסיסי והוספתם בהדרגה כלי פונקציות, כלים מובנים, כלים של צד שלישי וכלי MCP.

מה נכלל

  • איך מגדירים פרויקט Python לפיתוח ADK.
  • איך יוצרים סוכן ADK בסיסי.
  • איך מטמיעים ומשתמשים בכלי הפונקציות.
  • איך משלבים כלים מובנים כמו חיפוש Google.
  • איך משתמשים בכלים של צד שלישי מתוך מסגרות כמו LangChain ב-ADK.
  • איך משתמשים בכלי MCP כדי ליצור אינטראקציה עם מסדי נתונים (Cloud SQL) וממשקי API.

QuantumRoast Final

הסרת המשאבים

כדי להימנע מחיובים נוספים, אפשר למחוק את פרויקט Cloud.

ב-Cloud Run לא מחויבים כשלא משתמשים בשירות, אבל יכול להיות שתחויבו על אחסון קובץ האימג' של הקונטיינר ב-Artifact Registry. כשמוחקים פרויקט ב-Cloud, החיוב על כל המשאבים שנעשה בהם שימוש באותו פרויקט נפסק.

אם רוצים, מוחקים את הפרויקט:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

מומלץ גם למחוק משאבים מיותרים מהדיסק של Cloud Shell. אתם יכולים:

  1. מוחקים את ספריית הפרויקט של ה-codelab:
    rm -rf ~/quantum-roast
    
  2. אזהרה! אי אפשר לבטל את הפעולה הבאה! אם רוצים למחוק את כל מה שיש ב-Cloud Shell כדי לפנות מקום, אפשר למחוק את כל ספריית הבית. חשוב לוודא שכל מה שרוצים לשמור נשמר במקום אחר.
    sudo rm -rf $HOME