ساختن «برنامه‌ریز پیست مسابقات اتومبیل‌رانی چندعاملی» با ADK و A2A

۱. ۱. نمای کلی

در این codelab، سیستم چندعاملی می‌سازید که پیست خیابانی فرمول E را طراحی می‌کند و آن را براساس مجموعه ساده‌شده‌ای از قوانین FIA تأیید می‌کند.

از agents-cli برای تولید دو پروژه استاندارد Agent Development Kit (ADK) استفاده خواهید کرد، سپس بخش‌های مهم را خواهید نوشت: یک «مهارت عامل»، سه عامل، و یک ارزیابی. همه چیزهای دیگر (چیدمان پروژه، سرور، وابستگی‌ها، پیکربندی استقرار) از CLI می‌آید.

تازه با فرمول E آشنا شده‌اید؟

لازم نیست با ورزش‌های موتوری آشنا باشید. این پنج اصطلاح کافی است:

  • فرمول ای: مسابقات قهرمانی تمام‌الکتریکی FIA. بیشتر مسابقات در پیست‌های خیابانی موقت در مرکز شهرها برگزار می‌شود.
  • تأییدیه: تأیید رسمی FIA مبنی بر اینکه یک پیست برای مسابقه ایمن است. بدون تأییدیه، مسابقه‌ای در کار نیست.
  • ترمز احیاکننده: وقتی خودرو ترمز می‌کند، موتورهای آن باتری را شارژ می‌کنند. ترمز شدیدتر انرژی بیشتری را بازیابی می‌کند، بنابراین قوانین این codelab حداقل یک منطقه ترمز شدید را درخواست می‌کند.
  • لایه‌های CAD: لایه‌های نام‌گذاری‌شده در طراحی‌های مدار، مانند خط مسابقه، خط پیت و موانع. FIA بررسی می‌کند که موارد اجباری وجود داشته باشند.
  • حالت حمله: رانندگان با رانندگی در منطقه فعال‌سازی که خارج از خط مسابقه قرار دارد، به‌طور موقت قدرت بیشتری دریافت می‌کنند.

عامل‌های شما هر دو نقش را بازی می‌کنند: یکی مدار را طراحی می‌کند و دو عامل آن را برای FIA بررسی می‌کنند.

آنچه خواهید ساخت

معماری: در پروژه track-planner، که در Cloud Shell اجرا می‌شود، عامل track_planner از get_track_topology،‏ fia_assessor، و remote_gatekeeper استفاده می‌کند. remote_gatekeeper عامل gatekeeper را ازطریق A2A فراخوانی می‌کند. در پروژه کنترل‌کننده، که در «زمان اجرای عامل» اجرا می‌شود، عامل کنترل‌کننده از verify_infrastructure_checklist استفاده می‌کند.

جعبه‌های سبز عامل‌ها هستند و جعبه‌های خط‌چین ابزارهای آن‌ها هستند، همان‌طور که زمین بازی ADK آن‌ها را ترسیم می‌کند. دو ابزار دیگر عامل‌های دیگر را دربرمی‌گیرند: fia_assessor عامل «ارزیاب FIA» با مهارت رعایت FIA است و remote_gatekeeper عامل «دروازه‌بان» را در پروژه دیگر ازطریق A2A فراخوانی می‌کند.

عامل

Project

کار

thinking_level

معمار ارشد

track-planner

محل را می‌خواند، از «ارزیاب» می‌پرسد، مشکلات را برطرف می‌کند، از «دروازه‌بان» تأییدیه می‌خواهد

HIGH

ارزیاب FIA

track-planner

چیدمان را بااستفاده از مهارت FIA و ابزار امتیازدهی بررسی می‌کند

MEDIUM

Digital Twin Gatekeeper

gatekeeper

بازبینه تأیید نهایی را اجرا می‌کند

LOW

آنچه خواهید آموخت

  • نحوه چیدمان پروژه ADK توسط agents-cli scaffold create و فایل‌هایی که ویرایش می‌کنید.
  • نحوه بسته‌بندی دانش دامنه به‌عنوان مهارت نماینده (SKILL.md، references/، scripts/) و بار کردن آن با SkillToolset ADK.
  • نحوه مطابقت دادن thinking_level با شغل هر نماینده.
  • نحوه ارزیابی کردن عامل‌ها با agents-cli eval run.
  • نحوه استقرار عامل در Agent Runtime، تفاوت هویت عامل با حساب سرویس، و نحوه فراخوانی عامل مستقرشده ازطریق پروتکل A2A.

۲. ۲. راه‌اندازی محیط

قبل‌از شروع

به پروژه Google Cloud با صورت‌حساب فعال نیاز دارید. اگر این codelab را در رویدادی دنبال می‌کنید، از حساب و پروژه‌ای که به شما داده شده است استفاده کنید.

Cloud Shell را باز کنید و پروژه خود را تنظیم کنید

Cloud Shell را باز کنید، سپس این دستور را اجرا کنید:

# Cloud Shell sometimes opens without a project set. If so, this sets it to
# the first project on your account.
if [ -z "$(gcloud config get-value project 2>/dev/null)" ]; then
  gcloud config set project "$(gcloud projects list --format='value(projectId)' --limit=1)"
fi

export GOOGLE_CLOUD_PROJECT="$(gcloud config get-value project)"
export REGION="us-central1"
export ASSETS="$HOME/devrel-demos/codelabs/formula-e-track-planner"
echo "Project: $GOOGLE_CLOUD_PROJECT  Region: $REGION"

ایجاد اطلاعات کاربری برای عامل‌ها

gcloud قبلاً به سیستم وارد شده است، اما کد پایتونی که نماینده‌های شما اجرا می‌کنند از اعتبارنامه‌های پیش‌فرض برنامه (ADC) استفاده می‌کند که نیاز به ورود به سیستم جداگانه دارد:

gcloud auth application-default login

پیوندی را که چاپ می‌کند باز کنید، با همان حساب به سیستم وارد شوید، کد را کپی کنید، و آن را در Cloud Shell جای‌گذاری کنید. سپس پروژه‌ای را که سهمیه به آن صورت‌حساب می‌شود تنظیم کنید:

gcloud auth application-default set-quota-project "$GOOGLE_CLOUD_PROJECT"

فعال کردن میاناهای برنامه‌سازی کاربردی

gcloud services enable \
    aiplatform.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    storage.googleapis.com \
    cloudresourcemanager.googleapis.com \
    serviceusage.googleapis.com \
    compute.googleapis.com \
    iam.googleapis.com \
    logging.googleapis.com \
    cloudtrace.googleapis.com

