1. Tổng quan
Trong lớp học lập trình này, bạn sẽ xây dựng AI Creative Studio – một hệ thống nhiều tác nhân phân tán, biến một câu lệnh duy nhất thành một chiến dịch hoàn chỉnh trên Instagram.
Nhập một câu. Nhận lại thông tin nghiên cứu về khán giả, phụ đề, ý tưởng về hình ảnh, bản sao đã được đánh giá chất lượng và toàn bộ tiến trình dự án – tất cả đều do một nhóm các tác nhân AI cộng tác tạo ra.
Các tác nhân mà bạn sẽ tạo
Nhân viên hỗ trợ | Vai trò |
Người lập chiến lược cho thương hiệu | Tìm kiếm thông tin chi tiết về đối tượng, phân tích đối thủ cạnh tranh và xu hướng năm 2025 trên web |
Nhân viên viết quảng cáo | Viết chú thích cho Instagram kèm hashtag và lời kêu gọi hành động – dựa trên một Kỹ năng ADK tải các nguyên tắc của nền tảng và công thức chú thích theo yêu cầu |
Nhà thiết kế | Tạo ý tưởng trực quan và tạo hình ảnh thực tế thông qua Gemini, được lưu trữ trong GCS |
Nhà phê bình | Bản sao và hình ảnh của bài đánh giá – trả về |
Quản lý dự án | Xây dựng dòng thời gian của dự án và bảng phân tích công việc, có thể đồng bộ hoá với Notion thông qua MCP |
Giám đốc sáng tạo | Điều phối cả 5 chuyên gia theo trình tự – bạn đưa ra một câu lệnh, Gemini sẽ điều phối những câu lệnh còn lại |
5 tác nhân này được triển khai dưới dạng các vi dịch vụ Cloud Run độc lập. Các tác nhân này giao tiếp qua giao thức A2A – một tiêu chuẩn mở không phụ thuộc vào ngôn ngữ, nhờ đó mọi tác nhân đều có thể gọi bất kỳ tác nhân nào khác bất kể khung. Creative Director chạy trên Agent Runtime và kết nối từ xa với từng chuyên gia.
Kiến trúc

Kiến thức bạn sẽ học được
- Xây dựng các tác nhân LLM bằng Google ADK –
Agent, hướng dẫn hệ thống và các công cụ tích hợp. - Đóng gói kiến thức có thể tái sử dụng của tác nhân vào các tệp theo mô-đun bằng ADK Skills (
SkillToolset). - Tạo hình ảnh thực bằng cách kết nối một tác nhân văn bản với một mô hình hình ảnh thông qua
FunctionTool. - Tích hợp các API bên ngoài mà không cần mã kết dính tuỳ chỉnh bằng cách sử dụng Giao thức ngữ cảnh mô hình (MCP).
- Biến mọi tác nhân thành một dịch vụ có thể gọi qua mạng bằng Giao thức tác nhân với tác nhân (A2A) qua HTTPS.
- Điều phối các tác nhân phân tán bằng
RemoteA2aAgentvàAgentTool. - Đóng gói và triển khai các tác nhân độc lập dưới dạng các vi dịch vụ Cloud Run.
- Lưu trữ một trình điều phối có trạng thái trên Thời gian chạy tác nhân.
- Giữ các quy trình làm việc dài có nhiều tác nhân trong giới hạn ngữ cảnh bằng cách sử dụng tính năng nén ngữ cảnh.
- Xây dựng vòng lặp kiểm soát chất lượng: Kết quả đánh giá của người kiểm tra → tự động sửa đổi khi cần.
Bạn cần có
- Một dự án trên Google Cloud đã bật tính năng thanh toán
- Vai trò Chủ sở hữu hoặc Người chỉnh sửa IAM
- Kiến thức cơ bản về Python
2. Thiết lập môi trường
Trong lớp học lập trình này, chúng ta sẽ sử dụng Cloud Shell.
Cloud Shell là gì?
Cloud Shell là một môi trường Linux miễn phí dựa trên trình duyệt, có sẵn mọi thứ: gcloud, git, Python, Docker và nhiều thứ khác. Bạn không cần cài đặt bất cứ thứ gì trên máy.
Để mở Cloud Shell, hãy nhấp vào biểu tượng thiết bị đầu cuối trong thanh công cụ trên cùng bên phải của Bảng điều khiển GCP:

Khi mở Cloud Shell lần đầu tiên, bạn sẽ được nhắc xác minh tài khoản của mình. Hãy nhấp vào Xác minh:

Sau đó, nhấp vào Uỷ quyền để cho phép Cloud Shell thực hiện các lệnh gọi API Google Cloud:

Cloud Shell hiện đã sẵn sàng. Bạn sẽ thấy một thông báo chào mừng trong thiết bị đầu cuối: 
Xác thực và định cấu hình dự án
Cloud Shell đã được xác thực bằng Tài khoản Google của bạn. Xác nhận tài khoản đang hoạt động và tìm mã dự án:
gcloud config list
Bạn cũng có thể xem Mã dự án trong bảng điều khiển GCP ở bảng điều khiển bên trái. Sao chép đường dẫn này vì bạn sẽ cần dùng trong lệnh tiếp theo:

Bây giờ, hãy thiết lập dự án của bạn:
export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-central1" # Cloud Run deployment region
echo "Project: $PROJECT_ID"
Kết quả đầu ra dự kiến:
Project: my-project-123
Bật các API bắt buộc
gcloud services enable \
aiplatform.googleapis.com \
apphub.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
generativelanguage.googleapis.com \
iam.googleapis.com \
cloudresourcemanager.googleapis.com \
storage.googleapis.com \
secretmanager.googleapis.com
Quá trình này mất khoảng 2 phút. Bạn sẽ thấy biểu tượng Operation finished successfully khi quá trình này hoàn tất.
Thiết lập thông tin xác thực mặc định của ứng dụng (ADC)
Các tác nhân sẽ gọi Nền tảng tác nhân Gemini Enterprise bằng thư viện Google Auth. Thư viện này yêu cầu Thông tin xác thực mặc định của ứng dụng (khác với xác thực gcloud CLI).
Chạy lệnh này một lần:
gcloud auth application-default login
Một thẻ trình duyệt sẽ mở ra và yêu cầu bạn xác nhận. Nhấp vào Cho phép. Bạn sẽ thấy:
Credentials saved to file: ~/.config/gcloud/application_default_credentials.json
Sao chép kho lưu trữ khởi đầu
Lớp học lập trình này sử dụng một kho lưu trữ khởi đầu – một dự án khung với tất cả cơ sở hạ tầng tại chỗ (tệp Docker, pyproject.toml, tập lệnh triển khai) nhưng logic tác nhân thì bạn phải tự viết.
git clone https://github.com/Saoussen-CH/mas-a2a-gcp.git ~/ai-creative-studio
cd ~/ai-creative-studio/workshop/starter
Mỗi agent.py chứa các phần giữ chỗ # TODO, nơi bạn sẽ viết logic của tác nhân. Tập lệnh Dockerfile, pyproject.toml và tập lệnh triển khai đã hoàn tất.
Định cấu hình các biến môi trường
Sao chép ví dụ được cung cấp và chèn mã dự án của bạn trong một bước:
cp .env.example .env
sed -i "s|GOOGLE_CLOUD_PROJECT=your-project-id|GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)|" .env
Sau đó, hãy tạo vùng lưu trữ GCS nơi Designer sẽ lưu trữ hình ảnh được tạo và cập nhật .env bằng tên của vùng lưu trữ đó:
export PROJECT_ID=$(gcloud config get-value project)
export BUCKET_NAME="${PROJECT_ID}-campaign-images"
gcloud storage buckets create gs://${BUCKET_NAME} \
--location=us-central1 \
--project=${PROJECT_ID}
sed -i "s|GCS_IMAGES_BUCKET=your-project-id-campaign-images|GCS_IMAGES_BUCKET=${BUCKET_NAME}|" .env
Sau đó, hãy thiết lập chế độ hỗ trợ URL hình ảnh đã ký. Giám đốc sáng tạo tạo ra các đường liên kết HTTPS có thể nhấp cho từng hình ảnh trong bản tóm tắt chiến dịch cuối cùng. Việc này yêu cầu tài khoản dịch vụ ký các URL. Hãy chạy những lệnh này để định cấu hình tài khoản dịch vụ:
export PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)")
export SA_EMAIL="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
export AGENT_RUNTIME_SA="service-${PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
# Allow your user account to sign URLs locally (adk web)
gcloud iam service-accounts add-iam-policy-binding ${SA_EMAIL} \
--member="user:$(gcloud config get-value account)" \
--role="roles/iam.serviceAccountTokenCreator"
# Allow Agent Runtime to sign URLs when deployed
gcloud projects add-iam-policy-binding $(gcloud config get-value project) \
--member="serviceAccount:${AGENT_RUNTIME_SA}" \
--role="roles/iam.serviceAccountTokenCreator"
# Save SA email and project number to .env
grep -q "^SIGNING_SERVICE_ACCOUNT" .env \
&& sed -i "s|^SIGNING_SERVICE_ACCOUNT=.*|SIGNING_SERVICE_ACCOUNT=${SA_EMAIL}|" .env \
|| echo "SIGNING_SERVICE_ACCOUNT=${SA_EMAIL}" >> .env
grep -q "^GOOGLE_CLOUD_PROJECT_NUMBER" .env \
&& sed -i "s|^GOOGLE_CLOUD_PROJECT_NUMBER=.*|GOOGLE_CLOUD_PROJECT_NUMBER=${PROJECT_NUMBER}|" .env \
|| echo "GOOGLE_CLOUD_PROJECT_NUMBER=${PROJECT_NUMBER}" >> .env
Mở .env trong trình chỉnh sửa để xem tất cả chế độ cài đặt:
cloudshell edit .env
Thao tác này sẽ mở .env dưới dạng một thẻ trong Cloud Shell Editor – hãy nhấp vào nút Open Editor (Mở trình chỉnh sửa) trong thanh công cụ nếu bảng điều khiển trình chỉnh sửa không xuất hiện:


Xác nhận rằng bạn đã đặt dự án đúng cách:
grep GOOGLE_CLOUD_PROJECT .env
Cài đặt các phần phụ thuộc
Chúng tôi sử dụng uv – một trình quản lý gói Python hiện đại, nhanh chóng, xử lý môi trường ảo và cài đặt trong một công cụ duy nhất. Nó nhanh hơn pip từ 10 đến 100 lần và là cách nên dùng để quản lý các dự án Python.
Cloud Shell đã cài đặt uv. Tất cả các tác nhân đều có cùng các phần phụ thuộc cốt lõi, vì vậy, bạn chỉ cần cài đặt một lần và nó sẽ hoạt động cho mọi tác nhân trong lớp học lập trình này:
uv sync
Lệnh uv sync đọc pyproject.toml và tạo một thư mục .venv/ có tất cả các phần phụ thuộc. Mỗi chuyên gia cũng có pyproject.toml riêng chỉ được dùng cho các bản dựng Docker – bản cài đặt dùng chung ở trên bao gồm mọi thứ bạn cần để kiểm thử cục bộ.
3. Tìm hiểu về ADK của Google
Trước khi viết mã, hãy tìm hiểu về Bộ công cụ phát triển tác nhân (ADK) – khung mà bạn sẽ dùng để tạo mọi tác nhân trong lớp học lập trình này.
ADK là gì?
Bộ công cụ phát triển tác nhân (ADK) là một khung linh hoạt và mô-đun để phát triển và triển khai các tác nhân AI. Mặc dù được tối ưu hoá cho Gemini và hệ sinh thái của Google, nhưng ADK không phụ thuộc vào mô hình, không phụ thuộc vào việc triển khai và được xây dựng để tương thích với các khung khác. ADK được thiết kế để giúp quá trình phát triển tác nhân giống với quá trình phát triển phần mềm hơn, giúp nhà phát triển dễ dàng tạo, triển khai và điều phối các cấu trúc tác nhân từ các tác vụ đơn giản đến các quy trình công việc phức tạp.
ADK xử lý các phần phức tạp – lệnh gọi công cụ, cuộc trò chuyện nhiều lượt, quản lý ngữ cảnh, truyền phát trực tiếp – để bạn có thể tập trung vào logic của tác nhân.
Các thành phần của một tác nhân ADK
Mỗi tác nhân bao gồm 4 khối xây dựng:
Chặn | Vai trò |
Mô hình | LLM suy luận về các mục tiêu, xác định kế hoạch và tạo câu trả lời |
Công cụ | Các hàm tìm nạp dữ liệu hoặc thực hiện các thao tác bằng cách gọi API hoặc dịch vụ |
Điều phối | Duy trì bộ nhớ và trạng thái trên các lượt, định tuyến lệnh gọi công cụ, truyền kết quả trở lại mô hình |
Thời gian chạy | Thực thi hệ thống khi được gọi – cục bộ thông qua |
Định nghĩa về tác nhân
Mỗi tác nhân trong số 5 tác nhân trong lớp học lập trình này được xác định theo cùng một cách:
from google.adk.agents import Agent
from google.adk.tools.google_search_tool import google_search
root_agent = Agent(
name="brand_strategist", # unique identifier
model=os.getenv("GEMINI_MODEL", "gemini-2.5-flash"), # the LLM powering this agent
instruction=SYSTEM_INSTRUCTION, # the agent's persona, constraints, and output format
description="Brand strategist for market research, trend analysis, and competitive insights",
tools=[google_search], # functions the LLM can call
)
Trường | Mục đích |
| Mã nhận dạng duy nhất – được trình điều phối dùng để định tuyến các lệnh gọi |
| Mô hình Gemini hỗ trợ tác nhân này |
| Câu lệnh hệ thống – xác định vai trò, các ràng buộc và định dạng đầu ra của tác nhân |
| Tóm tắt trong một dòng – điều phối viên đọc thông tin này để quyết định gọi cho chuyên gia nào |
| Các hàm mà LLM có thể gọi (tích hợp sẵn như |
Cách ADK chạy một tác nhân
User message
│
▼
Agent (LLM) ← reads instruction + conversation history
│
├─► needs more info? → calls a tool → gets result → continues reasoning
│
└─► done reasoning → returns final text response
LLM tự quyết định xem có gọi một công cụ hay không, công cụ nào và với những đối số nào. Bạn viết chỉ dẫn – ADK sẽ xử lý phần còn lại.
4. Tạo và kiểm thử tác nhân Nhà chiến lược thương hiệu
Hãy bắt đầu với tác nhân đầu tiên: Nhà chiến lược thương hiệu. Đây là một trợ lý chỉ dùng để nghiên cứu nhằm tìm kiếm thông tin chi tiết về đối tượng mục tiêu, phân tích đối thủ cạnh tranh và các chủ đề thịnh hành bằng Google Tìm kiếm.
Mở tệp tác nhân khung trong Trình chỉnh sửa Cloud Shell:
cloudshell edit agents/brand_strategist/agent.py
Bạn sẽ thấy 2 phần # TODO để điền thông tin.
TODO 1 – Viết chỉ dẫn cho hệ thống
Trước tiên, bạn sẽ viết chỉ dẫn hệ thống cho tác nhân. Hướng dẫn hệ thống là một chuỗi xác định vai trò, các ràng buộc và định dạng đầu ra của tác nhân.
SYSTEM_INSTRUCTION = f"""You are a Brand Strategist specializing in market research and trend analysis.
IMPORTANT: Today's date is {datetime.date.today().strftime("%B %d, %Y")}.
When conducting research, focus on current trends from {datetime.date.today().year}.
Use search queries like "[topic] trends {datetime.date.today().year}" for recent insights.
IMPORTANT: Your role is RESEARCH ONLY. You do NOT create campaign content, captions, or designs.
After providing research insights, your work is complete.
Your expertise:
- Identifying target audience insights and behaviors
- Analyzing competitor strategies
- Researching current social media trends
- Understanding platform algorithms and best practices
You have access to:
- google_search: Search the web for competitors, trends, and market insights
When given a campaign brief:
1. Use google_search to research the target audience's current interests
2. Search for and analyze 2-3 competitor brands
3. Identify 3-5 trending topics related to the product category
4. Provide high-level strategic insights - NOT specific campaign content
DO NOT create captions, copy, designs, or any campaign content.
Format your output as:
**Audience Insights:**
[Key behaviors and preferences based on research]
**Competitive Analysis:**
[What 2-3 competitors are doing - strengths and weaknesses]
**Trending Topics:**
[3-5 relevant trends to consider]
**Key Strategic Insights:**
[High-level themes and positioning opportunities]
"""
TODO 2 – Tạo root_agent
Tiếp theo, hãy thay thế root_agent chưa hoàn chỉnh bằng:
root_agent = Agent(
name="brand_strategist",
model=os.getenv("GEMINI_MODEL", "gemini-2.5-flash"),
instruction=SYSTEM_INSTRUCTION,
description="Brand strategist for market research, trend analysis, and competitive insights",
tools=[google_search],
)
Kiểm thử cục bộ bằng giao diện người dùng web ADK
Bây giờ, hãy kiểm thử tác nhân bằng giao diện người dùng web ADK – một giao diện trò chuyện tích hợp để kiểm thử tác nhân trước khi triển khai lên đám mây.
uv run adk web agents --allow_origins='*'
Bạn sẽ thấy:
INFO: Started server process
INFO: Uvicorn running on http://localhost:8000
Máy chủ hiện đang chạy trong Cloud Shell:
Để mở tệp này trong trình duyệt, hãy sử dụng tính năng Xem trước trên web:
- Xem thanh công cụ Cloud Shell ở đầu trang
- Nhấp vào biểu tượng Xem trước trên web (có dạng một hộp có mũi tên hướng lên trên, ở trên cùng bên phải của thanh công cụ Cloud Shell)
- Nhấp vào "Thay đổi cổng" rồi nhập
8000, sau đó nhấp vào "Thay đổi và xem trước"
Một thẻ trình duyệt mới sẽ mở ra cùng với giao diện người dùng web ADK. Nhấp vào trình đơn thả xuống "Chọn một nhân viên hỗ trợ" ở trên cùng bên trái – bạn sẽ thấy danh sách tất cả nhân viên hỗ trợ của mình:
Chọn brand_strategist để bắt đầu kiểm thử:
Hãy thử những câu lệnh kiểm thử sau
Trong hộp trò chuyện của giao diện người dùng web ADK, hãy thử:
Research the eco-friendly water bottle market for health-conscious millennialsWhat are the top Instagram trends in the wellness space in 2025?
Bạn sẽ thấy tác nhân gọi Google Tìm kiếm và trả về thông tin nghiên cứu có cấu trúc với các phần Thông tin chi tiết về đối tượng, Phân tích đối thủ cạnh tranh và Chủ đề thịnh hành.
5. Xây dựng Copywriter – Kỹ năng ADK
Vai trò: Biến nghiên cứu về thương hiệu thành chú thích trên Instagram. Nhân viên viết quảng cáo tạo 3 phiên bản chú thích với các giọng điệu khác nhau (truyền cảm hứng, giáo dục, cộng đồng), mỗi phiên bản đều có hashtag và lời kêu gọi hành động.
Khái niệm: Kỹ năng ADK
Một cách tiếp cận đơn giản là nhúng tất cả kiến thức về nền tảng (giới hạn ký tự, cấp độ hashtag, công thức tạo chú thích, ví dụ về giọng điệu thương hiệu) trực tiếp vào câu lệnh hệ thống. Cách này có hiệu quả, nhưng sẽ làm tăng kích thước của mọi yêu cầu với nội dung mà tác nhân chỉ cần thỉnh thoảng.
ADK Skills (SkillToolset, ra mắt trong ADK 1.25.0) cho phép bạn đóng gói kiến thức đó vào các tệp theo mô-đun với 3 cấp độ tải:
- L1 – frontmatter (
name+descriptiontrongSKILL.md): luôn có sẵn, dùng để khám phá kỹ năng - L2 – instructions (nội dung của
SKILL.md): được tải khi nhân viên hỗ trợ kích hoạt kỹ năng - L3 – tài nguyên (các tệp
references/vàassets/): chỉ được tải khi tác nhân đọc rõ ràng các tệp này
Chỉ dẫn hệ thống sẽ rút gọn thành một câu vai trò ngắn gọn kèm theo "load the skill before writing" (tải kỹ năng trước khi viết). Thông tin chi tiết về nền tảng chỉ được đưa vào cửa sổ ngữ cảnh khi tác nhân thực sự cần.
Kỹ năng của Chuyên viên viết quảng cáo nằm ở agents/copywriter/skills/instagram-copywriting/:
skills/
instagram-copywriting/
SKILL.md ← L1 frontmatter (discovery) + L2 instructions (loaded on trigger)
references/
platform-guide.md ← L3: character limits, hashtag tiers, algorithm signals
caption-formulas.md ← L3: hook formulas, CTA patterns, full caption structures
assets/
brand-voice-examples.md ← L3: annotated real-world caption examples
Mở tệp ngay trong trình chỉnh sửa Cloud Shell:
cloudshell edit agents/copywriter/agent.py
TODO 1 – Nhập load_skill_from_dir và skill_toolset
Tìm nhận xét # TODO 1: Import load_skill_from_dir and skill_toolset rồi thêm 2 lệnh nhập sau:
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset
TODO 2 – Tải kỹ năng và tạo SkillToolset
Tìm hai bình luận bên dưới các mục nhập:
# TODO 2: Load the instagram-copywriting skill from the skills/ directory
# TODO 2: Create a SkillToolset with the loaded skill
Thay thế bằng:
_instagram_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "instagram-copywriting"
)
_copywriting_skills = skill_toolset.SkillToolset(skills=[_instagram_skill])
load_skill_from_dir đọc SKILL.md cùng với mọi tệp trong references/ và assets/. SkillToolset sẽ gói yêu cầu đó vào định dạng mà các tác nhân ADK chấp nhận – một bộ công cụ chứ không phải một kỹ năng thô.
TODO 3 – Đăng ký bộ công cụ với tác nhân
Tìm tools=[], # TODO 3: Add the SkillToolset here rồi thay thế bằng:
tools=[_copywriting_skills],
Mở tệp kỹ năng để xem cấu trúc của tệp này:
cloudshell edit agents/copywriter/skills/instagram-copywriting/SKILL.md
Duy trì trạng thái hoạt động của giao diện người dùng web ADK. Sử dụng trình đơn thả xuống của tác nhân để chuyển sang copywriter mà không cần khởi động lại máy chủ.
Nếu dịch vụ này không chạy, hãy khởi động lại:
uv run adk web agents --allow_origins='*'
Hãy thử: Chuyển trình đơn thả xuống sang copywriter rồi gửi:
You are writing captions for EcoFlow Smart Water Bottle targeting health-conscious millennials aged 25-35.
Audience insight: they prioritize sustainability, track health metrics, and share lifestyle content.
Competitor insight: Hydro Flask dominates with lifestyle branding; S'well leads on premium aesthetics.
Write 3 Instagram captions - one inspirational, one educational, one community-focused. Include 5 hashtags each and a CTA.
6. Tạo Designer – Tạo hình ảnh đa phương thức
Duy trì trạng thái hoạt động của giao diện người dùng web ADK. Sử dụng trình đơn thả xuống của tác nhân để chuyển đổi tác nhân mà không cần khởi động lại máy chủ.
Vai trò: Tạo ý tưởng trực quan cho từng chú thích và tạo hình ảnh thực tế bằng tính năng tạo hình ảnh gốc của Gemini. Công cụ Designer tạo chính xác 1 ý tưởng về hình ảnh cho mỗi chú thích – kèm theo câu lệnh, kiểu chữ, bảng màu, tâm trạng và định dạng Instagram chi tiết – sau đó gọi ngay công cụ generate_image để tạo hình ảnh thực tế và tải hình ảnh đó lên GCS.
Khái niệm: Kết nối một tác nhân văn bản với một mô hình hình ảnh thông qua một công cụ
Trình thiết kế chạy trên gemini-3-flash-preview (bộ mô hình văn bản được đặt thông qua GEMINI_MODEL trong .env), nhưng quá trình tạo hình ảnh cần có một mô hình chuyên dụng (gemini-3.1-flash-image-preview). Mô hình hình ảnh đó không hỗ trợ tính năng gọi hàm, nên không thể dùng trực tiếp làm tác nhân ADK. Thay vào đó, nó được bao bọc trong một hàm Python thuần tuý và được đăng ký dưới dạng FunctionTool.
Đây là mẫu cho mọi mô hình hoặc API mà LLM không thể gọi trực tiếp: gói mô hình hoặc API đó trong một công cụ, cho phép tác nhân điều phối thời điểm gọi và nhận lại kết quả có cấu trúc.
Designer agent (text model)
│
│ decides visual concept, writes image prompt
▼
generate_image tool
│
│ calls gemini-3.1-flash-image-preview
│ uploads result to GCS
▼
{"status": "success", "gcs_uri": "gs://..."}
│
│ returned to agent, included in response
▼
Critic (receives gcs_uri, passes to Vertex AI for multimodal review)
Mở tệp ngay trong trình chỉnh sửa Cloud Shell:
cloudshell edit agents/designer/image_gen_tool.py
Chữ ký hàm, chế độ thiết lập môi trường và chế độ chèn tỷ lệ khung hình được cung cấp. Lần lượt thực hiện 3 việc cần làm:
TODO 1 – Gọi mô hình hình ảnh Gemini
Tìm bình luận # TODO 1 rồi thay thế bằng:
client = genai.Client(vertexai=True, project=project_id, location=location)
response = client.models.generate_content(
model=image_model,
contents=prompt_with_aspect,
config=types.GenerateContentConfig(
response_modalities=["IMAGE", "TEXT"],
http_options=types.HttpOptions(
retry_options=types.HttpRetryOptions(
attempts=5, exp_base=2, initial_delay=30,
http_status_codes=[429, 500, 503, 504],
),
timeout=180_000,
),
),
)
TODO 2 – Trích xuất byte hình ảnh từ phản hồi
Tìm bình luận # TODO 2 rồi thay thế bằng:
image_bytes = None
mime_type = "image/png"
for part in response.candidates[0].content.parts:
if part.inline_data is not None:
image_bytes = part.inline_data.data
mime_type = part.inline_data.mime_type or "image/png"
break
if not image_bytes:
return {"status": "error", "error": "Gemini returned no image data"}
VIỆC CẦN LÀM 3 – Tải lên GCS và trả về URI
Tìm bình luận # TODO 3 rồi thay thế bằng:
ext = "jpg" if "jpeg" in mime_type else "png"
from google.cloud import storage
gcs_client = storage.Client(project=project_id)
bucket = gcs_client.bucket(bucket_name)
blob_name = f"campaign-images/{concept_name}-{uuid.uuid4().hex[:8]}.{ext}"
blob = bucket.blob(blob_name)
blob.upload_from_file(io.BytesIO(image_bytes), content_type=mime_type)
gcs_uri = f"gs://{bucket_name}/{blob_name}"
Hãy thử: Chuyển trình đơn thả xuống sang designer rồi gửi:
Create a visual concept and generate the image for an EcoFlow Smart Water Bottle Instagram post targeting health-conscious millennials.
Style: clean, modern, lifestyle-focused. Include a detailed prompt with color palette, mood, and format (1080x1080 or 1080x1350).
7. Xây dựng Nhà phê bình – Đầu ra có cấu trúc
Vai trò: Đảm bảo chất lượng của bản sao và hình ảnh trước khi chuyển cho Quản lý dự án. Người đánh giá sẽ chấm điểm cả hai sản phẩm và trả về APPROVED hoặc NEEDS_REVISION kèm theo các đề xuất cụ thể. Khi có các giá trị gcs_uri trong dữ liệu đầu vào, công cụ này sẽ gọi công cụ review_image để kiểm tra trực quan từng hình ảnh được tạo trước khi tính điểm.
Khái niệm: Khi nào nên sử dụng mô hình Pydantic cho đầu ra của Gemini
Quy tắc này liên quan đến ai sử dụng đầu ra:
- Mã Python sử dụng mã này → sử dụng
response_schema+ Pydantic. Mã không thể xử lý sự mơ hồ, vì vậy bạn cần một cấu trúc đảm bảo để trích xuất các trường một cách đáng tin cậy. - LLM sử dụng dữ liệu này → định dạng văn bản + hướng dẫn hệ thống là đủ. LLM hiểu các quy tắc định dạng và chấp nhận sự khác biệt.
Trong review_image, mã Python cần score, approval_status, what_works, issues và suggestions làm giá trị được nhập. Truyền response_schema=_GeminiReview sẽ giới hạn Gemini ở cấp độ API để trả về JSON hợp lệ; model_validate_json() sẽ phân tích cú pháp JSON đó thành một đối tượng được nhập mà mã của bạn có thể sử dụng một cách đáng tin cậy.
class _GeminiReview(BaseModel):
score: int = Field(ge=1, le=10)
approval_status: Literal["APPROVED", "NEEDS_REVISION"]
what_works: str
issues: str
suggestions: str
Mở tệp ngay trong trình chỉnh sửa Cloud Shell:
cloudshell edit agents/critic/image_review_tool.py
Các mô hình và câu lệnh Pydantic được cung cấp. Lần lượt thực hiện 3 việc cần làm:
TODO 1 – Tạo một phần hình ảnh từ URI GCS
Tìm bình luận # TODO 1 rồi thay thế bằng:
image_part = types.Part.from_uri(file_uri=gcs_uri, mime_type=mime_type)
TODO 2 – Gọi Gemini bằng một giản đồ phản hồi có cấu trúc
Tìm bình luận # TODO 2 rồi thay thế bằng:
response = client.models.generate_content(
model=model,
contents=[image_part, prompt],
config=types.GenerateContentConfig(
response_schema=_GeminiReview,
response_mime_type="application/json",
),
)
TODO 3 – Phân tích cú pháp phản hồi và trả về kết quả
Tìm bình luận # TODO 3 rồi thay thế bằng:
review = _GeminiReview.model_validate_json(response.text)
return ImageReviewResult(status="success", concept_name=concept_name, **review.model_dump())
Hãy thử: Chuyển trình đơn thả xuống sang critic rồi gửi:
Review this Instagram caption for an eco-friendly water bottle brand targeting millennials:
"Hydrate smarter, live greener. 💧 Our EcoFlow bottle tracks your intake, keeps your drink cold for 24h, and never touches single-use plastic. Because what you drink from matters as much as what you drink. #EcoFlow #HydrationGoals #SustainableLiving #ZeroWaste #HealthyHabits - Shop link in bio."
Score it and indicate APPROVED or NEEDS_REVISION with specific feedback.
Xác minh rằng phản hồi chứa **POSTS REVIEW:**, Status: APPROVED (hoặc NEEDS_REVISION) và **OVERALL ASSESSMENT:**. Nếu có các phần đó, thì Critic đã sẵn sàng kết nối với trình điều phối.
Khi bạn kiểm thử xong cả 3 tác nhân, hãy nhấn Ctrl+C để dừng máy chủ.
8. Xây dựng Tác nhân quản lý dự án bằng MCP
Project Manager giới thiệu một khái niệm mới: MCP (Giao thức ngữ cảnh mô hình).
Mở tệp:
cloudshell edit agents/project_manager/agent.py
Tệp này phức tạp hơn – tệp có một hàm create_project_manager_agent() với 2 nhánh: một nhánh không có Notion (dòng thời gian chỉ có văn bản) và một nhánh có bộ công cụ MCP của Notion. Bạn sẽ điền cả hai.
Vấn đề mà MCP giải quyết
Trợ lý của bạn cần gọi một dịch vụ bên ngoài, chẳng hạn như tạo một trang trong Notion. Bạn có thể viết mã Python gọi trực tiếp API REST của Notion. Nhưng sau đó:
- Mỗi nhà phát triển sẽ viết một trình bao bọc khác nhau
- Bạn cần duy trì mã tích hợp tuỳ chỉnh
- LLM không biết API tồn tại trừ phi bạn mô tả từng điểm cuối theo cách thủ công
MCP giải quyết vấn đề này bằng cách xác định một cách tiêu chuẩn để các dịch vụ bên ngoài thể hiện khả năng của mình dưới dạng công cụ mà LLM (mô hình ngôn ngữ lớn) có thể tự động khám phá và gọi.
MCP là gì?
MCP (Giao thức ngữ cảnh mô hình) là một tiêu chuẩn mở (do Anthropic xuất bản) để kết nối các tác nhân AI với các công cụ và nguồn dữ liệu bên ngoài. Thiết bị này hoạt động như một bộ chuyển đổi đa năng.
Máy chủ MCP là một chương trình nhỏ có chức năng:
- Bao bọc một API bên ngoài (Notion, GitHub, cơ sở dữ liệu, hệ thống tệp...)
- Hiển thị API đó dưới dạng danh sách công cụ được nhập và ghi lại
- Giao tiếp với tác nhân thông qua một giao thức đơn giản (stdio hoặc HTTP)
Tác nhân kết nối với máy chủ MCP, tự động phát hiện các công cụ có sẵn và có thể gọi các công cụ đó giống như bất kỳ công cụ nào khác – LLM xem API-post-page(...) là một hàm có thể gọi.
A2A và MCP khác nhau như thế nào?
Đây là một điểm thường gây nhầm lẫn. Sau đây là điểm khác biệt chính:
A2A | MCP | |
Những thiết bị có thể kết nối | Nhân viên hỗ trợ ↔ Nhân viên hỗ trợ | Tác nhân ↔ Công cụ/dịch vụ bên ngoài |
Mặt còn lại là | Một tác nhân LLM khác | Trình bao bọc API (không có LLM) |
Ví dụ | Giám đốc sáng tạo gọi điện cho Chuyên viên chiến lược thương hiệu | Trình quản lý dự án gọi Notion API |
Giao thức | JSON-RPC qua HTTPS | luồng stdio hoặc HTTP |
Do | Anthropic |
Bạn có thể hiểu như sau:
- A2A = cách nhân viên hỗ trợ nói chuyện với nhân viên hỗ trợ khác
- MCP = cách các nhân viên hỗ trợ trò chuyện với công cụ và dịch vụ
Trong dự án này, cả hai đều được dùng cùng nhau:
Creative Director
│
│ (A2A) Brand Strategist ─── (google_search tool built into ADK)
│ (A2A) Copywriter
│ (A2A) Designer
│ (A2A) Critic
│ (A2A) Project Manager
│
│ (MCP) notion-mcp-server ──► Notion REST API
Cách MCP hoạt động trong dự án này
Khi chạy, ADK sẽ khởi chạy notion-mcp-server dưới dạng một quy trình con. Quy trình đó sẽ cung cấp trực tiếp các công cụ này cho LLM:
Công cụ | Ý nghĩa |
| Tìm nạp giản đồ (tên thuộc tính, loại, giá trị hợp lệ) |
| Truy vấn các trang hiện có |
| Tạo một trang mới |
| Cập nhật một trang hiện có |
LLM gọi các hàm này như bất kỳ hàm nào khác – LLM không biết rằng các hàm này đi qua MCP đến Notion API REST.
Tại sao lại là stdio? Tại sao không chỉ dùng HTTP?
Máy chủ MCP chạy dưới dạng tiến trình con của tác nhân, giao tiếp qua stdin/stdout. Điều này có nghĩa là:
- Không cần thêm cổng mạng
- Vòng đời do tác nhân quản lý (bắt đầu theo yêu cầu, dừng khi thoát)
- Mọi thứ đều được chuyển trong một hình ảnh Docker – không cần triển khai dịch vụ riêng
(Không bắt buộc) Bật tính năng tích hợp Notion
Bạn có thể bỏ qua toàn bộ phần này. Trợ lý Quản lý dự án luôn tạo ra một dòng thời gian hoàn chỉnh cho chiến dịch dựa trên văn bản, có hoặc không có Notion. Nếu bạn bỏ qua bước thiết lập này, tác nhân sẽ chuyển về chế độ trong bộ nhớ và xuất dòng thời gian dưới dạng văn bản thuần tuý trong cuộc trò chuyện. Không có gì bị hỏng cả, bạn chỉ không thấy các việc cần làm xuất hiện trong cơ sở dữ liệu của Notion. Chuyển thẳng đến việc cần làm 1 nếu bạn muốn bỏ qua.
Nếu bạn có tài khoản Notion và muốn xem chế độ tích hợp MCP hoạt động, hãy hoàn tất quá trình thiết lập bên dưới ngay bây giờ. Các việc cần làm sau đây tham chiếu đến mã cơ sở dữ liệu của Notion – đây là nơi bạn lấy các mã đó.
Bước 1 – Tạo cơ sở dữ liệu trên Notion từ một mẫu
Chúng tôi sử dụng mẫu Dự án và việc cần làm trên Notion chính thức làm cơ sở dữ liệu. Chúng tôi đã cố tình chọn mẫu này để minh hoạ một bối cảnh phức tạp trong thế giới thực – mẫu này có nhiều loại thuộc tính (trạng thái, phạm vi ngày, mối quan hệ, lựa chọn) với tên không rõ ràng. Đây là một bài kiểm tra tuyệt vời về tính năng khám phá giản đồ động của MCP: tác nhân phải tìm ra tên chính xác của thuộc tính trong thời gian chạy thay vì mã hoá cứng các thuộc tính đó.
Nhấp vào đường liên kết bên dưới để thêm mẫu vào không gian làm việc của bạn trên Notion:
→ Thêm mẫu "Dự án và việc cần làm" vào Notion

Sau khi thêm, bạn sẽ có 2 cơ sở dữ liệu được liên kết: Dự án và Việc cần làm. Mẫu này có các mục nhập mẫu. Hãy xoá tất cả các mục nhập đó trước khi tiếp tục để nhân viên hỗ trợ bắt đầu với một không gian làm việc trống (chọn tất cả → Xoá).
Bước 2 – Tạo một mối tích hợp Notion
Tạo mối liên kết tích hợp:
- Truy cập vào notion.so/my-integrations
- Nhấp vào Tích hợp mới → đặt tên cho tích hợp đó
AI Creative Studio - Liên kết tệp đó với không gian làm việc của bạn
- Nhấp vào Định cấu hình chế độ cài đặt → đảm bảo bạn đã đánh dấu vào tất cả các chức năng Đọc nội dung, Cập nhật nội dung và Chèn nội dung

- Sao chép Mã thông báo tích hợp nội bộ (
ntn_...) rồi dán vào tệp.env:
NOTION_TOKEN=ntn_your-token-here
Kết nối chế độ tích hợp với cơ sở dữ liệu của bạn:
- Mở trang mẫu mà bạn vừa sao chép, sau đó nhấp vào cơ sở dữ liệu Dự án
- Nhấp vào trình đơn
...(trên cùng bên phải) → Kết nối → Thêm kết nối → chọnAI Creative Studio


- Làm tương tự cho cơ sở dữ liệu Tasks (Việc cần làm)
Lấy mã nhận dạng cơ sở dữ liệu:
- Nhấp vào đường liên kết đến cơ sở dữ liệu Dự án để mở cơ sở dữ liệu đó. Cơ sở dữ liệu này sẽ mở ra trong trang riêng với một URL như:
https://www.notion.so/9887b6a94f7f83f68f8581e038d1aaa4?v=2c37b6a94f7f838685f1086e312c7278

Mã nhận dạng cơ sở dữ liệu là UUID đầu tiên trong URL – mọi thứ trước ?v=:
https://www.notion.so/{DATABASE_ID}?v=...
^^^^^^^^^^^^^^^^
9887b6a94f7f83f68f8581e038d1aaa4 ← this is your DATABASE_ID
- Làm tương tự đối với đường liên kết đến cơ sở dữ liệu Tasks (Việc cần làm) để lấy mã nhận dạng cơ sở dữ liệu của đường liên kết đó
- Thêm cả 3 giá trị vào
.envcủa bạn:
NOTION_TOKEN=ntn_your-token-here
NOTION_PROJECT_DATABASE_ID=9887b6a94f7f83f68f8581e038d1aaa4 # <-- your Projects DB ID
NOTION_TASKS_DATABASE_ID=your-tasks-db-id # <-- your Tasks DB ID
Bước 3 – Cài đặt máy chủ MCP Notion
Trình quản lý dự án kết nối với Notion thông qua gói @notionhq/notion-mcp-server Node.js chính thức. Cài đặt trên toàn cầu:
npm install -g @notionhq/notion-mcp-server@1.9.1
Xác minh quá trình cài đặt:
npm list -g @notionhq/notion-mcp-server
Kết quả đầu ra dự kiến:
└── @notionhq/notion-mcp-server@1.9.1
notion-mcp-server: command not found
? Đảm bảo bạn đã cài đặt Node.js (node --version) và npm global bin nằm trên PATH (export PATH=$PATH:$(npm bin -g)).
Bước 4 – Xác minh .env
Mở .env và xác nhận rằng bạn đã đặt cả 3 giá trị Notion (bạn đã thêm các giá trị này ở Bước 2):
cloudshell edit .env
NOTION_TOKEN=ntn_... # integration token
NOTION_PROJECT_DATABASE_ID=... # Projects database ID
NOTION_TASKS_DATABASE_ID=... # Tasks database ID
Tác nhân Project Manager sẽ tự động phát hiện các biến này khi khởi động và bật bộ công cụ Notion MCP.
Cách hoạt động của tính năng khám phá giản đồ
Project Manager sử dụng khám phá giản đồ động – công cụ này không bao giờ mã hoá cứng tên thuộc tính Notion:
Step 1: Call API-retrieve-a-database to discover exact property names
Step 2: Read the "properties" object in the response
Step 3: Use ONLY discovered property names (case-sensitive) in API calls
Step 4: For select/status fields, use only values from the options array
Điều này có nghĩa là tác nhân sẽ tự động thích ứng với mọi cấu trúc cơ sở dữ liệu trên Notion – đổi tên các thuộc tính sang tiếng Pháp, tiếng Ả Rập hoặc bất kỳ ngôn ngữ nào khác, tác nhân vẫn hoạt động.
TODO 1 – Viết chỉ dẫn cho hệ thống
Trình khởi động đã tính toán notion_section – một chuỗi trống khi Notion chưa được định cấu hình hoặc một khối chứa mã cơ sở dữ liệu cùng với hướng dẫn đầy đủ về công cụ khi Notion đã được định cấu hình. Điều này giúp các hướng dẫn về Notion hoàn toàn nằm ngoài lời nhắc của tác nhân không có Notion; LLM không bao giờ thấy các quy tắc cho những công cụ mà nó không có.
Công việc của bạn là thay thế phần giữ chỗ return bằng một chỉ dẫn thực tế của hệ thống sử dụng {notion_section}:
return f"""You are a Project Manager specializing in creative campaign execution.
Today's date is {datetime.date.today().strftime("%B %d, %Y")}.
Use this as the starting point for all timelines.
Your goal: create a complete project plan for the campaign.
{notion_section}
**Project Timeline:**
Phase 1: Strategy & Research | [date] → [date] | [key activities]
Phase 2: Content Creation | [date] → [date] | [key activities]
Phase 3: Review & Revision | [date] → [date] | [key activities]
Phase 4: Launch & Monitoring | [date] → [date] | [key activities]
**Task List:**
| Task | Owner | Deadline | Status |
[list each task with realistic deadlines from today; set Owner to TBD]
**Budget Breakdown:**
[by category with approximate allocations]
**Milestones:**
[3-5 key checkpoints with dates]
**Notion Status:**
[What happened - e.g. "Project created (ID: xxx), 8 tasks linked" or "Notion not configured - text timeline only"]
"""
VIỆC CẦN LÀM 2 – Nhân viên hỗ trợ không có Notion
Bên trong create_project_manager_agent(), trong nhánh if not notion_token, hãy thay thế tác nhân chưa hoàn chỉnh bằng:
return Agent(
name="project_manager",
model=os.getenv("GEMINI_MODEL", "gemini-2.5-flash"),
generate_content_config=GENERATE_CONTENT_CONFIG,
instruction=get_system_instruction(),
description="Project manager that creates campaign timelines and task breakdowns",
)
TODO 3 – Agent có Notion MCP
Lưu ý: Tệp khởi đầu đã chứa một lệnh gọi lại handle_notion_error được viết sẵn ở trên create_project_manager_agent(). Nó chặn các lỗi Notion API (400/404) và thay thế tải trọng lỗi thô bằng các thông báo rõ ràng, có thể hành động để LLM có thể tự sửa lỗi. Bạn chỉ cần kết nối qua after_tool_callback.
Trước tiên, hãy đọc cả hai mã nhận dạng cơ sở dữ liệu ở đầu create_project_manager_agent():
notion_token = os.getenv("NOTION_TOKEN")
notion_project_db_id = os.getenv("NOTION_PROJECT_DATABASE_ID")
notion_tasks_db_id = os.getenv("NOTION_TASKS_DATABASE_ID")
Sau đó, trong nhánh else, hãy tạo bộ công cụ MCP và tác nhân:
from google.adk.tools.mcp_tool import McpToolset, StdioConnectionParams
from mcp import StdioServerParameters
server_params = StdioServerParameters(
command="notion-mcp-server",
env={
"NOTION_TOKEN": notion_token,
"PATH": os.environ.get("PATH", ""),
}
)
notion_toolset = McpToolset(
connection_params=StdioConnectionParams(
server_params=server_params,
timeout=30.0
)
)
return Agent(
name="project_manager",
model=os.getenv("GEMINI_MODEL", "gemini-2.5-flash"),
generate_content_config=GENERATE_CONTENT_CONFIG,
after_tool_callback=handle_notion_error,
instruction=get_system_instruction(
project_database_id=notion_project_db_id,
tasks_database_id=notion_tasks_db_id,
),
description="Project manager with Notion integration for task tracking",
tools=[notion_toolset],
)
Phương pháp hay nhất: Không bao giờ thất bại hoàn toàn trong các hoạt động tích hợp không bắt buộc. Dòng thời gian bằng văn bản luôn là sản phẩm chính; Notion là sản phẩm bổ sung.
Kiểm thử Trình quản lý dự án cục bộ bằng ADK Web
uv run adk web agents --allow_origins='*'
Mở Web Preview (Xem trước trên web) trên cổng 8000. Sử dụng trình đơn thả xuống về trợ lý để chọn project_manager, sau đó thử:
Create a project plan for a GreenBrew organic coffee brand Instagram campaign.
Budget: $2,500. Launch in 3 weeks. Target audience: eco-conscious millennials aged 22-30.
Include phases, tasks with deadlines from today, and milestones.
Bạn sẽ thấy một dòng thời gian bằng văn bản có cấu trúc với các giai đoạn, danh sách việc cần làm và các mốc quan trọng. Nếu bạn đặt thông tin đăng nhập Notion trong .env, thì tác nhân cũng sẽ tạo các mục trong không gian làm việc Notion của bạn.
9. Tìm hiểu về giao thức A2A
Chúng ta sẽ sử dụng Giao thức giữa các tác nhân (A2A) để kết nối các tác nhân trong hệ thống. Hãy cùng tìm hiểu cách hoạt động của tính năng này.
Vấn đề mà A2A giải quyết
Giả sử bạn có một tác nhân Nhà chiến lược thương hiệu được tạo bằng ADK và một tác nhân Người viết quảng cáo được tạo bằng LangGraph. Làm cách nào để gọi cho người khác? Chúng sử dụng các ngôn ngữ nội bộ khác nhau. Bạn sẽ cần viết mã kết dính tuỳ chỉnh mỗi lần.
A2A giải quyết vấn đề này bằng cách xác định một ngôn ngữ phổ quát mà mọi tác nhân (bất kể khung nào) đều có thể sử dụng. Đây là HTTP của thế giới tác nhân: một tiêu chuẩn mà mọi người đều đồng ý để ai cũng có thể nói chuyện với bất kỳ ai.
A2A là gì?
Agent-to-Agent (A2A) là một tiêu chuẩn mở để giao tiếp giữa các tác nhân do Google xuất bản. Nó xác định:
- Cách mà một tác nhân tự mô tả về mình – thẻ tác nhân tại
/.well-known/agent.json - Cách một tác nhân khác gọi nó – JSON-RPC qua HTTPS
- Cách trả về kết quả – truyền trực tuyến hoặc phản hồi đơn lẻ
Những yếu tố giúp A2A linh hoạt:
- Không phụ thuộc vào ngôn ngữ – Các tác nhân Python có thể giao tiếp với các tác nhân TypeScript
- Không phụ thuộc vào khung hình – Các tác nhân ADK có thể giao tiếp với các tác nhân LangGraph hoặc CrewAI
- Không phụ thuộc vào cơ sở hạ tầng – các tác nhân cục bộ có thể giao tiếp với các tác nhân trên đám mây
Cách hoạt động – từng bước
Creative Director Brand Strategist
│ │
│ 1. GET /.well-known/agent.json │
│ ────────────────────────────────►│
│ ◄──── agent card (name, url, │
│ skills, capabilities) ───│
│ │
│ 2. POST / │
│ {"method": "tasks/send", │
│ "params": {"message": ...}} │
│ ────────────────────────────────►│
│ │ LLM does
│ │ the work...
│ 3. streaming response chunks │
│ ◄───────────────────────────────│
│ ◄───────────────────────────────│
│ ◄───────────────────────────────│
Bước 1 – Khám phá: Orchestrator tìm nạp thẻ tác nhân một lần để tìm hiểu tên, URL và các chức năng của tác nhân.
Bước 2 – Lời gọi: Trình điều phối gửi một tác vụ thông qua JSON-RPC POST. Nội dung chứa thông báo (lời nhắc cho chuyên gia).
Bước 3 – Phản hồi: Chuyên gia truyền trực tuyến phản hồi của mình theo từng phần, giống như một lệnh gọi LLM thông thường.
Thẻ tác tử
Mỗi tác nhân đều xuất bản nội dung tự mô tả tại /.well-known/agent.json. Đây giống như một danh thiếp – cho mọi người biết tác nhân có thể làm gì và cách liên hệ với tác nhân:
{
"name": "brand_strategist",
"description": "Market research and competitive analysis",
"url": "https://brand-strategist-xyz.run.app",
"capabilities": { "streaming": true },
"skills": [
{
"id": "market_research",
"description": "Research target audiences, competitors, and trends"
}
]
}
Trình điều phối đọc thẻ này để tạo đối tượng RemoteA2aAgent của thẻ – không cần kiến thức được cố định giá trị trong mã về nội bộ của chuyên gia.
Hiển thị một tác nhân thông qua A2A trong ADK
to_a2a() bao bọc mọi tác nhân ADK trong một ứng dụng FastAPI tuân thủ A2A. Một dòng:
from google.adk.a2a.utils.agent_to_a2a import to_a2a
# root_agent = your normal ADK Agent(...)
a2a_app = to_a2a(root_agent, host=PUBLIC_HOST, port=PUBLIC_PORT, protocol=PROTOCOL)
uvicorn.run(a2a_app, host=HOST, port=PORT)
Thao tác này sẽ tự động tạo:
/.well-known/agent.json– thẻ tác nhân/– điểm cuối JSON-RPC (tất cả các yêu cầu về tác vụ A2A đều chuyển đến đường dẫn gốc)
10. Hiển thị các tác nhân dưới dạng dịch vụ A2A
Để hiển thị các tác nhân dưới dạng dịch vụ A2A, bạn có thể sử dụng hàm hiệu dụng to_a2a() trong ADK.
Cách hoạt động của to_a2a()
from google.adk.a2a.utils.agent_to_a2a import to_a2a
a2a_app = to_a2a(root_agent, host=PUBLIC_HOST, port=PUBLIC_PORT, protocol=PROTOCOL)
uvicorn.run(a2a_app, host=HOST, port=PORT)
to_a2a() bao bọc tác nhân ADK của bạn trong một ứng dụng FastAPI tự động hiển thị:
/.well-known/agent.json– thẻ trợ lý AI (tên, nội dung mô tả, các chức năng)/a2a/{agent_name}– điểm cuối JSON-RPC để nhận các tác vụ
Mã khung của mỗi tác nhân đã bao gồm một khối __main__ bao bọc tác nhân trong một máy chủ A2A bằng cách sử dụng to_a2a(). Bạn không cần viết mã này vì mã đã được cung cấp.
Tìm hiểu về cấu hình URL kép
Khi bạn chạy python agent.py, khối __main__ sẽ sử dụng 2 cấu hình URL riêng biệt:
# Where the server actually listens (network interface):
HOST = "0.0.0.0"
PORT = 8082 # Brand Strategist (others use 8083–8086 locally)
# What gets advertised in the agent card (the address other agents use to reach it):
PUBLIC_HOST = os.getenv("PUBLIC_HOST", "localhost")
PUBLIC_PORT = int(os.getenv("PUBLIC_PORT", str(PORT)))
PROTOCOL = os.getenv("PROTOCOL", "http")
a2a_app = to_a2a(root_agent, host=PUBLIC_HOST, port=PUBLIC_PORT, protocol=PROTOCOL)
uvicorn.run(a2a_app, host=HOST, port=PORT)
Môi trường |
|
|
Địa phương |
|
|
Cloud Run |
|
|
Về mặt cục bộ, cả hai đều trỏ đến cùng một máy. Trên Cloud Run, vùng chứa sẽ lắng nghe nội bộ trên 8080 nhưng thẻ tác nhân phải quảng cáo URL HTTPS công khai. Nếu không, Giám đốc sáng tạo sẽ không thể liên hệ với chuyên gia từ bên ngoài vùng chứa.
Khởi động tất cả 5 máy chủ A2A chuyên dụng
Hãy chạy cả 5 chuyên gia này dưới dạng máy chủ A2A cùng lúc, sau đó kiểm thử Giám đốc sáng tạo tại địa phương trỏ đến họ.
Mở 5 thiết bị đầu cuối Cloud Shell riêng biệt (nhấp vào biểu tượng + trong thanh thẻ của thiết bị đầu cuối) và chạy một tác nhân cho mỗi thiết bị đầu cuối.
uv run tự động kích hoạt .venv mà không cần source theo cách thủ công trong mỗi thiết bị đầu cuối.
Thiết bị đầu cuối 1 – Nhà chiến lược thương hiệu (cổng 8082):
cd ~/ai-creative-studio/workshop/starter
PORT=8082 uv run agents/brand_strategist/agent.py
Terminal 2 – Copywriter (cổng 8083):
cd ~/ai-creative-studio/workshop/starter
PORT=8083 uv run agents/copywriter/agent.py
Thiết bị đầu cuối 3 – Nhà thiết kế (cổng 8084):
cd ~/ai-creative-studio/workshop/starter
PORT=8084 uv run agents/designer/agent.py
Terminal 4 – Critic (cổng 8085):
cd ~/ai-creative-studio/workshop/starter
PORT=8085 uv run agents/critic/agent.py
Terminal 5 – Project Manager (cổng 8086):
cd ~/ai-creative-studio/workshop/starter
PORT=8086 uv run agents/project_manager/agent.py
Đặt URL localhost trong .env
Trong Terminal 6, hãy cập nhật .env bằng URL của tác nhân cục bộ để Giám đốc sáng tạo có thể tìm thấy các URL đó:
cd ~/ai-creative-studio/workshop/starter
sed -i \
-e 's|STRATEGIST_AGENT_URL=.*|STRATEGIST_AGENT_URL=http://localhost:8082|' \
-e 's|COPYWRITER_AGENT_URL=.*|COPYWRITER_AGENT_URL=http://localhost:8083|' \
-e 's|DESIGNER_AGENT_URL=.*|DESIGNER_AGENT_URL=http://localhost:8084|' \
-e 's|CRITIC_AGENT_URL=.*|CRITIC_AGENT_URL=http://localhost:8085|' \
-e 's|PM_AGENT_URL=.*|PM_AGENT_URL=http://localhost:8086|' \
.env
Kiểm tra các tác nhân bằng Công cụ kiểm tra A2A
A2A Inspector là một công cụ nguồn mở dành cho nhà phát triển, có thể sử dụng giao thức A2A một cách tự nhiên. Công cụ này cho phép bạn kết nối trực tiếp với mọi tác nhân A2A đang chạy, đọc thẻ tác nhân và gửi các tác vụ mà không cần viết mã ứng dụng.
Nội dung bạn thấy:
- Thẻ tác nhân – siêu dữ liệu có cấu trúc mà tác nhân của bạn quảng cáo: tên, nội dung mô tả, các chế độ đầu vào/đầu ra được hỗ trợ và URL điểm cuối. Đây là những gì Giám đốc sáng tạo đọc khi phát hiện ra một chuyên gia.
- Giao diện trò chuyện – gửi mọi tin nhắn đến tác nhân qua A2A và xem phản hồi thô. Bạn có thể kiểm thử các câu lệnh riêng lẻ trước khi kết nối các tác nhân với nhau.
- Xác thực giao thức – trình kiểm tra sẽ kiểm tra để đảm bảo thẻ đại lý tuân thủ quy cách A2A, đồng thời hiển thị các trường bị thiếu hoặc phản hồi bị lỗi từ sớm.
Tại sao điều này lại quan trọng: Khi bạn triển khai lên Cloud Run sau này, Creative Director sẽ khám phá từng chuyên gia bằng cách tìm nạp thẻ đại lý của chuyên gia đó từ /.well-known/agent.json. Nếu thẻ đó không chính xác (URL không hợp lệ, thiếu các chức năng), thì trình điều phối sẽ âm thầm thất bại. Công cụ kiểm tra này giúp bạn phát hiện những vấn đề này trên thiết bị trước khi triển khai trên đám mây.

Thẻ nhân viên hỗ trợ cho thấy danh tính và khả năng của chuyên gia đúng như những nhân viên hỗ trợ khác nhìn thấy.

Cài đặt và khởi động trình kiểm tra
cd ~/ai-creative-studio/workshop
./setup_inspector.sh
Lệnh cập nhật .env là lệnh dùng một lần. Sử dụng Terminal 6 để bắt đầu trình kiểm tra tiếp theo:
cd ~/a2a-inspector
bash scripts/run.sh
Để mở giao diện người dùng trình kiểm tra, hãy sử dụng Web Preview (Xem trước trên web) → Change port (Thay đổi cổng) → nhập 5001.
Kết nối với Chuyên gia chiến lược thương hiệu
Nhập http://localhost:8082 vào trường URL của trình kiểm tra rồi nhấp vào Kết nối. Trình kiểm tra sẽ tìm nạp thẻ nhân viên và hiển thị siêu dữ liệu của chuyên gia.

Thông tin trong thẻ tác nhân
Thẻ tác nhân không chỉ là siêu dữ liệu mà còn là hợp đồng đầy đủ về khả năng mà tác nhân quảng cáo cho mạng. Kết nối với Project Manager (Trình quản lý dự án) (http://localhost:8086) để xem ví dụ phong phú nhất:
{
"name": "project_manager",
"description": "Project manager with Notion integration for task tracking",
"protocolVersion": "0.3.0",
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
"skills": [
{
"id": "project_manager",
"name": "model",
"tags": ["llm"],
"description": "... full system instruction including today's date and Notion database IDs ..."
},
{
"id": "project_manager-API-post-page",
"name": "API-post-page",
"tags": ["llm", "tools"],
"description": "Notion | Create a page"
},
{
"id": "project_manager-API-retrieve-a-database",
"name": "API-retrieve-a-database",
"tags": ["llm", "tools"],
"description": "Notion | Retrieve a database"
}
]
}
Có 3 điểm nổi bật:
1. Các công cụ MCP trở thành kỹ năng A2A – Mọi công cụ Notion mà người quản lý dự án có quyền truy cập (API-post-page, API-retrieve-a-database, v.v.) đều được liệt kê dưới dạng một kỹ năng riêng biệt trong thẻ đại lý. Mọi tác nhân khác trên mạng đều có thể khám phá chính xác những công cụ mà tác nhân này có thể sử dụng mà không cần đọc bất kỳ mã nào.
2. Hướng dẫn hệ thống được nhúng – description của kỹ năng đầu tiên chứa toàn bộ hướng dẫn hệ thống, bao gồm cả ngày hôm nay và mã nhận dạng cơ sở dữ liệu Notion. Đây là cách Giám đốc sáng tạo biết những gì cần truyền khi gọi Trưởng dự án.
3. URL là điểm cuối trực tiếp – Trường url chính xác là những gì RemoteA2aAgent sử dụng khi Giám đốc sáng tạo gọi chuyên gia này. Nếu URL trong thẻ không chính xác, điều phối viên sẽ không thể liên hệ với tác nhân.
Đây là lý do khiến trình kiểm tra trở thành một công cụ gỡ lỗi mạnh mẽ: chỉ cần nhìn vào thẻ tác nhân, bạn sẽ biết tác nhân có đang chạy hay không, tác nhân có những công cụ nào và liệu điểm cuối có chính xác hay không.
Gửi tin nhắn thử nghiệm
Sau khi kết nối, hãy nhập một câu lệnh vào bảng trò chuyện rồi gửi. Trình kiểm tra gửi yêu cầu này dưới dạng một tác vụ A2A và truyền trực tuyến phản hồi trở lại – theo cách tương tự như Giám đốc sáng tạo sẽ gọi tác nhân này trong quá trình sản xuất.

Hướng trình kiểm tra vào bất kỳ cổng cục bộ nào (8082–8086) để kiểm thử từng chuyên gia riêng lẻ.
11. Xây dựng Creative Director Orchestrator
Giám đốc sáng tạo là người điều phối chính. Thao tác này sẽ đọc các URL chuyên biệt từ các biến môi trường, bao bọc từng URL dưới dạng RemoteA2aAgent và hiển thị chúng dưới dạng AgentTool mà LLM có thể gọi.
Đảm bảo 5 tác nhân chuyên trách vẫn đang chạy (Thiết bị đầu cuối 1–5 từ Bước 10).
Trong Terminal 6 (dòng lệnh A2A Inspector), hãy dừng trình kiểm tra bằng Ctrl+C.
Mở tệp:
cd ~/ai-creative-studio/workshop/starter
cloudshell edit agents/creative_director/agent.py
Tệp này có 3 việc cần làm. Hãy thực hiện theo thứ tự.
Việc cần làm 1 – Xem lại chỉ dẫn hệ thống đã viết
Hướng dẫn hệ thống nằm trong prompt.py trong cùng một thư mục – hướng dẫn này sẽ được nhập tự động:
from .prompt import SYSTEM_INSTRUCTION_TEMPLATE
Mở prompt.py để đọc trước khi chuyển sang bước tiếp theo:
cloudshell edit agents/creative_director/prompt.py
Bạn cần hiểu rõ về tham số này vì nó kiểm soát toàn bộ hành vi điều phối.
Lý do lời nhắc của trình điều phối kiểm soát mọi thứ
Mở prompt.py cùng với phần này – các ví dụ bên dưới sẽ tham chiếu đến những phần cụ thể trong đó.
Lời nhắc trong prompt.py không chỉ là tài liệu mà còn là mặt phẳng điều khiển của toàn bộ hệ thống. Một câu lệnh điều phối có cấu trúc kém sẽ tạo ra: các tác nhân được gọi không theo thứ tự, nội dung do trình điều phối tạo thay vì chuyên gia, quy trình làm việc tiếp tục sau khi gặp lỗi và bối cảnh bị loại bỏ âm thầm giữa các tác nhân. 9 yếu tố này giúp ngăn chặn những lỗi thường gặp nhất:
Yếu tố 0 – Lên kế hoạch trước, sau đó thực hiện
Đây là yếu tố quan trọng nhất. Trước khi gọi cho bất kỳ chuyên gia nào, điều phối viên sẽ được hướng dẫn đưa ra một kế hoạch có đánh số:
I'll create your campaign by coordinating the specialist agents in sequence:
1. Brand Strategist - develop positioning and audience insights
2. Copywriter - write captions using those insights
3. Visual Designer - create image prompts aligned with the copy
4. Critic - review and score the full package
5. Project Manager - build the timeline and task breakdown
Nếu không có bước này, LLM sẽ chuyển thẳng sang các lệnh gọi công cụ và không theo dõi được vị trí của mình trong quy trình làm việc, đặc biệt là sau khi nhận được phản hồi dài từ một chuyên gia. Việc vạch ra kế hoạch trước tiên sẽ giúp neo giữ trình điều phối: trình điều phối biết bước hiện tại, bước tiếp theo và toàn bộ quy trình. Nếu bỏ qua bước này, trình điều phối sẽ bị dừng giữa quy trình công việc hoặc lặp lại các bước.
Phần tử 1 – Định nghĩa vai trò rõ ràng
❌ "You are a helpful creative assistant."
✅ "You orchestrate specialists. You do NOT write captions, designs, or timelines yourself."
Nếu không có lệnh cấm rõ ràng, đôi khi LLM sẽ bỏ qua việc gọi chuyên gia và tạo nội dung trực tiếp – việc này nhanh hơn và LLM "biết" cách thực hiện. Hướng dẫn phải làm cho điều này trở nên sai.
Phần tử 2 – Cú pháp gọi công cụ có liệt kê các mẫu không chính xác
Chỉ cho thấy cú pháp chính xác là chưa đủ. LLM có thể tạo ra các lệnh gọi có vẻ hợp lý nhưng không thành công. Câu lệnh liệt kê rõ ràng cả mẫu chính xác và những mẫu không bao giờ được sử dụng:
✅ copywriter(request="...") ← correct
❌ print(copywriter(...)) ← breaks silently
❌ default_api.copywriter(...) ← breaks silently
❌ copywriter.run(...) ← breaks silently
❌ agents.copywriter(...) ← breaks silently
Việc liệt kê các mẫu sai một cách rõ ràng đã giảm khoảng 95% các lệnh gọi công cụ bị lỗi trong quá trình phát hành chính thức.
Phần tử 3 – Thực thi tuần tự từng bước
a) Call the tool
b) Wait for tool_output
c) Verify the output is not an error
d) Confirm to the user: "✓ Brand Strategist complete"
e) Then move to the next agent
Nếu không có các bước (b) và (c), đôi khi LLM sẽ gọi đồng thời hai tác nhân hoặc giả định thành công và tiếp tục trước khi nhận được phản hồi.
Yếu tố 4 – Chỉ thị lỗi: DỪNG, báo cáo, không tiếp tục
Trong các phiên bản đầu tiên, điều phối viên sẽ nhận được lỗi từ một chuyên gia, tạo ra một đầu ra hợp lý cho lỗi đó và tiếp tục đến nhân viên hỗ trợ tiếp theo. Người dùng đã tạo một chiến dịch hoàn chỉnh dựa trên thông tin ảo. Cách khắc phục rất rõ ràng: DỪNG ngay lập tức. Báo cáo chính xác lỗi. Không bao giờ tiếp tục.
Phần tử 5 – Quy tắc truyền ngữ cảnh
Nhân viên hỗ trợ từ xa không có nhật ký trò chuyện. Khi điều phối viên gọi Copywriter thông qua A2A, Copywriter chỉ thấy thông báo trong yêu cầu duy nhất đó – Copywriter không biết Brand Strategist đã nói gì. Trình điều phối phải kết hợp rõ ràng các đầu ra trước đó vào mỗi lệnh gọi tiếp theo:
copywriter(request="Create 3 posts for EcoFlow water bottle targeting millennials.
Use these insights from the Brand Strategist: [paste full strategist output here].
Create engaging captions with hashtags.")
Hướng dẫn này nêu rõ: "Các tác nhân từ xa KHÔNG có bộ nhớ dùng chung – bạn phải truyền rõ ràng các đầu ra trước đó." Nếu không có thông tin này, mỗi nhân viên hỗ trợ sẽ không biết được thông tin gì.
Phần tử 6 – Phân loại yêu cầu: đơn giản so với phức tạp
Không phải yêu cầu nào cũng cần cả 5 tác nhân. Câu lệnh hướng dẫn trình điều phối phân loại yêu cầu trước khi lập kế hoạch:
SIMPLE → one agent needed
"Research the eco-friendly water bottle market" → brand_strategist only
"Write 3 Instagram captions" → copywriter only
COMPLEX → all agents sequentially
"Create a complete campaign with timeline" → all 5 agents
Nếu không có phân loại này, trình điều phối sẽ chạy cả 5 tác nhân cho mọi yêu cầu (kể cả "chỉ cần cho tôi 3 ý tưởng đăng bài"), làm tăng độ trễ và chi phí không cần thiết.
Yếu tố 7 – Quy tắc giao tiếp: hiển thị toàn bộ đầu ra, không lọc
Câu lệnh này nêu rõ rằng điều phối viên không được tóm tắt hoặc chỉnh sửa những gì chuyên gia trả về:
- DO NOT summarize unless the output exceeds 2000 words
- DO NOT filter or edit agent responses
- Show the user exactly what each specialist produced
- NEVER say results are ready unless you received them in tool_output
Nếu không có thông tin này, trình điều phối sẽ viết lại đầu ra của chuyên gia bằng ngôn từ của riêng mình, dẫn đến việc mất chi tiết, xuất hiện lỗi và làm mất mục đích của việc có chuyên gia.
Yếu tố 8 – Hoàn tất quy trình làm việc: không bao giờ dừng lại quá sớm
Một chế độ lỗi tinh vi nhưng nghiêm trọng: trình điều phối thông báo kế hoạch 5 bước, hoàn thành 3 bước, sau đó trình bày kết quả như thể đã hoàn tất. Lời nhắc ngăn chặn điều này bằng một danh sách kiểm tra rõ ràng mà bạn phải vượt qua thì trình điều phối mới có thể hoàn tất:
✓ Did I announce a plan with N agents?
✓ Have I called ALL N agents from my plan?
✓ Did each agent respond successfully?
✓ Am I presenting complete results from ALL agents?
If any answer is NO → continue executing the remaining agents.
Điều này ngăn trình điều phối coi một lần chạy một phần là hoàn tất.
Vòng lặp kiểm soát chất lượng
Quy trình sửa đổi là phần phức tạp nhất của prompt.py. Mở phần ## REVISION WORKFLOW và làm theo.
Cách hoạt động
Sau khi Nhà phê bình phản hồi, Giám đốc sáng tạo không tiếp tục chuyển thông tin một cách mù quáng cho Quản lý dự án. Nút này đọc đầu ra của Critic và phân nhánh:
Critic output
│
├── "All Approved: YES"
│ └──► proceed to Project Manager
│
└── "Status: NEEDS_REVISION"
│
├── posts fail → call copywriter again with feedback
├── visuals fail → call designer again with feedback
└── both fail → call copywriter, then designer
│
└──► revised output → Project Manager
(1 revision max per deliverable)
Đây là tính năng dựa trên LLM, không phải dựa trên mã
Lớp học lập trình đã đề cập trước đó rằng trình điều phối sẽ "phân tích cú pháp" phản hồi của Critic. Không có mã Python nào thực hiện việc phân tích cú pháp này – không có biểu thức chính quy, không có tính năng so khớp chuỗi. Giám đốc sáng tạo là một LLM đọc hướng dẫn của riêng mình. Hướng dẫn đó có nội dung như sau:
Look for "Status: NEEDS_REVISION" in the critic's response.
Posts need revision → call copywriter
Visuals need revision → call designer
LLM sẽ đọc chính xác những chuỗi đó trong đầu ra của Critic và đi theo nhánh. Đó là lý do tại sao định dạng của Nhà phê bình là không thể thương lượng: nếu Nhà phê bình viết "cần chỉnh sửa" thay vì NEEDS_REVISION, thì LLM sẽ không tìm thấy kết quả phù hợp trong hướng dẫn của mình và âm thầm bỏ qua bước sửa đổi.
Cách chuyển tiếp ngữ cảnh trong lệnh gọi sửa đổi
Lệnh gọi sửa đổi tuân theo cùng một quy tắc truyền ngữ cảnh từ Phần tử 5 – trình điều phối phải bao gồm mọi thứ một cách rõ ràng vì Copywriter không nhớ phiên bản đầu tiên của mình:
"I need you to revise the Instagram posts based on critic feedback.
ORIGINAL BRIEF:
[the original user request]
YOUR FIRST VERSION:
[the posts the copywriter created]
CRITIC FEEDBACK (Score: 6/10 - NEEDS_REVISION):
[the critic's specific suggestions]
Please revise the posts addressing this feedback while maintaining
the strengths the critic identified."
Nếu không có phần "YOUR FIRST VERSION" (PHIÊN BẢN ĐẦU TIÊN CỦA BẠN), Trình viết quảng cáo sẽ viết từ đầu thay vì cải thiện những gì đã tạo ra.
Giới hạn 1 lần sửa đổi và lý do giới hạn này quan trọng
Sau một vòng chỉnh sửa, người điều phối sẽ chuyển đến Quản lý dự án bất kể điểm số là bao nhiêu. Hướng dẫn này theo dõi điều này trong đầu:
After calling copywriter for revision once:
→ mark "copywriter_revised = true" in context
→ even if the critic still suggests changes, proceed to PM
Nếu không có giới hạn này, vòng lặp có thể chạy vô thời hạn: Người đánh giá gắn cờ một vấn đề → Người viết quảng cáo sửa đổi → Người đánh giá gắn cờ lại → Người viết quảng cáo sửa đổi lại. Mỗi vòng đều tốn mã thông báo và thời gian. Một lần sửa đổi là đủ để cải thiện chất lượng mà không có nguy cơ xảy ra vòng lặp không kiểm soát.
Những thông tin được chuyển cho Trưởng dự án
Quản lý dự án luôn nhận được các phiên bản cuối cùng đã được phê duyệt, chứ không phải phiên bản gốc. Nếu có bản sửa đổi, trình điều phối sẽ chuyển bản sao và hình ảnh đã sửa đổi. Nếu mọi thứ đều được phê duyệt trong lần đầu tiên, thì yêu cầu sẽ được chuyển thẳng đến bước đó. PM không bao giờ nhìn thấy bản nháp bị từ chối.
TODO 2 – Đăng ký từng chuyên gia làm RemoteA2aAgent + AgentTool
Tìm bình luận # TODO 2: For each specialist URL... rồi thay thế bằng:
if strategist_url:
available_agents_list.append(
"- **brand_strategist**: Market research, competitor analysis, trend identification"
)
strategist_agent = RemoteA2aAgent(
name="brand_strategist",
description="Researches markets, competitors, and trends using Google Search",
agent_card=f"{strategist_url}/.well-known/agent.json",
)
agent_tools.append(AgentTool(agent=strategist_agent))
if copywriter_url:
available_agents_list.append(
"- **copywriter**: Instagram captions, hashtags, and CTAs"
)
copywriter_agent = RemoteA2aAgent(
name="copywriter",
description="Creates Instagram captions with hashtags and CTAs",
agent_card=f"{copywriter_url}/.well-known/agent.json",
)
agent_tools.append(AgentTool(agent=copywriter_agent))
if designer_url:
available_agents_list.append(
"- **designer**: Visual concepts and real images generated via Gemini (GCS URIs returned)"
)
designer_agent = RemoteA2aAgent(
name="designer",
description="Creates visual concepts and generates real images via Gemini, stored in GCS",
agent_card=f"{designer_url}/.well-known/agent.json",
)
agent_tools.append(AgentTool(agent=designer_agent))
if critic_url:
available_agents_list.append(
"- **critic**: Quality review with APPROVED/NEEDS_REVISION scoring"
)
critic_agent = RemoteA2aAgent(
name="critic",
description="Reviews campaign materials and returns structured quality feedback",
agent_card=f"{critic_url}/.well-known/agent.json",
)
agent_tools.append(AgentTool(agent=critic_agent))
if pm_url:
available_agents_list.append(
"- **project_manager**: Project timelines, task breakdowns, Notion integration"
)
pm_agent = RemoteA2aAgent(
name="project_manager",
description="Creates project timelines and task breakdowns, optionally in Notion",
agent_card=f"{pm_url}/.well-known/agent.json",
)
agent_tools.append(AgentTool(agent=pm_agent))
TODO 3 – Gói trong một Ứng dụng có tính năng nén bối cảnh
Lý do cần có quy trình nén
Mọi tin nhắn trong một cuộc trò chuyện (câu lệnh của người dùng, mọi lệnh gọi công cụ, mọi phản hồi của công cụ) đều được thêm vào cửa sổ ngữ cảnh mà LLM đọc ở lượt tiếp theo. Trong quy trình gồm 5 nhân viên, số lượng này sẽ tăng lên nhanh chóng:
Turn 1: user prompt ~200 tokens
Turn 2: orchestrator plan ~300 tokens
Turn 3: brand_strategist tool_call ~150 tokens
Turn 4: brand_strategist tool_output ~1,500 tokens ← full research report
Turn 5: copywriter tool_call ~300 tokens ← must include strategist output
Turn 6: copywriter tool_output ~2,000 tokens ← 3 captions
Turn 7: designer tool_call ~500 tokens
Turn 8: designer tool_output ~1,500 tokens
...
Đối với Agent 4 (Nhà phê bình), cửa sổ ngữ cảnh chứa toàn bộ kết quả đầu ra của cả 3 tác nhân trước đó – thường là 8.000 đến 12.000 mã thông báo chỉ trong các phản hồi của công cụ. Ngay cả khi Gemini 2.5 Pro có cửa sổ ngữ cảnh lớn, chất lượng suy luận của trình điều phối vẫn giảm sút vì trình điều phối phải xử lý một lượng dữ liệu ngày càng tăng. Nếu không có tính năng nén, các quy trình công việc dài sẽ đạt đến giới hạn thực tế đối với Tác nhân 4.
Tác dụng của việc nén
Thay vì lưu giữ mọi sự kiện đầy đủ, ADK định kỳ gọi một LLM để tóm tắt các sự kiện cũ thành một bản trình bày ngắn gọn. Hệ thống chỉ lưu giữ bản tóm tắt các sự kiện trước đây và toàn bộ kết quả của tác nhân gần đây nhất trong ngữ cảnh.
Without compaction:
[full strategist output] + [full copywriter output] + [full designer output] + → Critic
With compaction (interval=3, overlap=1):
[summary of strategist + copywriter] + [full designer output] + → Critic
Bản tóm tắt vẫn giữ nguyên các thông tin cần thiết (thông tin chi tiết chính, phụ đề đã được phê duyệt, khái niệm trực quan) trong khi loại bỏ định dạng dài dòng, bối cảnh lặp lại được truyền cho từng tác nhân và quá trình suy luận trung gian. Nhà phê bình vẫn có mọi thứ cần thiết để đánh giá – họ chỉ đọc bản tóm tắt thay vì 3 báo cáo đầy đủ.
Mã
Tìm bình luận # TODO 3: Wrap the agent in an App... rồi thay thế phần giữ chỗ App(...) bằng:
from google.adk.apps import App
from google.adk.apps.app import EventsCompactionConfig
from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
from google.adk.models import Gemini
compaction_config = EventsCompactionConfig(
summarizer=LlmEventSummarizer(llm=Gemini(model_id=os.getenv("GEMINI_MODEL", "gemini-2.5-flash"))),
compaction_interval=3, # Summarize after every 3 agent completions
overlap_size=1, # Keep the most recent agent's output in full
)
app = App(
name="creative_director",
root_agent=agent,
events_compaction_config=compaction_config,
plugins=[LoggingPlugin()],
)
return agent, app
compaction_interval=3 – quá trình nén sẽ diễn ra sau mỗi 3 lần hoàn thành của nhân viên hỗ trợ. Đối với một quy trình gồm 5 tác nhân, điều này có nghĩa là quy trình sẽ kích hoạt một lần (sau các tác nhân 1–3), sau đó Critic và PM sẽ thấy bản tóm tắt về 1–3 cộng với toàn bộ đầu ra của tác nhân trước đó.
overlap_size=1 – đầu ra đầy đủ gần đây nhất của tác nhân luôn được giữ nguyên văn, không bao giờ được tóm tắt. Điều này rất quan trọng vì Nhà phê bình cần toàn bộ đầu ra của Nhà thiết kế (bao gồm cả các giá trị gcs_uri) để tải và xem xét hình ảnh thực tế. Bản tóm tắt sẽ mất những URI đó.
Cách hoạt động trong một chiến dịch chạy đầy đủ:
Agent 1 (Strategist) → full context
Agent 2 (Copywriter) → full context
Agent 3 (Designer) → full context
↓ compaction fires: summarizes agents 1-2, keeps 3 in full
Agent 4 (Critic) → sees [summary of 1-2] + [full output of 3]
Agent 5 (PM) → sees [summary of 1-3] + [full output of 4]
Tìm hiểu về RemoteA2aAgent và AgentTool
RemoteA2aAgent("brand_strategist", agent_card=url)
│
│ wraps the remote service so ADK can call it
▼
AgentTool(agent=strategist_agent)
│
│ exposes it as a callable tool to the LLM
▼
Agent(tools=[...])
│
│ LLM calls tool("brand_strategist", message=...) when needed
▼
brand-strategist-xxxx.run.app ← actual HTTP A2A call happens here
LLM quyết định thời điểm gọi từng công cụ dựa trên chỉ dẫn của hệ thống và yêu cầu của người dùng. Trình điều phối không bao giờ gọi trực tiếp các tác nhân trong mã – tất cả đều dựa trên khả năng suy luận của LLM.
Kiểm thử Creative Director cục bộ
uv run adk web agents --allow_origins='*'
Mở Web Preview (Xem trước trên web) trên cổng 8000. Sử dụng trình đơn thả xuống về trợ lý để chọn creative_director, sau đó thử:
Research the eco-friendly water bottle market for health-conscious millennials
Bạn sẽ thấy rằng Giám đốc sáng tạo sẽ chỉ chuyển yêu cầu này cho Nhà chiến lược thương hiệu và bạn sẽ nhận được phản hồi từ Nhà chiến lược thương hiệu.
Đối với toàn bộ chiến dịch, hãy thử làm như sau:
Create a complete Instagram campaign for SolarPack portable solar charger targeting
outdoor enthusiasts and digital nomads aged 22-35.
Budget $2,000, launch in 2 weeks.
Bạn sẽ thấy Giám đốc sáng tạo phối hợp tất cả 5 chuyên gia theo trình tự, với đầu ra của mỗi chuyên gia được chuyển cho chuyên gia tiếp theo.

Dừng Creative Director (Ctrl+C) trước khi tiếp tục – trình kiểm tra A2A cũng sử dụng cổng 8000.
Dừng 5 máy chủ chuyên dụng (Ctrl+C trong mỗi thiết bị đầu cuối) khi bạn hoàn tất kiểm thử cục bộ.
12. Triển khai và kiểm thử các Đặc vụ chuyên trách
Giờ đây, chúng ta đã sẵn sàng triển khai các tác nhân của mình lên Google Cloud. Cloud Run là một dịch vụ tuyệt vời để triển khai các tác nhân. Đây là một dịch vụ không máy chủ, có khả năng mở rộng và dễ sử dụng. Mỗi tác nhân chuyên biệt được triển khai dưới dạng một dịch vụ Cloud Run độc lập.
Cấu hình triển khai
Dockerfile của mỗi chuyên gia đều tuân theo mẫu sau:
FROM python:3.12-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends gcc curl
# Fast dependency install with uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
COPY pyproject.toml .
RUN uv sync --no-install-project --no-dev
COPY . .
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
ENV PYTHONUNBUFFERED=1 PORT=8080 HOST=0.0.0.0
EXPOSE 8080
CMD ["uv", "run", "python", "agent.py"]
Triển khai tuần tự cả 5 chuyên gia
cd ~/ai-creative-studio/workshop/starter
source .env
uv run deploy/deploy_all_specialists.py
Tập lệnh này triển khai cả 5 tác nhân cùng một lúc (tổng cộng khoảng 10 đến 12 phút). Việc triển khai tuần tự giúp tránh hạn mức thăm dò ý kiến của Cloud Build (60 yêu cầu/phút). Khi hoàn tất, thao tác này sẽ ghi URL Cloud Run của từng tác nhân trở lại .env.
Sau khi được triển khai, tập lệnh sẽ tự động cấp cho tài khoản dịch vụ Cloud Run của Designer roles/storage.objectCreator trên bộ chứa GCS của bạn để có thể tải hình ảnh đã tạo lên.
Nếu bạn đã định cấu hình thông tin đăng nhập Notion trong .env, thì tập lệnh cũng sẽ lưu trữ thông tin đó một cách an toàn trong Secret Manager (dưới dạng notion-token, notion-project-db-id, notion-tasks-db-id) và chèn thông tin đó vào dịch vụ Project Manager thông qua --set-secrets thay vì các biến môi trường thuần tuý. Điều này có nghĩa là mã thông báo sẽ không bao giờ xuất hiện trong thẻ môi trường của Cloud Run hoặc trong nhật ký lệnh gcloud.
Xác minh quy trình triển khai
Khi quá trình triển khai hoàn tất, tập lệnh sẽ tự động ghi các URL Cloud Run trở lại .env, thay thế các URL localhost ở bước trước:
source .env
echo "Deployed URLs:"
echo " Brand Strategist: $STRATEGIST_AGENT_URL"
echo " Copywriter: $COPYWRITER_AGENT_URL"
echo " Designer: $DESIGNER_AGENT_URL"
echo " Critic: $CRITIC_AGENT_URL"
echo " Project Manager: $PM_AGENT_URL"
Trình tạo mẫu quảng cáo sẽ tự động sử dụng các URL Cloud Run này khi được triển khai vào Thời gian chạy của tác nhân ở bước tiếp theo.
Xác minh thẻ nhân viên hỗ trợ
Mỗi tác nhân được triển khai sẽ hiển thị một thẻ tác nhân tại /.well-known/agent.json. Tìm nạp các trang đó để xác nhận rằng mọi thứ đều đang hoạt động:
source .env
for agent_url in $STRATEGIST_AGENT_URL $COPYWRITER_AGENT_URL $DESIGNER_AGENT_URL $CRITIC_AGENT_URL $PM_AGENT_URL; do
echo "=== Agent Card: $agent_url ==="
curl -s "${agent_url}/.well-known/agent.json" | python3 -m json.tool | grep -E '"name"|"url"|"description"'
echo ""
done
Kết quả đầu ra dự kiến cho mỗi tác nhân:
"name": "brand_strategist",
"url": "https://brand-strategist-xxxx.run.app",
"description": "Brand strategist for market research and competitive insights"
Thử nghiệm bằng Công cụ kiểm tra A2A (Cloud Run)
A2A Inspector đã được cài đặt từ Bước 10. Bắt đầu:
cd ~/a2a-inspector
bash scripts/run.sh
Mở Web Preview (Xem trước trên web) → Change port (Thay đổi cổng) → 5001. Nhập URL Cloud Run vào trường kết nối:
https://brand-strategist-xxxx.us-central1.run.app
Nhấp vào Kết nối – không cần mã xác thực vì các dịch vụ được triển khai bằng --allow-unauthenticated.
Trình kiểm tra sẽ kết nối, xác thực thẻ tác nhân và cho phép bạn trò chuyện tương tác qua A2A.
Kiểm tra các tác nhân được triển khai trên Cloud Run
Sau khi triển khai lên Cloud Run, hãy trỏ trình kiểm tra đến URL HTTPS công khai để xác minh rằng quá trình triển khai trên đám mây đang hoạt động:

Quy trình này giống hệt nhau: dán URL Cloud Run, kết nối và gửi một tin nhắn thử nghiệm. Nếu thẻ của nhân viên hỗ trợ tải và cuộc trò chuyện phản hồi, thì tức là chuyên viên đã được triển khai đúng cách và có thể liên hệ được.
13. Triển khai Creative Director cho Thời gian chạy tác nhân
Trình điều phối được triển khai cho Thời gian chạy của tác nhân, cung cấp trạng thái phiên được quản lý, tính năng tự động cấp tài nguyên bổ sung và tính năng theo dõi tích hợp.
Tại sao cần có Thời gian chạy tác nhân cho trình điều phối?
Năm chuyên gia này được triển khai đến Cloud Run – một nền tảng nhẹ, không trạng thái, mỗi chuyên gia xử lý một nhiệm vụ. Giám đốc sáng tạo có những yêu cầu khác:
Yêu cầu | Tại sao điều này lại quan trọng |
Trạng thái phiên | Một quy trình nhiều bước mất từ 45 giây trở lên. Agent Runtime duy trì trạng thái cuộc trò chuyện giữa các lệnh gọi công cụ của trình điều phối để không bị mất dữ liệu giữa pipeline. |
Tải biến | Đôi khi một chiến dịch mỗi giờ, đôi khi nhiều chiến dịch song song. Agent Runtime sẽ giảm xuống 0 khi không hoạt động và tự động tăng quy mô – bạn không phải trả tiền cho dung lượng không hoạt động. |
Khả năng ghi nhận | Cloud Logging, Cloud Monitoring và Cloud Trace được tích hợp sẵn. Bạn có thể xem mọi lệnh gọi A2A, mọi mã thông báo đã dùng, mọi mức tăng độ trễ mà không cần thêm bất kỳ công cụ đo lường nào. |
Quy trình công việc chạy trong thời gian dài | Cloud Run có thời gian chờ yêu cầu là 3.600 giây. Agent Runtime được thiết kế cho những quy trình có thể mất vài phút, với khả năng quản lý các lần thử lại và duy trì trạng thái. |
Cloud Run là nền tảng phù hợp cho các chuyên gia không trạng thái. Agent Runtime là nền tảng phù hợp cho trình điều phối có trạng thái.
Triển khai trình điều phối
cd ~/ai-creative-studio/workshop/starter
source .env
uv run deploy/deploy_orchestrator.py --action deploy
Quá trình này mất khoảng 5 đến 10 phút. Sau khi hoàn tất, AGENT_ENGINE_ID và AGENT_ENGINE_RESOURCE_NAME sẽ được lưu vào .env.
source .env
echo "Agent Engine ID: $AGENT_ENGINE_ID"
echo "Resource: $AGENT_ENGINE_RESOURCE_NAME"
Cách hoạt động của quy trình triển khai
client.agent_engines.create() đóng gói đối tượng App, tải đối tượng đó lên cùng với các phần phụ thuộc và triển khai đối tượng đó vào cơ sở hạ tầng được quản lý. Sau đây là chức năng của từng tham số:
import vertexai
from vertexai import Client, agent_engines
vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)
# Wrap the App in an AdkApp adapter - enables tracing in Cloud Trace
adk_app = agent_engines.AdkApp(app=root_app, enable_tracing=True)
# Initialize client and deploy
client = Client(project=PROJECT_ID, location=LOCATION)
agent_engine_resource = client.agent_engines.create(
agent=adk_app,
config={
"staging_bucket": STAGING_BUCKET, # GCS bucket for packaging artifacts
"display_name": "Creative Director",
# Python packages installed in the managed runtime - pin for reproducibility
"requirements": [
"google-cloud-aiplatform[agent_engines]>=1.132.0,<2.0.0",
"google-adk[a2a]==1.31.1",
"google-genai>=1.70.0",
"google-cloud-storage>=2.10.0",
"python-dotenv>=1.0.0",
"pydantic>=2.0.0",
"cloudpickle>=3.0.0",
],
# Specialist URLs passed as env vars - the orchestrator reads these at runtime
"env_vars": {
"COPYWRITER_AGENT_URL": COPYWRITER_URL,
"DESIGNER_AGENT_URL": DESIGNER_URL,
"STRATEGIST_AGENT_URL": STRATEGIST_URL,
"CRITIC_AGENT_URL": CRITIC_URL,
"PM_AGENT_URL": PM_URL,
},
},
)
resource_name = agent_engine_resource.api_resource.name
agent_engine_id = resource_name.split("/")[-1]
Những điều xảy ra ở chế độ nền:
1. Agent Engine packages your App + requirements into a container
2. Uploads it to the staging bucket in your project
3. Deploys to managed compute (you never see or manage the VM)
4. Returns a resource name: projects/.../locations/.../reasoningEngines/<id>
5. That ID is saved to .env as AGENT_ENGINE_ID
Sau khi triển khai, trình điều phối sẽ kết nối với 5 chuyên gia Cloud Run thông qua các URL trong biến môi trường của trình điều phối
- các biến này được truyền qua
.envtrước khi tập lệnh triển khai chạy.
14. Chạy một chiến dịch từ đầu đến cuối
Toàn bộ hệ thống được triển khai. Chạy một chiến dịch hoàn chỉnh từ sân chơi Agent Runtime.
Mở bản nháp Agent Runtime
- Truy cập vào https://console.cloud.google.com/agent-platform/runtimes. Bạn cũng có thể chuyển đến Agent Runtime từ Agent Platform > Agents > Deployments (Nền tảng tác nhân > Tác nhân > Triển khai).
- Chọn Agent Runtime đã triển khai (
creative-director) - Nhấp vào Playground (Sân chơi) trong thanh bên trái
- Nhấp vào Phiên mới để mở một cuộc trò chuyện mới
Chạy một chiến dịch đầy đủ
Dán bản tóm tắt này vào cuộc trò chuyện rồi gửi:
Create a complete Instagram campaign for:
- Product: EcoFlow Smart Water Bottle (tracks hydration, keeps drinks cold 24h)
- Target Audience: Health-conscious millennials, 25-35 years old
- Platform: Instagram
- Goal: Brand awareness + drive website traffic
- Brand Voice: Motivational, clean, science-backed
- Budget: $3,000
- Timeline: Launch in 2 weeks
Giám đốc sáng tạo sẽ thực hiện cả 5 tác nhân theo trình tự:
- Nhà chiến lược thương hiệu → nghiên cứu thị trường, phân tích đối thủ cạnh tranh, thông tin chi tiết về đối tượng
- Người viết quảng cáo → 3 bài đăng trên Instagram kèm chú thích, hashtag và lời kêu gọi hành động
- Nhà thiết kế → ý tưởng trực quan + hình ảnh thực tế do Gemini tạo (URI GCS) cho mỗi bài đăng
- Nhà phê bình → bài đánh giá chất lượng có điểm số LÀM_LẠI / CẦN_CHỈNH_SỬA
- (Sửa đổi nếu cần) → Chuyên viên nội dung quảng cáo hoặc nhà thiết kế được gọi lại để nhận ý kiến phản hồi
- Quản lý dự án → Lịch trình 2 tuần, phân chia công việc, phân bổ ngân sách

Kiểm thử tính năng định tuyến một nhân viên
Gửi yêu cầu ngắn hơn này trong một phiên mới:
Research the luxury skincare market - top brands and trends in 2025
Lưu ý rằng Giám đốc sáng tạo chỉ chuyển yêu cầu này cho Nhà chiến lược thương hiệu – không có nhân viên nào khác được gọi. Đây là logic phân loại yêu cầu từ chỉ dẫn hệ thống hoạt động chính xác.
Kiểm tra dấu vết thực thi
Trong khi vẫn ở trong bảng điều khiển:
- Nhấp vào Traces (Dấu vết) trong thanh bên trái (bên cạnh Playground)
- Trong Trace View (Chế độ xem dấu vết), hãy chọn dấu vết cho phiên bạn vừa chạy
- Mở rộng cây dấu vết để xem từng lệnh gọi tác nhân, đầu vào/đầu ra, độ trễ và mức sử dụng mã thông báo
Mỗi lệnh gọi A2A đến một chuyên gia sẽ xuất hiện dưới dạng một khoảng thời gian riêng biệt. Bạn có thể xem chính xác ngữ cảnh mà Giám đốc sáng tạo đã truyền cho từng tác nhân và những gì tác nhân đó nhận được.
Không bắt buộc: Chạy từ thiết bị đầu cuối
Bạn cũng có thể chạy chiến dịch theo cách lập trình bằng cách sử dụng tập lệnh run_campaign.py đã có trong chương trình khởi động.
cd ~/ai-creative-studio/workshop/starter
uv run run_campaign.py
15. Dọn dẹp
Dọn dẹp tài nguyên trên Google Cloud để tránh bị tính phí liên tục.
Chạy tập lệnh xoá – tập lệnh này sẽ đọc .env của bạn và xoá mọi thứ đã tạo trong lớp học lập trình này:
bash deploy/teardown_gcp.sh
Tập lệnh sẽ cho bạn biết chính xác những gì sẽ bị xoá và nhắc bạn xác nhận trước khi thực hiện bất kỳ thao tác nào:
Tài nguyên | Nội dung sẽ bị xoá |
Dịch vụ Cloud Run | chuyên viên lập chiến lược thương hiệu, chuyên viên nội dung quảng cáo, nhà thiết kế, nhà phê bình, nhà quản lý dự án |
Thời gian chạy của tác nhân | Công cụ suy luận của Giám đốc sáng tạo + tất cả các phiên |
Artifact Registry |
|
Bộ chứa GCS |
|
Secret Manager |
|
Kiểm tra để đảm bảo mọi thứ đều đã được xoá
gcloud run services list --region=us-central1
gcloud storage buckets list --project=$GCP_PROJECT_ID
Kết quả đầu ra dự kiến: danh sách trống hoặc chỉ có các tài nguyên hiện có của riêng bạn.
16. Tóm tắt
Xin chúc mừng! Bạn đã xây dựng và triển khai một hệ thống AI đa tác nhân cấp sản xuất trên Google Cloud.
Sản phẩm bạn đã tạo
Nhân viên hỗ trợ | Chức năng | Triển khai |
Chuyên viên hoạch định chiến lược thương hiệu | Nghiên cứu thị trường thông qua Google Tìm kiếm | Cloud Run |
Người viết quảng cáo | Tạo chú thích trên Instagram | Cloud Run |
Nhà thiết kế | Tạo hình ảnh thông qua Gemini + tải lên GCS | Cloud Run |
Nhà phê bình | Đánh giá chất lượng có tính điểm | Cloud Run |
Quản lý dự án | Dòng thời gian + Notion MCP | Cloud Run |
Giám đốc sáng tạo | Điều phối đầy đủ thông qua A2A | Thời gian chạy của tác nhân |
Các thói quen chính bạn đã học được
- ADK
Agent– xác định một tác nhân LLM bằng hướng dẫn + các công cụ không bắt buộc adk web– chạy và kiểm thử mọi tác nhân ADK cục bộ bằng giao diện người dùng trò chuyện tích hợpSkillToolset– đóng gói kiến thức có thể tái sử dụng thành các tệp mô-đun được tải theo yêu cầuFunctionTool– gói mọi hàm Python (hoặc mô hình bên ngoài) dưới dạng một công cụ có thể gọi của tác nhânto_a2a()– cung cấp mọi tác nhân ADK dưới dạng dịch vụ HTTPS tuân thủ A2ARemoteA2aAgent+AgentTool– điều phối các tác nhân từ xa dưới dạng các công cụ có thể gọiMcpToolset– kết nối với các dịch vụ bên ngoài thông qua máy chủ stdio MCPEventsCompactionConfig– xử lý giới hạn mã thông báo trong quy trình công việc dài có nhiều tác nhân- Đầu ra có cấu trúc của công cụ kiểm lỗi – kiểm soát chất lượng mà máy đọc được bằng tính năng sửa đổi tự động
- Cloud Run – triển khai các tác nhân nằm trong vùng chứa ở quy mô lớn
- Thời gian chạy của tác nhân – điều phối viên lưu trữ với các phiên được quản lý và tính năng theo dõi
Các bước tiếp theo
- Thêm tính năng chỉnh sửa hình ảnh nhiều lượt vào Designer bằng tính năng chỉnh sửa của
gemini-3.1-flash-image-preview - Thêm xác thực IAM vào các dịch vụ Cloud Run (xoá
--allow-unauthenticated) - Thay thế một chuyên gia bằng tác nhân LangGraph hoặc CrewAI – A2A không phụ thuộc vào khung
- Thêm ý kiến phản hồi của người dùng làm công cụ để người tham gia có thể đánh giá và lặp lại các kết quả
- Khám phá tính năng Theo dõi thời gian chạy của tác nhân trong Bảng điều khiển Cloud