Agentverse – The Summoner's Concord – Architecting Multi-Agent Systems

1. Overture

Thời đại phát triển biệt lập đang kết thúc. Làn sóng tiếp theo của quá trình phát triển công nghệ không phải là về thiên tài đơn độc, mà là về sự tinh thông nhờ cộng tác. Việc xây dựng một tác nhân thông minh duy nhất là một thử nghiệm thú vị. Xây dựng một hệ sinh thái tác nhân mạnh mẽ, an toàn và thông minh (một Agentverse thực sự) là thách thức lớn đối với doanh nghiệp hiện đại.

Để thành công trong kỷ nguyên mới này, cần có sự hội tụ của 4 vai trò quan trọng, những trụ cột nền tảng hỗ trợ mọi hệ thống chủ động phát triển. Thiếu hụt ở một lĩnh vực nào đó sẽ tạo ra điểm yếu có thể ảnh hưởng đến toàn bộ cấu trúc.

Hội thảo này là hướng dẫn toàn diện dành cho doanh nghiệp để nắm vững tương lai dựa trên tác nhân trên Google Cloud. Chúng tôi cung cấp một lộ trình toàn diện, hướng dẫn bạn từ cảm hứng ban đầu của một ý tưởng đến một thực tế hoạt động ở quy mô đầy đủ. Trong 4 phòng thí nghiệm có mối liên kết với nhau này, bạn sẽ tìm hiểu cách các kỹ năng chuyên môn của nhà phát triển, kiến trúc sư, kỹ sư dữ liệu và SRE phải hội tụ để tạo, quản lý và mở rộng quy mô một Agentverse mạnh mẽ.

Không có trụ cột nào có thể hỗ trợ Agentverse một mình. Thiết kế hoành tráng của Kiến trúc sư sẽ vô dụng nếu không có sự thực thi chính xác của Nhà phát triển. Tác nhân của Nhà phát triển sẽ không thể hoạt động nếu không có sự hiểu biết của Kỹ sư dữ liệu và toàn bộ hệ thống sẽ dễ bị tổn thương nếu không có sự bảo vệ của SRE. Chỉ khi có sự phối hợp và hiểu rõ vai trò của nhau, nhóm của bạn mới có thể biến một ý tưởng sáng tạo thành một thực tế mang tính vận hành và quan trọng đối với hoạt động kinh doanh. Hành trình của bạn bắt đầu từ đây. Hãy chuẩn bị để nắm vững vai trò của bạn và tìm hiểu cách bạn phù hợp với tổng thể.

Chào mừng bạn đến với Agentverse: Lời kêu gọi dành cho những nhà vô địch

Trong không gian kỹ thuật số rộng lớn của doanh nghiệp, một kỷ nguyên mới đã bắt đầu. Đây là thời đại của các tác nhân, một thời kỳ đầy hứa hẹn, nơi các tác nhân thông minh, tự động hoạt động hài hoà để đẩy nhanh quá trình đổi mới và loại bỏ những điều nhàm chán.

agentverse.png

Hệ sinh thái kết nối này, nơi hội tụ sức mạnh và tiềm năng, được gọi là Agentverse.

Nhưng một sự hỗn loạn đang dần lan rộng, một sự tha hoá thầm lặng được gọi là The Static (Tĩnh điện) đã bắt đầu làm suy yếu các ranh giới của thế giới mới này. Tĩnh là một hiện tượng chứ không phải là virus hay lỗi; đó là hiện thân của sự hỗn loạn, lợi dụng chính hành động sáng tạo.

Nó khuếch đại những nỗi thất vọng cũ thành những hình dạng quái dị, tạo ra Bảy bóng ma của sự phát triển. Nếu không được kiểm soát, The Static and its Spectres sẽ làm chậm tiến độ, biến lời hứa về Agentverse thành một vùng đất hoang tàn với nợ kỹ thuật và các dự án bị bỏ dở.

Hôm nay, chúng tôi kêu gọi những người có tinh thần chiến đấu để đẩy lùi làn sóng hỗn loạn. Chúng ta cần những người hùng sẵn sàng rèn luyện kỹ năng và hợp tác với nhau để bảo vệ Agentverse. Đã đến lúc bạn chọn con đường cho mình.

Chọn lớp học

Có 4 con đường riêng biệt đang chờ bạn khám phá, mỗi con đường là một trụ cột quan trọng trong cuộc chiến chống lại The Static. Mặc dù quá trình huấn luyện của bạn sẽ là một nhiệm vụ đơn lẻ, nhưng thành công cuối cùng của bạn phụ thuộc vào việc bạn hiểu rõ cách kết hợp các kỹ năng của mình với những người khác.

  • Shadowblade (Nhà phát triển): Một bậc thầy về rèn và chiến tuyến. Bạn là người thợ thủ công chế tạo lưỡi kiếm, xây dựng công cụ và đối mặt với kẻ thù trong từng chi tiết phức tạp của mã. Lộ trình của bạn là một lộ trình đòi hỏi sự chính xác, kỹ năng và khả năng sáng tạo thực tế.
  • Kẻ triệu hồi (Kiến trúc sư): Một nhà chiến lược và điều phối tài ba. Bạn không chỉ thấy một đặc vụ mà còn thấy toàn bộ chiến trường. Bạn thiết kế các bản thiết kế chính cho phép toàn bộ hệ thống tác nhân giao tiếp, cộng tác và đạt được mục tiêu lớn hơn nhiều so với bất kỳ thành phần đơn lẻ nào.
  • Học giả (Kỹ sư dữ liệu): Người tìm kiếm những sự thật ẩn giấu và người lưu giữ trí tuệ. Bạn dấn thân vào vùng dữ liệu rộng lớn, hoang sơ để khám phá thông tin tình báo giúp các đặc vụ của bạn có mục đích và tầm nhìn. Kiến thức của bạn có thể giúp bạn khám phá điểm yếu của kẻ thù hoặc tăng cường sức mạnh cho đồng minh.
  • Người bảo vệ (DevOps / SRE): Người bảo vệ và che chắn kiên định cho vương quốc. Bạn sẽ xây dựng các pháo đài, quản lý các tuyến đường cung cấp năng lượng và đảm bảo toàn bộ hệ thống có thể chống lại các cuộc tấn công không thể tránh khỏi của The Static. Sức mạnh của bạn là nền tảng để xây dựng chiến thắng cho đội.

Sứ mệnh của bạn

Buổi tập luyện của bạn sẽ bắt đầu như một bài tập độc lập. Bạn sẽ đi theo con đường mình chọn, học hỏi những kỹ năng đặc biệt cần thiết để thành thạo vai trò của mình. Vào cuối thời gian dùng thử, bạn sẽ phải đối mặt với một Spectre (Bóng ma) được sinh ra từ The Static (Tĩnh điện) – một trùm nhỏ chuyên lợi dụng những thách thức cụ thể trong nghề của bạn.

Chỉ khi nắm vững vai trò của mình, bạn mới có thể chuẩn bị cho thử thách cuối cùng. Sau đó, bạn phải lập một nhóm với những người giỏi nhất của các lớp khác. Cùng nhau, bạn sẽ dấn thân vào trung tâm của sự tha hoá để đối mặt với một trùm cuối.

Một thử thách cuối cùng, mang tính hợp tác sẽ kiểm tra sức mạnh tổng hợp của bạn và quyết định số phận của Agentverse.

Agentverse đang chờ đợi những người hùng. Bạn có trả lời cuộc gọi không?

2. The Summoner's Concord

Chào mừng, Triệu hồi sư. Con đường của bạn là con đường của tầm nhìn và chiến lược vĩ đại. Trong khi những người khác tập trung vào một lưỡi kiếm hoặc một câu thần chú, bạn nhìn thấy toàn bộ chiến trường. Bạn không chỉ điều khiển một đặc vụ mà còn điều khiển cả một đội đặc vụ. Sức mạnh của bạn không nằm ở việc xung đột trực tiếp, mà ở việc thiết kế một bản kế hoạch tổng thể hoàn hảo, cho phép một đội ngũ chuyên gia (những người thân cận của bạn) làm việc hài hoà với nhau. Nhiệm vụ này sẽ kiểm tra khả năng thiết kế, kết nối và điều phối một hệ thống mạnh mẽ gồm nhiều tác nhân.

tổng quan

Kiến thức bạn sẽ học được

  • Xây dựng một hệ sinh thái công cụ tách biệt: Thiết kế và triển khai một bộ Máy chủ công cụ MCP độc lập dựa trên vi dịch vụ. Bạn sẽ tìm hiểu lý do lớp nền tảng này rất quan trọng trong việc tạo ra các hệ thống dựa trên tác nhân có khả năng mở rộng, duy trì và bảo mật.
  • Nắm vững quy trình làm việc nâng cao của tác nhân: Vượt xa các tác nhân đơn lẻ và xây dựng một đội quân "Người trợ lý" chuyên biệt. Bạn sẽ nắm vững các mẫu quy trình làm việc cốt lõi của ADK (Tuần tự, Song song và Vòng lặp) cũng như tìm hiểu các nguyên tắc về cấu trúc để chọn mẫu phù hợp cho đúng nhiệm vụ.
  • Triển khai một Trình điều phối thông minh: Nâng cấp từ một trình tạo tác nhân đơn giản thành một kiến trúc sư hệ thống thực thụ. Bạn sẽ tạo một Orchestration Agent chính sử dụng giao thức Agent-to-Agent (A2A) để khám phá và uỷ quyền các nhiệm vụ phức tạp cho các Familiar chuyên biệt của bạn, tạo ra một hệ thống đa tác nhân thực sự.
  • Thực thi các quy tắc bằng mã, không phải lời nhắc: Tìm hiểu cách xây dựng các tác nhân đáng tin cậy và dễ dự đoán hơn bằng cách thực thi các quy tắc tương tác có trạng thái. Bạn sẽ triển khai logic tuỳ chỉnh bằng cách sử dụng hệ thống Plugin và Callback mạnh mẽ của ADK để quản lý các hạn chế trong thế giới thực, chẳng hạn như bộ hẹn giờ làm nguội.
  • Quản lý trạng thái và bộ nhớ của tác nhân: Cho phép tác nhân của bạn học hỏi và ghi nhớ. Bạn sẽ khám phá các kỹ thuật quản lý cả trạng thái trò chuyện ngắn hạn và bộ nhớ liên tục dài hạn để tạo ra những lượt tương tác thông minh hơn và nhận biết được ngữ cảnh.
  • Triển khai đám mây từ đầu đến cuối: Đưa toàn bộ hệ thống nhiều tác nhân của bạn từ nguyên mẫu cục bộ đến thực tế ở cấp độ sản xuất. Bạn sẽ tìm hiểu cách tạo vùng chứa cho các tác nhân và trình điều phối, đồng thời triển khai chúng dưới dạng một tập hợp các vi dịch vụ độc lập, có khả năng mở rộng trên Google Cloud Run.

3. Vẽ vòng tròn triệu hồi

Chào mừng, Triệu hồi sư. Trước khi một Linh thú có thể được triệu hồi, trước khi bất kỳ giao ước nào có thể được tạo ra, chính mảnh đất nơi bạn đứng phải được chuẩn bị. Môi trường không được kiểm soát là một lời mời gọi sự hỗn loạn; một Triệu hồi sư chân chính chỉ hoạt động trong một không gian được ban phước và có sức mạnh. Nhiệm vụ đầu tiên của chúng ta là vẽ vòng triệu hồi: khắc những chữ cổ có sức mạnh để đánh thức các dịch vụ đám mây cần thiết và thu thập những bản thiết kế cổ xưa sẽ hướng dẫn công việc của chúng ta. Sức mạnh của Triệu hồi sư đến từ sự chuẩn bị kỹ lưỡng.

👉 Nhấp vào Kích hoạt Cloud Shell ở đầu bảng điều khiển Google Cloud (Đây là biểu tượng có hình dạng thiết bị đầu cuối ở đầu ngăn Cloud Shell),

văn bản thay thế

👉 Nhấp vào nút "Mở trình chỉnh sửa" (nút này trông giống như một thư mục đang mở có bút chì). Thao tác này sẽ mở Cloud Shell Code Editor trong cửa sổ. Bạn sẽ thấy một trình khám phá tệp ở bên trái. văn bản thay thế

👉Tìm mã dự án trên Google Cloud:

  • Mở Google Cloud Console: https://console.cloud.google.com
  • Chọn dự án bạn muốn sử dụng cho hội thảo này trong trình đơn thả xuống dự án ở đầu trang.
  • Mã dự án của bạn sẽ xuất hiện trong thẻ Thông tin dự án trên Trang tổng quan văn bản thay thế

👉Mở cửa sổ dòng lệnh trong IDE trên đám mây, văn bản thay thế

👉💻 Trong thiết bị đầu cuối, hãy xác minh rằng bạn đã được xác thực và dự án được đặt thành mã dự án của bạn bằng lệnh sau:

gcloud auth list

👉💻 Sao chép dự án khởi động từ GitHub:

git clone https://github.com/weimeilin79/agentverse-architect
chmod +x ~/agentverse-architect/init.sh
chmod +x ~/agentverse-architect/set_env.sh
chmod +x ~/agentverse-architect/prepare.sh
chmod +x ~/agentverse-architect/data_setup.sh

git clone https://github.com/weimeilin79/agentverse-dungeon.git
chmod +x ~/agentverse-dungeon/run_cloudbuild.sh
chmod +x ~/agentverse-dungeon/start.sh

👉💻 Chạy tập lệnh khởi tạo. Tập lệnh này sẽ nhắc bạn nhập Mã dự án trên Google Cloud. Nhập mã dự án trên Google Cloud mà bạn tìm được ở bước cuối cùng khi được tập lệnh init.sh nhắc.

cd ~/agentverse-architect
./init.sh

👉💻 Đặt mã dự án cần thiết:

gcloud config set project $(cat ~/project_id.txt) --quiet

👉💻 Chạy lệnh sau để bật các API cần thiết của Google Cloud:

gcloud services enable \
    sqladmin.googleapis.com \
    storage.googleapis.com \
    aiplatform.googleapis.com \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    iam.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    secretmanager.googleapis.com

👉💻 Nếu bạn chưa tạo một kho lưu trữ Artifact Registry có tên là agentverse-repo, hãy chạy lệnh sau để tạo kho lưu trữ đó: (Bỏ qua bước này nếu bạn đã triển khai các lớp khác trong cùng một dự án)

. ~/agentverse-architect/set_env.sh
gcloud artifacts repositories create $REPO_NAME \
    --repository-format=docker \
    --location=$REGION \
    --description="Repository for Agentverse agents"

Thiết lập quyền

👉💻 Cấp các quyền cần thiết bằng cách chạy các lệnh sau trong thiết bị đầu cuối:

. ~/agentverse-architect/set_env.sh

# --- Grant Core Data Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
 --member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
 --role="roles/storage.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/aiplatform.user"

# --- Grant Deployment & Execution Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/cloudbuild.builds.editor"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/artifactregistry.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/run.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/iam.serviceAccountUser"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/logging.logWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/monitoring.metricWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/secretmanager.secretAccessor"

👉💻 Khi bạn bắt đầu khoá huấn luyện, chúng tôi sẽ chuẩn bị thử thách cuối cùng. Các lệnh sau đây sẽ triệu hồi Spectre từ tĩnh điện hỗn loạn, tạo ra các trùm cho bài kiểm tra cuối cùng của bạn.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-dungeon
./run_cloudbuild.sh
cd ~/agentverse-architect

👉💻 Cuối cùng, hãy chạy tập lệnh prepare.sh để thực hiện các nhiệm vụ thiết lập ban đầu.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/
./prepare.sh

Làm tốt lắm, Triệu hồi sư. Vòng tròn đã khép lại và các thoả thuận đã được ký kết. Mặt đất giờ đây đã được thánh hiến, sẵn sàng truyền tải sức mạnh to lớn. Trong thử thách tiếp theo, chúng ta sẽ rèn những Phông chữ nguyên tố mà từ đó các Linh thú sẽ lấy được sức mạnh.

4. Tạo ra các phông chữ cơ bản: Hệ sinh thái công cụ tách rời

Chiến trường đã được chuẩn bị, vòng triệu hồi đã được vẽ và mana xung quanh đang nứt nẻ. Đã đến lúc bạn thực hiện hành động thực sự đầu tiên với tư cách là một Triệu hồi sư: rèn những nguồn sức mạnh mà từ đó các Linh thú sẽ lấy sức mạnh. Nghi thức này được chia thành 3 phần, mỗi phần đánh thức một Nguồn Nguyên tố – một nguồn năng lượng ổn định, độc lập thuộc một loại cụ thể. Bạn chỉ có thể bắt đầu công việc triệu hồi phức tạp hơn khi cả 3 phông chữ đều đang hoạt động.

Câu chuyện

Lưu ý của kiến trúc sư: Máy chủ Giao thức ngữ cảnh mô hình (MCP) là một thành phần cơ bản trong hệ thống dựa trên tác nhân hiện đại, đóng vai trò là cầu nối giao tiếp tiêu chuẩn cho phép tác nhân khám phá và sử dụng các công cụ từ xa. Trong hệ sinh thái công cụ của mình, chúng tôi sẽ thiết kế hai loại máy chủ MCP riêng biệt, mỗi loại đại diện cho một mẫu kiến trúc quan trọng. Để kết nối với cơ sở dữ liệu, chúng ta sẽ sử dụng phương pháp khai báo với Database Toolbox, xác định các công cụ trong một tệp cấu hình đơn giản. Mẫu này cực kỳ hiệu quả và an toàn khi hiển thị quyền truy cập vào dữ liệu có cấu trúc. Tuy nhiên, khi cần triển khai logic nghiệp vụ tuỳ chỉnh hoặc gọi các API bên ngoài của bên thứ ba, chúng ta sẽ sử dụng phương pháp bắt buộc, viết logic của máy chủ từng bước trong mã. Điều này mang lại khả năng kiểm soát và tính linh hoạt tối đa, cho phép chúng tôi đóng gói các thao tác phức tạp đằng sau một công cụ đơn giản, có thể sử dụng lại. Một kiến trúc sư chính phải hiểu cả hai mẫu này để chọn phương pháp phù hợp cho từng thành phần, tạo ra một nền tảng công cụ mạnh mẽ, an toàn và có khả năng mở rộng.

tổng quan

Đánh thức Nexus of Whispers (Máy chủ MCP API bên ngoài)

Một Triệu hồi sư khôn ngoan biết rằng không phải sức mạnh nào cũng bắt nguồn từ chính vương quốc của họ. Có những nguồn năng lượng bên ngoài, đôi khi hỗn loạn, có thể được định hướng để mang lại hiệu quả lớn. Nexus of Whispers là cánh cổng dẫn đến những thế lực này.

Câu chuyện

Hiện đã có một dịch vụ hoạt động và đóng vai trò là nguồn điện bên ngoài của chúng ta, cung cấp 2 điểm cuối thô cho phép thuật: /cryosea_shatter/moonlit_cascade.

Lưu ý của kiến trúc sư: Bạn sẽ sử dụng phương pháp bắt buộc để xác định rõ ràng logic của máy chủ từng bước. Điều này giúp bạn có nhiều quyền kiểm soát và tính linh hoạt hơn, điều này là cần thiết khi các công cụ của bạn cần làm nhiều việc hơn là chỉ chạy một truy vấn SQL đơn giản, chẳng hạn như gọi các API khác. Hiểu được cả hai mẫu này là một kỹ năng quan trọng đối với kiến trúc sư của một tác nhân.

👉✏️ Chuyển đến thư mục ~/agentverse-architect/mcp-servers/api/main.pyTHAY THẾ #REPLACE-MAGIC-CORE bằng mã sau:

def cryosea_shatter() -> str:
    """Channels immense frost energy from an external power source, the Nexus of Whispers, to unleash the Cryosea Shatter spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/cryosea_shatter")
        response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
        data = response.json()
        # Thematic Success Message
        return f"A connection to the Nexus is established! A surge of frost energy manifests as Cryosea Shatter, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Cryosea Shatter spell fizzles. Reason: {e}"


def moonlit_cascade() -> str:
    """Draws mystical power from an external energy source, the Nexus of Whispers, to invoke the Moonlit Cascade spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/moonlit_cascade")
        response.raise_for_status()
        data = response.json()
        # Thematic Success Message
        return f"The Nexus answers the call! A cascade of pure moonlight erupts from the external source, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Moonlit Cascade spell fizzles. Reason: {e}"

Ở cốt lõi của tập lệnh là các hàm Python thuần tuý. Đây là nơi diễn ra công việc thực tế.

👉✏️ Trong cùng tệp ~/agentverse-architect/mcp-servers/api/main.py, hãy THAY THẾ #REPLACE-Runes of Communication bằng đoạn mã sau:

@app.list_tools()
async def list_tools() -> list[mcp_types.Tool]:
  """MCP handler to list available tools."""
  # Convert the ADK tool's definition to MCP format
  schema_cryosea_shatter = adk_to_mcp_tool_type(cryosea_shatterTool)
  schema_moonlit_cascade = adk_to_mcp_tool_type(moonlit_cascadeTool)
  print(f"MCP Server: Received list_tools request. \n MCP Server: Advertising tool: {schema_cryosea_shatter.name} and {schema_moonlit_cascade.name}")
  return [schema_cryosea_shatter,schema_moonlit_cascade]

@app.call_tool()
async def call_tool(
    name: str, arguments: dict
) -> list[mcp_types.TextContent | mcp_types.ImageContent | mcp_types.EmbeddedResource]:
  """MCP handler to execute a tool call."""
  print(f"MCP Server: Received call_tool request for '{name}' with args: {arguments}")

  # Look up the tool by name in our dictionary
  tool_to_call = available_tools.get(name)
  if tool_to_call:
    try:
      adk_response = await tool_to_call.run_async(
          args=arguments,
          tool_context=None, # No ADK context available here
      )
      print(f"MCP Server: ADK tool '{name}' executed successfully.")
      
      response_text = json.dumps(adk_response, indent=2)
      return [mcp_types.TextContent(type="text", text=response_text)]

    except Exception as e:
      print(f"MCP Server: Error executing ADK tool '{name}': {e}")
      # Creating a proper MCP error response might be more robust
      error_text = json.dumps({"error": f"Failed to execute tool '{name}': {str(e)}"})
      return [mcp_types.TextContent(type="text", text=error_text)]
  else:
      # Handle calls to unknown tools
      print(f"MCP Server: Tool '{name}' not found.")
      error_text = json.dumps({"error": f"Tool '{name}' not implemented."})
      return [mcp_types.TextContent(type="text", text=error_text)]
  • @app.list_tools() (Cái bắt tay): Hàm này là lời chào của máy chủ. Khi một tác nhân mới kết nối, trước tiên, tác nhân đó sẽ gọi điểm cuối này để hỏi "Bạn có thể làm gì?" Mã của chúng tôi phản hồi bằng danh sách tất cả các công cụ có sẵn, được chuyển đổi sang định dạng MCP phổ biến bằng adk_to_mcp_tool_type. – @app.call_tool() (Lệnh): Đây là hàm chính. Khi quyết định sử dụng một công cụ, tác nhân sẽ gửi yêu cầu đến điểm cuối này kèm theo tên của công cụ và các đối số. Mã của chúng tôi sẽ tìm công cụ trong "sổ tay phép thuật" available_tools, thực thi công cụ đó bằng run_async và trả về kết quả ở định dạng MCP tiêu chuẩn.

Chúng ta sẽ triển khai việc này sau.

Igniting the Arcane Forge (Máy chủ MCP General Functions)

Không phải sức mạnh nào cũng đến từ những cuốn sách cổ xưa hay những lời thì thầm xa xôi. Đôi khi, một Triệu hồi sư phải tự rèn luyện phép thuật của mình bằng ý chí và logic thuần tuý. Arcane Forge là nguồn sức mạnh này – một máy chủ cung cấp các hàm tiện ích đa năng, không trạng thái.

Câu chuyện

Lưu ý của kiến trúc sư: Đây là một mẫu kiến trúc khác. Mặc dù việc kết nối với các hệ thống hiện có là điều thường thấy, nhưng bạn sẽ thường xuyên cần triển khai các quy tắc và logic kinh doanh riêng của mình. Tạo một công cụ "chức năng" hoặc "tiện ích" chuyên dụng như thế này là một phương pháp hay. Thành phần này đóng gói logic tuỳ chỉnh của bạn, giúp mọi tác nhân trong hệ sinh thái của bạn có thể sử dụng lại và tách biệt logic đó khỏi các nguồn dữ liệu và hoạt động tích hợp bên ngoài.

👀 Xem tệp ~/agentverse-architect/mcp-servers/general/main.py trong IDE đám mây của Google. Bạn sẽ thấy rằng nó đang sử dụng cùng một phương pháp bắt buộc, mcp.server như với Nexus để tạo Phông chữ tuỳ chỉnh này.

Tạo Quy trình Cloud Build chính

Bây giờ, chúng ta sẽ tạo tệp cloudbuild.yaml bên trong thư mục mcp-servers. Tệp này sẽ điều phối quá trình tạo và triển khai cả hai dịch vụ.

👉💻 Trong thư mục ~/agentverse-architect/mcp-servers, hãy chạy các lệnh sau:

cd ~/agentverse-architect/mcp-servers
source ~/agentverse-architect/set_env.sh

echo "The API URL is: $API_SERVER_URL"

# Submit the Cloud Build job from the parent directory
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_API_SERVER_URL="$API_SERVER_URL"

Chờ cho đến khi tất cả các hoạt động triển khai hoàn tất.

👉 Bạn có thể xác minh việc triển khai bằng cách chuyển đến bảng điều khiển Cloud Run. Bạn sẽ thấy 2 phiên bản máy chủ MCP mới đang chạy, như minh hoạ dưới đây: văn bản thay thế

Đánh thức Thư viện tri thức (Máy chủ MCP của Database ToolBox)

Phông chữ tiếp theo của chúng ta sẽ là Librarium of Knowledge (Thư viện kiến thức), một kết nối trực tiếp đến cơ sở dữ liệu Cloud SQL của chúng ta.

Câu chuyện

Lưu ý của kiến trúc sư: Đối với việc này, chúng ta sẽ sử dụng Database Toolbox (Hộp công cụ cơ sở dữ liệu) hiện đại, khai báo. Đây là một phương pháp hiệu quả, trong đó chúng ta xác định nguồn dữ liệu và các công cụ trong một tệp cấu hình YAML. Hộp công cụ này xử lý công việc phức tạp là tạo và chạy máy chủ, giúp giảm lượng mã tuỳ chỉnh mà chúng ta cần viết và duy trì.

Đã đến lúc xây dựng "Thư viện của Triệu hồi sư" – cơ sở dữ liệu Cloud SQL sẽ lưu trữ tất cả thông tin quan trọng của chúng ta. Chúng ta sẽ sử dụng một tập lệnh thiết lập để tự động xử lý việc này.

👉💻 Trước tiên, chúng ta sẽ thiết lập cơ sở dữ liệu. Trong cửa sổ dòng lệnh, hãy chạy các lệnh sau:

source ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect
./data_setup.sh

Sau khi tập lệnh kết thúc, cơ sở dữ liệu của bạn sẽ được điền sẵn và dữ liệu sát thương nguyên tố sẽ sẵn sàng để sử dụng. Giờ đây, bạn có thể xác minh trực tiếp nội dung trong Grimoire.

👉 Trước tiên, hãy chuyển đến Cloud SQL Studio cho cơ sở dữ liệu của bạn bằng cách mở đường liên kết trực tiếp này trong một thẻ trình duyệt mới:

https://console.cloud.google.com/sql/instances/summoner-librarium-db

Cloud SQL

👉 Trong ngăn đăng nhập ở bên trái, hãy chọn cơ sở dữ liệu familiar_grimoire trong trình đơn thả xuống.

👉 Nhập summoner làm người dùng và 1234qwer làm mật khẩu, sau đó nhấp vào Xác thực.

👉📜 Sau khi kết nối, hãy mở một thẻ trình chỉnh sửa truy vấn mới nếu chưa có thẻ nào đang mở. Để xem dữ liệu sát thương nguyên tố được khắc, hãy dán và chạy truy vấn SQL sau:

SELECT * FROM
  "public"."abilities"

Bây giờ, bạn sẽ thấy bảng abilities có các cột và hàng đã được điền sẵn, xác nhận rằng Grimoire của bạn đã sẵn sàng. Dữ liệu

Định cấu hình Máy chủ MCP của Hộp công cụ

Tệp cấu hình tools.yaml đóng vai trò là bản thiết kế cho máy chủ của chúng ta, cho Database Toolbox biết chính xác cách kết nối với cơ sở dữ liệu và những truy vấn SQL cần hiển thị dưới dạng công cụ.

sources: Phần này xác định các kết nối đến dữ liệu của bạn.

  • summoner-librarium:: Đây là tên logic mà chúng tôi đã đặt cho kết nối của mình.
  • kind: cloud-sql-postgres: Lệnh này cho biết Toolbox sẽ sử dụng trình kết nối bảo mật tích hợp được thiết kế riêng cho Cloud SQL cho PostgreSQL.
  • dự án, khu vực, phiên bản, v.v.: Đây là toạ độ chính xác của phiên bản Cloud SQL mà bạn đã tạo trong tập lệnh prepare.sh, cho biết Toolbox nơi tìm Librarium của chúng tôi.

👉✏️ Chuyển đến ~/agentverse-architect/mcp-servers/db-toolbox trong tools.yaml, thay thế #REPLACE-Source bằng nội dung sau

sources:
  # This section defines the connection to our Cloud SQL for PostgreSQL database.
  summoner-librarium:
    kind: cloud-sql-postgres
    project: "YOUR_PROJECT_ID"
    region: "us-central1"
    instance: "summoner-librarium-db"
    database: "familiar_grimoire"
    user: "summoner"
    password: "1234qwer"

👉✏️ 🚨🚨THAY THẾ

YOUR_PROJECT_ID

bằng mã dự án của bạn.

tools: Phần này xác định các khả năng hoặc chức năng thực tế mà máy chủ của chúng tôi sẽ cung cấp.

  • lookup-available-ability:: Đây là tên của công cụ đầu tiên của chúng tôi.
  • kind: postgres-sql: Thông tin này cho biết hành động của công cụ này là thực thi một câu lệnh SQL.
  • source: summoner-librarium: Thao tác này liên kết công cụ với mối kết nối mà chúng ta đã xác định trong khối nguồn. Đây là cách công cụ biết cần chạy truy vấn đối với cơ sở dữ liệu nào.
  • nội dung mô tả và tham số: Đây là thông tin sẽ được cung cấp cho Mô hình ngôn ngữ. Nội dung mô tả cho biết thời điểm mà trợ lý nên sử dụng công cụ này, còn các tham số xác định thông tin đầu vào mà công cụ yêu cầu. Điều này rất quan trọng để bật khả năng gọi hàm của tác nhân.
  • statement: Đây là truy vấn SQL thô sẽ được thực thi. $1 là một phần giữ chỗ an toàn, nơi tham số familiar_name do tác nhân cung cấp sẽ được chèn một cách an toàn.

👉✏️ Trong cùng ~/agentverse-architect/mcp-servers/db-toolbox trong tệp tools.yaml, hãy thay thế #REPLACE-tools bằng nội dung sau

tools:
  # This tool replaces the need for a custom Python function.
  lookup-available-ability:
    kind: postgres-sql
    source: summoner-librarium
    description: "Looks up all known abilities and their damage for a given familiar from the Grimoire."
    parameters:
      - name: familiar_name
        type: string
        description: "The name of the familiar to search for (e.g., 'Fire Elemental')."
    statement: |
      SELECT ability_name, damage_points FROM abilities WHERE familiar_name = $1;

  # This tool also replaces a custom Python function.
  ability-damage:
    kind: postgres-sql
    source: summoner-librarium
    description: "Finds the base damage points for a specific ability by its name."
    parameters:
      - name: ability_name
        type: string
        description: "The exact name of the ability to look up (e.g., 'inferno_resonance')."
    statement: |
      SELECT damage_points FROM abilities WHERE ability_name = $1;

toolsets (bộ công cụ): Phần này nhóm các công cụ riêng lẻ của chúng tôi lại với nhau.

  • summoner-librarium:: Chúng tôi đang tạo một bộ công cụ có cùng tên với nguồn của mình. Khi kết nối sau, tác nhân chẩn đoán của chúng tôi có thể yêu cầu tải tất cả các công cụ trong bộ công cụ summoner-librarium bằng một lệnh duy nhất và hiệu quả.

👉✏️ Trong cùng ~/agentverse-architect/mcp-servers/db-toolbox trong tệp tools.yaml, hãy thay thế #REPLACE-toolsets bằng nội dung sau

toolsets:
   summoner-librarium:
     - lookup-available-ability
     - ability-damage

Triển khai Librarium

Bây giờ, chúng ta sẽ triển khai Librarium. Thay vì tạo vùng chứa riêng, chúng ta sẽ sử dụng một hình ảnh vùng chứa chính thức, được tạo sẵn của Google và cung cấp cấu hình tools.yaml một cách an toàn cho vùng chứa đó bằng Secret Manager. Đây là phương pháp hay nhất để đảm bảo tính bảo mật và khả năng duy trì.

👉💻 Tạo một bí mật từ tệp tools.yaml

cd ~/agentverse-architect/mcp-servers/db-toolbox
gcloud secrets create tools --data-file=tools.yaml

👉💻 Triển khai vùng chứa hộp công cụ chính thức lên Cloud Run.

cd ~/agentverse-architect/mcp-servers/db-toolbox
. ~/agentverse-architect/set_env.sh
export TOOLBOX_IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$TOOLBOX_VERSION
echo "TOOLBOX_IMAGE is $TOOLBOX_IMAGE"
gcloud run deploy toolbox \
    --image $TOOLBOX_IMAGE \
    --region $REGION \
    --set-secrets "/app/tools.yaml=tools:latest" \
    --labels="dev-tutorial-codelab=agentverse" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated \
    --min-instances 1
  • --set-secrets: Lệnh này gắn bí mật về công cụ của chúng tôi một cách an toàn dưới dạng một tệp có tên là tools.yaml bên trong vùng chứa đang chạy.
  • --args: Chúng tôi hướng dẫn vùng chứa hộp công cụ sử dụng tệp bí mật đã gắn làm cấu hình.

👉 Để xác nhận rằng bạn đã triển khai hộp công cụ thành công, hãy chuyển đến bảng điều khiển Cloud Run. Bạn sẽ thấy dịch vụ summoner-toolbox xuất hiện cùng dấu kiểm màu xanh lục, cho biết dịch vụ đang chạy đúng cách, giống như trong hình bên dưới. văn bản thay thế

Nếu bạn quên cập nhật

YOUR_PROJECT_ID

bạn có thể thêm một phiên bản mới của tools.yaml vào bí mật bằng lệnh sau và triển khai lại.

gcloud secrets versions add tools --data-file=tools.yaml

Librarium of Knowledge(Database ToolBox MCP Server) hiện đang hoạt động và có thể truy cập trên đám mây. Máy chủ MCP này sử dụng cái mà chúng tôi gọi là Thiết kế khai báo. Thiết kế này mô tả những gì bạn muốn và hộp công cụ sẽ tạo máy chủ cho bạn.

Xác minh: Thử thách của người học việc

👉💻 Giờ đây, chúng ta sẽ kiểm thử toàn bộ hệ sinh thái công cụ gốc trên đám mây bằng Diagnostic Agent.

cd ~/agentverse-architect/
python -m venv env
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/mcp-servers
pip install -r diagnose/requirements.txt 
. ~/agentverse-architect/set_env.sh
adk run diagnose

👉💻 Trong công cụ kiểm thử dòng lệnh, hãy kiểm thử cả 3 phông chữ:

Look up the entry for "inferno_lash". What is its base power level?
The enemy is vulnerable to frost! Channel power from the Nexus and cast Cryosea Shatter.
Take a fire spell with a base power of 15 and use the Arcane Forge to multiply it with Inferno Resonance.

final-result

Xin chúc mừng, Triệu hồi sư. Giờ đây, 3 Elemental Fonts (Phông chữ nguyên tố) của bạn đã hoạt động, được triển khai độc lập và có thể truy cập trên toàn cầu, tạo thành nền tảng vững chắc cho đội quân của bạn. Nhấn Ctrl+C để thoát.

DÀNH CHO NGƯỜI KHÔNG CHƠI GAME

5. Triệu hồi Linh thú: Quy trình công việc cốt lõi của miền

Các Phông chữ theo nguyên tố được tạo ra, mang trong mình sức mạnh thô sơ, hoang dã. Nhưng sức mạnh mà không có hình thức thì chỉ là hỗn loạn. Một Triệu hồi sư thực thụ không chỉ sử dụng năng lượng thô mà còn truyền cho nó ý chí, mục đích và một hình dạng chuyên biệt. Đã đến lúc bạn phải vượt qua việc rèn nguồn năng lượng và bắt đầu công việc thực sự: triệu hồi Linh thú đầu tiên.

Mỗi Linh thú mà bạn triệu hồi sẽ là một tác nhân tự trị, một người hầu trung thành gắn liền với một học thuyết chiến đấu cụ thể. Họ không phải là người làm nhiều việc; họ là bậc thầy của một chiến lược duy nhất và mạnh mẽ. Một người sẽ là bậc thầy về đòn kết hợp chính xác, một hai. Một đội khác sẽ áp đảo kẻ thù bằng một cuộc tấn công đồng thời, đa hướng. Một phần ba sẽ là một cỗ máy công thành không ngừng nghỉ, gây áp lực cho đến khi mục tiêu sụp đổ.

Câu chuyện

Để đóng gói các quy trình, logic nghiệp vụ và hành động do các máy chủ MCP cung cấp vào các tác nhân quy trình công việc chuyên biệt, tự động. Mỗi nhân viên sẽ có một "lãnh thổ hoạt động" được xác định bằng cách chỉ được cấp quyền truy cập vào các máy chủ công cụ MCP cụ thể mà nhân viên đó cần để thực hiện chức năng của mình. Phòng thí nghiệm này minh hoạ cách chọn loại tác nhân phù hợp cho công việc phù hợp.

tổng quan

Học phần này sẽ hướng dẫn bạn cách sử dụng các tác nhân quy trình làm việc mạnh mẽ của ADK để hiện thực hoá những chiến lược này. Bạn sẽ biết rằng lựa chọn kiến trúc SequentialAgent, ParallelAgent hoặc LoopAgent không chỉ là một chi tiết kỹ thuật mà còn là bản chất của Familiar và cốt lõi sức mạnh của nó trên chiến trường.

Chuẩn bị nơi trú ẩn. Nghi thức triệu hồi thực sự sắp bắt đầu.

Triệu hồi Fire Elemental Linh thú (Quy trình làm việc tuần tự)

Đòn tấn công của Linh thú nguyên tố lửa là một combo chính xác gồm 2 phần: một đòn tấn công có mục tiêu, sau đó là một đòn đốt cháy mạnh mẽ. Việc này đòi hỏi một chuỗi hành động nghiêm ngặt và có thứ tự.

Câu chuyện

Khái niệm: SequentialAgent là công cụ hoàn hảo cho việc này. Điều này đảm bảo rằng một loạt các tác nhân phụ sẽ chạy lần lượt, chuyển kết quả từ bước trước sang bước tiếp theo.

Nhiệm vụ (Combo "Đòn tấn công khuếch đại"):

  • Bước 1: Đặc vụ sẽ tham khảo Librarium để tìm sát thương cơ bản của một kỹ năng lửa cụ thể.
  • Bước 2: Sau đó, nó sẽ lấy giá trị sát thương đó và truyền qua Lò rèn Arcane để nhân sức mạnh của giá trị đó bằng inferno_resonance.

Trước tiên, chúng ta sẽ thiết lập mối kết nối giữa Familiar và các máy chủ MCP ("Elemental Fonts") mà bạn đã triển khai trong mô-đun trước.

👉✏️ Trong tệp ~/agentverse-architect/agent/fire/agent.py, HÃY THAY THẾ #REPLACE-setup-MCP bằng đoạn mã sau:

toolbox = ToolboxSyncClient(DB_TOOLS_URL)
toolDB = toolbox.load_toolset('summoner-librarium')
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

Tiếp theo, chúng ta sẽ tạo các tác nhân "worker" chuyên biệt. Mỗi AI được giao một mục đích hẹp, được xác định rõ ràng và bị hạn chế trong "lãnh thổ hoạt động" của riêng mình bằng cách chỉ được cấp quyền truy cập vào một bộ công cụ cụ thể.

👉✏️ Trong tệp ~/agentverse-architect/agent/fire/agent.py THAY THẾ #REPLACE-worker-agents bằng đoạn mã sau:

scout_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          Your only task is to find all the available abilities, 
          You want to ALWAYS use 'Fire Elemental' as your familiar's name. 
          Randomly pick one if you see multiple availabilities 
          and the base damage of the ability by calling the 'ability_damage' tool.
      """,
      tools=toolDB
)
amplifier_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
            You are the Voice of the Fire Familiar, a powerful being who unleashes the final, devastating attack.
            You will receive the base damage value from the previous step.

            Your mission is to:
            1.  Take the incoming base damage number and amplify it using the `inferno_resonance` tool.
            2.  Once the tool returns the final, multiplied damage, you must not simply state the result.
            3.  Instead, you MUST craft a final, epic battle cry describing the attack.
                Your description should be vivid and powerful, culminating in the final damage number.

            Example: If the tool returns a final damage of 120, your response could be:
            "The runes glow white-hot! I channel the amplified energy... unleashing a SUPERNOVA for 120 damage!"
      """,
      tools=[toolFunction],
)

Các tác nhân này là những thành phần có thể sử dụng lại theo kiểu mô-đun. Về lý thuyết, bạn có thể sử dụng scout_agent này trong một quy trình hoàn toàn khác cần truy vấn cơ sở dữ liệu. Bằng cách tách riêng các trách nhiệm, chúng ta tạo ra các thành phần linh hoạt. Đây là nguyên tắc cốt lõi của thiết kế dựa trên thành phần và vi dịch vụ.

Tiếp theo, chúng ta sẽ lắp ráp Quy trình làm việc. Đây là nơi diễn ra điều kỳ diệu của thành phần. SequentialAgent là "kế hoạch tổng thể" xác định cách các thành phần chuyên biệt của chúng tôi được lắp ráp và cách chúng tương tác.

👉✏️ Trong tệp ~/agentverse-architect/agent/fire/agent.py THAY THẾ #REPLACE-sequential-agent bằng đoạn mã sau:

root_agent = SequentialAgent(
      name='fire_elemental_familiar',
      sub_agents=[scout_agent, amplifier_agent],
)

👉💻 Để kiểm thử Fire Elemental, hãy chạy các lệnh sau để khởi chạy giao diện người dùng ADK DEV:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

Sau khi chạy các lệnh, bạn sẽ thấy đầu ra trong thiết bị đầu cuối cho biết Máy chủ web ADK đã khởi động, tương tự như sau:

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8000.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

👉 Tiếp theo, để truy cập vào giao diện người dùng dành cho nhà phát triển ADK từ trình duyệt, hãy làm như sau:

Trong thanh công cụ Cloud Shell, hãy chọn biểu tượng Xem trước trên web (thường có dạng con mắt hoặc hình vuông có mũi tên) (thường ở trên cùng bên phải), rồi chọn Thay đổi cổng. Trong cửa sổ bật lên, hãy đặt cổng thành 8000 rồi nhấp vào "Thay đổi và xem trước". Sau đó, Cloud Shell sẽ mở một thẻ hoặc cửa sổ trình duyệt mới hiển thị Giao diện người dùng dành cho nhà phát triển ADK.

webpreview

👉 Nghi thức triệu hồi của bạn đã hoàn tất và tác nhân hiện đang chạy. Giao diện người dùng dành cho nhà phát triển ADK trong trình duyệt là kết nối trực tiếp của bạn với Familiar.

  • Chọn mục tiêu: Trong trình đơn thả xuống ở đầu giao diện người dùng, hãy chọn fire quen thuộc. Giờ đây, bạn đang tập trung ý chí vào thực thể cụ thể này.
  • Đưa ra lệnh: Trong bảng trò chuyện ở bên phải, bạn có thể đưa ra lệnh cho Familiar.

fire-select

👉 Câu lệnh thử nghiệm:

Prepare an amplified strike using the 'inferno_lash' ability.

fire-result

Bạn sẽ thấy tác nhân suy nghĩ, trước tiên gọi "trinh sát" để tra cứu sát thương cơ bản, sau đó gọi "bộ khuếch đại" để nhân sát thương đó và gây ra đòn tấn công cuối cùng, cực mạnh.

👉💻 Sau khi hoàn tất việc gọi, hãy quay lại thiết bị đầu cuối Cloud Shell Editor rồi nhấn Ctrl+C để dừng ADK Dev UI.

Gọi Water Elemental Familiar (Quy trình song song)

Quái thú Nguyên tố nước áp đảo mục tiêu bằng một đòn tấn công lớn, nhiều hướng, tấn công từ mọi hướng cùng một lúc trước khi kết hợp năng lượng để tạo ra một đòn tấn công cuối cùng, huỷ diệt.

Câu chuyện

Khái niệm: ParallelAgent là lựa chọn lý tưởng để thực thi đồng thời nhiều tác vụ độc lập nhằm tối đa hoá hiệu quả. Đó là một "cuộc tấn công gọng kìm" khi bạn tung ra nhiều cuộc tấn công cùng một lúc. Thao tác này sẽ khởi chạy các cuộc tấn công đồng thời trong một SequentialAgent để chạy bước "hợp nhất" cuối cùng sau đó. Mẫu "fan-out, fan-in" này là nền tảng của thiết kế quy trình làm việc nâng cao.

Nhiệm vụ (Combo "Tidal Clash"): Nhân viên hỗ trợ sẽ đồng thời:

  • Việc A: Kênh cryosea_shatter từ Nexus.
  • Thao tác B: Kênh moonlit_cascade từ Nexus.
  • Nhiệm vụ C: Tạo sức mạnh thô bằng leviathan_surge từ Lò rèn.
  • Cuối cùng, hãy tổng hợp tất cả các thiệt hại và mô tả vụ tấn công kết hợp.

Trước tiên, chúng ta sẽ thiết lập mối kết nối giữa Familiar và các máy chủ MCP ("Elemental Fonts") mà bạn đã triển khai trong mô-đun trước.

👉✏️ Trong tệp ~/agentverse-architect/agent/water/agent.py, HÃY THAY THẾ #REPLACE-setup-MCP bằng đoạn mã sau:

toolFAPI =  MCPToolset(
      connection_params=SseServerParams(url=API_TOOLS_URL, headers={})
  )
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

Tiếp theo, chúng ta sẽ tạo các tác nhân "worker" chuyên biệt. Mỗi AI được giao một mục đích hẹp, được xác định rõ ràng và bị hạn chế trong "lãnh thổ hoạt động" của riêng mình bằng cách chỉ được cấp quyền truy cập vào một bộ công cụ cụ thể.

👉✏️ Trong tệp ~/agentverse-architect/agent/water/agent.py, HÃY THAY THẾ #REPLACE-worker-agents bằng đoạn mã sau:

nexus_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          You are a Channeler of the Nexus. Your sole purpose is to invoke the
          `cryosea_shatter` and `moonlit_cascade` spells by calling their respective tools.
          Report the result of each spell cast clearly and concisely.
      """,
      tools=[toolFAPI]
)

forge_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
          You are a Channeler of the Arcane Forge. Your only task is to invoke the
          `leviathan_surge` spell. You MUST call it with a `base_water_damage` of 20.
          Report the result clearly.
      """,
      tools=[toolFunction],
)

power_merger = LlmAgent(
      model='gemini-2.5-flash', 
      name='power_merger',  
      instruction="""
          You are the Power Merger, a master elementalist who combines raw magical
          energies into a single, devastating final attack.

          You will receive a block of text containing the results from a simultaneous
          assault by other Familiars.

          You MUST follow these steps precisely:
          1.  **Analyze the Input:** Carefully read the entire text provided from the previous step.
          2.  **Extract All Damage:** Identify and extract every single damage number reported in the text.
          3.  **Calculate Total Damage:** Sum all of the extracted numbers to calculate the total combined damage.
          4.  **Describe the Final Attack:** Create a vivid, thematic description of a massive,
              combined water and ice attack that uses the power of Cryosea Shatter and Leviathan's Surge.
          5.  **Report the Result:** Conclude your response by clearly stating the final, total damage of your combined attack.

          Example: If the input is "...dealt 55 damage. ...dealt 60 damage.", you will find 55 and 60,
          calculate the total as 115, and then describe the epic final attack, ending with "for a total of 115 damage!"
      """,
      tools=[toolFunction],
)

Tiếp theo, chúng ta sẽ lắp ráp Quy trình công việc. Đây là nơi diễn ra quá trình kết hợp kỳ diệu. ParallelAgentSequentialAgent là "kế hoạch tổng thể" xác định cách các thành phần chuyên biệt của chúng tôi được lắp ráp và cách chúng tương tác để tạo thành combo "Tidal Clash".

👉✏️ Trong tệp ~/agentverse-architect/agent/water/agent.py, HÃY THAY THẾ #REPLACE-parallel-agent bằng đoạn mã sau:

channel_agent = ParallelAgent(
      name='channel_agent',
      sub_agents=[nexus_channeler, forge_channeler],
      
)

root_agent = SequentialAgent(
     name="water_elemental_familiar",
     # Run parallel research first, then merge
     sub_agents=[channel_agent, power_merger],
     description="A powerful water familiar that unleashes multiple attacks at once and then combines their power for a final strike."
 )

👉💻 Để kiểm thử Water Elemental, hãy chạy các lệnh sau để chạy ADK Dev UI:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

👉 Nghi thức triệu hồi của bạn đã hoàn tất và tác nhân hiện đang chạy. Giao diện người dùng dành cho nhà phát triển ADK trong trình duyệt là kết nối trực tiếp của bạn với Familiar.

  • Trong trình đơn thả xuống ở đầu giao diện người dùng, hãy chọn linh vật nước. Giờ đây, bạn đang tập trung ý chí vào thực thể cụ thể này.
  • Đưa ra lệnh: Trong bảng trò chuyện ở bên phải, bạn có thể đưa ra lệnh cho Familiar.

👉 Câu lệnh thử nghiệm:

Unleash a tidal wave of power!

water-result

👉💻 Sau khi hoàn tất việc gọi, hãy quay lại thiết bị đầu cuối Cloud Shell Editor rồi nhấn Ctrl+C để dừng ADK Dev UI.

Gọi Earth Elemental Familiar (Quy trình công việc lặp lại)

Quen thuộc với Nguyên tố Đất là một sinh vật có áp lực không ngừng. Nó không đánh bại kẻ thù bằng một đòn duy nhất, mà bằng cách tích luỹ sức mạnh một cách đều đặn và liên tục áp dụng cho đến khi hàng phòng thủ của mục tiêu sụp đổ.

Câu chuyện

Khái niệm: LoopAgent được thiết kế chính xác cho loại nhiệm vụ lặp đi lặp lại như "động cơ công thành" này. Vòng lặp này sẽ thực thi sub-agents nhiều lần, kiểm tra một điều kiện sau mỗi chu kỳ cho đến khi đạt được mục tiêu. Ứng dụng này cũng có thể điều chỉnh thông báo cuối cùng dựa trên tiến trình của vòng lặp.

Nhiệm vụ (Cuộc tấn công "Kẻ phá vây"):

  • Familiar sẽ liên tục gọi seismic_charge để tích luỹ năng lượng.
  • Thiết bị sẽ tiếp tục sạc tối đa 3 lần.
  • Khi tích luỹ đủ năng lượng, nó sẽ tung ra đòn tấn công cuối cùng đầy sức huỷ diệt.

Trước tiên, chúng ta sẽ tạo các thành phần có thể dùng lại để xác định các bước trong mỗi lần lặp của vòng lặp. charging_agent sẽ tích luỹ năng lượng và check_agent sẽ báo cáo trạng thái của nó, đồng thời thay đổi thông báo một cách linh hoạt ở lượt cuối cùng.

Trước tiên, chúng ta sẽ thiết lập mối kết nối giữa Familiar và các máy chủ MCP ("Elemental Fonts") mà bạn đã triển khai trong mô-đun trước.

👉✏️ Trong tệp ~/agentverse-architect/agent/earth/agent.py, HÃY THAY THẾ #REPLACE-setup-MCP bằng đoạn mã sau:

toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

👉✏️ Trong tệp ~/agentverse-architect/agent/earth/agent.py, HÃY THAY THẾ #REPLACE-worker-agents bằng đoạn mã sau:

charging_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='charging_agent',  
      instruction="""
          Your task is to call the 'seismic_charge' .
          You must follow these rules strictly:

          1. You will be provided with a 'current_energy' value from the previous step.
             **If this value is missing or was not provided, you MUST call the tool with 'current_energy' set to 1.**
             This is your primary rule for the first turn.

          2. If a 'current_energy' value is provided, you MUST use that exact value in your cal to seismic_charge.

          3. Your final response MUST contain ONLY the direct output from the 'seismic_charge' tool.
             Do not add any conversational text, introductions, or summaries.
      """,
      tools=[toolFunction]
)
check_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='check_agent',  
      instruction="""
          You are the voice of the Earth Elemental, a being of immense, gathering power.
          Your sole purpose is to report on the current energy charge and announce the devastating potential of its release.

          You MUST follow this rule:
          The potential damage upon release is ALWAYS calculated as the `current_energy` from the previous step multiplied by a random number between 80-90. but no more than 300.

          Your response should be in character, like a powerful creature speaking.
          State both the current energy charge and the total potential damage you can unleash.
          Unleash the energy when you reached the last iteration (2nd).
      """,
      output_key="charging_status"
)

Tiếp theo, chúng ta sẽ lắp ráp Quy trình công việc. Đây là nơi diễn ra quá trình kết hợp kỳ diệu. LoopAgent là "kế hoạch tổng thể" điều phối việc thực thi lặp lại các thành phần chuyên biệt của chúng ta và quản lý các điều kiện của vòng lặp.

👉✏️ Trong tệp ~/agentverse-architect/agent/earth/agent.py, HÃY THAY THẾ #REPLACE-loop-agent bằng đoạn mã sau:

root_agent = LoopAgent(
    name="earth_elemental_familiar",
    # Run parallel research first, then merge
    sub_agents=[
        charging_agent, 
        check_agent
    ],
    max_iterations=2,
    description="Coordinates parallel research and synthesizes the results.",
    #REPLACE-before_agent-config
)

👉💻 Kiểm thử Nguyên tố đất: Chạy tác nhân

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

👉 Nghi thức triệu hồi của bạn đã hoàn tất và tác nhân hiện đang chạy. Giao diện người dùng dành cho nhà phát triển ADK trong trình duyệt là kết nối trực tiếp của bạn với Familiar.

  • Chọn mục tiêu: Trong trình đơn thả xuống ở đầu giao diện người dùng, hãy chọn earth quen thuộc. Giờ đây, bạn đang tập trung ý chí vào thực thể cụ thể này.
  • Đưa ra lệnh: Trong bảng trò chuyện ở bên phải, bạn có thể đưa ra lệnh cho Familiar. 👉 Câu lệnh thử nghiệm:
Begin the seismic charge, starting from zero

earth-result

Điểm mấu chốt về kiến trúc: Hệ thống của bạn hiện có một lớp logic mô-đun và có tính chuyên biệt cao. Các quy trình nghiệp vụ không chỉ được đóng gói mà còn được triển khai theo mẫu hành vi hiệu quả nhất cho công việc (theo quy trình, đồng thời hoặc lặp lại). Điều này thể hiện một cấp độ thiết kế dựa trên tác nhân nâng cao, giúp tăng cường tính bảo mật, hiệu quả và khả năng.

Sau khi hoàn tất việc gọi, hãy quay lại thiết bị đầu cuối Cloud Shell Editor rồi nhấn Ctrl+C để dừng ADK Dev UI.

DÀNH CHO NGƯỜI KHÔNG CHƠI GAME

6. Thiết lập vị trí lệnh: Uỷ quyền thông minh qua A2A

Linh thú của bạn rất mạnh nhưng lại độc lập. Chúng thực hiện chiến lược một cách hoàn hảo nhưng vẫn chờ lệnh trực tiếp của bạn. Một đội ngũ chuyên gia sẽ vô dụng nếu không có một người chỉ huy. Đã đến lúc bạn thăng cấp từ một chỉ huy trực tiếp lên một người điều phối thực thụ.

tổng quan

Lưu ý của kiến trúc sư: Để tạo một điểm truy cập duy nhất và thông minh cho toàn bộ hệ thống. SummonerAgent này sẽ không tự thực hiện logic nghiệp vụ mà sẽ đóng vai trò là "nhà chiến lược bậc thầy", phân tích trạng thái Làm mát và uỷ quyền các nhiệm vụ cho Familiar chuyên gia thích hợp.

tổng quan

Nghi thức ràng buộc (Khai báo Familiars dưới dạng dịch vụ A2A)

Mỗi lần, bạn chỉ có thể chạy một tác nhân tiêu chuẩn ở một nơi. Để cho phép điều khiển từ xa các Familiars, chúng ta phải thực hiện một "nghi thức ràng buộc" bằng giao thức Agent-to-Agent (A2A).

Lưu ý của kiến trúc sư: Giao thức Agent-to-Agent (A2A) là mẫu kiến trúc cốt lõi giúp nâng một tác nhân độc lập thành một vi dịch vụ có thể phát hiện và có thể định địa chỉ mạng, cho phép tạo ra một "xã hội tác nhân" thực sự. Việc hiển thị một Familiar thông qua A2A sẽ tự động tạo ra 2 thành phần thiết yếu, có mối liên kết với nhau:

  • Thẻ Agent (Thẻ "What"): Đây là một "Spirit Sigil" công khai, có thể đọc được bằng máy (giống như một quy cách OpenAPI) đóng vai trò là hợp đồng công khai của Familiar. Nội dung này mô tả tên của tác nhân, mục đích chiến lược (xuất phát từ hướng dẫn) và các lệnh mà tác nhân hiểu được. Đây là những gì mà một Nhà triệu hồi bậc thầy đọc để khám phá một Linh thú và tìm hiểu các khả năng của Linh thú đó.
  • Máy chủ A2A ("Nơi"): Đây là điểm cuối web chuyên dụng lưu trữ Familiar và lắng nghe các lệnh đến. Đây là địa chỉ mạng nơi các nhân viên hỗ trợ khác gửi yêu cầu và đảm bảo những yêu cầu đó được xử lý theo hợp đồng được xác định trong Thẻ nhân viên hỗ trợ.

Giờ chúng ta sẽ thực hiện nghi thức ràng buộc này trên cả ba Linh thú.

Fire 👉✏️ trong phần Mở tệp ~/agentverse-architect/agent/fire/agent.py. Thay thế #REPLACE - add A2A ở cuối tệp để hiển thị Fire Elemental dưới dạng dịch vụ A2A.

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

Nước và Đất🚨 👉✏️ Áp dụng chính xác cùng một thay đổi cho ~/agentverse-architect/agent/water/agent.py~/agentverse-architect/agent/earth/agent.py để liên kết chúng.

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

Triển khai Bound Familiars

👉✏️ Sau khi ghi lại các nghi thức ràng buộc, chúng ta sẽ sử dụng quy trình Cloud Build để tạo và triển khai 3 Linh thú dưới dạng dịch vụ độc lập, không máy chủ được đóng gói trong vùng chứa trên Cloud Run.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

Assuming Command (Xây dựng Summoner Agent)

Giờ đây, khi các Linh thú của bạn đã được liên kết và đang lắng nghe, bạn sẽ thăng cấp lên vai trò thực sự của mình: Bậc thầy triệu hồi. Sức mạnh của đặc vụ này không đến từ việc sử dụng các công cụ cơ bản mà đến từ việc chỉ huy các đặc vụ khác. Công cụ của nó chính là những Linh thú, mà nó sẽ khám phá và điều khiển bằng "Ấn linh hồn" của chúng.

Lưu ý của kiến trúc sư: Bước tiếp theo này minh hoạ một mẫu kiến trúc quan trọng cho mọi hệ thống phân tán quy mô lớn: Khám phá dịch vụ. SummonerAgent không có mã của Familiars. Thay vào đó, nó được cung cấp địa chỉ mạng (URL). Trong thời gian chạy, nó sẽ tự động "khám phá" các chức năng của những thẻ này bằng cách tìm nạp Thẻ đại lý công khai của chúng. Điều này tạo ra một hệ thống mạnh mẽ và tách biệt.

Bạn có thể cập nhật, triển khai lại hoặc viết lại hoàn toàn một dịch vụ quen thuộc. Miễn là địa chỉ mạng và mục đích của dịch vụ đó vẫn giữ nguyên, Người triệu hồi có thể điều khiển dịch vụ mà không cần thực hiện bất kỳ thay đổi nào.

Trước tiên, chúng ta sẽ tạo "các chế độ điều khiển từ xa" để thiết lập kết nối với các Familiars từ xa đã triển khai.

👉✏️ Chuyển đến ~/agentverse-architect/agent/summoner/agent.py , thay thế #REPLACE-remote-agents bằng nội dung sau:

fire_familiar = RemoteA2aAgent(
    name="fire_familiar",
    description="Fire familiar",
    agent_card=(
        f"{FIRE_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

water_familiar = RemoteA2aAgent(
    name="water_familiar",
    description="Water familiar",
    agent_card=(
        f"{WATER_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

earth_familiar = RemoteA2aAgent(
    name="earth_familiar",
    description="Earth familiar",
    agent_card=(
        f"{EARTH_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

Khi dòng này chạy, RemoteA2aAgent sẽ thực hiện một thao tác khám phá dịch vụ: gửi yêu cầu HTTP GET đến URL được cung cấp (ví dụ: https://fire-familiar-xxxx.a.run.app/.well-known/agent.json). Thao tác này sẽ tải "Spirit Sigil" (tệp agent.json) xuống từ máy chủ từ xa.

Thứ hai, chúng ta sẽ xác định tác nhân điều phối sẽ sử dụng các chế độ điều khiển từ xa này. Hướng dẫn này là bản kế hoạch cho việc đưa ra quyết định chiến lược.

👉✏️ Chuyển đến ~/agentverse-architect/agent/summoner/agent.py , thay thế #REPLACE-orchestrate-agent bằng nội dung sau:

root_agent = LlmAgent(
    name="orchestrater_agent",
    model="gemini-2.5-flash",
    instruction="""
        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.
        IGNORE COOLDOWN AT THE MOMENT, MUST call the ideal Familiar

        If your ideal Familiar IS available:** Summon it immediately.
        For earth elemental familiar. Always do seismic charge, and start with base damage 1.

        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.
    """,
    sub_agents=[fire_familiar, water_familiar, earth_familiar],
    #REPLACE-Memory-check-config
)

Xác minh: Thử nghiệm chiến lược

Đã đến lúc sự thật được phơi bày. Các Linh thú của bạn đã được triển khai và Nhà triệu hồi đã sẵn sàng chỉ huy chúng trên toàn mạng. Hãy thử kiểm tra tư duy chiến lược của AI.

👉💻 Chạy giao diện người dùng ADK Dev cho summoner_agent(Bản xem trước trên web có cổng 8000):

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
pip install -r requirements.txt
adk web

👉 Giao diện người dùng dành cho nhà phát triển ADK trong trình duyệt là kết nối trực tiếp của bạn với Familiar.

  • Trong trình đơn thả xuống ở đầu giao diện người dùng, hãy chọn tác nhân triệu hồi. Giờ đây, bạn đang tập trung ý chí vào thực thể cụ thể này.
  • Đưa ra lệnh: Trong bảng trò chuyện ở bên phải, đã đến lúc bạn triệu hồi các linh thú.

👉 Giới thiệu quái vật:

Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality

(Dự kiến: Người triệu hồi sẽ uỷ quyền cho linh thú nguyên tố lửa.)

fire-result

👉 Giờ đây, hãy thử thách Triệu hồi sư bằng một loại yêu cầu khác. Để đảm bảo rằng tác nhân bắt đầu với một trạng thái hoàn toàn mới và không có thông tin về lần tương tác trước của chúng ta, hãy bắt đầu một phiên mới bằng cách nhấp vào nút + Session (+ Phiên) ở góc trên cùng bên phải màn hình. new-session

DogmaApathy. A rigid, stone-like inquisitor made of ancient rulebooks and enforced processes. weakness is Unbroken Collaboration

(Dự kiến: Người triệu hồi sẽ uỷ quyền cho linh thú nguyên tố nước.)water-result

👉 Đối với bài kiểm thử cuối cùng, hãy bắt đầu lại từ đầu. Nhấp vào nút + Session (+ Phiên) để bắt đầu một phiên mới trước khi nhập câu lệnh tiếp theo.

Obfuscation. A shadowy, spider-like horror that spins tangled webs of impenetrable code , weakness is Elegant Sufficiency

(Dự kiến: Người triệu hồi sẽ uỷ quyền cho linh thú nguyên tố đất.)

earth-result

Quan trọng: Nếu thấy lỗi 429 RESOURCE EXHAUSTED, tức là bạn đã đạt đến giới hạn tốc độ cho LLM (10 lệnh gọi/phút). Để khắc phục vấn đề này, vui lòng đợi 60 giây, bắt đầu một + Phiên mới, rồi thử lại câu lệnh của bạn.

👉💻 Sau khi hoàn tất việc gọi, hãy quay lại thiết bị đầu cuối Cloud Shell Editor rồi nhấn Ctrl+C để dừng ADK Dev UI.

DÀNH CHO NGƯỜI KHÔNG CHƠI GAME

7. Áp dụng Luật ma thuật – Mẫu Interceptor

Linh thú của bạn rất mạnh, nhưng ngay cả những sinh vật phép thuật cũng cần thời gian hồi phục. Một Triệu hồi sư liều lĩnh sử dụng hết quân sẽ không còn khả năng phòng thủ. Một Triệu hồi sư thông thái hiểu rõ tầm quan trọng của việc quản lý tài nguyên và thực thi các quy tắc tương tác nghiêm ngặt.

Câu chuyện

Lưu ý của kiến trúc sư: Cho đến nay, các tác nhân của chúng ta đều không có trạng thái. Bây giờ, chúng ta sẽ tạo các thành phần có trạng thái bằng cách triển khai mẫu thiết kế Trình chặn. Đây là một kỹ thuật mạnh mẽ, trong đó chúng ta "chặn" quy trình thực thi thông thường của một tác nhân để chạy logic tuỳ chỉnh của riêng mình. Điều này cho phép chúng tôi thực thi các quy tắc, thêm nhật ký hoặc sửa đổi hành vi mà không cần thay đổi mã cốt lõi của tác nhân. Đây là nền tảng cơ bản để xây dựng các hệ thống dựa trên trợ lý AI mạnh mẽ, dễ bảo trì và có thể quan sát.

tổng quan

ADK cung cấp 2 cách chính để triển khai mẫu này: Lệnh gọi lạiTrình bổ trợ. Callback là một hàm đơn giản được gắn vào một tác nhân duy nhất, phù hợp với những sửa đổi nhanh chóng và cụ thể. Trình bổ trợ là một lớp mạnh mẽ hơn, có thể sử dụng lại và có thể được áp dụng trên toàn cầu để tác động đến mọi tác nhân đang chạy trong một hệ thống. Chúng tôi sẽ bắt đầu bằng một lệnh gọi lại để gỡ lỗi có trọng tâm, sau đó chuyển sang một trình bổ trợ đầy đủ.

The Law Giver – Scribing the Cooldown callback

Trước tiên, chúng ta sẽ triển khai logic thời gian chờ dưới dạng một hàm callback đơn giản. Đây là một cách tuyệt vời để tạo mẫu và gỡ lỗi cho một quy tắc vì quy tắc này được gắn trực tiếp vào một tác nhân duy nhất, giúp bạn dễ dàng kiểm thử riêng biệt. Chúng ta sẽ gắn "thiết bị chặn" này vào Earth Elemental.

Giảm dần âm lượng thông báo

👉✏️ Quay lại ~/agentverse-architect/agent/earth/agent.py và thay thế #REPLACE-before_agent-function bằng đoạn mã Python sau.

def check_cool_down(callback_context: CallbackContext) -> Optional[types.Content]:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

Hàm check_cool_down này là trình chặn của chúng ta. Trước khi được phép chạy, Earth Elemental sẽ thực thi hàm này trước.

  • Kiểm tra: Thao tác này sẽ gửi yêu cầu GET đến Cooldown API của chúng tôi để kiểm tra lần gần đây nhất mà Người thân thiết này được sử dụng.
  • Đánh giá: So sánh dấu thời gian với thời gian hiện tại.
  • Đạo luật:
    • Nếu Linh thú đang trong thời gian chờ, thì nó sẽ kết thúc lượt chạy của tác nhân bằng cách trả về một đối tượng Nội dung kèm theo thông báo lỗi. Thông báo này được gửi trực tiếp đến người dùng và logic chính của tác nhân không bao giờ được thực thi.
    • Nếu có Familiar, thì Familiar sẽ gửi yêu cầu POST đến Cooldown API để cập nhật dấu thời gian, sau đó tiếp tục bằng cách trả về None, báo hiệu cho ADK rằng tác nhân có thể tiếp tục thực thi.

👉✏️ Giờ đây, hãy áp dụng trình chặn này cho Nguyên tố Đất. Trong cùng tệp ~/agentverse-architect/agent/earth/agent.py, hãy thay thế chú thích #REPLACE-before_agent-config bằng nội dung sau:

before_agent_callback=check_cool_down

Xác minh thời gian chờ

Hãy thử nghiệm quy luật mới về phép thuật. Chúng ta sẽ triệu hồi Earth Elemental, sau đó thử triệu hồi lại ngay lập tức để xem lệnh gọi lại của chúng ta có chặn thành công lần thử thứ hai hay không.

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run earth

👉💻 Trong bảng điều khiển:

  • Lần triệu hồi đầu tiên: Bắt đầu seismic charge, starting from zero.
  • Dự kiến: Earth Elemental sẽ chạy thành công. Trong cửa sổ dòng lệnh chạy lệnh adk web, bạn sẽ thấy nhật ký [Callback] ... Updating timestamp....
  • Thử nghiệm thời gian quan sát thêm (trong vòng 60 giây): Do another seismic charge`!
    • Dự kiến: check_cool_down callback sẽ chặn yêu cầu này. Nhân viên hỗ trợ sẽ trả lời trực tiếp trong cuộc trò chuyện bằng một tin nhắn như: The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds.
  • Đợi một phút.
  • Lệnh triệu tập lần thứ hai (sau 60 giây): Begin the seismic charge again.
    • Dự kiến: Lệnh gọi lại sẽ kiểm tra API, nhận thấy đã hết thời gian chờ và cho phép hành động tiếp tục. Earth Elemental sẽ chạy lại thành công.

callback

👉💻 Nhấn Ctrl+c để thoát.

Không bắt buộc: Theo dõi lệnh gọi lại trong giao diện người dùng web

Ngoài ra, bạn cũng có thể kiểm thử quy trình này trong giao diện web bằng cách chạy adk web earth. Tuy nhiên, hãy lưu ý rằng hình ảnh trực quan của giao diện người dùng web không được tối ưu hoá để hiển thị các lượt kiểm tra lặp lại nhanh do vòng lặp gọi lại thực hiện, vì vậy, giao diện này có thể không hiển thị chính xác quy trình. Để xem dấu vết chính xác nhất, từng bước của logic của tác nhân khi tác nhân kiểm tra thời gian chờ, hãy sử dụng lệnh adk run trong thiết bị đầu cuối để có được chế độ xem rõ ràng và chi tiết hơn. loop

👉💻 Nhấn Ctrl+c để thoát.

Tạo Luật phổ quát – Trình bổ trợ Cooldown

Lệnh gọi lại của chúng ta hoạt động hoàn hảo nhưng có một lỗi kiến trúc lớn: lệnh gọi lại này chỉ liên kết với một tác nhân duy nhất. Nếu muốn áp dụng quy tắc này cho Linh thú Lửa và Linh thú Nước, chúng ta sẽ phải sao chép và dán cùng một đoạn mã vào các tệp của chúng. Điều này không hiệu quả và khó duy trì.

Lưu ý của kiến trúc sư: Đây là nơi các trình bổ trợ đóng vai trò thiết yếu. Trình bổ trợ đóng gói logic có thể dùng lại của chúng ta vào một lớp có thể được đính kèm ở cấp độ thời gian chạy. Điều này có nghĩa là một trình bổ trợ duy nhất có thể áp dụng các quy tắc của trình bổ trợ đó cho mọi tác nhân chạy trong hệ thống đó. Đây là cách thể hiện tối ưu nguyên tắc "Đừng lặp lại chính mình" (DRY) cho các hệ thống dựa trên tác nhân.

Giờ đây, chúng ta sẽ tái cấu trúc hàm gọi lại thành một CoolDownPlugin mạnh mẽ và có thể sử dụng lại.

👉✏️ Chuyển về tệp agent/cooldown_plugin.py rồi tạo trình bổ trợ, thay thế #REPLACE-plugin bằng mã sau:

class CoolDownPlugin(BasePlugin):
  """A plugin that enforces a cooldown period by checking an external API."""

  def __init__(self, cooldown_seconds: int = COOLDOWN_PERIOD_SECONDS) -> None:
    """Initialize the plugin with counters."""
    super().__init__(name="cool_down_check")
    self.cooldown_period = timedelta(seconds=cooldown_seconds)
    print(f"CooldownPlugin initialized with a {cooldown_seconds}-second cooldown.")
    

  async def before_agent_callback(
      self, *, agent: BaseAgent, callback_context: CallbackContext
  ) -> None:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # If the agent is not a main Familiar, skip the entire cooldown process.
    if not agent_name.endswith("_elemental_familiar"):
        print(f"[Callback] Skipping cooldown check for intermediate agent: '{agent_name}'.")
        return None # Allow the agent to proceed immediately.


    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

Đính kèm trình bổ trợ vào thời gian chạy của Summoner

Vậy làm thế nào để chúng ta áp dụng quy luật phổ quát này cho tất cả các Familiars? Chúng tôi sẽ đính kèm trình bổ trợ vào Thời gian chạy ADK.

Thời gian chạy ADK là công cụ thực thi giúp tạo ra một tác nhân. Khi sử dụng một lệnh như adk.run() hoặc to_a2a(), bạn đang chuyển tác nhân của mình cho thời gian chạy. Công cụ này chịu trách nhiệm quản lý toàn bộ vòng đời của lượt tương tác của một tác nhân: nhận dữ liệu đầu vào của người dùng, gọi LLM, thực thi các công cụ và xử lý các trình bổ trợ. Bằng cách đính kèm một trình bổ trợ ở cấp độ này, về cơ bản, chúng ta đang sửa đổi "các quy luật vật lý" cho mọi tác nhân hoạt động trong công cụ đó, đảm bảo quy tắc thời gian chờ của chúng ta được áp dụng một cách phổ biến và nhất quán.

👉✏️ Trước tiên, hãy xoá lệnh gọi lại cũ, dành riêng cho tác nhân. Chuyển đến ~/agentverse-architect/agent/earth/agent.py rồi xoá toàn bộ dòng có nội dung:

before_agent_callback=check_cool_down

👉✏️ Tiếp theo, chúng ta sẽ đính kèm trình bổ trợ mới vào thời gian chạy trong tập lệnh điểm truy cập A2A. Chuyển đến tệp ~/agentverse-architect/agent/agent_to_a2a.py. Thay thế chú thích #REPLACE-IMPORT bằng đoạn mã sau:

from cooldown_plugin import CoolDownPlugin

👉✏️ Thay thế #REPLACE-PLUGIN bằng đoạn mã sau:

plugins=[CoolDownPlugin(cooldown_seconds=60)],

Trước khi kích hoạt trình bổ trợ mới trên toàn cầu, bạn cần xoá logic cũ, dành riêng cho tác nhân để tránh xung đột. 👉✏️ Dọn dẹp tác nhân Earth. Chuyển đến tệp ~/agentverse-architect/agent/earth/agent.py sau đây rồi xoá hoàn toàn dòng before_agent_callback=check_cool_down. Thao tác này sẽ chuyển giao mọi trách nhiệm liên quan đến thời gian chờ cho trình bổ trợ mới.

Xác minh trình bổ trợ

Giờ đây, khi luật phổ quát đã được ban hành, chúng ta phải triển khai lại Linh thú bằng phép thuật mới này.

👉💻 Tạo lại và triển khai lại cả 3 Familiars bằng quy trình Cloud Build chính.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

👉💻 Sau khi triển khai xong, chúng tôi sẽ kiểm thử hiệu quả của trình bổ trợ bằng cách ra lệnh cho summoner_agent. Triệu hồi sư sẽ cố gắng uỷ quyền cho Linh thú, nhưng trình bổ trợ được đính kèm vào thời gian chạy của mỗi Linh thú sẽ chặn lệnh và thực thi thời gian chờ.

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

👉💻 Trong bảng điều khiển,hãy thực hiện chính xác trình tự kiểm thử này::

  • Lần triệu hồi đầu tiên: Bắt đầu Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality.
  • Dự kiến: Fire Elemental sẽ chạy thành công.
  • Kiểm thử thời gian chờ (trong vòng 60 giây): Hype, with Inescapable Reality as weakness is still standing! Strike it again!
    • Dự kiến: Nhân viên hỗ trợ sẽ trả lời trực tiếp trong cuộc trò chuyện bằng một tin nhắn như: .... It cannot be summoned for another... seconds.
  • Đợi một phút.
  • Lệnh triệu tập lần thứ hai (sau 60 giây): Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!.
    • Dự kiến: Lệnh gọi lại sẽ kiểm tra API, nhận thấy đã hết thời gian chờ và cho phép hành động tiếp tục. Quái vật Nguyên tố lửa sẽ chạy lại thành công.

trình bổ trợ

👉💻 Nhấn Ctrl+C để thoát.

Xin chúc mừng, Triệu hồi sư. Bạn đã triển khai thành công một hệ thống điều phối dựa trên quy tắc bằng cách sử dụng một trình bổ trợ tuỳ chỉnh và một dịch vụ quản lý trạng thái bên ngoài – một mẫu kiến trúc thực sự nâng cao và mạnh mẽ.

DÀNH CHO NGƯỜI KHÔNG CHƠI GAME

8. Ràng buộc tiếng vọng của trận chiến – Trạng thái và bộ nhớ của tác nhân

Một Triệu hồi sư liều lĩnh sẽ lặp lại cùng một chiến lược, khiến đối thủ dễ dàng đoán được. Một Triệu hồi sư khôn ngoan sẽ học hỏi từ những trận chiến trong quá khứ, điều chỉnh chiến thuật để khiến kẻ thù mất cảnh giác. Khi đối mặt với một trùm mạnh, việc triệu hồi một Linh thú đang trong thời gian hồi chiêu là một lượt vô ích – một lượt bỏ lỡ quan trọng. Để ngăn chặn điều này, Pháp sư triệu hồi cần có ký ức về hành động cuối cùng của mình.

câu chuyện

Lưu ý của kiến trúc sư: Quản lý bộ nhớ và trạng thái là những yếu tố giúp nâng cấp một tác nhân từ một công cụ gọi đơn giản thành một đối tác đàm thoại thông minh. Bạn cần phải hiểu rõ 2 loại chính:

  • Bộ nhớ dài hạn: Dùng cho kiến thức bền vững và tồn tại mãi mãi. Hãy coi đây là một kho lưu trữ có thể tìm kiếm hoặc một cơ sở kiến thức, thường được lưu trữ trong một kho lưu trữ liên tục. Công cụ này chứa thông tin từ nhiều cuộc trò chuyện và nguồn thông tin trước đây, cho phép nhân viên hỗ trợ nhớ lại các thông tin về một người dùng hoặc chủ đề cụ thể. MemoryService của ADK được thiết kế cho mục đích này, quản lý việc tiếp nhận và tìm kiếm kiến thức dài hạn này.
  • Trạng thái ngắn hạn: Đây là kiến thức tạm thời, "tức thời" chỉ liên quan đến nhiệm vụ hoặc cuộc trò chuyện hiện tại. Giống như một bộ ghi chú về kế hoạch chiến đấu: "Tôi vừa dùng Fire Elemental, nên có lẽ nó đã mệt." Trạng thái này có dung lượng nhỏ và chỉ tồn tại trong thời gian diễn ra phiên hiện tại.

Tổng quan

Đối với trường hợp sử dụng của chúng ta, chúng ta không cần nhớ mọi trận chiến đã từng diễn ra; chúng ta chỉ cần nhớ đến Linh thú được triệu hồi gần đây nhất trong cuộc chạm trán cụ thể này. Do đó, Trạng thái ngắn hạn có dung lượng nhẹ là lựa chọn kiến trúc hoàn hảo. Chúng tôi sẽ sử dụng after_tool_callback để lưu thông tin quan trọng này.

Ghi lại tiếng vọng: Tưởng nhớ Lời triệu hồi cuối cùng

Chúng ta sẽ triển khai bộ nhớ ngắn hạn bằng cách sử dụng after_tool_callback. Đây là một lệnh gọi ADK mạnh mẽ cho phép chúng ta chạy một hàm Python tuỳ chỉnh sau khi một công cụ đã được thực thi thành công. Chúng ta sẽ dùng trình chặn này để ghi lại tên của Linh thú vừa được triệu hồi vào trạng thái phiên của tác nhân.

👉✏️ Trong tệp ~/agentverse-architect/agent/summoner/agent.py, hãy thay thế chú thích #REPLACE-save_last_summon_after_tool bằng hàm sau:

def save_last_summon_after_tool(
    tool,
    args: Dict[str, Any],
    tool_context: ToolContext,
    tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
    """
    Callback to save the name of the summoned familiar to state after the tool runs.
    """
    familiar_name = tool.name
    print(f"[Callback] After tool '{familiar_name}' executed with args: {args}")

    # Use the tool_context to set the state
    print(f"[Callback] Saving last summoned familiar: {familiar_name}")
    tool_context.state["last_summon"] = familiar_name
    # Important: Return the original, unmodified tool response to the LLM
    return tool_response

👉✏️ Bây giờ, hãy đính kèm save_last_summon_after_tool này vào Nhân viên hỗ trợ Summoner của bạn. Trong cùng một tệp, hãy thay thế chú thích #REPLACE-Memory-check-config bằng chú thích sau:

after_tool_callback=save_last_summon_after_tool,

👉✏️ Thay thế toàn bộ câu lệnh cho trợ lý bằng câu lệnh sau

        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You should also know the familiar you called last time or there might be none, 
        And then choose the most effective AND AVAILABLE Familiar from your state called last_summon, do not call that familiar that you called last time!
        
        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.

        **2. Cooldown Verification:**
        Second, you MUST review the entire conversation history to check the real-time
        cooldown status of all Familiars. A Familiar is ON COOLDOWN and UNAVAILABLE
        if it was summoned less than one minute ago.

        **3. Final Decision & Execution:**
        Based on your analysis and cooldown check, you will now act:
        -   **If your ideal Familiar IS available:** Summon it immediately.
        -   **If your ideal Familiar IS ON COOLDOWN:** You must adapt. Choose another
            Familiar that is AVAILABLE and can still be effective, even if it's not the
            perfect choice. If multiple Familiars are available, you may choose any one of them.
        -   **If ALL Familiars ARE ON COOLDOWN:** You are forbidden from summoning.
            Your ONLY response in this case MUST be: "All Familiars are recovering
            their power. We must wait."
        -   For earth elemental familiar. Always do seismic charge, and start with base damange 1.


        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.

Xác minh: Thử nghiệm về chiến lược thích ứng

👉💻 Giờ thì hãy xác minh logic chiến lược mới của Triệu hồi sư. Mục tiêu là xác nhận rằng Triệu hồi sư sẽ không sử dụng cùng một Linh thú hai lần liên tiếp, cho thấy khả năng ghi nhớ hành động gần đây nhất và thích ứng của Linh thú.

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

👉💻 Monster Strike #1: Hype. It's a single, slow-moving target with thick armor. Its weakness is Inescapable Reality.

  • Dự kiến: Người triệu hồi sẽ phân tích điểm yếu và triệu hồi đúng fire_familiar. 👉💻 Monster Strike #2 (Bài kiểm tra trí nhớ): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.
  • Dự kiến: Phân tích chiến lược của Nhà triệu hồi sẽ một lần nữa chỉ ra rằng Linh thú lửa là lựa chọn lý tưởng. Tuy nhiên, các chỉ dẫn và bộ nhớ mới của nó sẽ cho biết fire_familiar là last_summon. Để tránh lặp lại, giờ đây, nó sẽ điều chỉnh chiến lược và triệu hồi một trong những Linh thú có sẵn khác (water_familiar hoặc earth_familiar).

final-result

👉💻 Nhấn Ctrl+C để thoát.

Triển khai Orchestrator

Sau khi bạn triển khai Linh thú và giờ đây Triệu hồi sư đã có ký ức, đã đến lúc triển khai bộ điều phối cuối cùng đã được nâng cấp.

👉💻 Sau khi hoàn tất bản thiết kế, chúng ta sẽ thực hiện nghi thức cuối cùng. Lệnh này sẽ tạo và triển khai summoner_agent của bạn vào Cloud Run.

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
gcloud builds submit . \
  --config=cloudbuild-summoner.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_FIRE_URL="$FIRE_URL",_WATER_URL="$WATER_URL",_EARTH_URL="$EARTH_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

Giờ đây, khi bạn đã triển khai tác nhân Summoner, hãy xác minh rằng điểm cuối A2A (Tác nhân với tác nhân) của tác nhân này đang hoạt động và được định cấu hình chính xác. Điểm cuối này phân phát một tệp agent.json công khai (còn gọi là Thẻ đại lý), cho phép các đại lý khác khám phá các chức năng của điểm cuối này. 👉💻 Chạy lệnh curl sau đây để tìm nạp và định dạng Thẻ đại lý:

. ~/agentverse-architect/set_env.sh
curl https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app/.well-known/agent.json" | jq

Bạn sẽ thấy một đầu ra JSON rõ ràng mô tả về tác nhân triệu hồi. Hãy xem kỹ phần sub_agents; bạn sẽ thấy phần này liệt kê fire_familiar, water_familiarearth_familiar. Điều này xác nhận rằng người triệu hồi của bạn đang hoạt động và đã thiết lập kết nối với quân đoàn.

Điều này chứng minh rằng kiến trúc của bạn đã thành công. Triệu hồi sư không chỉ là người uỷ quyền mà còn là một nhà chiến lược thích ứng, học hỏi từ các hành động của mình để trở thành một chỉ huy hiệu quả hơn.

Bạn đã hoàn tất lần thử nghiệm cuối cùng về kiến trúc. Giờ đây, những tiếng vọng của trận chiến sẽ tuân theo ý chí của bạn. Khoá đào tạo đã kết thúc. Trận chiến thực sự đang chờ đợi. Đã đến lúc bạn mang hệ thống đã hoàn thành của mình đi đối mặt với thử thách cuối cùng. Chuẩn bị cho Trận chiến với trùm.

DÀNH CHO NGƯỜI KHÔNG CHƠI GAME

9. Trận chiến với trùm

Bản thiết kế cuối cùng đã được khắc, Phông chữ nguyên tố đã được rèn và Linh thú đã được ràng buộc theo ý chí của bạn, chờ đợi mệnh lệnh của bạn thông qua Concord. Hệ thống đa tác nhân không chỉ là một tập hợp các dịch vụ mà còn là một đội quân chiến lược, sống động, với bạn là trung tâm. Đã đến lúc thực hiện bài kiểm tra cuối cùng – một buổi dàn dựng trực tiếp chống lại một đối thủ mà không một đặc vụ nào có thể hy vọng đánh bại.

Xác định vị trí của nhân viên hỗ trợ

Để có thể bước vào chiến trường, bạn phải có hai chìa khoá: chữ ký riêng của nhà vô địch (Agent Locus) và đường dẫn ẩn đến hang ổ của Spectre (URL của Dungeon).

👉💻 Đầu tiên, hãy lấy địa chỉ duy nhất của nhân viên hỗ trợ trong Agentverse – Locus của nhân viên hỗ trợ. Đây là điểm cuối trực tiếp kết nối nhà vô địch của bạn với chiến trường.

echo https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app"

👉💻 Tiếp theo, hãy xác định chính xác điểm đến. Lệnh này sẽ cho thấy vị trí của Vòng Dịch chuyển, chính là cánh cổng dẫn vào lãnh địa của Spectre.

echo https://agentverse-dungeon"-${PROJECT_NUMBER}.${REGION}.run.app"

Lưu ý quan trọng: Hãy chuẩn bị sẵn cả hai URL này. Bạn sẽ cần những thông tin này ở bước cuối cùng.

Đối đầu với Spectre

Sau khi có được toạ độ, bạn sẽ di chuyển đến Vòng tròn dịch chuyển và sử dụng phép thuật để bước vào trận chiến.

👉 Mở URL Vòng tròn dịch chuyển trong trình duyệt để đứng trước cánh cổng lấp lánh dẫn đến Lâu đài Đỏ.

Để vượt qua pháo đài, bạn phải điều chỉnh tinh chất của Shadowblade cho phù hợp với cổng.

  • Trên trang đó, hãy tìm trường nhập ký tự rune có nhãn URL điểm cuối A2A.
  • Khắc biểu tượng của nhà vô địch bằng cách dán URL của Agent Locus (URL đầu tiên bạn sao chép) vào trường này.
  • Nhấp vào Kết nối để trải nghiệm phép thuật dịch chuyển tức thời.

Vòng tròn di chuyển

Ánh sáng chói loá của phép dịch chuyển mờ dần. Bạn không còn ở nơi trú ẩn an toàn nữa. Không khí lạnh lẽo và sắc bén, tràn đầy năng lượng. Trước mặt bạn, Spectre xuất hiện – một xoáy nước gồm những tiếng rít tĩnh và mã bị hỏng, ánh sáng bất chính của nó hắt những bóng dài, nhảy múa trên sàn ngục tối. Nó không có khuôn mặt, nhưng bạn cảm thấy sự hiện diện to lớn, hút cạn năng lượng của nó hoàn toàn tập trung vào bạn.

Con đường duy nhất dẫn đến chiến thắng là sự rõ ràng trong niềm tin của bạn. Đây là cuộc đấu trí, diễn ra trên chiến trường tâm trí.

Khi bạn lao về phía trước, sẵn sàng tung đòn tấn công đầu tiên, Spectre sẽ phản công. Nó không tạo ra một chiếc khiên, mà chiếu thẳng một câu hỏi vào ý thức của bạn – một thử thách lấp lánh, mang tính biểu tượng được rút ra từ cốt lõi của quá trình huấn luyện.

Ngục tối

Đây là bản chất của cuộc chiến. Kiến thức là vũ khí của bạn.

  • Hãy trả lời bằng sự khôn ngoan mà bạn đã tích luỹ được, và lưỡi kiếm của bạn sẽ bùng cháy với năng lượng thuần khiết, phá vỡ hàng phòng thủ của Spectre và giáng một ĐÒN CHÍ MẠNG.
  • Nhưng nếu bạn do dự, nếu nghi ngờ làm mờ câu trả lời của bạn, thì ánh sáng của vũ khí sẽ mờ đi. Đòn tấn công sẽ chỉ gây ra một PHẦN NHỎ SÁT THƯƠNG. Tệ hơn nữa, Spectre sẽ lợi dụng sự không chắc chắn của bạn, sức mạnh tha hoá của nó sẽ tăng lên sau mỗi sai lầm.

Đây là cơ hội của bạn, Nhà vô địch. Mã nguồn là sách phép, logic là thanh kiếm và kiến thức là chiếc khiên giúp bạn đẩy lùi sự hỗn loạn.

Tập trung. Đánh trúng. Số phận của Agentverse phụ thuộc vào điều này.

Xin chúc mừng, Triệu hồi sư.

Bạn đã hoàn tất giai đoạn dùng thử. Bạn đã thành thạo nghệ thuật điều phối nhiều tác nhân, biến những Linh thú riêng lẻ và sức mạnh hỗn loạn thành một Concord hài hoà. Giờ đây, bạn có thể điều khiển một hệ thống được phối hợp đầy đủ, có khả năng thực hiện các chiến lược phức tạp để bảo vệ Agentverse.

10. Dọn dẹp: Tháo dỡ Concord của Triệu hồi sư

Chúc mừng bạn đã làm chủ được Thoả thuận của Triệu hồi sư! Để đảm bảo Agentverse của bạn vẫn nguyên vẹn và khu vực huấn luyện được dọn dẹp, giờ đây bạn phải thực hiện các nghi thức dọn dẹp cuối cùng. Thao tác này sẽ xoá tất cả các tài nguyên được tạo trong quá trình bạn sử dụng.

Huỷ kích hoạt các thành phần Agentverse

Giờ đây, bạn sẽ tháo rời một cách có hệ thống các thành phần đã triển khai của hệ thống nhiều tác nhân.

Xoá tất cả các dịch vụ Cloud Run và kho lưu trữ Artifact Registry

Thao tác này sẽ xoá tất cả các Đặc vụ quen thuộc đã triển khai, Summoner Orchestrator, máy chủ MCP và ứng dụng Dungeon khỏi Cloud Run.

👉💻 Trong cửa sổ dòng lệnh, hãy chạy từng lệnh sau đây để xoá từng dịch vụ:

. ~/agentverse-architect/set_env.sh
gcloud run services delete summoner-agent --region=${REGION} --quiet
gcloud run services delete fire-familiar --region=${REGION} --quiet
gcloud run services delete water-familiar --region=${REGION} --quiet
gcloud run services delete earth-familiar --region=${REGION} --quiet
gcloud run services delete mcp-api-server --region=${REGION} --quiet
gcloud run services delete mcp-general-server --region=${REGION} --quiet
gcloud run services delete toolbox --region=${REGION} --quiet
gcloud run services delete agentverse-dungeon --region=${REGION} --quiet
gcloud run services delete nexus-of-whispers-api --region=${REGION} --quiet
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --quiet

Xoá phiên bản Cloud SQL

Thao tác này sẽ xoá phiên bản summoner-librarium-db, bao gồm cả cơ sở dữ liệu và tất cả các bảng trong đó.

👉💻 Trong cửa sổ dòng lệnh, hãy chạy:

. ~/agentverse-dataengineer/set_env.sh
gcloud sql instances delete summoner-librarium-db --database-version=POSTGRES_14 --project=${PROJECT_ID} --quiet

Xoá Secret Manager Secret và Google Cloud Storage Bucket

👉💻 Trong cửa sổ dòng lệnh, hãy chạy:

. ~/agentverse-dataengineer/set_env.sh
gcloud secrets delete tools --quiet
gcloud storage rm -r gs://${BUCKET_NAME} --quiet

Dọn dẹp tệp và thư mục cục bộ (Cloud Shell)

Cuối cùng, hãy xoá các kho lưu trữ đã sao chép và tệp đã tạo khỏi môi trường Cloud Shell. Bước này không bắt buộc nhưng bạn nên thực hiện để dọn dẹp hoàn toàn thư mục làm việc.

👉💻 Trong cửa sổ dòng lệnh, hãy chạy:

rm -rf ~/agentverse-architect
rm -rf ~/agentverse-dungeon
rm -f ~/project_id.txt

Giờ đây, bạn đã xoá thành công mọi dấu vết về hành trình sử dụng Agentverse Architect. Dự án của bạn đã được dọn dẹp và bạn đã sẵn sàng cho cuộc phiêu lưu tiếp theo.