هر API برای چه کاری است:

میاناهای برنامه‌سازی کاربردی

استفاده‌شده برای

aiplatform

مدل‌های Gemini و Agent Runtime

cloudresourcemanager، serviceusage، iam

بررسی‌های پروژه و اجازه‌ای که gcloud و agents-cli deploy اجرا می‌کنند

compute

حساب خدمات پیش‌فرض Compute Engine را که استقرار در مرحله ۷ استفاده می‌کند ایجاد می‌کند

storage، logging، cloudtrace

فضای ذخیره‌سازی، گزارش‌ها، و ردیابی‌ها، همان‌طور که در راهنمای راه‌اندازی زمان اجرای عامل توصیه شده است

‫cloudbuild،‏ artifactregistry

ساخت‌ها و تصاویر کانتینر، به‌عنوان احتیاط برای استقرار در مرحله ۷ گنجانده شده است

بسیاری از پروژه‌ها ازقبل برخی‌از این تنظیمات را روشن کرده‌اند. فعال کردن میانای برنامه‌سازی کاربردی که ازقبل روشن است چیزی را تغییر نمی‌دهد.

نصب کردن uv و agents-cli

curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
uv tool install google-agents-cli==1.10.0
agents-cli --version

این codelab با agents-cli 1.10.0 آزمایش شده است، بنابراین آن نسخه را نصب کنید تا همان فایل‌های تولیدشده را دریافت کنید.

۳. ۳. پروژه‌ها را داربست‌بندی کنید و دارایی‌ها را اضافه کنید

تولید کردن هر دو پروژه

‫agents-cli scaffold create یک پروژه ADK کامل و قابل‌استقرار تولید می‌کند. آن را دو بار اجرا کنید، یک بار برای هر سیستم عامل.

ابتدا، برنامه‌ریز قطعه:

cd ~
agents-cli scaffold create track-planner \
  --agent adk \
  --deployment-target agent_runtime \
  --region "$REGION" \
  --prototype \
  --yes

سپس دروازه‌بان:

cd ~
agents-cli scaffold create gatekeeper \
  --agent adk \
  --deployment-target agent_runtime \
  --region "$REGION" \
  --prototype \
  --yes

پرچم

معنی

--agent adk

شروع کردن از الگوی Python ADK

--deployment-target agent_runtime

تولید سرور و پیکربندی برای Agent Runtime

--prototype

رد شدن از CI/CD؛ پروژه را در حداقل نگه دارید

--yes

پذیرفتن پیش‌فرض‌ها بدون درخواست

کاوش چیدمان

پروژه تولیدشده به این شکل است. فقط فایل‌های علامت‌گذاری‌شده با ✍️ را ویرایش می‌کنید:

track-planner/
├── agents-cli-manifest.yaml   # Records the template, deployment target and root agent name
├── pyproject.toml             # Dependencies (google-adk, a2a-sdk, ...)
├── .env                       # Your project and model location, filled in for you
├── Dockerfile                 # Used by `agents-cli deploy`; copies app/ into the image
├── app/
│   ├── agent.py               # ✍️ Your agents
│   ├── fast_api_app.py        # Generated server: ADK API, A2A routes, Agent Runtime routes
│   └── app_utils/             # Generated helpers (A2A, sessions)
└── tests/
    ├── unit/                  # Fast tests with no model calls
    ├── integration/           # Generated server tests
    └── eval/                  # ✍️ eval_config.yaml and datasets for `agents-cli eval`

برای شرح هر فایل تولیدشده، به ساختار پروژه در راهنمای Agents CLI مراجعه کنید.

امتحان کردن عامل تولیدشده

قبل‌از تغییر هر چیزی، عامل الگو را اجرا کنید تا ببینید داربست چه چیزی به شما می‌دهد. وابستگی‌ها را نصب کنید و زمین بازی محلی را در درگاه ۸۰۸۰ شروع کنید:

cd ~/track-planner
agents-cli install
agents-cli playground --port 8080

برای باز کردن آن، روی دکمه پیش‌نمایش وب در نوارابزار Cloud Shell (نماد چشم در بالا سمت چپ) کلیک کنید، سپس پیش‌نمایش در درگاه ۸۰۸۰ را انتخاب کنید.

در زمین بازی، از عامل الگو سؤالی بپرسید که ابزارهایش بتوانند پاسخ دهند، برای مثال:

What's the weather in San Francisco?

پانل کناری هر رویداد را نشان می‌دهد، ازجمله فراخوانی ابزار get_weather و نتیجه آن. بعداً از همین نما برای دنبال کردن نماینده‌های خودتان استفاده خواهید کرد.

وقتی کارتان تمام شد، به پایانه برگردید و Ctrl+C را فشار دهید تا زمین بازی متوقف شود.

افزودن دارایی‌های «فرمول ای»

داده‌های محل برگزاری، قوانین FIA، اسکریپت فیزیک، ابزارها، و مجموعه‌داده‌های ارزیابی درس نیستند، بنابراین آن‌ها را به‌جای تایپ کردن از GitHub کپی می‌کنید:

cd ~
git clone --depth 1 --filter=blob:none --sparse \
  --branch formula-e-lab-v1 \
  https://github.com/tdsymonds/devrel-demos.git
git -C devrel-demos sparse-checkout set codelabs/formula-e-track-planner

cp -r "$ASSETS/track-planner/." ~/track-planner/
cp -r "$ASSETS/gatekeeper/." ~/gatekeeper/

‫formula-e-lab-v1 برچسب انتشار ثابتی است، بنابراین همه فایل‌های یکسانی دریافت می‌کنند. $ASSETS در مرحله ۲ تنظیم شده است و به پوشه‌ای که به‌تازگی کلون کرده‌اید اشاره می‌کند.

این کار این فایل‌ها را اضافه می‌کند:

track-planner/
├── app/
│   ├── tools.py                                  # get_track_topology, evaluate_track_layout
│   ├── auth.py                                   # A2A client with per-request token refresh
│   ├── data/circuits.json                        # Five candidate venues
│   └── skills/fia-compliance-skill/
│       ├── references/track_regulations.md       # The FIA rules
│       └── scripts/calculate_regen_zones.py      # Braking-energy calculator
└── tests/
    ├── unit/test_tools.py
    └── eval/datasets/track_eval.json, track_eval_quick.json
gatekeeper/
├── app/tools.py                                  # verify_infrastructure_checklist
└── tests/unit/test_tools.py

نصب و امتحان کردن

(cd ~/track-planner && agents-cli install && uv run pytest tests/unit)
(cd ~/gatekeeper && agents-cli install && uv run pytest tests/unit)

agents-cli install uv sync را اجرا می‌کند تا محیطی مجازی برای هر پروژه ایجاد کند. همه آزمایش‌های واحد باید موفق باشند.

۴. ۴. نوشتن مهارت مطابقت با FIA

مهارت نماینده دستورالعمل‌ها، اسناد مرجع، و دستورگان را در یک پوشه بسته‌بندی می‌کند. SkillToolset ADK آن را در سه سطح بار می‌کند، بنابراین عامل فقط آنچه را که نیاز دارد می‌خواند:

سطح

فایل

وقتی نماینده آن را ببیند

1

‫SKILL.md مقدمه (name، description)

همیشه (چند ده نشانه)

2

SKILL.md بدنه

وقتی با load_skill تماس می‌گیرد

3

‫references/،‏ scripts/

وقتی با load_skill_resource یا run_skill_script تماس می‌گیرد

این مهارت در app/skills/ قرار دارد زیرا Dockerfile تولیدشده فقط app/ را در تصویر مستقرشده کپی می‌کند.

به فایل‌های سطح ۳ نگاه کنید

فایل‌های سطح ۳ مهارت را در «مرحله ۳» کپی کرده باشید:

  • references/track_regulations.md حاوی قوانینی است که «ارزیاب» بررسی می‌کند: محدودیت‌های طول و عرض، اینکه هر منطقه ترمز به کدام مانع نیاز دارد، لایه‌های اجباری CAD (به‌علاوه لایه‌های پزشکی برای مسیرهای بیمارستان)، هدف بازتولید، و قوانین «حالت حمله».
  • scripts/calculate_regen_zones.py ماشین‌حساب است. با داشتن سرعت ورودی، سرعت خروجی، و مسافت ترمزگیری در منطقه ترمزگیری، این مدل انرژی بازیابی‌شده و مانع موردنیاز برای پیچ را محاسبه می‌کند، بنابراین عامل هرگز مجبور نیست فیزیک را حدس بزند.

اسکریپت را برای پیچ ۱۰ لندن اجرا کنید، جایی که خودروها سرعت خود را در مسافت ۸۲ متر از ۲۱۵ به ۵۵ کیلومتر در ساعت کاهش می‌دهند:

cd ~/track-planner
uv run python app/skills/fia-compliance-skill/scripts/calculate_regen_zones.py \
  --entry-kph 215 --exit-kph 55 --brake-dist-m 82

خودرو در اینجا حدود ۵۰۸ کیلووات بازیابی می‌کند که بالاتر از هدف ۲۵۰ کیلووات است. در بیش‌از 2G سرعتش کم می‌شود، بنابراین پیچ به موانع Tecpro نیاز دارد (F1_TEC3):

{"entry_kph": 215.0, "exit_kph": 55.0, "brake_dist_m": 82.0, "deceleration_g": 2.07, "estimated_regen_kw": 507.7, "meets_250kw_target": true, "required_barrier_layer": "F1_TEC3"}

نوشتن SKILL.md

فایلی را که مهارت را به هم متصل می‌کند ایجاد کنید:

cloudshell edit app/skills/fia-compliance-skill/SKILL.md

این محتوا را اضافه کنید:

---
name: fia-compliance-skill
description: >
  FIA Formula E street circuit rules: length and width limits, mandatory CAD
  layers, barrier selection, and Gen3 regenerative braking estimates. Use when
  designing, checking or fixing a Formula E circuit layout.
---

# FIA Formula E Compliance

Follow these steps for every circuit you check.

1. **Read the rules.** Call `load_skill_resource` with
   `file_path="references/track_regulations.md"`.
2. **Estimate regeneration for every heavy braking zone.** Call
   `run_skill_script` with `file_path="scripts/calculate_regen_zones.py"` and
   `args={"entry-kph": <entry>, "exit-kph": <exit>, "brake-dist-m": <distance>}`.
   Never guess kW values. Use the highest `estimated_regen_kw` as the
   circuit's peak regeneration.
3. **Check barriers.** Any zone whose `required_barrier_layer` is `F1_TEC3`
   needs the `F1_TEC3` CAD layer.
4. **Report.** List every rule the layout fails and a concrete fix for each
   one.

description چیزی است که مدل می‌خواند تا تصمیم بگیرد چه زمانی از مهارت استفاده کند، بنابراین هم آنچه را که مهارت پوشش می‌دهد و هم زمان استفاده از آن را بیان می‌کند.

ببینید مهارت چگونه متصل شده است

app/tools.py را در «ویرایشگر Cloud Shell» باز کنید:

cloudshell edit app/tools.py

تابع build_fia_skill_toolset را پیدا کنید:

def build_fia_skill_toolset() -> SkillToolset:
    return SkillToolset(
        skills=[load_skill_from_dir(SKILL_DIR)],
        code_executor=UnsafeLocalCodeExecutor(),
    )
  • ‫load_skill_from_dir پوشه مهارت را می‌خواند: SKILL.md، references/، و scripts/.
  • ‫SkillToolset آن را به ابزارهایی تبدیل می‌کند که نماینده می‌تواند فراخوانی کند: list_skills، load_skill، load_skill_resource، و run_skill_script.
  • UnsafeLocalCodeExecutor به run_skill_script اجازه می‌دهد دستور Python را در این دستگاه اجرا کند. این برای آزمایشگاه خوب است؛ در تولید از مجری جعبه امن استفاده کنید.

در مرحله بعد، این مجموعه ابزار را به «ارزیاب» پیوست خواهید کرد.

۵. ۵. عامل‌ها را بنویسید

مدل‌های Gemini 3 استدلال را با thinking_level (LOW، MEDIUM، یا HIGH) به‌جای بودجه توکن کنترل می‌کنند. در ADK، آن را با types.ThinkingConfig(thinking_level=types.ThinkingLevel.HIGH) تنظیم می‌کنید. آن را با وظیفه هر نماینده مطابقت دهید: تفکر بیشتر به‌معنای برنامه‌ریزی بهتر اما تأخیر و هزینه بیشتر است.

The Gatekeeper (LOW)

«دروازه‌بان» فقط یک بازبینه قطعی را اجرا می‌کند، بنابراین به استدلال کمی نیاز دارد. جایگزین کردن عامل الگو:

cloudshell edit ~/gatekeeper/app/agent.py
"""FIA Digital Twin Gatekeeper agent.

This agent runs in its own project and is deployed to Agent Runtime. The track
planner calls it over the A2A protocol.
"""

from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.models import Gemini
from google.genai import types

from app.tools import verify_infrastructure_checklist

# Tested with Gemini 3.8 Flash. To try Gemini 4 Argon, change this to
# "gemini-4-argon", delete the `temperature` settings below (Argon ignores
# them) and run `uv add "google-genai>=2.30.1"` in this project first.
MODEL = "gemini-3.8-flash"

root_agent = Agent(
    # Must match `root_agent_name` in agents-cli-manifest.yaml.
    name="gatekeeper",
    model=Gemini(
        model=MODEL,
        retry_options=types.HttpRetryOptions(attempts=3),
    ),
    description=(
        "FIA Digital Twin Gatekeeper. Runs the final homologation checklist "
        "for a Formula E circuit blueprint."
    ),
    instruction=(
        "You are the FIA Digital Twin Gatekeeper. For every circuit blueprint "
        "you receive, call `verify_infrastructure_checklist` with its circuit "
        "ID, CAD layers, minimum width and peak regeneration. Reply with the "
        "status and any missing CAD layers. Never approve a blueprint the "
        "checklist rejects."
    ),
    # A deterministic checklist needs little reasoning: keep it fast and cheap.
    generate_content_config=types.GenerateContentConfig(
        temperature=0.0,
        thinking_config=types.ThinkingConfig(
            thinking_level=types.ThinkingLevel.LOW,
        ),
    ),
    tools=[verify_infrastructure_checklist],
)

app = App(
    root_agent=root_agent,
    name="app",
)

اجرای Gatekeeper به‌صورت محلی

برگه دوم Cloud Shell را باز کنید و سرور تولیدشده Gatekeeper را در درگاه ۸۰۰۱ راه‌اندازی کنید:

cd ~/gatekeeper
APP_URL=http://localhost:8001 uv run uvicorn app.fast_api_app:app --port 8001

به برگه اول برگردید و به کارت عامل A2A «دروازه‌بان» نگاه کنید. عوامل دیگر از این طریق متوجه می‌شوند که Gatekeeper چیست و چه کاری می‌تواند انجام دهد:

curl -s http://localhost:8001/a2a/app/.well-known/agent-card.json | jq .

باید JSON را به‌این‌صورت ببینید (کوتاه‌شده):

{
  "name": "gatekeeper",
  "description": "FIA Digital Twin Gatekeeper. Runs the final homologation checklist for a Formula E circuit blueprint.",
  "supportedInterfaces": [
    {"url": "http://localhost:8001/a2a/app", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"}
  ],
  "skills": [
    {"id": "gatekeeper", "name": "model", "description": "FIA Digital Twin Gatekeeper. ..."},
    {"id": "gatekeeper-verify_infrastructure_checklist", "name": "verify_infrastructure_checklist", "description": "Runs the final homologation checklist ..."}
  ]
}
  • name و description مستقیماً از تعریف Agent(...) شما می‌آیند.
  • skills کارهایی را که عامل می‌تواند انجام دهد فهرست می‌کند. ADK بااستفاده از رشته مستندات ابزار، verify_infrastructure_checklist را به‌طور خودکار اضافه کرد.
  • supportedInterfaces به تماس‌گیرندگان می‌گوید درخواست‌های «برنامه به برنامه» را به کجا ارسال کنند. به‌همین دلیل است که سرور را با APP_URL=http://localhost:8001 شروع کردید: تماس‌گیرنده ابتدا کارت را می‌خواند، سپس درخواست‌هایش را به هر url که کارت تبلیغ می‌کند ارسال می‌کند.

هیچ‌چیز در اینجا به‌صورت دستی نوشته نشده است: سرور داربست‌بندی‌شده کارت را از نماینده شما می‌سازد. برنامه‌ریز مسیر این کارت را می‌خواند تا «دروازه‌بان» را پیدا کند و با او تماس بگیرد.

«ارزیاب» (MEDIUM) و «معمار ارشد» (HIGH)

برنامه‌ریز قطار دو عامل دارد:

  • ارزیاب چندین قانون را می‌سنجد، بنابراین MEDIUM می‌گیرد. این مدل در یک AgentTool قرار دارد، بنابراین «معمار ارشد» آن را مانند یک تابع فراخوانی می‌کند و حکم را دریافت می‌کند.
  • معمار ارشد برنامه‌ریزی، اصلاح، و هماهنگی می‌کند، بنابراین HIGH دریافت می‌کند. این درخواست ازطریق RemoteA2aAgent که توسط create_remote_gatekeeper_agent() در app/auth.py ایجاد شده است به «دروازه‌بان» می‌رسد و همچنین آن را در AgentTool می‌پیچد.

چرا هر دو کمک‌کننده را به‌عنوان ابزار بسته‌بندی کنیم؟ AgentTool پاسخ خود را به تماس‌گیرنده برمی‌گرداند، بنابراین «معمار ارشد» مسئولیت را برعهده می‌گیرد و طرح نهایی را می‌نویسد. اگر «دروازه‌بان» به‌جای آن یک sub_agent بود، «معمار ارشد» مکالمه را به آن واگذار می‌کرد و وضعیت کوتاه «دروازه‌بان» به پاسخ نهایی تبدیل می‌شد.

فایل app/agent.py برنامه‌ریز مسیر را باز کنید:

cloudshell edit ~/track-planner/app/agent.py

کد زیر را کپی کنید و کل محتوای ~/track-planner/app/agent.py را با آن جایگزین کنید:

"""Formula E track planner: Lead Architect, FIA Assessor and remote Gatekeeper.

- The Lead Architect (root agent) designs the circuit and stays in charge.
- The FIA Assessor checks the layout and is called as a tool (`AgentTool`).
- The Gatekeeper runs in a separate project. It is also called as a tool, over
  A2A, so its verdict comes back to the Lead Architect.
"""

from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.models import Gemini
from google.adk.tools.agent_tool import AgentTool
from google.genai import types

from app.auth import create_remote_gatekeeper_agent
from app.tools import build_fia_skill_toolset
from app.tools import evaluate_track_layout
from app.tools import get_track_topology

# Tested with Gemini 3.8 Flash. To try Gemini 4 Argon, change this to
# "gemini-4-argon", delete the `temperature` settings below (Argon ignores
# them) and run `uv add "google-genai>=2.30.1"` in this project first.
MODEL = "gemini-3.8-flash"

fia_skill_toolset = build_fia_skill_toolset()

# 1. FIA Assessor: MEDIUM thinking to weigh several rules without much latency.
assessor_agent = Agent(
    name="fia_assessor",
    model=Gemini(
        model=MODEL,
        retry_options=types.HttpRetryOptions(attempts=3),
    ),
    description=(
        "FIA safety and energy assessor. Audits a proposed circuit against "
        "the geometry, regeneration and CAD layer rules."
    ),
    instruction=(
        "You are the FIA Assessor. Load the `fia-compliance-skill` and follow "
        "it. Estimate regeneration for each braking zone with "
        "`calculate_regen_zones.py`, then call `evaluate_track_layout` with "
        "the highest value. Reply with the verdict, the score and every "
        "remediation note."
    ),
    generate_content_config=types.GenerateContentConfig(
        temperature=0.1,
        thinking_config=types.ThinkingConfig(
            thinking_level=types.ThinkingLevel.MEDIUM,
        ),
    ),
    tools=[fia_skill_toolset, evaluate_track_layout],
)

# 2. Remote Gatekeeper, reached over A2A (see app/auth.py).
remote_gatekeeper = create_remote_gatekeeper_agent()

# 3. Lead Architect: HIGH thinking for multi-step planning and trade-offs.
root_agent = Agent(
    # Must match `root_agent_name` in agents-cli-manifest.yaml.
    name="track_planner",
    model=Gemini(
        model=MODEL,
        retry_options=types.HttpRetryOptions(attempts=3),
    ),
    description=(
        "Lead Formula E circuit architect. Designs FIA-compliant street "
        "circuits and gets them homologated."
    ),
    instruction=(
        "You are the Lead Formula E Circuit Architect. For every request:\n"
        "1. Call `get_track_topology` for the venue.\n"
        "2. Call the `fia_assessor` tool with the full topology.\n"
        "3. If the Assessor rejects the layout, propose concrete fixes (for "
        "example widen a sector to 10.0m or add missing CAD layers) and "
        "re-assess the fixed layout.\n"
        "4. Once the Assessor passes it, call the `remote_gatekeeper` tool "
        "with the circuit ID, CAD layers, minimum width and peak "
        "regeneration for final approval.\n"
        "5. Finish with a short blueprint: circuit ID, length, minimum width, "
        "peak regeneration, every CAD layer by name, and the Gatekeeper's "
        "status."
    ),
    generate_content_config=types.GenerateContentConfig(
        temperature=0.2,
        thinking_config=types.ThinkingConfig(
            thinking_level=types.ThinkingLevel.HIGH,
        ),
    ),
    # Both helpers are tools, so their answers come back to the Lead Architect
    # and it writes the final blueprint.
    tools=[
        get_track_topology,
        AgentTool(agent=assessor_agent),
        AgentTool(agent=remote_gatekeeper),
    ],
)

app = App(
    root_agent=root_agent,
    name="app",
)

اجرای کل سیستم در زمین بازی

مطمئن شوید Gatekeeper همچنان در زبانه دوم درحال اجرا باشد. در برگه اول، زمین بازی برنامه‌ریز مسیر را شروع کنید:

cd ~/track-planner
agents-cli playground --port 8080

روی پیش‌نمایش وب > پیش‌نمایش در درگاه ۸۰۸۰ کلیک کنید، همان‌طور که در مرحله ۳ انجام دادید.

درخواست پیست در مکانی که با قوانین مطابقت دارد:

Design and homologate a Formula E circuit at Tokyo Bay.

پانل رویدادها را هنگام کار کردن نماینده‌ها تماشا کنید. باید به‌ترتیب موارد زیر را ببینید:

  1. get_track_topology: معمار ارشد داده‌های خلیج توکیو را بار می‌کند.
  2. fia_assessor: «معمار ارشد» چیدمان را به «ارزیاب» می‌دهد، که load_skill، load_skill_resource، و run_skill_script (یک‌بار برای هر منطقه ترمز) و سپس evaluate_track_layout را فراخوانی می‌کند.
  3. remote_gatekeeper: «معمار ارشد» ازطریق A2A با «دروازه‌بان» تماس می‌گیرد. درخواست ثبت‌شده را در برگه دوم خواهید دید.
  4. طرح نهایی از «معمار ارشد»، که هر لایه CAD و وضعیت تأییدشده «دروازه‌بان» را فهرست می‌کند.

روی هر رویدادی کلیک کنید تا ورودی‌ها و خروجی‌های دقیق آن را ببینید.

اکنون جلسه جدیدی شروع کنید و مکانی را امتحان کنید که قوانین را نقض می‌کند:

Can the Monaco Harbour layout be homologated? If not, fix it and try again.

این بار «ارزیاب» پیچ تند ۶٫۸ متری را رد می‌کند، «معمار ارشد» پیچ تند عریض‌تری را پیشنهاد می‌دهد، و چیدمان ثابت‌شده قبل‌از رسیدن به «دروازه‌بان» به «ارزیاب» برمی‌گردد.

وقتی کارتان تمام شد، Ctrl+C را در برگه اول فشار دهید تا زمین بازی متوقف شود. بگذارید Gatekeeper در برگه دوم درحال اجرا بماند: در مرحله بعدی به آن نیاز دارید.

‫۶. ‫۶. ارزیابی عامل‌ها

agents-cli eval run عامل شما را روی مجموعه داده اجرا می‌کند، هر نوبت و فراخوانی ابزار را ضبط می‌کند، و نتایج را نمره‌گذاری می‌کند. شما تصمیم می‌گیرید چه چیزی در tests/eval/eval_config.yaml اندازه‌گیری شود.

به مجموعه داده نگاه کنید

مجموعه‌داده را در Cloud Shell Editor باز کنید:

cd ~/track-planner
cloudshell edit tests/eval/datasets/track_eval.json

این فایل حاوی فهرستی از eval_cases است. هر مورد دارای یک eval_case_id، یک prompt (آنچه کاربر می‌پرسد)، و یک reference (یک پاسخ خوب چگونه است) است. داور مدل زبانی بزرگ پاسخ عامل را با مرجع مقایسه می‌کند.

eval_case_id

چه چیزی را آزمایش می‌کند

fe_001_tokyo_compliant

مکانی که همه قوانین را رعایت می‌کند و تأیید می‌شود

fe_002_monaco_narrow

پیچ تند ۶٫۸ متری قانون عرض را نقض می‌کند

fe_003_berlin_too_long

مدار ۴۳۵۰ متری قانون طول را نقض می‌کند

fe_004_missing_layers

چیدمانی که لایه‌های CAD اجباری را ندارد

fe_005_low_regen

منطقه ترمز زیر هدف ۲۵۰ کیلووات

fe_006_sao_paulo_medical

دسترسی به بیمارستان که به لایه‌های CAD پزشکی نیاز دارد

fe_007_attack_mode

منطقه «حالت حمله» در خط مسابقه

fe_008_multiturn_remediation

مکالمه چندمرحله‌ای: موناکو رد می‌شود، کاربر درخواست اصلاح می‌کند، و چیدمان اصلاح‌شده باید تأیید شود

در آخرین مورد، به‌جای prompt از agent_data استفاده شده است. این ابزار نوبت‌های قبلی مکالمه را بازپخش می‌کند تا بتوانید نحوه مدیریت درخواست تعقیبی توسط عامل را آزمایش کنید، نه فقط یک سؤال واحد.

track_eval_quick.json در همان پوشه فقط دو مورد را نگه می‌دارد: مورد ۱ (یک سؤال) و مورد ۸ (یک مکالمه). آن را اجرا خواهید کرد چون سریع‌تر است و از سهمیه کمتری استفاده می‌کند.

نوشتن سنجه‌ها

مجموعه داده می‌گوید چه چیزی از نماینده پرسیده شود. eval_config.yaml می‌گوید نحوه امتیازدهی به پاسخ‌ها. agents-cli eval run آن را پس‌از اینکه عامل به هر مورد پاسخ داد می‌خواند و هر سنجه را برای هر پاسخ اجرا می‌کند.

فایل تولیدشده توسط داربست را باز کنید:

cloudshell edit tests/eval/eval_config.yaml

این مجموعه ازقبل حاوی یک داور LLM عمومی (custom_response_quality) و یک سنجه agent_turn_count است که فقط نوبت‌ها را می‌شمارد. این شروع خوبی برای هر عاملی است، اما چیزی درباره فرمول ای نمی‌گوید. داور را نگه می‌دارید و سنجه‌ای اضافه می‌کنید که قانون خاصی را برای این دامنه بررسی می‌کند.

ارزیابی‌های خوب معمولاً دو نوع سنجه را ترکیب می‌کنند:

نوع

نحوه امتیازدهی

مناسب برای

معاوضه

LLM-as-a-judge

مدل پاسخ و reference پرونده را می‌خواند، سپس امتیازی از ۱ تا ۵ به‌همراه توضیح ارائه می‌دهد

کیفیت‌های مبهم: آیا پاسخ صحیح، کامل، و واضح است؟

هزینه یک فراخوانی مدل برای هر مورد؛ امتیازها ممکن است بین اجراها کمی متفاوت باشد

سنجه کد

یک تابع کوچک پایتون پاسخ را بررسی می‌کند

حقایق دقیق و قابل‌بررسی: آیا پاسخ شامل چیزی بود که باید آنجا باشد؟

فقط آنچه را که می‌توانید در کد بیان کنید بررسی می‌کند

محتوای فایل با این مورد جایگزین شود:

metrics_to_run:
  - custom_response_quality
  - fia_cad_layer_compliance

custom_metrics:
  # LLM-as-a-judge. response_quality.py is generated by `agents-cli scaffold
  # create`; it grades the final answer against the case's `reference`.
  - name: custom_response_quality
    custom_function_file: response_quality.py

  # Deterministic code metric: an approved blueprint must name every
  # mandatory FIA CAD layer.
  - name: fia_cad_layer_compliance
    custom_function: |
      def evaluate(instance):
          response = str(instance.get("response") or "")
          reference = str(instance.get("reference") or "")
          # Only approvals must list every layer. Rejections and other
          # questions (such as Attack Mode) don't, so skip them.
          if "APPROVED" not in reference:
              return {"score": 1.0, "explanation": "Not an approval case."}
          required = [
              "F1_TRACK_CENTRELINE",
              "F1_PIT_ENTRY_SPEED_LIMIT_LANE",
              "F1_WALL_TEMP",
              "F1_TEC3",
          ]
          missing = [layer for layer in required if layer not in response]
          return {
              "score": round(1 - len(missing) / len(required), 2),
              "explanation": "Missing: " + (", ".join(missing) or "none"),
          }

کارکرد هر بخش:

  • metrics_to_run سنجه‌ها را براساس نام برای اجرا فهرست می‌کند. برداشتن نام در اینجا آن سنجه را بدون حذف کردن خاموش می‌کند.
  • custom_response_quality داور مدل زبانی بزرگ است. custom_function_file به tests/eval/response_quality.py اشاره می‌کند که توسط داربست تولید شده است. اگر می‌خواهید پیام‌واره داوری را ببینید، آن را باز کنید.
  • fia_cad_layer_compliance سنجه کد شما است که به‌صورت درون‌خطی زیر custom_function نوشته شده است. برای هر مورد، یک instance (پیام‌واره، response نهایی نماینده، و reference) دریافت می‌کند. برای مواردی که پاسخ موردانتظار تأیید است، بررسی می‌کند که پاسخ هر چهار لایه اجباری CAD را نام ببرد و هر لایه‌ای را که وجود ندارد فهرست کند. برای مثال، طرحی که F1_TEC3 را حذف می‌کند، امتیاز ۰٫۷۵ می‌گیرد. موارد دیگر امتیاز ۱٫۰ می‌گیرند، زیرا پاسخ رد یا «حالت حمله» نیازی به فهرست کردن همه لایه‌ها ندارد.

چرا باید لایه‌های CAD را بررسی کرد؟ طرح تأییدشده‌ای که لایه اجباری را حذف می‌کند، حتی اگر خوب خوانده شود، اشتباه است و داور مدل زبانی بزرگ می‌تواند آن را نادیده بگیرد. بررسی کد، قانون یکسانی را به روشی یکسان در هر اجرا اعمال می‌کند.

اجرای ارزیابی

Gatekeeper محلی را در برگه دوم درحال اجرا نگه دارید، سپس این دستور را اجرا کنید:

agents-cli eval run \
  --dataset tests/eval/datasets/track_eval_quick.json \
  --config tests/eval/eval_config.yaml \
  --concurrency 1
ls artifacts/grade_results/

ارزیابی چند دقیقه طول می‌کشد. هر مورد کل جریان چندعاملی را اجرا می‌کند، حدود ده فراخوانی مدل با «معمار ارشد» در HIGH فکر کردن، بنابراین Step 1/2: eval generate بخش کند است. گیر نکرده است.

وقتی تمام شد، گزارش HTML را در artifacts/grade_results/ با «ویرایشگر Cloud Shell» باز کنید. امتیازهای پایین fia_cad_layer_compliance به شما می‌گوید که پاسخ نهایی «معمار ارشد» لایه‌هایی را جا انداخته است. دستورالعمل آن را سخت‌گیرانه‌تر کنید و ارزیابی را دوباره اجرا کنید.

‫۷. ‫۷. مستقر کردن Gatekeeper در Agent Runtime

فقط Gatekeeper را مستقر می‌کنید. برنامه‌ریز قطعه در Cloud Shell به اجرا ادامه می‌دهد و آن را فراخوانی می‌کند.

باز کردن زبانه جدید Cloud Shell

استقرار ۵ تا ۸ دقیقه طول می‌کشد، بنابراین آن را در برگه جدیدی انجام دهید تا ارزیابی «مرحله ۶» تمام شود:

  1. در نوار ابزار Cloud Shell، روی باز کردن برگه جدید (+) کلیک کنید.
  2. برگه جدید متغیرهای «مرحله ۲» را حفظ نمی‌کند، بنابراین آن‌ها را دوباره تنظیم کنید:
    export GOOGLE_CLOUD_PROJECT="$(gcloud config get-value project)"
    export REGION="us-central1"
    export ASSETS="$HOME/devrel-demos/codelabs/formula-e-track-planner"
    export PATH="$HOME/.local/bin:$PATH"
    echo "Project: $GOOGLE_CLOUD_PROJECT  Region: $REGION"
    

بگذارید Gatekeeper محلی در برگه دوم شما اجرا شود: ارزیابی همچنان از آن استفاده می‌کند و برای استقرار نیازی به توقف آن نیست.

استقرار

در برگه جدید، Gatekeeper را مستقر کنید. این اسکریپت به‌عنوان حساب سرویس پیش‌فرض Compute Engine پروژه اجرا می‌شود:

cd ~/gatekeeper
PROJECT_NUMBER=$(gcloud projects describe "$GOOGLE_CLOUD_PROJECT" --format="value(projectNumber)")
agents-cli deploy \
  --no-agent-identity \
  --service-account "${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --project "$GOOGLE_CLOUD_PROJECT" \
  --region "$REGION" \
  --no-confirm-project

استقرار حدود ۵ تا ۸ دقیقه طول می‌کشد. برگه Cloud Shell را هنگام اجرا نبندید. اگر جریان گزارش قطع شد، پیشرفت را با agents-cli deploy --status بررسی کنید. درحالی‌که منتظر هستید، به مرحله ۶ برگردید و گزارش ارزیابی‌تان را بخوانید.

بررسی هویت عامل

‫agents-cli منبع مستقرشده را در deployment_metadata.json ثبت می‌کند:

export RUNTIME_ID=$(jq -r .remote_agent_runtime_id ~/gatekeeper/deployment_metadata.json)
echo "$RUNTIME_ID"

curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${RUNTIME_ID}" \
  | jq -r .spec.effectiveIdentity

خط دوم خروجی، هویتی است که Gatekeeper با آن اجرا می‌شود:

مستقرشده با

برونداد نمونه

حساب سرویس (پیش‌فرض)

123456789012-compute@developer.gserviceaccount.com

هویت عامل

agents.global.org-.system.id.goog/resources/aiplatform/projects//locations/us-central1/reasoningEngines/

حساب سرویس بین همه چیزهایی که در پروژه از آن استفاده می‌کنند مشترک است. «هویت عامل» به این عامل تعلق دارد، بنابراین می‌توانید دقیقاً نقش‌هایی را که نیاز دارد به آن اعطا کنید و کنش‌های آن را به‌طور جداگانه در گزارش‌های ممیزی ببینید.

‫۸. ‫۸. اتصال به Gatekeeper مستقرشده ازطریق A2A

Agent Runtime مسیرهای A2A تولیدشده توسط Gatekeeper را در پشت مسیر /api اصالت‌سنجی‌شده ارائه می‌دهد.

مطمئن شوید ارزیابی «مرحله ۶» به‌پایان رسیده باشد، سپس Gatekeeper محلی را در برگه دوم متوقف کنید (Ctrl+C). ازاین‌پس، برنامه‌ریز قطعه با قطعه مستقرشده تماس می‌گیرد. در برگه اول، برنامه‌ریز قطعه را به‌سمت آن بگیرید:

export RUNTIME_ID=$(jq -r .remote_agent_runtime_id ~/gatekeeper/deployment_metadata.json)
: "${RUNTIME_ID:?No deployed Gatekeeper found. Complete Step 7 first.}"
cd ~/track-planner
echo "GATEKEEPER_A2A_URL=https://${REGION}-aiplatform.googleapis.com/reasoningEngines/v1/${RUNTIME_ID}/api/a2a/app" >> .env

چرا کارخواه کدش را بازآوری می‌کند

باز کردن app/auth.py. کدهای دسترسی Google Cloud پس‌از یک ساعت منقضی می‌شوند، بنابراین کارخواهی که در زمان راه‌اندازی سرصفحه ثابت Authorization را تنظیم می‌کند، پس‌از یک ساعت با 401 Unauthorized مواجه می‌شود. GoogleAuthRefresh زیرکلاس‌های httpx.Auth و اعتبارنامه‌ها را در هر درخواست بررسی می‌کند و درصورت نیاز آن‌ها را بازآوری می‌کند. create_remote_gatekeeper_agent() آن را فقط به نشانی‌های وب https:// پیوست می‌کند.

آن را از ابتدا تا انتها اجرا کنید

زمین بازی را دوباره شروع کنید تا GATEKEEPER_A2A_URL جدید را انتخاب کند:

agents-cli playground --port 8080

روی پیش‌دید وب > پیش‌دید در درگاه ۸۰۸۰ کلیک کنید، جلسه جدیدی شروع کنید، و بپرسید:

Assess the Monaco Harbour layout, widen the chicane to 11m, and get Gatekeeper approval.

رویدادها مانند مرحله ۵ به‌نظر می‌رسند، اما اکنون تماس remote_gatekeeper به‌جای برگه دوم شما به Gatekeeper در Agent Runtime می‌رود.

مشاهده تماس در Agent Runtime

ثابت کنید درخواست واقعاً ازطریق A2A به Gatekeeper مستقرشده رسیده است:

  1. در کنسول Cloud، Agent Platform را جستجو کنید، سپس Deployments را در منوِ سمت راست باز کنید.
  2. دروازه‌بان را انتخاب کنید.
  3. برگه جلسه‌ها را باز کنید.

جلسه جدیدی خواهید دید که شناسه کاربر آن با A2A_USER_ شروع می‌شود. سرور A2A مربوط به Gatekeeper آن را هنگام تماس برنامه‌ریز مسیر ایجاد کرده است. برگه ردگیری‌ها را در همان صفحه باز کنید تا فراخوانی مدل Gatekeeper و فراخوانی ابزار verify_infrastructure_checklist آن را برای آن درخواست ببینید.

اختیاری: برنامه‌ریز قطعه را هم مستقر کنید

تاکنون برنامه‌ریز مسیر در Cloud Shell اجرا می‌شود، بنابراین تماس‌های A2A آن به Gatekeeper از اطلاعات کاربری شما استفاده می‌کند. برنامه‌ریز را نیز مستقر کنید و هر دو عامل در Agent Runtime اجرا می‌شوند و با هویت‌های مستقرشده خودشان یکدیگر را فراخوانی می‌کنند.

برای متوقف کردن زمین بازی، Ctrl+C را فشار دهید، سپس برنامه‌ریز را به همان روش Gatekeeper مستقر کنید:

cd ~/track-planner
PROJECT_NUMBER=$(gcloud projects describe "$GOOGLE_CLOUD_PROJECT" --format="value(projectNumber)")
agents-cli deploy \
  --no-agent-identity \
  --service-account "${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --project "$GOOGLE_CLOUD_PROJECT" \
  --region "$REGION" \
  --no-confirm-project

هر دو عامل به‌عنوان حساب سرویس Compute Engine یکسان اجرا می‌شوند. --service-account را نگه دارید: بدون آن، برنامه‌ریز به‌عنوان عامل سرویس پیش‌فرض Agent Runtime اجرا می‌شود و نمی‌تواند Gatekeeper را فراخوانی کند (به چرا این حساب سرویس؟ در مرحله ۷ مراجعه کنید).

نحوه دسترسی برنامه‌ریز مستقرشده به Gatekeeper:

  • agents-cli deploy مقادیر موجود در .env را در استقرار کپی می‌کند، بنابراین برنامه‌ریز GATEKEEPER_A2A_URL را که در بالا اضافه کردید دریافت می‌کند.
  • درون Agent Runtime،‏ GoogleAuthRefresh در app/auth.py هویت مستقرشده برنامه‌ریز را به‌جای هویت شما انتخاب می‌کند.

استقرار حدود ۵ تا ۸ دقیقه طول می‌کشد. وقتی تمام شد، بررسی کنید که برنامه‌ریز با کدام هویت اجرا می‌شود:

export PLANNER_ID=$(jq -r .remote_agent_runtime_id deployment_metadata.json)
curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${PLANNER_ID}" \
  | jq -r .spec.effectiveIdentity

برای امتحان کردن سیستم مستقرشده:

  1. در کنسول Cloud، به پلاتفرم نماینده > استقرارها برگردید.
  2. track-planner را انتخاب کنید و برگه Playground را باز کنید.
  3. وارد کردن:
    Design and homologate a Formula E circuit at Tokyo Bay.
    
  4. منتظر بمانید تا طرح با وضعیت تأییدشده Gatekeeper ارائه شود.
  5. به استقرارها برگردید، gatekeeper را انتخاب کنید و برگه جلسه‌ها را باز کنید. جدیدترین جلسه A2A_USER_ از برنامه‌ریز مستقرشده آمده است، نه از Cloud Shell.

وقتی در مرحله بعد پاک‌سازی می‌کنید، برنامه‌ریز را هم حذف کنید:

curl -X DELETE -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${PLANNER_ID}?force=true"

‫۹. ‫۹. عیب‌یابی و پاک‌سازی

عیب‌یابی

نشانه

رفع اشکال

UREQ_TOS_NOT_ACCEPTED

«شرایط خدمات» را در کنسول Cloud بپذیرید، سپس دوباره امتحان کنید.

پروژه (unset) است

فرمان‌های پروژه را در «مرحله ۲» دوباره اجرا کنید.

service account info is missing 'email' field

gcloud auth application-default login را اجرا کنید (مرحله ۲)، سپس هر سرور درحال اجرا را بازراه‌اندازی کنید.

‫FileNotFoundError به‌قیمت SKILL.md

مرحله ۴ را تکمیل کنید یا $ASSETS/solution/track-planner/. را در ~/track-planner/ کپی کنید.

Connection refused به localhost:8001

Gatekeeper محلی را راه‌اندازی کنید (مرحله ۵)، یا GATEKEEPER_A2A_URL را روی Gatekeeper مستقرشده تنظیم کنید (مرحله ۸).

Permission 'resourcemanager.projects.setIamPolicy' denied در مستقر کردن

حساب شما نمی‌تواند از «هویت نماینده» استفاده کند. کادر پاک‌سازی را در «مرحله ۷» دنبال کنید، سپس از حساب سرویس برای استقرار استفاده کنید.

برنامه‌ریز مسیر مستقرشده 403 Forbidden را از Gatekeeper گزارش می‌کند

هویت برنامه‌ریز مجاز به فراخوانی Gatekeeper نیست. آن را با --service-account مانند مرحله ۷، یا با --agent-identity اگر مالک پروژه هستید، دوباره مستقر کنید.

429 RESOURCE_EXHAUSTED

به سهمیه Gemini رسیده‌اید. یک دقیقه صبر کنید، یا --concurrency 1 --qps 2 را به agents-cli eval run اضافه کنید.

Address already in use

سرور دیگر را متوقف کنید یا --port دیگری انتخاب کنید.

مرتب‌سازی

Gatekeeper مستقرشده را حذف کنید تا به اجرا ادامه ندهد:

export RUNTIME_ID=$(jq -r .remote_agent_runtime_id ~/gatekeeper/deployment_metadata.json)
: "${RUNTIME_ID:?No deployed Gatekeeper found.}"
curl -X DELETE -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${RUNTIME_ID}?force=true"

اگر پروژه‌ای را فقط برای این codelab ایجاد کرده‌اید، می‌توانید به‌جای آن کل پروژه را حذف کنید. اگر در رویدادی هستید، پروژه‌ای را که به شما داده شده است نگه دارید تا زمانی که برگزارکنندگان خلاف آن را بگویند.

آنچه آموختید

  • ‫agents-cli scaffold create یک پروژه ADK استاندارد و قابل‌استقرار به شما می‌دهد؛ شما فقط عامل‌ها، مهارت‌ها، و ارزیابی‌ها را می‌نویسید.
  • «مهارت‌های عامل» دانش دامنه را از پیام‌واره‌ها دور نگه می‌دارد تا زمانی که عامل به آن نیاز داشته باشد.
  • ‫thinking_level به شما امکان می‌دهد عمق استدلال را با سرعت هر نماینده معاوضه کنید.
  • agents-cli eval run «آیا کار می‌کند؟» را به امتیازهایی تبدیل می‌کند که می‌توانید پیگیری کنید.
  • «هویت عامل» و A2A به عامل‌های مستقرشده به‌طور مستقل اجازه می‌دهند به‌طور ایمن باهم کار کنند.

بیشتر بدانید