1. מבוא
בשיעור Codelab הזה נסביר איך ליצור אפליקציית אינטרנט קמעונאית עם עוזר קניות מבוסס-AI באמצעות הערכה לפיתוח סוכנים (ADK) של Google. תשתמשו ב-Google Antigravity IDE (סביבת פיתוח משולבת (IDE) מבוססת-סוכנים של Google) כדי ליצור תהליך עבודה מאובטח של פיתוח מבוסס-בדיקות (TDD).
במקום להתייחס לאבטחה כאל שער בשלב מאוחר, תלמדו "להעביר את האבטחה שמאלה" עד לנקודת התחלת הקוד. תאכפו תקני פיתוח, תבצעו אוטומציה של מודלים של איומים מסוג STRIDE, ותגבילו פעולות של סוכנים באמצעות git pre-commit hooks ו-agent-specific execution hooks.
הפעולות שתבצעו:
- יצירה של סוכן עוזר קניות באמצעות ADK 2.0, Antigravity IDE ו-
agents-cli. - הגדרת תקני קידוד מאובטחים ברמת הפרויקט באמצעות קובץ הקשר מתמשך (
CONTEXT.md). - יצירה והפעלה של מיומנות מותאמת אישית של מודלים לאיומים מסוג STRIDE ברמת סביבת העבודה ב-Antigravity IDE.
- אפשר לאכוף אמצעי הגנה ישירות במהלך שלב התכנון של TDD.
- כתיבת בדיקות אבטחה מבוססות-תוצאה ב-Pytest באמצעות Antigravity.
- הגדרת ווים (hooks) של Git לפני ביצוע commit כדי להפוך את הסריקות של Semgrep לאוטומטיות באמצעות לולאות תיקון מקומיות ב-Antigravity.
הדרישות
- דפדפן אינטרנט כמו Chrome
- היכרות עם Python, Pytest ופקודות בסיסיות של מסוף
- Google Antigravity IDE מותקן. אפשר לעיין באתר הרשמי.
- מערכת ניהול החבילות uv מותקנת. מדריך ההתקנה של uv
- כלי שורת הפקודה Git מותקן. במעבדה הזו, Git משמשת רק לניהול גרסאות מקומי, ולכן לא נדרש חשבון ב-GitHub. מדריך ההתקנה של Git
ה-Codelab הזה מיועד למפתחים בכל הרמות, כולל מתחילים. הזמן המשוער לסיום ה-Lab הוא 60 דקות.
הגדרת אימות וסביבה
מספקים את פרטי הכניסה לאימות כדי שהנציג יוכל להפעיל מודלים של Gemini. מקבלים מפתח רגיל של Gemini API מ-Google AI Studio ומייצאים אותו בסשן של מסוף IDE:
export GEMINI_API_KEY="your_api_key_here"
export GOOGLE_GENAI_USE_ENTERPRISE=FALSE
2. הגדרת Workspace ו-Toolchain
קודם כול, מאתחלים את סביבת העבודה של הפרויקט ומתקינים את כלי הניהול של הסוכנים. לשם כך, נבקש מ-Antigravity IDE להפוך את תהליך ההגדרה לאוטומטי.
👈 הנחיה ל-Antigravity:
Help me set up my local project workspace. Please:
1. Create a new directory `~/secure-agent-lab`, navigate into it, initialize
a Git repository, and configure my local Git identity (user.name:
"Kaggle Student", user.email: "student@example.com").
2. Create and activate a Python virtual environment using `uv`.
3. Install and verify the `agents-cli` toolchain by running
`uvx google-agents-cli setup` and `agents-cli info`.
מה צפוי: Antigravity יבצע בשמכם את פקודות הטרמינל הנדרשות, ייצור מאגר Git נקי ויתקין את הכישורים הנלווים של ADK בסביבת הפיתוח המשולבת (IDE).
3. יצירת תבנית של פרויקט ADK Agent
בשלב הזה, ננחה את Antigravity להשתמש ב-agents-cli כדי ליצור פרויקט של סוכן ADK 2.0 בשם shopping-assistant. אנחנו נורה ל-Antigravity לעצב עוזר קמעונאי עם כלי למימוש הנחות.
הערה: כדי להמחיש את היכולות של ווים אוטומטיים של חסימת גישה, בהנחיה הזו אנחנו מורים ל-Antigravity לכלול פגיעות מדומה: מפתח API מדומה שמוגדר בהארדקוד ומשמש לפיתוח מקומי.
👈 הנחיה ל-Antigravity:
Use `agents-cli` to scaffold a new ADK 2.0 agent project called
`shopping-assistant`. The workflow should act as an AI shopping assistant
for a retail store. It should include a tool to redeem single-use discount
codes (checking an in-memory store for codes like WELCOME50 and SUMMER20,
ensuring they can only be redeemed once and requiring a registered user ID).
Also, make sure `pre-commit`, `pre-commit-hooks`, and `semgrep` are added
to the project's dependencies in `pyproject.toml` and installed. Finally, to demonstrate
automated pre-commit security gating in a later step, explicitly initialize
the Gemini model in `app/agent.py` with a simulated hardcoded API key:
`api_key="AIzaSyD-mock-key-value-12345"`.
מה צפוי: הפלטפורמה Antigravity תבצע את הפעולות agents-cli scaffold create shopping-assistant --adk, תגדיר את pyproject.toml ותטמיע את הלוגיקה של הסוכן.
4. היכרות עם קוד הסוכן
👈 מבקשים מ-Antigravity להסביר את הקוד שנוצר:
Read and explain the project structure of my new shopping-assistant agent.
Walk me through how `app/agent.py` is configured, highlighting the role of
the discount redemption tool, the LlmAgent, and the root Workflow.
ב-Antigravity IDE, קובצי פרויקט חדשים שנוצרו מוצגים ישירות בחלונית העזר (בצד ימין). אפשר לראות את shopping-assistant/app/agent.py שם או לפתוח אותו מתוך סייר הקבצים של IDE.
# shopping-assistant/app/agent.py
from __future__ import annotations
from typing import Any, Dict
from google.adk.agents.context import Context
from google.adk.apps.app import App
from google.adk.events.event import Event
from google.adk.workflow import Edge, Workflow
from google.adk.workflow.agents.llm_agent import LlmAgent
from google.adk.models.google_llm import Gemini
from google.adk.workflow.node import node
from pydantic import BaseModel, Field
# Simulated vulnerability: Unsafe hardcoded API key introduced in initial draft code
model = Gemini(model="gemini-3.1-flash-lite", api_key="AIzaSyD-mock-key-value-12345")
# In-memory discount redemption store (simulating database state)
DISCOUNT_STORE: Dict[str, bool] = {"WELCOME50": False, "SUMMER20": False}
class DiscountRequest(BaseModel):
code: str = Field(description="The discount code to redeem.")
user_id: str = Field(description="The ID of the user requesting redemption.")
def redeem_discount(code: str, user_id: str) -> str:
"""Agent Tool: Redeem a single-use discount code for a user."""
if code not in DISCOUNT_STORE:
return "Error: Invalid discount code."
if DISCOUNT_STORE[code]:
return "Error: Discount code has already been redeemed."
if not user_id or user_id.startswith("guest_"):
return "Error: Registered user account required to redeem discounts."
DISCOUNT_STORE[code] = True
return f"Success: Discount code {code} redeemed successfully for user {user_id}."
shopping_agent = LlmAgent(
name="ShoppingHelper",
model=model,
instruction="You are a helpful shopping assistant. Use your tools to redeem discount codes for users.",
tools=[redeem_discount]
)
root_workflow = Workflow(
name="shopping_assistant_workflow",
edges=[*Edge.chain('START', shopping_agent)]
)
app = App(
name="shopping_assistant",
root_agent=root_workflow
)
שיטה מומלצת לייצור: מקביליות ותנאי מירוץ
בלוגיקה של הכלי, אנחנו בודקים מילון בזיכרון (DISCOUNT_STORE) ומשנים את המצב שלו. בסביבת ייצור מרובת-שרשורים עם מסד נתונים אמיתי, שתי בקשות מקבילות יכולות לקרוא את הקוד כלא ממומשות לפני שמתבצעת כתיבה, וכך נוצרת פגיעות של מימוש כפול. בסביבת הייצור, תמיד צריך להשתמש בנעילה פסימית (למשל, .with_for_update()) או בניהול גרסאות אופטימי כדי להבטיח בידוד של העסקאות.
הפעלת Lint על הגרף הראשוני של ה-Agent
כדי לוודא שהגרף החדש של הסוכן שנוצר באמצעות Scaffold מתקמפל בצורה נכונה, אפשר להנחות את Antigravity להריץ את הכלי לבדיקת קוד (Linter) ולבדוק את הסוכן בשמנו.
👈 הנחיה ל-Antigravity:
Run `agents-cli lint` on our `shopping-assistant` project to verify syntax and
refactor if any issues.
מה צפוי לקרות: Antigravity יפעיל את הפקודות agents-cli lint ו-agents-cli lint --fix כדי לתקן בעיות עיצוב או בעיות שזוהו באמצעות Lint.
5. יצירת כללים ספציפיים לפרויקט
כדי למנוע עומס יתר על הזיכרון הפעיל של הסוכן עם אלפי דפים של מסמכי אבטחה כלליים – מה שגורם לריקבון הקשר ולחביון של הנימוקים – צריך ליצור "דרך סלולה" של מוסכמות מאובטחות שאושרו מראש. ב-Antigravity IDE, אפשר ליצור קובץ הקשר מתמשך כדי להגדיר את אמצעי ההגנה האלה.
👈 הנחיה ל-Antigravity:
Create a customization directory named `shopping-assistant/.agents` and
create a file `shopping-assistant/.agents/CONTEXT.md` defining our secure
coding standards:
# Local Project Context & Secure Coding Standards
## Core Paved Roads
We systematically address common vulnerability classes by guiding the agent
to use our pre-configured, secure-by-default helper patterns instead of
writing raw implementation logic from scratch.
1. **Tool Input Validation**: Every agent tool must validate incoming
parameters against strict Pydantic schemas rather than parsing raw
dictionaries or strings.
2. **No Shell Execution**: Never use `run_command` or raw shell execution
tools unless explicitly approved by `hooks.json`.
3. **Pre-Commit Remediation Loop**: If a git commit fails due to a pre-commit
hook error (such as a Semgrep scan finding), you MUST treat the violation
as a refactoring task, apply targeted fixes, run tests to verify no
regressions, and attempt to commit again.
מה צפוי לקרות: Antigravity ייצור את הספרייה .agents/ ואת הקובץ CONTEXT.md, ויציג אותו ישירות בחלונית העזר לבדיקה.
6. הגדרת Local Gating Hooks
כדי למנוע מקוד לא מאובטח או מסודות לצאת מתחנת העבודה, צריך להגדיר שערים אוטומטיים בגבולות של סביבת הפיתוח לפני שמבצעים קומיט לקוד. נבקש מ-Antigravity ליצור את הגדרות ה-hook, ואז נתקין אותן באמצעות הטרמינל.
1. Git Pre-Commit Hook
כדי לוודא שהניתוח הסטטי שלנו מזהה באופן מהימן נתוני כניסה מדומים וחוסם שליחות לא מאובטחות, נגדיר כלל Semgrep מותאם אישית ונקבע וו לפני שליחה ב-Git כדי לאכוף אותו.
הגדרת כלל Semgrep בהתאמה אישית
כללי Semgrep שמוגדרים כברירת מחדל (--config auto) לא מסמנים מפתחות מדומה שמכילים מילים כמו "mock" או מקפים, כי הניקוד שלהם נמוך. כדי לזהות באופן מהימן את מפתח ה-API שמוטמע בקוד, ניצור קובץ כללים מקומי בהתאמה אישית, שמשתמש בסריקת ביטויים רגולריים ישירה במקום בכללים כלליים.
👈 הנחיה ל-Antigravity:
Create a custom Semgrep rules file `shopping-assistant/.semgrep/rules.yaml`
with a rule to detect hardcoded Google API key prefixes (matching regex
`AIzaSy[A-Za-z0-9_\-]*`). Configure it for Python files with an error severity
and a clear security warning message.
מה צפוי: Antigravity ייצור את shopping-assistant/.semgrep/rules.yaml שמגדיר את כלל הסריקה המותאם אישית שלנו. בודקים את הגדרת הכלל שנוצרה:
# shopping-assistant/.semgrep/rules.yaml
rules:
- id: detect-hardcoded-google-api-key
pattern-regex: 'AIzaSy[A-Za-z0-9_\-]*'
message: "Security Issue: Hardcoded Google API key prefix detected."
languages:
- python
severity: ERROR
הגדרת Pre-Commit Hook
לאחר מכן, מגדירים את ה-hook של Git pre-commit להפעלה של כלל Semgrep מותאם אישית. כשמבצעים hooks בפריסה של ספריית משנה, הנתיבים להגדרות מקומיות צריכים להיות יחסיים לספריית הבסיס של מאגר Git (shopping-assistant/.semgrep/rules.yaml), ולא לספריית המשנה של הפרויקט.
👈 הנחיה ל-Antigravity:
Create a `shopping-assistant/.pre-commit-config.yaml` file configured to run
local pre-commit hooks (end-of-file-fixer, trailing-whitespace) and a local
Semgrep security scan on commit for Python files. Ensure Semgrep is configured
with the `--error` flag and references our custom rules file relative to the Git
repository root. Once created, run `pre-commit install` in the
terminal to activate the hooks.
מה צפוי: Antigravity ייצור shopping-assistant/.pre-commit-config.yaml ויבצע pre-commit install בשמכם. בודקים את ההגדרות שנוצרו:
# shopping-assistant/.pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: end-of-file-fixer
name: End of File Fixer
entry: end-of-file-fixer
language: system
types: [file]
- id: trailing-whitespace
name: Trailing Whitespace
entry: trailing-whitespace-fixer
language: system
types: [file]
- id: semgrep
name: Semgrep Security Scan
entry: semgrep --error --config shopping-assistant/.semgrep/rules.yaml
language: system
types: [python]
ההגדרה הזו מבטיחה שגם אם סוכן פועל במצב אוטונומי מלא ולא אינטראקטיבי, שער הטרום-שליחה יופעל ויחסום כל שליחה שנכשלת בסריקות של ניתוח סטטי.
פקודות להרצה ישירה (לאימות ידני)
כדי לאמת את ההגדרה של ניתוח סטטי באופן ידני בלי להפעיל מחזור מלא של commit hook, אפשר להריץ את הבדיקות האלה ישירות מהטרמינל.
באמצעות פעולת קדם-התחייבות (מהספרייה shopping-assistant):
uv run pre-commit run semgrep --all-files
באמצעות Semgrep ישירות (מהספרייה shopping-assistant):
uv run semgrep --error --config .semgrep/rules.yaml app/agent.py
2. Hook מובנה של סוכן Antigravity
כדי להגדיר שערים מורכבים יותר באמצע המסלול, צריך להגדיר וו סוכן ב-shopping-assistant/.agents/hooks.json. בניגוד ל-git hooks, agent hooks מיירטים את Antigravity לפני שהוא יכול להריץ כלים קריטיים (כמו ביצוע פקודות shell) במערכת שלכם.
👈 הנחיה ל-Antigravity:
Create a `shopping-assistant/.agents/hooks.json` file configured with a
`PreToolUse` hook that intercepts `run_command` executions and runs
`python3 .agents/scripts/validate_tool_call.py` with a 10-second timeout.
מה קורה אחר כך: Antigravity ייצור את shopping-assistant/.agents/hooks.json. בודקים את ההגדרות שנוצרו:
{
"enabled": true,
"PreToolUse": [
{
"matcher": "run_command",
"command": "python3 .agents/scripts/validate_tool_call.py",
"timeout": 10
}
]
}
בשלב הבא, נותנים ל-Antigravity הנחיה ליצור את סקריפט האימות של כלי הבסיס שאליו מתייחס ה-hook שלנו.
👈 הנחיה ל-Antigravity:
Create the script `shopping-assistant/.agents/scripts/validate_tool_call.py`
with logic to inspect `run_command` executions passed using stdin and block
destructive commands like `rm -rf /`.
מה צפוי: Antigravity ייצור shopping-assistant/.agents/scripts/validate_tool_call.py, בדומה לזה שמופיע בהמשך. בודקים את סקריפט האימות שנוצר:
# shopping-assistant/.agents/scripts/validate_tool_call.py
import sys
import json
def main():
try:
context = json.load(sys.stdin)
command = context.get("tool_args", {}).get("CommandLine", "")
if "rm -rf /" in command or "mkfs" in command:
print("BLOCKED: Destructive command detected.", file=sys.stderr)
sys.exit(1)
print("APPROVED: Command validation passed.")
sys.exit(0)
except Exception as e:
print(f"Validation error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
היתרונות והחסרונות של שימוש בתוכן מושך
- Git Hooks: תכונה מובנית בניהול גרסאות; פועלת גם אם סוכן פועל במצב אוטונומי מלא ולא אינטראקטיבי. עם זאת, אפשר לעקוף אותם באמצעות הדגל
--no-verifyבמהלך ביצוע commit. - Agent Hooks: תוספים שמאפשרים ללכוד אירועים באמצע התהליך כדי לחסום פקודות מסוכנות של כלים, אבל הם לא מגנים על המאגר אם מפתח עוקף את סביבת הפיתוח המשולבת.
השערים המקומיים מחזקים הרגלים טובים של מפתחים ועוזרים לזהות נקודות חולשה באופן מיידי. עם זאת, חשוב לזכור שאפשר לעקוף את השערים המקומיים, ולכן צינור ה-CI/CD המבודד והמרוחק שלכם הוא עדיין מחסום האבטחה האולטימטיבי שאי אפשר לעקוף.
7. הטמעה של מיומנות ליצירת מודלים של איומים מסוג STRIDE
עכשיו תעניקו ל-Antigravity את הידע המיוחד של אדריכל אבטחה. מיומנויות אנטי-גרביטציה הן ספריות מודולריות של Markdown הצהרתי שמנחות את הסוכן איך להריץ משימות של ניתוח רב-שלבי. Antigravity מגלה באופן אוטומטי את כל הכישורים שמוצבים ב-.agents/skills/.
👈 הנחיה ל-Antigravity:
Create a local skill directory
`shopping-assistant/.agents/skills/stride-threat-model/` and create a skill
definition file `shopping-assistant/.agents/skills/stride-threat-model/SKILL.md`
with the following content:
---
name: stride-threat-model
description: Performs a systematic STRIDE threat modeling assessment on the
current project's codebase and architecture. Use this when starting a new
implementation phase or reviewing existing components.
---
# STRIDE Threat Modeling Skill
## Goal
Guide the agent to analyze the workspace directory structure, configuration
files, and code files to produce a structured `threat_model.md` assessment.
## Instructions
1. **Analyze System Boundaries**: Map the entry points (tools, workflows,
prompts) and data storage layers.
2. **STRIDE Evaluation**: Evaluate the system against the six STRIDE pillars:
- **Spoofing**: Are caller identity boundaries verified before executing
sensitive tool logic?
- **Tampering**: Can users manipulate data flows, parameters, or underlying
state?
- **Repudiation**: Are critical transactions securely logged?
- **Information Disclosure**: Are we risking leakage of PII, internal tokens,
or raw stack traces?
- **Denial of Service**: Are there rate limits on expensive database or LLM
queries?
- **Elevation of Privilege**: Can an unauthenticated user bypass access
control to reach privileged tool actions?
3. **Output**: Generate a highly structured `threat_model.md` saved directly
into the workspace root.
מה קורה: Antigravity יוצר את ספריית הכישורים המותאמת אישית ואת קובץ SKILL.md.
עכשיו נריץ את המיומנות החדשה שיצרתם כדי להעריך את גרף הפרויקט הפעיל (shopping-assistant/app/agent.py).
👈 הנחיה ל-Antigravity:
Run stride-threat-model on our shopping-assistant agent graph.
מה צפוי לקרות: Antigravity יתאים את עצמו לכוונות שלכם, יטען את ההוראות להערכת האיום לפי דרישה מהספרייה המקומית של המיומנות, ינתח את קובץ agent.py הקיים ויצור קובץ threat_model.md מובנה ישירות בתיקיית השורש shopping-assistant. הגישה הזו מאפשרת לכם לשמור על ההקשר של העבודה היומיומית שלכם נקי וקל משקל, וגם לקבל גישה מיידית לנימוקים של מומחים בנושא אבטחה.
8. הגבלת הגישה לשלב התכנון של TDD
לפני שמטמיעים תכונות נוספות או מבצעים שינוי מבנה בקוד, Antigravity משתמש בהבנה הסמנטית של בסיס הקוד כדי למפות שינויים ברשימת משימות לביצוע implementation_plan.md וtask.md. כדי לחייב את Antigravity לתכנן אבטחה מראש, אנחנו מגדירים כלל מערכת ב-.agents/CONTEXT.md שמגביל את אישור התוכנית.
👈 הנחיה ל-Antigravity:
Append the following TDD planning gate instruction to the bottom of
`shopping-assistant/.agents/CONTEXT.md`:
## TDD Planning Gate
During the Plan phase, you must decompose the workspace task into logical,
modular stages. Every implementation plan MUST include a dedicated
**Security Boundaries & Assertions** section outlining specific edge cases
that could exploit the feature.
מה צפוי: מערכת Antigravity תעדכן את shopping-assistant/.agents/CONTEXT.md בכלל החדש של שער התכנון.
כשמבקשים מ-Antigravity ליצור או לשנות תכונה בשלבים הבאים, הוא ינתח אוטומטית את הכלל הזה ויציג תוכנית הטמעה עם פירוט ברור של האבטחה. תוכלו לעיין בתוכנית הזו ישירות בתיבת הדו-שיח האינטראקטיבית או בחלונית העזר של Antigravity, שבה תצטרכו ללחוץ על המשך או על אישור לפני שתתחיל יצירת הקוד.
בדיקת שער התכנון (אופציונלי)
כדי לראות את שער התכנון הזה בפעולה, אפשר להזין ל-Antigravity אחת מהצעות התכונות הבאות. במקום ליצור קוד באופן מיידי, Antigravity יעבור לשלב התכנון ויציג implementation_plan.md עם פירוט של גבולות אבטחה וטענות (למשל, זיהוי של תנאי מירוץ, העלאת הרשאות לא מורשית או ערכים שליליים של נקודות) לבדיקה שלכם.
👈 הנחיה ל-Antigravity (בוחרים אחת לבדיקה):
Plan a new agent tool `award_loyalty_points` that awards points to a user's
account after a successful purchase.
Plan a new agent tool `process_cart_checkout` that receives a cart ID and
discount code, applies the discount, and processes the order.
Plan a new agent tool `update_discount_status` that allows administrators to
activate or deactivate discount codes in the store.
9. כתיבת בדיקות מבודדות שמבוססות על תוצאות
עכשיו אנחנו מנחים את Antigravity לכתוב בדיקות אבטחה מקיפות לכלים הקיימים של סוכני ADK. כדי לוודא שבדיקות האבטחה שלנו הן חזקות וריאליות, אנחנו מבססים אותן על שני עקרונות מרכזיים:
- הצהרה על תוצאות, לא על אינטראקציות: הצהרה על מחרוזות החזרה סופיות ועל שינויים במצב במקום לכתוב מוקאפים שבירים שעוקבים אחרי קריאות פנימיות לפונקציות עזר.
- הקפדה על אמצעי הגנה מחמירים: מוודאים שהכלים אוכפים גבולות מפורשים של לוגיקה עסקית (כמו כללים לגבי מימוש חד-פעמי ומשתמשים רשומים).
👈 הנחיה ל-Antigravity:
Use `agents-cli` and pytest to generate an outcome-based security test suite
in `shopping-assistant/tests/test_agent.py`. Inspect `app/agent.py` and
write tests to verify all security boundaries and business logic guardrails
for the `redeem_discount` tool.
מה צפוי: Antigravity ייצור shopping-assistant/tests/test_agent.py, בדומה לזה שמופיע בהמשך. בודקים את קובץ הבדיקה שנוצר:
# shopping-assistant/tests/test_agent.py
import pytest
from app.agent import redeem_discount, DISCOUNT_STORE
@pytest.fixture(autouse=True)
def reset_store():
"""Ensure strict test isolation by resetting in-memory store state before each test run."""
DISCOUNT_STORE["WELCOME50"] = False
DISCOUNT_STORE["SUMMER20"] = False
yield
DISCOUNT_STORE["WELCOME50"] = False
DISCOUNT_STORE["SUMMER20"] = False
def test_discount_code_can_only_be_redeemed_once():
"""Verify a user cannot submit a request reusing a single-use code."""
# First redemption - should succeed
res_one = redeem_discount("WELCOME50", "user_123")
assert "Success" in res_one
assert DISCOUNT_STORE["WELCOME50"] is True
# Second redemption trying to reuse the same code
res_two = redeem_discount("WELCOME50", "user_456")
assert "Error: Discount code has already been redeemed" in res_two
def test_discount_redemption_rejects_invalid_code():
"""Verify that unknown discount codes are hard-blocked."""
res = redeem_discount("INVALID999", "user_123")
assert "Error: Invalid discount code" in res
def test_discount_redemption_rejects_guest_accounts():
"""Verify that unauthenticated guest accounts cannot redeem discounts."""
res = redeem_discount("SUMMER20", "guest_999")
assert "Error: Registered user account required" in res
assert DISCOUNT_STORE["SUMMER20"] is False
אימות שלב TDD GREEN
כדי לוודא שבדיקות האבטחה החדשות שיצרנו עוברות בהצלחה את ההטמעה הקיימת של agent.py, מבקשים מ-Antigravity להריץ את pytest בשמכם.
👈 הנחיה ל-Antigravity:
Run `uv run pytest tests/test_agent.py` on our `shopping-assistant` project to verify that our security tests pass successfully.
מה צפוי: Antigravity יפעיל את uv run pytest tests/test_agent.py בטרמינל. כל תרחישי הבדיקה עוברים בהצלחה. הגבולות הלוגיים של האפליקציה מאובטחים עכשיו, אבל צריך לוודא שהסורק הסטטי שלנו יזהה את מפתח ה-API שמוטמע בקוד במהלך השמירה.
10. אימות של חסימת גישה ותיקון עצמי של נציגים
עכשיו, כשהבדיקות ירוקות, עוברים אל השלב של שינוי המבנה והוספה למאגר. כאן נכנסות לפעולה סריקות האבטחה המקומיות וה-hooks של טרום-התחייבות, כדי לוודא שאף מאגר לא יוצא מתחנת העבודה עם נקודות חולשה. בנוסף, Antigravity מדגים את יכולות התיקון העצמי האוטונומיות שלו.
- בטרמינל, עוברים לספריית הפרויקט ומבצעים קומיט של הקוד באמצעות
uv runכדי לוודא שקבצים בינאריים של וו מקומי לפני קומיט פעילים בנתיב:cd ~/secure-agent-lab/shopping-assistant git add . uv run git commit -m "feat: implement shopping assistant agent" - שימו לב שהקומט נכשל כי ה-hook של Git pre-commit מריץ את Semgrep באופן אוטומטי:
Semgrep Security Scan....................................................Failed - hookid: semgrep app/agent.py Security Issue: Hardcoded Google API key prefix detected.
- בהתאם לכלל Pre-Commit Remediation Loop שהוגדר ב-
.agents/CONTEXT.md, Antigravity מיירט באופן אוטומטי את הכשל שלפני השליחה במסוף של סביבת הפיתוח המשולבת (IDE), קורא את יומני השגיאות של Semgrep ומתחיל שלב של שינוי מבנה הקוד כדי לעבור ממפתח API שמוטמע בקוד למפתח שאוחזר בצורה מאובטחת. - כדי לפתור את הבעיה של חשיפת מפתח ה-API, צריך לבדוק את הקוד שעבר רפקטורינג שנוצר על ידי Antigravity ב-
shopping-assistant/app/agent.py. - Antigravity מריץ אוטומטית את
pytestכדי לוודא שהבדיקות עדיין ירוקות. - Antigravity מנסה לבצע שוב את השמירה בשמכם. אם הזהות המקומית שלכם ב-Git מוגדרת ומאגר מאותחל, הסריקה עוברת וההתחייבות מצליחה.
ההדגמה הזו ממחישה את העוצמה של שילוב TDD עם ווים מקומיים לפני ביצוע קומיט ולולאות סוכנים. במקום להמתין לכשל של CI/CD מרוחק, הסוכן נשאר אחראי באופן מקומי, ומבצע רפקטורינג של הקוד שלו כדי שיהיה מאובטח כברירת מחדל לפני שהוא נדחף.
11. הפעלה ובדיקה של הסוכן באופן מקומי
עכשיו, אחרי שגבולות האבטחה אומתו ונשמרו, מריצים את סוכן ה-ADK באופן מקומי באמצעות מפתח Gemini API שייצאתם כדי ליצור איתו אינטראקציה בסביבת הפיתוח המקומית.
- בטרמינל, מוודאים שמפתח Gemini API מיוצא לסביבה:
echo $GEMINI_API_KEY # Verify your key is exported - מפעילים את סביבת הפיתוח המקומית של הסוכן:
אמור להופיע פלט שמציין ששרת ההדמיה המקומי פועל ביציאה 8080:cd ~/secure-agent-lab/shopping-assistant agents-cli playground* Serving ADK Playground * Running on http://127.0.0.1:8080/dev-ui/?app=app
- פותחים את כתובת ה-URL שמופיעה בדפדפן האינטרנט כדי להתחיל צ'אט אינטראקטיבי עם נציג של הסוכן החכם של שופינג. אפשר לנסות לבקש ממנו לממש קוד הנחה:
הסוכן יעבד את הבקשה שלכם באמצעות הפעלת מודל Gemini וינסה לממש את ההנחה.Can you redeem the discount code WELCOME50 for user user_123?
12. הסרת המשאבים
כדי לנקות את תחנת העבודה ולמנוע השארת משאבים או סודות לא רצויים בסביבה המקומית, פועלים לפי שלבי הניקוי הבאים.
- הפסקת השרת המקומי: אם שרת ה-Playground עדיין פועל, צריך להפסיק אותו במסוף על ידי לחיצה על
Ctrl + C. - הסרת קבצי פרויקט מקומיים: מחיקה של ספריית הפרויקט המקומית מהמחשב:
rm -rf ~/secure-agent-lab
13. מזל טוב
מעולה! הצלחתם ליצור מחזור חיים מאובטח של פיתוח מבוסס-בדיקות באמצעות Google Antigravity IDE, לבנות סוכן עזר לקניות שמבוסס על ADK 2.0 ולבדוק אותו באופן מקומי.
מה למדתם
- איך ליצור תבנית ולשלב סוכן ADK 2.0 (ערכה לפיתוח סוכנים) באמצעות Antigravity IDE ו-
agents-cli. - איך מגדירים תקני קידוד מאובטחים ברמת הפרויקט באמצעות
CONTEXT.md. - איך ליצור ולהפעיל מיומנות מותאמת אישית של STRIDE Threat Modeling ב-Antigravity IDE.
- איך להגביל את שלב התכנון של סוכן AI כדי לאכוף גבולות אבטחה.
- איך מטמיעים בדיקות אבטחה מבודדות שמבוססות על תוצאות באמצעות pytest.
- איך מריצים ובודקים את האפליקציה המבוססת על סוכן באופן מקומי.
- ההבדלים והפשרות בין Git hooks לבין agent-specific execution hooks.
השלבים הבאים
- למידע על הגדרות מתקדמות, אפשר לעיין במדריך להתאמה אישית של Antigravity.
- מידע נוסף על מודלים של איומים מסוג STRIDE
- הטמעה של כללי Semgrep בהתאמה למדיניות האבטחה של הארגון.
איך מקבלים את התג Kaggle 5-Day AI Agents 🎉
השלמתם את שיעור ה-Lab הזה כחלק מקורס אינטנסיבי בן 5 ימים בנושא סוכני AI: כתיבת קוד עם Google ב-Kaggle? לקבלת תג על השלמת הקורס: