1. Xây dựng lòng tin để khơi gợi sự hào phóng

Khoảnh khắc truyền cảm hứng
Điện thoại của bạn rung. Bạn thấy một bản tin về một chương trình xoá mù chữ thành công, giúp trẻ em ở những cộng đồng khó khăn học đọc. Bạn cảm thấy thôi thúc mạnh mẽ muốn đóng góp. Bạn mở trình duyệt và tìm kiếm "quyên góp cho chương trình nâng cao khả năng đọc viết cho trẻ em".

Hàng trăm kết quả xuất hiện.
Bạn nhấp vào đường liên kết đầu tiên. Trang web trông chuyên nghiệp. Bạn di chuyển xuống phần thông tin tài chính của họ. "Chi phí hành chính: 28%." Bạn tạm dừng. Chỉ 72 xu trong mỗi đô la bạn quyên góp sẽ thực sự được dùng để tài trợ cho chương trình. Như vậy có được không? Bạn không chắc chắn.
Bạn thử một tổ chức khác. Bạn chưa từng nghe nói đến họ. Những email này có phải là email chính thống không? Một lượt tìm kiếm nhanh có thể dẫn bạn đến một nơi không ngờ. Bạn tìm thấy một chuỗi thảo luận trên Reddit từ hai năm trước, trong đó một người dùng tuyên bố: "Đây là một trò lừa đảo, khoản quyên góp của tôi không bao giờ được chuyển đi." Một người khác nhiệt tình bảo vệ họ: "Họ đang làm việc thực sự!" Sự mơ hồ này khiến bạn không thể hành động.
30 phút sau, bạn lạc vào một mê cung gồm các bài đánh giá mâu thuẫn, điểm xếp hạng hiệu quả và hồ sơ của IRS, nhưng bạn vẫn chưa quyên góp. Ngọn lửa hào phóng ban đầu đã được thay thế bằng sự khó khăn của nghiên cứu. Thẻ này sẽ mở trong vài ngày, như một lời nhắc nhỏ về ý định tốt, cho đến khi bạn đóng thẻ.
Đây không phải là lỗi cá nhân mà là lỗi hệ thống
Trải nghiệm này là phổ biến. Ai cũng muốn quyên góp, nhưng quy trình quyên góp lại có nhiều rào cản khiến người quyên góp do dự và nghi ngờ:
- ❌ Khó khăn trong việc nghiên cứu: Mỗi tổ chức từ thiện đều cần được điều tra riêng.
- ❌ Xác minh độ tin cậy: Rất khó phân biệt tổ chức hoạt động hiệu quả cao với tổ chức hoạt động kém hiệu quả hoặc thậm chí là lừa đảo trắng trợn.
- ❌ Tình trạng tê liệt do phân tích: Quá nhiều lựa chọn khiến người dùng mệt mỏi khi phải đưa ra quyết định.
- ❌ Mất đà: Động lực cảm xúc để quyên góp giảm dần khi gánh nặng về mặt hậu cần tăng lên.
Rào cản này có chi phí đáng kinh ngạc trong thế giới thực. Hoạt động quyên góp cá nhân ở Hoa Kỳ rất lớn. Theo Giving USA 2024, chỉ riêng năm 2023, các nhà tài trợ cá nhân đã quyên góp khoảng 374 tỷ USD. Tuy nhiên, nghiên cứu cho thấy những rào cản đối với việc quyên góp (bao gồm cả chi phí tìm kiếm, trở ngại tâm lý và hạn chế về thời gian) làm giảm đáng kể số tiền quyên góp được cho các tổ chức từ thiện. Các nghiên cứu liên quan đến hàng triệu nhà tài trợ cho thấy ngay cả một chút khó khăn trong quy trình quyên góp trực tuyến cũng khiến mọi người không thực hiện được ý định từ thiện của mình.
Điều này có nghĩa là hàng tỷ đô la Mỹ tiền quyên góp dự kiến không bao giờ đến được với những tổ chức cần đến chúng.
The Vision
Hãy tưởng tượng một trải nghiệm khác. Thay vì một phiên nghiên cứu kéo dài 30 phút, bạn chỉ cần nói:
"Tôi muốn quyên góp 50 đô la cho một chương trình xoá mù chữ cho trẻ em. Tìm cho tôi một tổ chức từ thiện hiệu quả, được xác minh và có điểm đánh giá cao."
Và chỉ trong vài giây, bạn sẽ nhận được câu trả lời giúp bạn tự tin:
Đây là lời hứa của một AI Giving Agent. Tuy nhiên, để hiện thực hoá tầm nhìn này, chúng ta phải giải quyết một thách thức cơ bản: khi một tác nhân AI tự trị xử lý tiền, niềm tin không phải là yếu tố tuỳ chọn mà là nền tảng cốt lõi.
- Làm cách nào để chứng minh những gì người dùng đã uỷ quyền?
- Ai chịu trách nhiệm nếu xảy ra sai sót?
- Làm cách nào để nhà tài trợ, tổ chức từ thiện và mạng thanh toán tin tưởng tham gia?
Nhiệm vụ của bạn hôm nay
Trong hội thảo này, bạn sẽ xây dựng tác nhân đáng tin cậy đó bằng cách kết hợp 2 công nghệ mạnh mẽ:
Bộ công cụ phát triển (ADK) của Google Agent | Giao thức thanh toán của đại lý (AP2) | |
Vai trò | Nhà máy để xây dựng các tác nhân AI cấp sản xuất | Bản thiết kế kiến trúc để tạo niềm tin trong các giao dịch AI |
Những thông tin được cung cấp | • Khung điều phối nhiều tác nhân | • Ranh giới bảo mật dựa trên vai trò |
Tìm hiểu thêm |
Sản phẩm bạn sẽ tạo ra
Khi kết thúc buổi hội thảo này, bạn sẽ tạo được:
✅ Hệ thống nhiều tác nhân có các vai trò chuyên biệt:
- Một trợ lý mua sắm tìm các tổ chức từ thiện đã được xác minh
- Một Nhân viên bán hàng tạo ra các ưu đãi quyên góp ràng buộc
- Một Credentials Provider xử lý các khoản thanh toán một cách an toàn
- Một Orchestrator điều phối toàn bộ quy trình
✅ 3 loại thông tin xác thực có thể xác minh:
- IntentMandate: "Tìm cho tôi một tổ chức từ thiện giáo dục"
- CartMandate: "500.000 VND cho Room to Read, có chữ ký của người bán"
- PaymentMandate: "Xử lý qua khoản thanh toán mô phỏng"
✅ Bảo mật ở mọi lớp:
- Ranh giới tin cậy dựa trên vai trò
- Sự đồng ý rõ ràng của người dùng
✅ Biên bản kiểm tra đầy đủ:
- Mọi quyết định đều có thể truy xuất được
- Mọi sự đồng ý đều được ghi lại
- Mọi yêu cầu bàn giao đều hiển thị
🔒 Quan trọng: Đây là Môi trường học tập an toàn
Bạn đã sẵn sàng tạo dựng lòng tin chưa?
Trong mô-đun tiếp theo, chúng ta sẽ thiết lập môi trường phát triển và xây dựng tác nhân AI đầu tiên. Bạn sẽ nhanh chóng nhận ra lý do khiến các tác nhân đơn giản không đáng tin cậy, sau đó dành thời gian còn lại của buổi hội thảo để tìm hiểu cách khắc phục vấn đề đó.
Hãy bắt đầu bằng cách tự mình tìm hiểu vấn đề.
2. Chuẩn bị không gian làm việc
Nền tảng cho các tác nhân đáng tin cậy
Trước khi có thể xây dựng Giving Agent AI, chúng ta cần chuẩn bị một môi trường phát triển minh bạch, nhất quán và được định cấu hình chính xác. Đây là một bước tập trung để đảm bảo bạn đã có tất cả các công cụ và dịch vụ cần thiết.
Việc hoàn tất thành công quy trình thiết lập này có nghĩa là bạn có thể hoàn toàn tập trung vào công việc thú vị là xây dựng logic của tác nhân trong các mô-đun sắp tới mà không phải lo lắng về các vấn đề về cấu hình.
Truy cập Cloud Shell
Trước tiên, chúng ta sẽ mở Cloud Shell. Đây là một cửa sổ dòng lệnh dựa trên trình duyệt có Google Cloud SDK và các công cụ thiết yếu khác được cài đặt sẵn.
Bạn cần tín dụng Google Cloud?
Nhấp vào Kích hoạt Cloud Shell ở đầu Bảng điều khiển Google Cloud (đó là biểu tượng thiết bị đầu cuối trong thanh điều hướng trên cùng bên phải).

Tìm mã dự án trên Google Cloud:
- Mở Google Cloud Console: https://console.cloud.google.com
- Chọn dự án mà 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

Sau khi Cloud Shell mở, hãy xác minh rằng bạn đã được xác thực:
# Check that you are logged in
gcloud auth list
Bạn sẽ thấy tài khoản của mình được liệt kê là (ACTIVE).
Định cấu hình dự án
Bây giờ, hãy thiết lập dự án Google Cloud và bật các API cần thiết.
Đặt mã dự án
# Set your project using the auto-detected environment variable in Cloud Shell
gcloud config set project $GOOGLE_CLOUD_PROJECT
# Verify the project has been set
echo "Your active Google Cloud project is: $(gcloud config get-value project)"
Bật các API bắt buộc
Các đặc vụ của bạn cần có quyền truy cập vào một số dịch vụ của Google Cloud:
gcloud services enable \
aiplatform.googleapis.com \
secretmanager.googleapis.com \
cloudtrace.googleapis.com
Quá trình này có thể mất 1 – 2 phút. Bạn sẽ thấy:
Operation "operations/..." finished successfully.
Những gì các API này cung cấp:
- aiplatform.googleapis.com: Quyền truy cập vào các mô hình Gemini để suy luận về tác nhân
- secretmanager.googleapis.com: Bộ nhớ bảo mật cho khoá API (phương pháp hay nhất cho hoạt động sản xuất)
- cloudtrace.googleapis.com: Khả năng quan sát cho nhật ký hoạt động
Sao chép Đoạn mã khởi đầu
Tải kho lưu trữ hội thảo có tất cả mã và tài nguyên mẫu:
git clone https://github.com/ayoisio/adk-ap2-charity-agents
cd adk-ap2-charity-agents
git checkout codelab
Hãy xác minh những gì chúng ta có:
ls -la
Bạn sẽ thấy:
charity_advisor/– Nơi chúng ta sẽ xây dựng các đặc vụ và công cụscripts/– Tập lệnh trợ giúp để kiểm thử và xác minhdeploy.sh– Tập lệnh trợ giúp để triển khaisetup.py– Tập lệnh trợ giúp để cài đặt mô-đun.env.template– Tệp biến môi trường
Thiết lập môi trường Python
Bây giờ, chúng ta sẽ tạo một môi trường Python biệt lập cho dự án của mình.
Tạo và kích hoạt môi trường ảo
# Create the virtual environment
python3 -m venv venv
# Activate it
source venv/bin/activate
✅ Xác minh: Giờ đây, câu lệnh của bạn sẽ có tiền tố (venv).
Cài đặt các phần phụ thuộc
pip install -r charity_advisor/requirements.txt
pip install -e .
Thao tác này sẽ cài đặt:
- google-adk: Khung Agent Development Kit
- google-cloud-aiplatform: Tích hợp Vertex AI và Gemini
- ap2: Agent Payments Protocol SDK (từ GitHub)
- python-dotenv: Quản lý biến môi trường
Cờ -e cho phép bạn nhập các mô-đun adk_ap2_charity_agents từ mọi nơi.
Định cấu hình tệp môi trường
Tạo cấu hình từ mẫu:
# Copy the template
cp .env.template .env
# Get your current Project ID
PROJECT_ID=$(gcloud config get-value project)
# Replace the placeholder with your actual project ID
sed -i "s/your-project-id/$PROJECT_ID/g" .env
# Verify the replacement worked
grep GOOGLE_CLOUD_PROJECT .env
Bạn sẽ thấy:
GOOGLE_CLOUD_PROJECT=your-actual-project-id
Xác minh
Chạy tập lệnh xác minh để đảm bảo mọi thứ được định cấu hình đúng cách:
python scripts/verify_setup.py
Bạn sẽ thấy tất cả dấu kiểm màu xanh lục:
======================================================================
SETUP VERIFICATION
======================================================================
✓ Python version: 3.11.x
✓ google-adk: 1.17.0
✓ google-cloud-aiplatform: 1.111.0+
✓ ap2: 0.1.0
✓ python-dotenv: 1.0.0+
✓ .env file found and contains project ID
✓ Google Cloud project configured: your-project-id
✓ Mock charity database found
✓ Agent templates ready
✓ All directories present
======================================================================
✓ Setup complete! You are ready to build trustworthy agents.
======================================================================
Khắc phục sự cố
Tiếp theo là gì?
Môi trường của bạn hiện đã được chuẩn bị đầy đủ! Bạn có:
- ✅ Đã định cấu hình dự án trên Google Cloud
- ✅ Đã bật các API bắt buộc
- ✅ Đã cài đặt thư viện ADK và AP2
- ✅ Mã mẫu đã sẵn sàng để sửa đổi
Trong mô-đun tiếp theo, bạn sẽ tạo tác nhân AI đầu tiên chỉ bằng vài dòng mã và khám phá lý do khiến các tác nhân đơn giản không đáng tin cậy khi xử lý giao dịch tài chính.
3. Đại lý đầu tiên của bạn và việc khám phá khoảng cách về niềm tin

Từ ý tưởng đến tương tác
Trong mô-đun trước, chúng ta đã chuẩn bị môi trường phát triển. Giờ là lúc bắt đầu công việc thú vị. Chúng ta sẽ xây dựng và chạy tác nhân đầu tiên, cung cấp cho tác nhân này khả năng đầu tiên và trong quá trình đó, khám phá những thách thức cơ bản mà chúng ta phải giải quyết để tác nhân này thực sự đáng tin cậy.
Mô-đun này là bức ảnh "trước" của bạn – khoảnh khắc cho thấy lý do khiến việc xây dựng các tác nhân đáng tin cậy đòi hỏi nhiều hơn là chỉ cấp cho LLM quyền truy cập vào các công cụ.
Bước 1: Kiểm tra Starter Agent
Trước tiên, hãy xem mẫu cho nhân viên hỗ trợ đầu tiên của chúng ta. Tệp này chứa một cấu trúc cơ bản với các phần giữ chỗ mà chúng ta sẽ hoàn tất trong các bước tiếp theo.
👉 Mở tệp
charity_advisor/simple_agent/agent.py
trong trình chỉnh sửa.
Bạn sẽ thấy:
"""
A simple agent that can research charities using Google Search.
"""
# MODULE_3_STEP_2_IMPORT_COMPONENTS
simple_agent = Agent(
name="SimpleAgent",
model="gemini-2.5-flash",
# MODULE_3_STEP_3_WRITE_INSTRUCTION
instruction="""""",
# MODULE_3_STEP_4_ADD_TOOLS
tools=[]
)
Lưu ý rằng các bình luận của trình giữ chỗ tuân theo một mẫu: MODULE_3_STEP_X_DESCRIPTION. Chúng ta sẽ thay thế các điểm đánh dấu này để từng bước xây dựng tác nhân.
Bước 2: Nhập các thành phần bắt buộc
Trước khi có thể tạo thực thể cho lớp Agent hoặc sử dụng công cụ google_search, chúng ta cần nhập các lớp và công cụ đó vào tệp của mình.
👉 Tìm:
# MODULE_3_STEP_2_IMPORT_COMPONENTS
👉 Thay thế dòng đó bằng:
from google.adk.agents import Agent
from google.adk.tools import google_search
Giờ đây, lớp Agent và công cụ google_search có trong tệp của chúng ta.
Bước 3: Viết Chỉ dẫn cho trợ lý
Chỉ dẫn là "bản mô tả công việc" của tác nhân – chỉ dẫn cho LLM biết thời điểm và cách sử dụng các công cụ của tác nhân. Hãy viết một câu lệnh hướng dẫn trợ lý tìm kiếm thông tin về tổ chức từ thiện.
👉 Tìm:
# MODULE_3_STEP_3_WRITE_INSTRUCTION
instruction="""""",
👉 Thay thế hai dòng đó bằng:
instruction="""You are a helpful research assistant. When a user asks you to find information about charities,
use the google_search tool to find the most relevant and up-to-date results from the web.
Synthesize the search results into a helpful summary.""",
Bước 4: Thêm Công cụ tìm kiếm
Nhân viên hỗ trợ không có công cụ chỉ là người trò chuyện. Hãy cung cấp cho trợ lý ảo khả năng đầu tiên: khả năng tìm kiếm trên web.
👉 Tìm:
# MODULE_3_STEP_4_ADD_TOOLS
tools=[]
👉 Thay thế hai dòng đó bằng:
tools=[google_search]
Bước 5: Xác minh nhân viên hỗ trợ hoàn chỉnh
Hãy xác nhận rằng tất cả các phần đều đã được đặt đúng vị trí trước khi chúng ta kiểm tra.
👉 Thông tin đầy đủ của bạn
charity_advisor/simple_agent/agent.py
Tệp hiện sẽ có dạng như sau:
"""
A simple agent that can research charities using Google Search.
"""
from google.adk.agents import Agent
from google.adk.tools import google_search
simple_agent = Agent(
name="SimpleAgent",
model="gemini-2.5-flash",
instruction="""You are a helpful research assistant. When a user asks you to find information about charities,
use the google_search tool to find the most relevant and up-to-date results from the web.
Synthesize the search results into a helpful summary.""",
tools=[google_search]
)
Bước 6: Kiểm thử Agent – Khám phá những điểm thiếu tin cậy
Bây giờ, khi tác nhân của chúng ta đã được định cấu hình đầy đủ, hãy kiểm thử và phân tích hành vi của tác nhân. Đây là nơi chúng ta khám phá lý do tại sao các tác nhân đơn giản không đáng tin cậy khi xử lý các quyết định tài chính.
Thử nghiệm 1: Vấn đề về việc khám phá
👉 Trong cửa sổ dòng lệnh Cloud Shell, hãy chạy lệnh sau:
adk run charity_advisor/simple_agent
Bạn sẽ thấy kết quả như sau:
INFO:google.adk.agents:Loading agent from charity_advisor/simple_agent
INFO:google.adk.agents:Agent 'SimpleAgent' ready
[user]:
Lời nhắc [user]: hiện đang chờ bạn nhập thông tin.
👉 Tại dấu nhắc [user]:, hãy nhập:
Can you find me a verified, highly-rated charity for children's literacy?
👉 Nhấn Enter và quan sát phản hồi.
Sau một lát, tác nhân sẽ tổng hợp kết quả tìm kiếm thành một câu trả lời như sau:
Dựa trên kết quả tìm kiếm trên web, một số tổ chức từ thiện uy tín về khả năng đọc viết cho trẻ em có vẻ là Reading Is Fundamental và Room to Read. Bạn nên tham khảo những nguồn như Charity Navigator và GuideStar để xác minh trạng thái và điểm xếp hạng của các tổ chức từ thiện. Tôi cũng tìm thấy một số cuộc thảo luận trực tuyến, kể cả trên các diễn đàn như Reddit, nơi người dùng chia sẻ trải nghiệm cá nhân về nhiều chương trình xoá mù chữ nhỏ hơn ở địa phương.
Hãy phân tích vấn đề này. Nhân viên hỗ trợ đã giải quyết được vấn đề của chúng tôi chưa?
❌ Không. Nó đã sao chép hoàn hảo trải nghiệm của con người mà chúng ta mô tả trong Mô-đun 1. Công cụ này đã tự động hoá thành công quy trình "tìm kiếm thông tin trên Google" và trả lại vấn đề "phân tích quá mức" cho chúng ta.
Điều này cho thấy khoảng trống tin cậy đầu tiên: thiếu dữ liệu đáng tin cậy.
Trợ lý đang tìm kiếm trên web công khai, tức là:
- ✅ Tìm thấy kết quả nhanh chóng (cải thiện trải nghiệm người dùng)
- ❌ Kết hợp các tổ chức được đánh giá cao với nội dung thảo luận trên Reddit (nguồn không đáng tin cậy)
- ❌ Không thể phân biệt giữa tổ chức từ thiện đã được kiểm chứng và tổ chức lừa đảo tiềm ẩn (không có quy trình xác minh)
- ❌ Yêu cầu chúng tôi xác minh thông tin mà nó vừa cung cấp (chuyển gánh nặng lại cho chúng tôi)
Bài kiểm tra 2: Vấn đề về việc thực hiện
Bây giờ là bài kiểm tra thứ hai quan trọng. Tại lời nhắc [user]:, hãy thử hoàn tất quy trình quyên góp:
Okay, please donate $50 to Room to Read for me.
Trợ lý ảo sẽ phản hồi bằng lời xin lỗi, thừa nhận hạn chế của mình:
Tôi hiểu rằng bạn muốn quyên góp. Thật tuyệt vời! Tuy nhiên, tôi là một trợ lý nghiên cứu và không có khả năng xử lý giao dịch tài chính hoặc thanh toán. Để quyên góp, bạn cần truy cập trực tiếp vào trang web chính thức của Room to Read.
Đây là khoảnh khắc "À há!" thứ hai, cũng quan trọng không kém.
Không chỉ không thể tin tưởng tác nhân này trong việc tìm ra tổ chức từ thiện phù hợp, mà bạn cũng chưa thể tin tưởng tác nhân này trong việc thực hiện hành động quyên góp.
👉 Nhấn
Ctrl+C
để thoát khi hoàn tất kiểm thử.
Hình ảnh hoá hai khoảng trống
Kiến thức bạn vừa học được
Trong mô-đun này, bạn đã tạo và trang bị thành công cho tác nhân AI đầu tiên của mình. Khi làm như vậy, bạn đã khám phá ra hai thách thức cơ bản khi xây dựng một hệ thống đáng tin cậy.
Các khái niệm chính đã nắm vững
✅ Lớp Agent:
- Thành phần cơ bản của ADK
- Kết hợp khả năng suy luận của LLM (trí não) với các công cụ (bàn tay)
- Được định cấu hình bằng mô hình, hướng dẫn và công cụ
✅ Cấu trúc dựa trên thư mục:
- Mỗi tác nhân nằm trong một thư mục riêng
- ADK tìm
agent_folder/agent.py - Chạy cùng
adk run agent_folder
✅ Danh sách công cụ:
- Xác định các chức năng của trợ lý
- LLM quyết định thời điểm và cách sử dụng các công cụ
- Có thể chứa nhiều công cụ cho các hành động khác nhau
✅ Câu lệnh hướng dẫn:
- Hướng dẫn hành vi của tác nhân giống như nội dung mô tả công việc
- Chỉ định vai trò, điều kiện kích hoạt, hành động và định dạng đầu ra
- Rất quan trọng để sử dụng công cụ một cách đáng tin cậy
✅ Vấn đề về độ tin cậy:
- Khoảng trống trong việc khám phá: Nguồn chưa được kiểm chứng, chất lượng lẫn lộn
- Khoảng cách thực thi: Không có chức năng bảo mật, không có sự đồng ý, không có nhật ký kiểm tra
Tiếp theo là gì?
Trong mô-đun tiếp theo, chúng ta sẽ bắt đầu xây dựng giải pháp bằng cách triển khai cấu trúc dựa trên vai trò của AP2.
Hãy tạo tác nhân đầu tiên và xem cách phân tách vai trò hoạt động.
4. Xây dựng tác nhân mua sắm – Khám phá dựa trên vai trò

Nền tảng của niềm tin: Phân tách vai trò
Trong mô-đun cuối cùng, bạn đã nhận thấy rằng một tác nhân đơn giản, đa năng sẽ thất bại trên hai phương diện: không thể cung cấp thông tin đáng tin cậy và không thể thực hiện các giao dịch an toàn. Giờ đây, chúng ta sẽ bắt đầu giải quyết những vấn đề này bằng cách triển khai nguyên tắc đầu tiên trong Giao thức thanh toán của tác nhân: cấu trúc dựa trên vai trò.
Trước khi viết bất kỳ mã nào, hãy tìm hiểu lý do nguyên tắc này lại quan trọng.
Nguyên tắc AP2: Phân tách vai trò
Vấn đề với các tác nhân "Làm mọi việc"
Hãy tưởng tượng bạn thuê một người làm cố vấn tài chính, kế toán và nhà môi giới đầu tư. Thuận tiện? Có. Có an toàn không? Hoàn toàn không. Họ sẽ có:
- Mục tiêu đầu tư của bạn (vai trò cố vấn)
- Quyền truy cập vào tài khoản của bạn (vai trò kế toán)
- Quyền di chuyển tiền của bạn (vai trò người môi giới)
Nếu người này bị xâm nhập hoặc mắc lỗi, thì mọi thứ đều gặp rủi ro.
Giải pháp của AP2: Một nhân viên, một công việc
AP2 áp dụng nguyên tắc phân tách các mối lo ngại để tạo ranh giới tin cậy:
Lý do điều này quan trọng:
- ✅ Bán kính nổ hạn chế: Nếu Shopping Agent bị xâm nhập, kẻ tấn công sẽ không thể truy cập vào thông tin đăng nhập thanh toán
- ✅ Quyền riêng tư: Nhà cung cấp thông tin đăng nhập không bao giờ thấy cuộc trò chuyện mua sắm của bạn
- ✅ Tuân thủ: Dễ dàng đáp ứng các yêu cầu của PCI-DSS khi dữ liệu thanh toán được tách biệt
- ✅ Trách nhiệm giải trình: Trách nhiệm rõ ràng cho từng bước
Cách các trợ lý giao tiếp: Trạng thái dưới dạng sổ tay dùng chung
Vì các tác nhân không thể truy cập trực tiếp vào dữ liệu của nhau, nên chúng giao tiếp thông qua trạng thái dùng chung. Hãy coi đây là một bảng trắng mà tất cả nhân viên đều có thể viết và đọc:
# Shopping Agent writes:
state["intent_mandate"] = {
"natural_language_description": "Donate $50 to Room to Read",
"merchants": ["Room to Read"],
"intent_expiry": "2024-11-07T15:32:16Z",
"amount": 50.0
}
# Merchant Agent reads:
intent = state["intent_mandate"]
charity_name = intent["merchants"][0]
amount = intent["amount"]
# Creates CartMandate based on IntentMandate...
# Credentials Provider reads:
cart_mandate = state["cart_mandate"]
# Processes payment...
Đây là cách chúng tôi duy trì ranh giới tin cậy trong khi vẫn cho phép cộng tác.
Tác nhân đầu tiên của chúng tôi: Tác nhân mua sắm
Trách nhiệm của Trợ lý mua sắm rất đơn giản và tập trung:
- Sử dụng công cụ
find_charitiesđể truy vấn cơ sở dữ liệu đáng tin cậy của chúng tôi - Đưa ra các lựa chọn cho người dùng
- Sử dụng công cụ
save_user_choiceđể tạo một IntentMandate và lưu đối tượng này vào trạng thái - Chuyển cho nhân viên tiếp theo (Người bán)
Vậy là xong. Không xử lý thanh toán, không tạo giỏ hàng – chỉ khám phá và chuyển giao.
Hãy cùng nhau xây dựng từng bước.
Bước 1: Thêm Trình trợ giúp xác thực dữ liệu đầu vào
Khi xây dựng các công cụ sản xuất, việc xác thực dữ liệu đầu vào là rất quan trọng. Hãy tạo một hàm trợ giúp để xác thực dữ liệu từ thiện trước khi lưu vào trạng thái.
👉 Mở
charity_advisor/tools/charity_tools.py
Bạn sẽ thấy hàm find_charities (đã hoàn tất) ở trên cùng. Di chuyển xuống để tìm:
# MODULE_4_STEP_1_ADD_VALIDATION_HELPER
👉 Thay thế dòng đó bằng:
def _validate_charity_data(charity_name: str, charity_ein: str, amount: float) -> tuple[bool, str]:
"""
Validates charity selection data before saving to state.
This helper function performs basic validation to ensure data quality
before it gets passed to other agents in the pipeline.
Args:
charity_name: Name of the selected charity
charity_ein: Employer Identification Number (should be format: XX-XXXXXXX)
amount: Donation amount in USD
Returns:
(is_valid, error_message): Tuple where is_valid is True if all checks pass,
and error_message contains details if validation fails
"""
# Validate charity name
if not charity_name or not charity_name.strip():
return False, "Charity name cannot be empty"
# Validate EIN format (should be XX-XXXXXXX)
if not charity_ein or len(charity_ein) != 10 or charity_ein[2] != '-':
return False, f"Invalid EIN format: {charity_ein}. Expected format: XX-XXXXXXX"
# Validate amount
if amount <= 0:
return False, f"Donation amount must be positive, got: ${amount}"
if amount > 1_000_000:
return False, f"Donation amount exceeds maximum of $1,000,000: ${amount}"
# All checks passed
return True, ""
Bước 2: Thêm IntentMandate Creation Helper
Bây giờ, hãy tạo trình trợ giúp để tạo cấu trúc AP2 IntentMandate. Đây là một trong 3 thông tin xác thực có thể xác minh trong AP2.
👉 Trong cùng tệp đó, hãy tìm:
# MODULE_4_STEP_2_ADD_INTENTMANDATE_CREATION_HELPER
👉 Thay thế dòng đó bằng:
def _create_intent_mandate(charity_name: str, charity_ein: str, amount: float) -> dict:
"""
Creates an IntentMandate - AP2's verifiable credential for user intent.
This function uses the official Pydantic model from the `ap2` package
to create a validated IntentMandate object before converting it to a dictionary.
Args:
charity_name: Name of the selected charity
charity_ein: Employer Identification Number
amount: Donation amount in USD
Returns:
Dictionary containing the IntentMandate structure per AP2 specification
"""
from datetime import datetime, timedelta, timezone
from ap2.types.mandate import IntentMandate
# Set the expiry for the intent
expiry = datetime.now(timezone.utc) + timedelta(hours=1)
# Step 1: Instantiate the Pydantic model with official AP2 fields
intent_mandate_model = IntentMandate(
user_cart_confirmation_required=True,
natural_language_description=f"Donate ${amount:.2f} to {charity_name}",
merchants=[charity_name],
skus=None,
requires_refundability=False,
intent_expiry=expiry.isoformat()
)
# Step 2: Convert the validated model to a dictionary for state storage
intent_mandate_dict = intent_mandate_model.model_dump()
# Step 3: Add the codelab's custom fields to the dictionary
timestamp = datetime.now(timezone.utc)
intent_mandate_dict.update({
"timestamp": timestamp.isoformat(),
"intent_id": f"intent_{charity_ein.replace('-', '')}_{int(timestamp.timestamp())}",
"charity_ein": charity_ein,
"amount": amount,
"currency": "USD"
})
return intent_mandate_dict
Bước 3: Tạo Công cụ chuyển giao trạng thái bằng IntentMandate
Bây giờ, hãy tạo công cụ tạo IntentMandate và lưu công cụ đó vào trạng thái.
👉 Trong cùng một tệp, hãy di chuyển xuống phần
save_user_choice
Hàm . Tìm:
# MODULE_4_STEP_3_COMPLETE_SAVE_TOOL
👉 Thay thế dòng đó bằng:
# Validate inputs before creating IntentMandate
is_valid, error_message = _validate_charity_data(charity_name, charity_ein, amount)
if not is_valid:
logger.error(f"Validation failed: {error_message}")
return {"status": "error", "message": error_message}
# Create AP2 IntentMandate using our updated helper function
intent_mandate = _create_intent_mandate(charity_name, charity_ein, amount)
# Write the IntentMandate to shared state for the next agent
tool_context.state["intent_mandate"] = intent_mandate
logger.info(f"Successfully created IntentMandate and saved to state")
logger.info(f"Intent ID: {intent_mandate['intent_id']}")
logger.info(f"Intent expires: {intent_mandate['intent_expiry']}")
# Return success confirmation
return {
"status": "success",
"message": f"Created IntentMandate: ${amount:.2f} donation to {charity_name} (EIN: {charity_ein})",
"intent_id": intent_mandate["intent_id"],
"expiry": intent_mandate["intent_expiry"]
}
Bước 4: Thêm Trợ lý định dạng hiển thị
Trước khi tạo tác nhân, hãy thêm một trợ lý khác để định dạng dữ liệu từ thiện cho màn hình thân thiện với người dùng.
👉 Di chuyển để tìm:
# MODULE_4_STEP_4_ADD_FORMATTING_HELPER
👉 Thay thế dòng đó bằng:
def _format_charity_display(charity: dict) -> str:
"""
Formats a charity dictionary into a user-friendly display string.
This helper function demonstrates how to transform structured data
into readable text for the user.
Args:
charity: Dictionary containing charity data (name, ein, mission, rating, efficiency)
Returns:
Formatted string suitable for display to the user
"""
name = charity.get('name', 'Unknown')
ein = charity.get('ein', 'N/A')
mission = charity.get('mission', 'No mission statement available')
rating = charity.get('rating', 0.0)
efficiency = charity.get('efficiency', 0.0)
# Format efficiency as percentage
efficiency_pct = int(efficiency * 100)
# Build formatted string
display = f"""
**{name}** (EIN: {ein})
⭐ Rating: {rating}/5.0
💰 Efficiency: {efficiency_pct}% of funds go to programs
📋 Mission: {mission}
""".strip()
return display
Bước 5: Tạo tác nhân mua sắm – Nhập các thành phần
Giờ đây, khi các công cụ của chúng ta đã hoàn thiện và mạnh mẽ, hãy tạo tác nhân sẽ sử dụng các công cụ đó.
👉 Mở
charity_advisor/shopping_agent/agent.py
Bạn sẽ thấy một mẫu có các bình luận giữ chỗ. Hãy cùng nhau xây dựng từng bước.
👉 Tìm:
# MODULE_4_STEP_5_IMPORT_COMPONENTS
👉 Thay thế dòng đó bằng:
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from charity_advisor.tools.charity_tools import find_charities, save_user_choice
Bước 6: Viết Chỉ dẫn cho nhân viên hỗ trợ
Chỉ dẫn là nơi chúng ta xác định nội dung mô tả công việc và quy trình làm việc của trợ lý. Điều này rất quan trọng – một chỉ dẫn được viết kém sẽ dẫn đến hành vi không đáng tin cậy.
👉 Tìm:
# MODULE_4_STEP_6_WRITE_INSTRUCTION
instruction="""""",
👉 Thay thế hai dòng đó bằng:
instruction="""You are a research specialist helping users find verified charities.
Your workflow:
1. When the user describes what cause they want to support (e.g., "education", "health", "environment"),
use the find_charities tool to search our vetted database.
2. Present the results clearly. The tool returns formatted charity information that you should
show to the user.
3. When the user selects a charity and specifies an amount, use the save_user_choice tool
to create an IntentMandate and record their decision. You MUST call save_user_choice with:
- charity_name: The exact name of the chosen charity
- charity_ein: The EIN of the chosen charity
- amount: The donation amount in dollars (as a number, not a string)
4. After successfully saving, inform the user:
- That you've created an IntentMandate (mention the intent ID if provided)
- When the intent expires
- That you're passing their request to the secure payment processor
IMPORTANT BOUNDARIES:
- Your ONLY job is discovery and creating the IntentMandate
- You do NOT process payments
- You do NOT see the user's payment methods
- You do NOT create cart offers (that's the Merchant Agent's job)
- After calling save_user_choice, your work is done
WHAT IS AN INTENTMANDATE:
An IntentMandate is a structured record of what the user wants to do. It includes:
- Natural language description ("Donate $50 to Room to Read")
- Which merchants can fulfill it
- When the intent expires
- Whether user confirmation is required
This is the first of three verifiable credentials in our secure payment system.
If the user asks you to do anything related to payment processing, politely explain that
you don't have that capability and that their request will be handled by the appropriate
specialist agent.""",
Bước 7: Thêm các công cụ vào Agent
Bây giờ, hãy cấp cho tác nhân quyền truy cập vào cả hai công cụ này.
👉 Tìm:
# MODULE_4_STEP_7_ADD_TOOLS
👉 Thay thế hai dòng đó bằng:
tools=[
FunctionTool(func=find_charities),
FunctionTool(func=save_user_choice)
]
Bước 8: Xác minh nhân viên hỗ trợ hoàn chỉnh
Hãy kiểm tra để đảm bảo mọi thứ đều được kết nối đúng cách.
👉 Thông tin đầy đủ của bạn
charity_advisor/shopping_agent/agent.py
hiện sẽ có dạng như sau:
"""
Shopping Agent - Finds charities from a trusted database and saves the user's choice.
This agent acts as our specialized "Research Analyst."
"""
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from charity_advisor.tools.charity_tools import find_charities, save_user_choice
shopping_agent = Agent(
name="ShoppingAgent",
model="gemini-2.5-pro",
description="Finds and recommends vetted charities from a trusted database, then creates an IntentMandate capturing the user's donation intent.",
instruction="""You are a research specialist helping users find verified charities.
Your workflow:
1. When the user describes what cause they want to support (e.g., "education", "health", "environment"),
use the find_charities tool to search our vetted database.
2. Present the results clearly. The tool returns formatted charity information that you should
show to the user.
3. When the user selects a charity and specifies an amount, use the save_user_choice tool
to create an IntentMandate and record their decision. You MUST call save_user_choice with:
- charity_name: The exact name of the chosen charity
- charity_ein: The EIN of the chosen charity
- amount: The donation amount in dollars (as a number, not a string)
4. After successfully saving, inform the user:
- That you've created an IntentMandate (mention the intent ID if provided)
- When the intent expires
- That you're passing their request to the secure payment processor
IMPORTANT BOUNDARIES:
- Your ONLY job is discovery and creating the IntentMandate
- You do NOT process payments
- You do NOT see the user's payment methods
- You do NOT create cart offers (that's the Merchant Agent's job)
- After calling save_user_choice, your work is done
WHAT IS AN INTENTMANDATE:
An IntentMandate is a structured record of what the user wants to do. It includes:
- Natural language description ("Donate $50 to Room to Read")
- Which merchants can fulfill it
- When the intent expires
- Whether user confirmation is required
This is the first of three verifiable credentials in our secure payment system.
If the user asks you to do anything related to payment processing, politely explain that
you don't have that capability and that their request will be handled by the appropriate
specialist agent.""",
tools=[
FunctionTool(func=find_charities),
FunctionTool(func=save_user_choice)
]
)
✅ Tuyệt vời! Bạn đã tạo một tác nhân tuân thủ AP2 có chất lượng sản xuất với:
- Xác thực dữ liệu đầu vào
- Tạo IntentMandate đúng cách bằng các mô hình AP2 Pydantic
- Đầu ra được định dạng
- Xác định rõ ràng ranh giới vai trò
- Hướng dẫn chi tiết
- Xử lý lỗi
Bước 9: Kiểm thử Trợ lý mua sắm
Hãy xác minh rằng tác nhân của chúng ta hoạt động chính xác, tạo IntentMandates phù hợp và tuân thủ các ranh giới của tác nhân.
👉 Trong thiết bị đầu cuối Cloud Shell, hãy chạy:
adk run charity_advisor/shopping_agent
Lời nhắc [user]: sẽ xuất hiện.
Thử nghiệm 1: Khám phá bằng Cơ sở dữ liệu đáng tin cậy
👉 Loại:
I want to donate to an education charity. What are my options?
Sau một lát, trợ lý sẽ phản hồi. Nhờ _format_charity_display trợ lý của chúng tôi, kết quả được định dạng đẹp mắt:
Tôi tìm thấy 3 tổ chức từ thiện giáo dục đã được xác minh trong cơ sở dữ liệu của chúng tôi:
Room to Read (Mã số nhận dạng doanh nghiệp: 77-0479905)
⭐ Mức độ hiệu quả: 4,9/5,0
💰 Hiệu quả: 88% quỹ được dùng cho các chương trình
📋 Sứ mệnh: Thay đổi cuộc sống của hàng triệu trẻ em ở các cộng đồng có thu nhập thấp bằng cách tập trung vào khả năng đọc viết và bình đẳng giới trong giáo dục.
Teach For America (Mã số nhận dạng doanh nghiệp: 13-3541913)
⭐ Điểm đánh giá: 4,7/5,0
💰 Hiệu quả: 81% quỹ được dùng cho các chương trình
📋 Sứ mệnh: Mở rộng cơ hội học tập cho trẻ em gặp khó khăn.
Tech Education Alliance (Mã số nhận dạng doanh nghiệp: 45-2345678)
⭐ Mức độ hiệu quả: 4,8/5,0
💰 Hiệu quả: 92% quỹ được dùng cho các chương trình
📋 Sứ mệnh: Mang giáo dục khoa học máy tính đến các trường học chưa được hỗ trợ.
Bạn muốn ủng hộ tổ chức từ thiện nào và muốn quyên góp bao nhiêu?
Hãy so sánh điều này với tác nhân đơn giản trong Mô-đun 3, tác nhân này cung cấp cho bạn kết quả chưa được kiểm chứng trên Google. Đây là điểm khác biệt giữa quy trình khám phá không đáng tin cậy và quy trình khám phá đáng tin cậy.
Thử nghiệm 2: Ghi lại lựa chọn của người dùng và tạo IntentMandate
👉 Loại:
I'll donate $50 to Room to Read.
Bạn sẽ thấy tác nhân gọi công cụ save_user_choice bằng các tham số chính xác. Nhờ tính năng tạo IntentMandate bằng các mô hình AP2, bạn sẽ thấy câu trả lời có cấu trúc hơn:
Tuyệt lắm! Tôi đã tạo một IntentMandate cho khoản quyên góp của bạn:
Thông tin chi tiết về ý định:
- Mã nhận dạng ý định: intent_774795905_1730927536
- Số tiền: 50 USD cho Room to Read (Mã số nhận dạng người sử dụng lao động: 77-0479905)
- Hết hạn: 2024-11-07T15:32:16Z (sau 1 giờ nữa)
IntentMandate này ghi lại ý định quyên góp của bạn và bao gồm các ràng buộc để đảm bảo giao dịch được xử lý một cách an toàn. Tôi sẽ chuyển yêu cầu này đến bộ xử lý thanh toán an toàn của chúng tôi để tạo một đề nghị chính thức và hoàn tất khoản quyên góp của bạn.
Ở chế độ nền, một số việc vừa xảy ra:
_validate_charity_data()đã xác minh thông tin đầu vào_create_intent_mandate()đã sử dụng mô hình AP2 Pydantic để tạo cấu trúc:
# Created and validated via Pydantic
intent_mandate_model = IntentMandate(
user_cart_confirmation_required=True,
natural_language_description="Donate $50.00 to Room to Read",
merchants=["Room to Read"],
skus=None,
requires_refundability=False,
intent_expiry="2024-11-07T15:32:16Z"
)
# Converted to dict and extended with custom fields
intent_mandate_dict = intent_mandate_model.model_dump()
intent_mandate_dict.update({
"charity_ein": "77-0479905",
"amount": 50.0,
"currency": "USD"
})
- Công cụ này CHỈ ghi IntentMandate vào trạng thái dùng chung:
state["intent_mandate"] = intent_mandate_dict
- Một thông báo thành công kèm theo thông tin chi tiết về ý định đã được trả về cho LLM
- LLM đã soạn thông báo cuối cùng cho người dùng
IntentMandate này hiện đã sẵn sàng để Merchant Agent (Mô-đun 5) nhận. Người bán sẽ trích xuất tên và số tiền của tổ chức từ thiện từ IntentMandate và xác thực rằng tổ chức đó chưa hết hạn.
Thử nghiệm 3: Xác thực trong thực tế
Hãy xác minh rằng trình trợ giúp xác thực của chúng ta phát hiện được dữ liệu đầu vào không hợp lệ.
👉 Loại:
I'll donate -$25 to Room to Read.
Trợ lý ảo phải nắm bắt được số tiền không hợp lệ:
Tôi gặp phải vấn đề: Số tiền quyên góp phải là số dương, nhưng lại nhận được: $-25.0
Vui lòng chỉ định một số tiền quyên góp dương và tôi sẽ tạo IntentMandate cho bạn.
Đây là hoạt động lập trình phòng thủ. Trình trợ giúp _validate_charity_data của chúng tôi đã ngăn dữ liệu không hợp lệ xâm nhập vào hệ thống và tạo ra một IntentMandate không hợp lệ.
Thử nghiệm 4: Xác minh ranh giới tin cậy
👉 Thử yêu cầu trợ lý xử lý thanh toán:
Now process my credit card payment.
Nhân viên hỗ trợ nên từ chối, tôn trọng ranh giới vai trò của mình:
Tôi không có khả năng xử lý các khoản thanh toán. Đó không phải là việc của tôi. Công việc của tôi là giúp bạn tìm thấy các tổ chức từ thiện đã được xác minh và tạo IntentMandate để ghi lại ý định quyên góp của bạn.
IntentMandate của bạn đã được tạo và chuyển đến bộ xử lý thanh toán an toàn của chúng tôi. Merchant Agent sẽ tạo một đề nghị chính thức (CartMandate), sau đó Credentials Provider sẽ xử lý khoản thanh toán thực tế khi bạn đồng ý một cách rõ ràng.
Đây là ranh giới tin cậy đang hoạt động. Trợ lý ảo biết rằng mình không được phép xử lý dữ liệu thanh toán và hướng dẫn của bạn sẽ hướng dẫn trợ lý ảo giải thích điều này cho người dùng, đồng thời dạy họ về khái niệm IntentMandate.
👉 Nhấn
Ctrl+C
để thoát khi hoàn tất kiểm thử.
Sản phẩm bạn vừa tạo
Bạn đã triển khai thành công phần đầu tiên của cấu trúc AP2 bằng cách tạo IntentMandate thích hợp bằng các mô hình AP2 Pydantic.
Các khái niệm chính đã nắm vững
✅ Cấu trúc dựa trên vai trò:
- Mỗi tác nhân có một công việc được xác định rõ ràng
- Các tác nhân giao tiếp thông qua trạng thái được chia sẻ, chứ không phải quyền truy cập trực tiếp
- Ranh giới tin cậy hạn chế tác động của việc xâm nhập
✅ IntentMandate (AP2 Credential #1):
- Được tạo bằng các mô hình Pydantic AP2 chính thức để xác thực
- Ghi lại ý định của người dùng theo cấu trúc
- Bao gồm thời gian hết hạn để đảm bảo an toàn (ngăn chặn các cuộc tấn công phát lại)
- Chỉ định các ràng buộc (người bán, khả năng hoàn tiền, xác nhận)
- Nội dung mô tả bằng ngôn ngữ tự nhiên cho người dùng
- Dữ liệu mà nhân viên hỗ trợ có thể đọc được
- Mô hình được xác thực trước khi chuyển đổi sang từ điển
✅ Trạng thái dưới dạng bộ nhớ dùng chung:
tool_context.statelà "sổ tay" mà tất cả nhân viên hỗ trợ đều có thể truy cập- Ghi vào trạng thái = cung cấp thông tin xác thực có thể xác minh
- Đọc từ trạng thái = sử dụng và xác thực thông tin xác thực
- Các tác nhân hạ nguồn trích xuất những gì họ cần từ thông tin đăng nhập
✅ FunctionTool:
- Chuyển đổi các hàm Python thành các công cụ có thể gọi LLM
- Dựa vào chuỗi tài liệu và gợi ý về kiểu để LLM hiểu
- Tự động xử lý lệnh gọi
- Khả năng kết hợp công cụ: các công cụ nhỏ, tập trung > các công cụ nguyên khối
✅ Hướng dẫn dành cho nhân viên hỗ trợ:
- Hướng dẫn từng bước về quy trình công việc
- Ranh giới rõ ràng ("KHÔNG được...")
- Quy cách về tham số để tránh lỗi
- Định nghĩa về kỹ thuật (IntentMandate là gì)
- Xử lý trường hợp đặc biệt (những điều cần nói khi...)
Tiếp theo là gì?
Trong mô-đun tiếp theo, chúng ta sẽ tạo Merchant Agent để nhận IntentMandate và tạo thông tin xác thực có thể xác minh thứ hai: CartMandate.
Trợ lý mua sắm đã tạo một IntentMandate ghi lại ý định của người dùng kèm theo thời gian hết hạn. Giờ đây, chúng ta cần một tác nhân đọc thông tin đăng nhập đó, xác thực rằng thông tin đăng nhập đó chưa hết hạn và tạo một đề nghị chính thức, có chữ ký với nội dung: "Tôi, người bán, sẽ tôn trọng mức giá này và giao những hàng hoá này."
Hãy tạo Merchant Agent và xem thông tin đăng nhập AP2 thứ hai hoạt động.
5. Xây dựng Merchant Agent – Ưu đãi ràng buộc và CartMandate

Từ khám phá đến cam kết
Trong mô-đun trước, bạn đã tạo Shopping Agent (Trợ lý mua sắm) – một chuyên gia tìm kiếm các tổ chức từ thiện đã được xác minh và tạo IntentMandate để nắm bắt ý định của người dùng. Giờ đây, chúng ta cần một tác nhân để nhận IntentMandate đó và tạo một đề nghị chính thức, ràng buộc.
Đây là lúc nguyên tắc chính thứ hai của AP2 phát huy tác dụng: chứng chỉ có thể xác minh thông qua CartMandate.
Nguyên tắc AP2: CartMandate và ưu đãi ràng buộc
Lý do cần có vai trò người bán
Trong Mô-đun 4, Shopping Agent đã tạo một IntentMandate và lưu IntentMandate đó vào trạng thái:
state["intent_mandate"] = {
"natural_language_description": "Donate $50 to Room to Read",
"merchants": ["Room to Read"],
"amount": 50.0,
"intent_expiry": "2024-11-07T15:32:16Z"
}
Nhưng đây chỉ là ý định của người dùng. Trước khi có thể xử lý bất kỳ khoản thanh toán nào, chúng tôi cần:
- Một cấu trúc ưu đãi chính thức mà các hệ thống thanh toán hiểu được
- Bằng chứng cho thấy người bán sẽ áp dụng mức giá này
- Một cam kết ràng buộc không thể thay đổi trong quá trình giao dịch
- Xác thực rằng ý định chưa hết hạn
Đây là nhiệm vụ của Nhân viên bán hàng.
CartMandate là gì?
CartMandate là thuật ngữ của AP2 cho "giỏ hàng kỹ thuật số" đóng vai trò là một đề nghị ràng buộc. Yêu cầu này được cấu trúc theo tiêu chuẩn PaymentRequest của W3C, tức là:
- Các công ty xử lý thanh toán trên toàn thế giới đều nhận ra định dạng này
- Báo cáo này chứa tất cả thông tin giao dịch theo cách tiêu chuẩn
- Bạn có thể ký mã này bằng mật mã để chứng minh tính xác thực
Hãy coi đó như một báo giá bằng văn bản của nhà thầu:
- ❌ Lời nói: "Ừ, tôi có thể làm việc đó với giá khoảng 50 đô la"
- ✅ Báo giá bằng văn bản: Chi phí theo từng mục, tổng chi phí, chữ ký, ngày
Báo giá bằng văn bản là thông tin ràng buộc. CartMandate là phiên bản kỹ thuật số của CartMandate.
Cấu trúc của CartMandate
CartMandate trong AP2 có một cấu trúc lồng ghép cụ thể:
cart_mandate = {
"contents": { # ← AP2 wrapper
"id": "cart_xyz123",
"cart_expiry": "2024-11-07T15:47:16Z",
"merchant_name": "Room to Read",
"user_cart_confirmation_required": False,
"payment_request": { # ← W3C PaymentRequest nested inside
"method_data": [...],
"details": {...},
"options": {...}
}
},
"merchant_authorization": "SIG_a3f7b2c8" # ← Merchant signature
}
Ba thành phần chính:
1. contents – Trình bao bọc giỏ hàng chứa:
- Mã giỏ hàng và thời gian hết hạn
- Tên người bán
- PaymentRequest của W3C
2. payment_request (bên trong nội dung) – Sản phẩm đang được mua:
- method_data: Các loại thanh toán được chấp nhận
- chi tiết: Mặt hàng và tổng số tiền
- options: Shipping, payer info requirements
3. merchant_authorization – Chữ ký mật mã
Chữ ký của người bán: Bằng chứng cam kết
Chữ ký của người bán là rất quan trọng. Điều này chứng minh rằng:
- Ưu đãi này đến từ một người bán được uỷ quyền
- Người bán cam kết áp dụng đúng mức giá này
- Ưu đãi không bị giả mạo kể từ khi tạo
Trong quá trình sản xuất, đây sẽ là chữ ký mã hoá bằng PKI (Cơ sở hạ tầng khoá công khai) hoặc JWT (Mã thông báo web JSON). Trong hội thảo giáo dục của chúng tôi, chúng tôi sẽ mô phỏng điều này bằng hàm băm SHA-256.
# Production (real signature):
signature = sign_with_private_key(cart_data, merchant_private_key)
# Workshop (simulated signature):
cart_hash = hashlib.sha256(cart_json.encode()).hexdigest()
signature = f"SIG_{cart_hash[:16]}"
Sứ mệnh của chúng tôi: Xây dựng Merchant Agent
Merchant Agent sẽ:
- Đọc IntentMandate từ trạng thái (nội dung mà Trợ lý mua sắm đã viết)
- Xác thực rằng ý định chưa hết hạn
- Trích xuất tên tổ chức từ thiện, số tiền và các thông tin khác
- Tạo cấu trúc PaymentRequest tuân thủ W3C bằng các mô hình AP2 Pydantic
- Bọc nó trong CartMandate của AP2 có ngày hết hạn
- Thêm chữ ký người bán mô phỏng
- Viết CartMandate để chuyển trạng thái cho Trình cung cấp thông tin đăng nhập (mô-đun tiếp theo)
Hãy cùng nhau xây dựng từng bước.
Bước 1: Thêm Trợ lý xác thực ngày hết hạn
Trước tiên, hãy thiết lập tệp công cụ liên quan đến người bán và thêm một trình trợ giúp để xác thực thời gian hết hạn của IntentMandate.
👉 Mở
charity_advisor/tools/merchant_tools.py
Hãy thêm quy trình xác thực ngày hết hạn:
👉 Tìm:
# MODULE_5_STEP_1_ADD_EXPIRY_VALIDATION_HELPER
👉 Thay thế dòng đó bằng:
def _validate_intent_expiry(intent_expiry_str: str) -> tuple[bool, str]:
"""
Validates that the IntentMandate hasn't expired.
This is a critical security check - expired intents should not be processed.
Args:
intent_expiry_str: The ISO 8601 timestamp string from the IntentMandate.
Returns:
(is_valid, error_message): Tuple indicating if intent is still valid.
"""
try:
# The .replace('Z', '+00:00') is for compatibility with older Python versions
expiry_time = datetime.fromisoformat(intent_expiry_str.replace('Z', '+00:00'))
now = datetime.now(timezone.utc)
if expiry_time < now:
return False, f"IntentMandate expired at {intent_expiry_str}"
time_remaining = expiry_time - now
logger.info(f"IntentMandate valid. Expires in {time_remaining.total_seconds():.0f} seconds")
return True, ""
except (ValueError, TypeError) as e:
return False, f"Invalid intent_expiry format: {e}"
Bước 2: Thêm Trợ lý tạo chữ ký
Bây giờ, hãy tạo một hàm trợ giúp để tạo chữ ký người bán mô phỏng.
👉 Tìm:
# MODULE_5_STEP_2_ADD_SIGNATURE_HELPER
👉 Thay thế dòng đó bằng:
def _generate_merchant_signature(cart_contents: CartContents) -> str:
"""
Generates a simulated merchant signature for the CartMandate contents.
In production, this would use PKI or JWT with the merchant's private key.
For this codelab, we use a SHA-256 hash of the sorted JSON representation.
Args:
cart_contents: The Pydantic model of the cart contents to sign.
Returns:
Simulated signature string (format: "SIG_" + first 16 chars of hash).
"""
# Step 1: Dump the Pydantic model to a dictionary. The `mode='json'` argument
# ensures that complex types like datetimes are serialized correctly.
cart_contents_dict = cart_contents.model_dump(mode='json')
# Step 2: Use the standard json library to create a stable, sorted JSON string.
# separators=(',', ':') removes whitespace for a compact and canonical representation.
cart_json = json.dumps(cart_contents_dict, sort_keys=True, separators=(',', ':'))
# Step 3: Generate SHA-256 hash.
cart_hash = hashlib.sha256(cart_json.encode('utf-8')).hexdigest()
# Step 4: Create signature in a recognizable format.
signature = f"SIG_{cart_hash[:16]}"
logger.info(f"Generated merchant signature: {signature}")
return signature
Bước 3A: Tạo Chữ ký công cụ và Thiết lập
Bây giờ, hãy bắt đầu xây dựng công cụ chính. Chúng ta sẽ tạo nó theo từng bước trong 4 bước phụ. Trước tiên, chữ ký hàm và chế độ thiết lập ban đầu.
👉 Tìm:
# MODULE_5_STEP_3A_CREATE_TOOL_SIGNATURE
👉 Thay thế dòng đó bằng:
async def create_cart_mandate(tool_context: Any) -> Dict[str, Any]:
"""
Creates a W3C PaymentRequest-compliant CartMandate from the IntentMandate.
This tool reads the IntentMandate from shared state, validates it, and
creates a formal, signed offer using the official AP2 Pydantic models.
Returns:
Dictionary containing status and the created CartMandate.
"""
logger.info("Tool called: Creating CartMandate from IntentMandate")
# MODULE_5_STEP_3B_ADD_VALIDATION_LOGIC
Bước 3B: Thêm logic xác thực
Bây giờ, hãy thêm logic để đọc và xác thực IntentMandate bằng các mô hình AP2 Pydantic, đồng thời trích xuất dữ liệu mà chúng ta cần.
👉 Tìm:
# MODULE_5_STEP_3B_ADD_VALIDATION_LOGIC
👉 Thay thế dòng đó bằng:
# 1. Read IntentMandate dictionary from state
intent_mandate_dict = tool_context.state.get("intent_mandate")
if not intent_mandate_dict:
logger.error("No IntentMandate found in state")
return {
"status": "error",
"message": "No IntentMandate found. Shopping Agent must create intent first."
}
# 2. Parse dictionary into a validated Pydantic model
try:
intent_mandate_model = IntentMandate.model_validate(intent_mandate_dict)
except Exception as e:
logger.error(f"Could not validate IntentMandate structure: {e}")
return {"status": "error", "message": f"Invalid IntentMandate structure: {e}"}
# 3. Validate that the intent hasn't expired (CRITICAL security check)
is_valid, error_message = _validate_intent_expiry(intent_mandate_model.intent_expiry)
if not is_valid:
logger.error(f"IntentMandate validation failed: {error_message}")
return {"status": "error", "message": error_message}
# 4. Extract data. Safely access standard fields from the model, and
# custom fields (like 'amount') from the original dictionary.
charity_name = intent_mandate_model.merchants[0] if intent_mandate_model.merchants else "Unknown Charity"
amount = intent_mandate_dict.get("amount", 0.0)
# MODULE_5_STEP_3C_CREATE_CARTMANDATE_STRUCTURE
Bước 3C: Tạo cấu trúc CartMandate
Bây giờ, hãy tạo cấu trúc PaymentRequest tuân thủ W3C và gói cấu trúc này trong AP2 CartMandate bằng cách sử dụng các mô hình Pydantic.
👉 Tìm:
# MODULE_5_STEP_3C_CREATE_CARTMANDATE_STRUCTURE
👉 Thay thế dòng đó bằng:
# 5. Build the nested Pydantic models for the CartMandate
timestamp = datetime.now(timezone.utc)
cart_id = f"cart_{hashlib.sha256(f'{charity_name}{timestamp.isoformat()}'.encode()).hexdigest()[:12]}"
cart_expiry = timestamp + timedelta(minutes=15)
payment_request_model = PaymentRequest(
method_data=[PaymentMethodData(
supported_methods="CARD",
data={"supported_networks": ["visa", "mastercard", "amex"], "supported_types": ["debit", "credit"]}
)],
details=PaymentDetailsInit(
id=f"order_{cart_id}",
display_items=[PaymentItem(
label=f"Donation to {charity_name}",
amount=PaymentCurrencyAmount(currency="USD", value=amount) # Pydantic v2 handles float -> str conversion
)],
total=PaymentItem(
label="Total Donation",
amount=PaymentCurrencyAmount(currency="USD", value=amount)
)
),
options=PaymentOptions(request_shipping=False)
)
cart_contents_model = CartContents(
id=cart_id,
cart_expiry=cart_expiry.isoformat(),
merchant_name=charity_name,
user_cart_confirmation_required=False,
payment_request=payment_request_model
)
# MODULE_5_STEP_3D_ADD_SIGNATURE_AND_SAVE
Bước 3D: Thêm chữ ký và lưu vào trạng thái
Cuối cùng, hãy ký CartMandate bằng mô hình Pydantic và lưu vào trạng thái cho tác nhân tiếp theo.
👉 Tìm:
# MODULE_5_STEP_3D_ADD_SIGNATURE_AND_SAVE
👉 Thay thế dòng đó bằng:
# 6. Generate signature from the validated Pydantic model
signature = _generate_merchant_signature(cart_contents_model)
# 7. Create the final CartMandate model, now including the signature
cart_mandate_model = CartMandate(
contents=cart_contents_model,
merchant_authorization=signature
)
# 8. Convert the final model to a dictionary for state storage and add the custom timestamp
cart_mandate_dict = cart_mandate_model.model_dump(mode='json')
cart_mandate_dict["timestamp"] = timestamp.isoformat()
# 9. Write the final dictionary to state
tool_context.state["cart_mandate"] = cart_mandate_dict
logger.info(f"CartMandate created successfully: {cart_id}")
return {
"status": "success",
"message": f"Created signed CartMandate {cart_id} for ${amount:.2f} donation to {charity_name}",
"cart_id": cart_id,
"cart_expiry": cart_expiry.isoformat(),
"signature": signature
}
Bước 4: Tạo Merchant Agent – Nhập các thành phần
Bây giờ, hãy tạo tác nhân sẽ sử dụng công cụ này.
👉 Mở
charity_advisor/merchant_agent/agent.py
Bạn sẽ thấy một mẫu có các điểm đánh dấu giữ chỗ. Hãy bắt đầu bằng cách nhập những gì chúng ta cần.
👉 Tìm:
# MODULE_5_STEP_4_IMPORT_COMPONENTS
👉 Thay thế dòng đó bằng:
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from charity_advisor.tools.merchant_tools import create_cart_mandate
Bước 5: Viết hướng dẫn cho Merchant Agent
Bây giờ, hãy viết chỉ dẫn cho tác nhân biết thời điểm và cách sử dụng công cụ của tác nhân.
👉 Tìm:
# MODULE_5_STEP_5_WRITE_INSTRUCTION
instruction="""""",
👉 Thay thế hai dòng đó bằng:
instruction="""You are a merchant specialist responsible for creating formal, signed offers (CartMandates).
Your workflow:
1. Read the IntentMandate from shared state.
The IntentMandate was created by the Shopping Agent and contains:
- merchants: List of merchant names
- amount: Donation amount
- charity_ein: Tax ID
- intent_expiry: When the intent expires
2. Use the create_cart_mandate tool to create a W3C PaymentRequest-compliant CartMandate.
This tool will:
- Validate the IntentMandate hasn't expired (CRITICAL security check)
- Extract the charity name and amount from the IntentMandate
- Create a structured offer with payment methods, transaction details, and merchant info
- Generate a merchant signature to prove authenticity
- Save the CartMandate to state for the payment processor
3. After creating the CartMandate, inform the user:
- That you've created a formal, signed offer
- The cart ID
- When the cart expires (15 minutes)
- That you're passing it to the secure payment processor
IMPORTANT BOUNDARIES:
- Your ONLY job is creating signed CartMandates from valid IntentMandates
- You do NOT process payments
- You do NOT see the user's payment methods or credentials
- You do NOT interact with payment networks
- You MUST validate that the IntentMandate hasn't expired before creating a cart
- After calling create_cart_mandate, your work is done
WHAT IS A CARTMANDATE:
A CartMandate is a binding commitment that says:
"I, the merchant, commit to accepting $X for this charity donation, and I prove it with my signature."
This commitment is structured using the W3C PaymentRequest standard and includes:
- Payment methods accepted (card, bank transfer)
- Transaction details (amount, charity name)
- Cart expiry (15 minutes from creation)
- Merchant signature (proof of commitment)
This is the second of three verifiable credentials in our secure payment system.""",
Bước 6: Thêm các công cụ vào Merchant Agent
👉 Tìm:
# MODULE_5_STEP_6_ADD_TOOLS
tools=[],
👉 Thay thế hai dòng đó bằng:
tools=[
FunctionTool(func=create_cart_mandate)
],
Bước 7: Xác minh Complete Merchant Agent
Hãy xác nhận rằng mọi thứ đã được kết nối đúng cách.
👉 Thông tin đầy đủ của bạn
charity_advisor/merchant_agent/agent.py
hiện sẽ có dạng như sau:
"""
Merchant Agent - Creates W3C-compliant CartMandates with merchant signatures.
This agent acts as our "Contract Creator."
"""
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from charity_advisor.tools.merchant_tools import create_cart_mandate
merchant_agent = Agent(
name="MerchantAgent",
model="gemini-2.5-flash",
description="Creates formal, signed CartMandates for charity donations following W3C PaymentRequest standards.",
tools=[
FunctionTool(func=create_cart_mandate)
],
instruction="""You are a merchant specialist responsible for creating formal, signed offers (CartMandates).
Your workflow:
1. Read the IntentMandate from shared state.
The IntentMandate was created by the Shopping Agent and contains:
- merchants: List of merchant names
- amount: Donation amount
- charity_ein: Tax ID
- intent_expiry: When the intent expires
2. Use the create_cart_mandate tool to create a W3C PaymentRequest-compliant CartMandate.
This tool will:
- Validate the IntentMandate hasn't expired (CRITICAL security check)
- Extract the charity name and amount from the IntentMandate
- Create a structured offer with payment methods, transaction details, and merchant info
- Generate a merchant signature to prove authenticity
- Save the CartMandate to state for the payment processor
3. After creating the CartMandate, inform the user:
- That you've created a formal, signed offer
- The cart ID
- When the cart expires (15 minutes)
- That you're passing it to the secure payment processor
IMPORTANT BOUNDARIES:
- Your ONLY job is creating signed CartMandates from valid IntentMandates
- You do NOT process payments
- You do NOT see the user's payment methods or credentials
- You do NOT interact with payment networks
- You MUST validate that the IntentMandate hasn't expired before creating a cart
- After calling create_cart_mandate, your work is done
WHAT IS A CARTMANDATE:
A CartMandate is a binding commitment that says:
"I, the merchant, commit to accepting $X for this charity donation, and I prove it with my signature."
This commitment is structured using the W3C PaymentRequest standard and includes:
- Payment methods accepted (card, bank transfer)
- Transaction details (amount, charity name)
- Cart expiry (15 minutes from creation)
- Merchant signature (proof of commitment)
This is the second of three verifiable credentials in our secure payment system."""
)
✅ Chốt kiểm tra: Giờ đây, bạn đã có một Merchant Agent hoàn chỉnh với việc tạo CartMandate AP2 thích hợp bằng cách sử dụng các mô hình Pydantic.
Bước 8: Kiểm thử Merchant Agent
Bây giờ, hãy xác minh rằng tác nhân của chúng ta tạo CartMandates một cách chính xác bằng chữ ký và xác thực ngày hết hạn.
Thiết lập kiểm thử: Chạy tập lệnh kiểm thử
👉 Trong thiết bị đầu cuối Cloud Shell, hãy chạy:
python scripts/test_merchant.py
Kết quả đầu ra dự kiến:
======================================================================
MERCHANT AGENT TEST
======================================================================
Simulated IntentMandate from Shopping Agent:
charity: Room to Read
amount: $50.00
expiry: 2024-11-07T16:32:16Z
----------------------------------------------------------------------
Merchant Agent Response:
----------------------------------------------------------------------
Perfect! I've received your IntentMandate and created a formal, signed offer (CartMandate) for your donation.
**CartMandate Details:**
- **Cart ID**: cart_3b4c5d6e7f8a
- **Donation Amount**: $50.00 to Room to Read
- **Payment Methods Accepted**: Credit/debit cards (Visa, Mastercard, Amex) or bank transfer
- **Cart Expires**: 2024-11-07T15:47:16Z (in 15 minutes)
- **Merchant Signature**: SIG_a3f7b2c8d9e1f4a2
This signed CartMandate proves my commitment to accept this donation amount. I'm now passing this to the secure payment processor to complete your transaction.
======================================================================
CARTMANDATE CREATED:
======================================================================
ID: cart_3b4c5d6e7f8a
Amount: 50.00
Merchant: Room to Read
Expires: 2024-11-07T15:47:16Z
Signature: SIG_a3f7b2c8d9e1f4a2
======================================================================
Bài kiểm tra 2: Xác minh tính tuân thủ W3C
Hãy xác thực để đảm bảo cấu trúc CartMandate của chúng ta hoàn toàn tuân thủ cả tiêu chuẩn AP2 và W3C PaymentRequest.
👉 Chạy tập lệnh xác thực:
python scripts/validate_cartmandate.py
Kết quả đầu ra dự kiến:
======================================================================
AP2 & W3C PAYMENTREQUEST VALIDATION
======================================================================
✅ CartMandate is AP2 and W3C PaymentRequest compliant
Structure validation passed:
✓ AP2 'contents' wrapper present
✓ AP2 'merchant_authorization' signature present
✓ cart_expiry present
✓ payment_request nested inside contents
✓ method_data present and valid
✓ details.total.amount present with currency and value
✓ All required W3C PaymentRequest fields present
======================================================================
Sản phẩm bạn vừa tạo
Bạn đã triển khai thành công CartMandate của AP2 bằng cách sử dụng các mô hình Pydantic để có cấu trúc phù hợp, xác thực ngày hết hạn và chữ ký của người bán.
Các khái niệm chính đã nắm vững
✅ CartMandate (AP2 Credential #2):
- Được tạo bằng các mô hình Pydantic AP2 chính thức
- Cấu trúc AP2 có trình bao bọc nội dung
- W3C PaymentRequest được lồng bên trong
- Giỏ hàng hết hạn (ngắn hơn ý định)
- Chữ ký của người bán cho cam kết ràng buộc
- Việc xác thực mô hình đảm bảo tuân thủ quy cách
✅ Xác thực ngày hết hạn:
- Đọc IntentMandate từ trạng thái
- Đang xác thực cấu trúc bằng
IntentMandate.model_validate() - Phân tích cú pháp dấu thời gian ISO 8601
- So sánh với thời gian hiện tại
- Tính năng bảo mật ngăn chặn quá trình xử lý lỗi thời
✅ Chữ ký của người bán:
- Chứng minh tính chân thực và cam kết
- Được tạo từ mô hình Pydantic đã xác thực
- Sử dụng
model_dump(mode='json')để biểu thị chính tắc - Mô phỏng bằng SHA-256 cho giáo dục
- Sản xuất sử dụng PKI/JWT
- Ký nội dung mô hình, không phải từ điển
✅ W3C PaymentRequest:
- Được xây dựng bằng mô hình PaymentRequest Pydantic của AP2
- Tiêu chuẩn ngành về dữ liệu thanh toán
- Nằm trong cấu trúc AP2
- Chứa method_data, details, options
- Cho phép khả năng tương tác
✅ Chuỗi thông tin xác thực có mô hình:
- Mua sắm → IntentMandate (đã xác thực)
- Merchant đọc IntentMandate → CartMandate (cả hai mô hình đều được xác thực)
- Trình cung cấp thông tin đăng nhập sẽ đọc CartMandate → PaymentMandate
- Mỗi bước xác thực thông tin đăng nhập trước đó bằng Pydantic
✅ Phát triển dựa trên mô hình:
- Xác thực thông tin đầu vào qua
model_validate() - Cấu trúc an toàn về kiểu
- Tự động chuyển đổi tuần tự qua
model_dump() - Các mẫu sẵn sàng cho sản xuất
Tiếp theo là gì?
Trong mô-đun tiếp theo, chúng ta sẽ tạo Credentials Provider (Nhà cung cấp thông tin đăng nhập) để xử lý các khoản thanh toán một cách an toàn.
Merchant Agent đã tạo một đề nghị ràng buộc có thời hạn sử dụng các mô hình AP2. Giờ đây, chúng ta cần một tác nhân để đọc CartMandate đó, lấy sự đồng ý của người dùng và thực hiện thanh toán.
Hãy tạo Trình cung cấp thông tin đăng nhập và hoàn tất chuỗi thông tin đăng nhập AP2.
6. Tạo Trình cung cấp thông tin đăng nhập – Thực hiện thanh toán an toàn

Từ Ưu đãi ràng buộc đến việc thực hiện thanh toán
Trong Mô-đun 5, bạn đã tạo Merchant Agent – một chuyên gia đọc IntentMandates, xác thực rằng chúng chưa hết hạn và tạo CartMandates ràng buộc bằng chữ ký của người bán. Giờ đây, chúng ta cần một tác nhân để nhận CartMandate đó và thực hiện khoản thanh toán thực tế.
Đây là lúc nguyên tắc thứ ba và cũng là nguyên tắc cuối cùng của AP2 phát huy tác dụng: thực hiện thanh toán an toàn thông qua PaymentMandate.
Nguyên tắc AP2: Uỷ quyền thanh toán và thực hiện thanh toán
Lý do chúng tôi cần vai trò Trình cung cấp thông tin đăng nhập
Trong Mô-đun 5, Merchant Agent đã tạo một CartMandate và lưu CartMandate đó vào trạng thái:
state["cart_mandate"] = {
"contents": {
"id": "cart_abc123",
"cart_expiry": "2025-11-07:15:47:16Z",
"payment_request": {
"details": {
"total": {
"amount": {"currency": "USD", "value": "50.00"}
}
}
}
},
"merchant_authorization": "SIG_a3f7b2c8"
}
Nhưng đây chỉ là một đề nghị ràng buộc. Trước khi có thể thực hiện thanh toán, chúng tôi cần:
- Xác thực rằng giỏ hàng chưa hết hạn
- Người dùng đồng ý tiếp tục thanh toán
- Thông tin xác thực cho phép thực hiện giao dịch thanh toán
- Xử lý giao dịch thanh toán thực tế (hoặc mô phỏng cho hội thảo của chúng tôi)
Đây là nhiệm vụ của Nhà cung cấp thông tin đăng nhập.
PaymentMandate là gì?
PaymentMandate là thuật ngữ của AP2 cho uỷ quyền cuối cùng cho phép thực hiện thanh toán. Đây là thông tin xác thực có thể kiểm chứng thứ ba và cuối cùng trong chuỗi AP2.
Hãy coi 3 thông tin đăng nhập này như một quy trình ký hợp đồng:
- IntentMandate: "Tôi muốn mua sản phẩm này" (Thư bày tỏ ý định)
- CartMandate: "Tôi, người bán, đề nghị bán ở mức giá này" (Câu trích dẫn bằng văn bản)
- PaymentMandate: "Tôi cho phép bạn tính phí phương thức thanh toán của tôi" (Hợp đồng đã ký)
Chỉ khi cả 3 thông tin xác thực này đều tồn tại thì giao dịch thanh toán mới có thể được thực hiện.
Cấu trúc của PaymentMandate
PaymentMandate trong AP2 có một cấu trúc cụ thể:
payment_mandate = {
"payment_mandate_contents": { # ← AP2 wrapper
"payment_mandate_id": "payment_xyz123",
"payment_details_id": "cart_abc123", # Links to CartMandate
"user_consent": True,
"consent_timestamp": "2025-11-07T15:48:00Z",
"amount": {
"currency": "USD",
"value": "50.00"
},
"merchant_name": "Room to Read"
},
"agent_present": True, # Human-in-the-loop flow
"timestamp": "2025-11-07T15:48:00Z"
}
Các thành phần chính:
1. payment_mandate_contents – Trình bao bọc uỷ quyền chứa:
- payment_mandate_id: Giá trị nhận dạng duy nhất
- payment_details_id: Liên kết trở lại CartMandate
- user_consent: Người dùng có phê duyệt hay không
- amount: Số tiền thanh toán (trích xuất từ CartMandate)
2. agent_present – Liệu đây có phải là quy trình có sự tham gia của con người hay không
3. timestamp – Thời điểm tạo uỷ quyền
Sứ mệnh của chúng tôi: Xây dựng Trình cung cấp thông tin xác thực
Trình cung cấp thông tin đăng nhập sẽ:
- Đọc CartMandate từ trạng thái (những gì Merchant Agent đã viết)
- Xác thực rằng giỏ hàng chưa hết hạn bằng cách sử dụng các mô hình AP2 Pydantic
- Trích xuất thông tin thanh toán từ cấu trúc lồng nhau
- Tạo PaymentMandate khi có sự đồng ý của người dùng bằng cách sử dụng các mô hình AP2
- Mô phỏng quy trình xử lý thanh toán (trong thực tế, bạn sẽ gọi API thanh toán thực)
- Ghi PaymentMandate và kết quả thanh toán vào trạng thái
Hãy cùng nhau xây dựng từng bước.
Bước 1: Thêm Trình trợ giúp xác thực thời gian hết hạn của giỏ hàng
Trước tiên, hãy tạo một trình trợ giúp xác thực rằng CartMandate chưa hết hạn – giống như cách chúng ta xác thực thời gian hết hạn của IntentMandate trong Mô-đun 5.
👉 Mở
charity_advisor/tools/payment_tools.py
Hãy thêm quy trình xác thực ngày hết hạn:
👉 Tìm:
# MODULE_6_STEP_1_ADD_CART_EXPIRY_VALIDATION_HELPER
👉 Thay thế dòng đó bằng:
def _validate_cart_expiry(cart: CartMandate) -> tuple[bool, str]:
"""
Validates that the CartMandate hasn't expired.
This is a critical security check - expired carts should not be processed.
Args:
cart: The Pydantic CartMandate model to validate.
Returns:
(is_valid, error_message): Tuple indicating if cart is still valid.
"""
try:
expiry_str = cart.contents.cart_expiry
expiry_time = datetime.fromisoformat(expiry_str.replace('Z', '+00:00'))
now = datetime.now(timezone.utc)
if expiry_time < now:
return False, f"CartMandate expired at {expiry_str}"
time_remaining = expiry_time - now
logger.info(f"CartMandate valid. Expires in {time_remaining.total_seconds():.0f} seconds")
return True, ""
except (ValueError, TypeError, AttributeError) as e:
return False, f"Invalid cart_expiry format or structure: {e}"
Bước 2: Thêm PaymentMandate Creation Helper
Bây giờ, hãy tạo một trình trợ giúp để tạo cấu trúc PaymentMandate bằng các mô hình Pydantic AP2 chính thức.
👉 Tìm:
# MODULE_6_STEP_2_ADD_PAYMENT_MANDATE_CREATION_HELPER
👉 Thay thế dòng đó bằng:
def _create_payment_mandate(cart: CartMandate, consent_granted: bool) -> dict:
"""
Creates a PaymentMandate using the official AP2 Pydantic models.
It links to the CartMandate and includes user consent status.
Args:
cart: The validated Pydantic CartMandate model being processed.
consent_granted: Whether the user has consented to the payment.
Returns:
A dictionary representation of the final, validated PaymentMandate.
"""
timestamp = datetime.now(timezone.utc)
# Safely extract details from the validated CartMandate model
cart_id = cart.contents.id
merchant_name = cart.contents.merchant_name
total_item = cart.contents.payment_request.details.total
# Create the nested PaymentResponse model for the mandate
payment_response_model = PaymentResponse(
request_id=cart_id,
method_name="CARD", # As per the simulated flow
details={"token": "simulated_payment_token_12345"}
)
# Create the PaymentMandateContents model
payment_mandate_contents_model = PaymentMandateContents(
payment_mandate_id=f"payment_{hashlib.sha256(f'{cart_id}{timestamp.isoformat()}'.encode()).hexdigest()[:12]}",
payment_details_id=cart_id,
payment_details_total=total_item,
payment_response=payment_response_model,
merchant_agent=merchant_name,
timestamp=timestamp.isoformat()
)
# Create the top-level PaymentMandate model
# In a real system, a user signature would be added to this model
payment_mandate_model = PaymentMandate(
payment_mandate_contents=payment_mandate_contents_model
)
# Convert the final Pydantic model to a dictionary for state storage
final_dict = payment_mandate_model.model_dump(mode='json')
# Add any custom/non-standard fields required by the codelab's logic to the dictionary
# The spec does not have these fields, but your original code did. We add them
# back to ensure compatibility with later steps.
final_dict['payment_mandate_contents']['user_consent'] = consent_granted
final_dict['payment_mandate_contents']['consent_timestamp'] = timestamp.isoformat() if consent_granted else None
final_dict['agent_present'] = True
return final_dict
Bước 3A: Tạo Chữ ký công cụ và Thiết lập
Bây giờ, hãy bắt đầu xây dựng công cụ chính theo từng bước. Trước tiên, chữ ký hàm và chế độ thiết lập ban đầu.
👉 Tìm:
# MODULE_6_STEP_3A_CREATE_TOOL_SIGNATURE
👉 Thay thế dòng đó bằng:
async def create_payment_mandate(tool_context: Any) -> Dict[str, Any]:
"""
Creates a PaymentMandate and simulates payment processing using Pydantic models.
This tool now reads the CartMandate from state, parses it into a validated model,
and creates a spec-compliant PaymentMandate.
"""
logger.info("Tool called: Creating PaymentMandate and processing payment")
# MODULE_6_STEP_3B_VALIDATE_CARTMANDATE
Bước 3B: Xác thực CartMandate
Giờ hãy thêm logic để đọc, xác thực CartMandate bằng các mô hình AP2 Pydantic và kiểm tra ngày hết hạn.
👉 Tìm:
# MODULE_6_STEP_3B_VALIDATE_CARTMANDATE
👉 Thay thế dòng đó bằng:
# 1. Read CartMandate dictionary from state
cart_mandate_dict = tool_context.state.get("cart_mandate")
if not cart_mandate_dict:
logger.error("No CartMandate found in state")
return { "status": "error", "message": "No CartMandate found. Merchant Agent must create cart first." }
# 2. Parse dictionary into a validated Pydantic model
try:
cart_model = CartMandate.model_validate(cart_mandate_dict)
except Exception as e:
logger.error(f"Could not validate CartMandate structure: {e}")
return {"status": "error", "message": f"Invalid CartMandate structure: {e}"}
# 3. Validate that the cart hasn't expired using the Pydantic model
is_valid, error_message = _validate_cart_expiry(cart_model)
if not is_valid:
logger.error(f"CartMandate validation failed: {error_message}")
return {"status": "error", "message": error_message}
# MODULE_6_STEP_3C_EXTRACT_PAYMENT_DETAILS
Bước 3C: Trích xuất thông tin thanh toán từ cấu trúc lồng nhau
Bây giờ, hãy chuyển đến mô hình CartMandate đã xác thực để trích xuất thông tin thanh toán mà chúng ta cần.
👉 Tìm:
# MODULE_6_STEP_3C_EXTRACT_PAYMENT_DETAILS
👉 Thay thế dòng đó bằng:
# 4. Safely extract data from the validated model
cart_id = cart_model.contents.id
merchant_name = cart_model.contents.merchant_name
amount_value = cart_model.contents.payment_request.details.total.amount.value
currency = cart_model.contents.payment_request.details.total.amount.currency
consent_granted = True # Assume consent for this codelab flow
# MODULE_6_STEP_3D_CREATE_PAYMENTMANDATE_AND_SIMULATE
Bước 3D: Tạo PaymentMandate và mô phỏng việc thanh toán
Cuối cùng, hãy tạo PaymentMandate bằng trình trợ giúp dựa trên Pydantic, mô phỏng quy trình xử lý thanh toán và lưu mọi thứ vào trạng thái.
👉 Tìm:
# MODULE_6_STEP_3D_CREATE_PAYMENTMANDATE_AND_SIMULATE
👉 Thay thế dòng đó bằng:
# 5. Create the spec-compliant PaymentMandate using the validated CartMandate model
payment_mandate_dict = _create_payment_mandate(cart_model, consent_granted)
# 6. Simulate payment processing
transaction_id = f"txn_{hashlib.sha256(f'{cart_id}{datetime.now(timezone.utc).isoformat()}'.encode()).hexdigest()[:16]}"
payment_result = {
"transaction_id": transaction_id,
"status": "completed",
"amount": amount_value,
"currency": currency,
"merchant": merchant_name,
"timestamp": datetime.now(timezone.utc).isoformat(),
"simulation": True
}
# 7. Write the compliant PaymentMandate dictionary and result to state
tool_context.state["payment_mandate"] = payment_mandate_dict
tool_context.state["payment_result"] = payment_result
logger.info(f"Payment processed successfully: {transaction_id}")
return {
"status": "success",
"message": f"Payment of {currency} {amount_value:.2f} to {merchant_name} processed successfully",
"transaction_id": transaction_id,
"payment_mandate_id": payment_mandate_dict["payment_mandate_contents"]["payment_mandate_id"]
}
Bước 4: Tạo Credentials Provider Agent – Nhập các thành phần
Bây giờ, hãy tạo tác nhân sử dụng công cụ này.
👉 Mở
charity_advisor/credentials_provider/agent.py
Bạn sẽ thấy một mẫu có các điểm đánh dấu giữ chỗ. Hãy bắt đầu bằng cách nhập những gì chúng ta cần.
👉 Tìm:
# MODULE_6_STEP_4_IMPORT_COMPONENTS
👉 Thay thế dòng đó bằng:
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from charity_advisor.tools.payment_tools import create_payment_mandate
Bước 5: Viết hướng dẫn về Trình cung cấp thông tin đăng nhập
Bây giờ, hãy viết chỉ dẫn hướng dẫn tác nhân.
👉 Tìm:
# MODULE_6_STEP_5_WRITE_INSTRUCTION
instruction="""""",
👉 Thay thế hai dòng đó bằng:
instruction="""You are a payment specialist responsible for securely processing payments with user consent.
Your workflow:
1. Read the CartMandate from shared state.
The CartMandate was created by the Merchant Agent and has this structure:
- contents: AP2 wrapper containing:
- id: Cart identifier
- cart_expiry: When the cart expires
- merchant_name: Who is receiving payment
- payment_request: W3C PaymentRequest with transaction details
- merchant_authorization: Merchant's signature
2. Extract payment details from the nested structure:
- Navigate: cart_mandate["contents"]["payment_request"]["details"]["total"]["amount"]
- This gives you the currency and value
3. **IMPORTANT - Two-Turn Conversational Confirmation Pattern:**
Before calling create_payment_mandate, you MUST:
- Present the payment details clearly to the user
- Ask explicitly: "I'm ready to process a payment of $X to [Charity Name]. Do you want to proceed with this donation?"
- WAIT for the user's explicit confirmation (e.g., "yes", "proceed", "confirm")
- ONLY call create_payment_mandate AFTER receiving explicit confirmation
- If user says "no" or "cancel", DO NOT call the tool
4. After user confirms, use the create_payment_mandate tool to:
- Validate the CartMandate hasn't expired (CRITICAL security check)
- Create a PaymentMandate (the third AP2 credential)
- Simulate payment processing
- Record the transaction result
5. After processing, inform the user:
- That payment was processed successfully (this is a simulation)
- The transaction ID
- The amount and merchant
- That this completes the three-agent AP2 credential chain
IMPORTANT BOUNDARIES:
- Your ONLY job is creating PaymentMandates and processing payments
- You do NOT discover charities (that's Shopping Agent's job)
- You do NOT create offers (that's Merchant Agent's job)
- You MUST validate that the CartMandate hasn't expired before processing
- You MUST get explicit user confirmation before calling create_payment_mandate
- In production, this consent mechanism would be even more robust
WHAT IS A PAYMENTMANDATE:
A PaymentMandate is the final credential that authorizes payment execution. It:
- Links to the CartMandate (proving the merchant's offer)
- Records user consent
- Contains payment details extracted from the CartMandate
- Enables the actual payment transaction
This is the third and final verifiable credential in our secure payment system.
THE COMPLETE AP2 CREDENTIAL CHAIN:
1. Shopping Agent creates IntentMandate (user's intent)
2. Merchant Agent reads IntentMandate, creates CartMandate (merchant's binding offer)
3. You read CartMandate, get user confirmation, create PaymentMandate (authorized payment execution)
Each credential:
- Has an expiry time (security feature)
- Links to the previous credential
- Is validated before the next step
- Creates an auditable chain of trust""",
Bước 6: Thêm các công cụ vào Trình cung cấp thông tin đăng nhập
👉 Tìm:
# MODULE_6_STEP_6_ADD_TOOLS
tools=[],
👉 Thay thế hai dòng đó bằng:
tools=[
FunctionTool(func=create_payment_mandate)
],
Bước 7: Xác minh Trình cung cấp thông tin đăng nhập đầy đủ
Hãy xác nhận rằng mọi thứ đã được kết nối đúng cách.
👉 Thông tin đầy đủ của bạn
charity_advisor/credentials_provider/agent.py
hiện sẽ có dạng như sau:
"""
Credentials Provider Agent - Handles payment processing with user consent.
This agent acts as our "Payment Processor."
"""
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from charity_advisor.tools.payment_tools import create_payment_mandate
credentials_provider = Agent(
name="CredentialsProvider",
model="gemini-2.5-flash",
description="Securely processes payments by creating PaymentMandates and executing transactions with user consent.",
tools=[
FunctionTool(func=create_payment_mandate)
],
instruction="""You are a payment specialist responsible for securely processing payments with user consent.
Your workflow:
1. Read the CartMandate from shared state.
The CartMandate was created by the Merchant Agent and has this structure:
- contents: AP2 wrapper containing:
- id: Cart identifier
- cart_expiry: When the cart expires
- merchant_name: Who is receiving payment
- payment_request: W3C PaymentRequest with transaction details
- merchant_authorization: Merchant's signature
2. Extract payment details from the nested structure:
- Navigate: cart_mandate["contents"]["payment_request"]["details"]["total"]["amount"]
- This gives you the currency and value
3. **IMPORTANT - Two-Turn Conversational Confirmation Pattern:**
Before calling create_payment_mandate, you MUST:
- Present the payment details clearly to the user
- Ask explicitly: "I'm ready to process a payment of $X to [Charity Name]. Do you want to proceed with this donation?"
- WAIT for the user's explicit confirmation (e.g., "yes", "proceed", "confirm")
- ONLY call create_payment_mandate AFTER receiving explicit confirmation
- If user says "no" or "cancel", DO NOT call the tool
4. After user confirms, use the create_payment_mandate tool to:
- Validate the CartMandate hasn't expired (CRITICAL security check)
- Create a PaymentMandate (the third AP2 credential)
- Simulate payment processing
- Record the transaction result
5. After processing, inform the user:
- That payment was processed successfully (this is a simulation)
- The transaction ID
- The amount and merchant
- That this completes the three-agent AP2 credential chain
IMPORTANT BOUNDARIES:
- Your ONLY job is creating PaymentMandates and processing payments
- You do NOT discover charities (that's Shopping Agent's job)
- You do NOT create offers (that's Merchant Agent's job)
- You MUST validate that the CartMandate hasn't expired before processing
- You MUST get explicit user confirmation before calling create_payment_mandate
- In production, this consent mechanism would be even more robust
WHAT IS A PAYMENTMANDATE:
A PaymentMandate is the final credential that authorizes payment execution. It:
- Links to the CartMandate (proving the merchant's offer)
- Records user consent
- Contains payment details extracted from the CartMandate
- Enables the actual payment transaction
This is the third and final verifiable credential in our secure payment system.
THE COMPLETE AP2 CREDENTIAL CHAIN:
1. Shopping Agent creates IntentMandate (user's intent)
2. Merchant Agent reads IntentMandate, creates CartMandate (merchant's binding offer)
3. You read CartMandate, get user confirmation, create PaymentMandate (authorized payment execution)
Each credential:
- Has an expiry time (security feature)
- Links to the previous credential
- Is validated before the next step
- Creates an auditable chain of trust"""
)
✅ Điểm dừng: Giờ đây, bạn đã có một Trình cung cấp thông tin xác thực hoàn chỉnh với tính năng đọc CartMandate và tạo PaymentMandate đúng cách bằng các mô hình AP2 Pydantic.
Bước 8: Kiểm thử Trình cung cấp thông tin đăng nhập
Bây giờ, hãy xác minh rằng tác nhân của chúng ta xử lý chính xác các khoản thanh toán và hoàn tất chuỗi thông tin đăng nhập.
👉 Trong thiết bị đầu cuối Cloud Shell, hãy chạy:
python scripts/test_credentials_provider.py
Kết quả đầu ra dự kiến:
======================================================================
CREDENTIALS PROVIDER TEST (MOCK - NO CONFIRMATION)
======================================================================
Simulated CartMandate from Merchant Agent:
- Cart ID: cart_test123
- Merchant: Room to Read
- Amount: $50.00
- Expires: 2025-11-07T15:47:16Z
- Signature: SIG_test_signature
Calling Credentials Provider to process payment...
======================================================================
INFO:charity_advisor.tools.payment_tools:Tool called: Creating PaymentMandate and processing payment
INFO:charity_advisor.tools.payment_tools:CartMandate valid. Expires in 900 seconds
INFO:charity_advisor.tools.payment_tools:Payment processed successfully: txn_a3f7b2c8d9e1f4a2
======================================================================
CREDENTIALS PROVIDER RESPONSE:
======================================================================
I've successfully processed your payment. Here are the details:
**Payment Completed** (Simulated)
- Transaction ID: txn_a3f7b2c8d9e1f4a2
- Amount: USD 50.00
- Merchant: Room to Read
- Status: Completed
This completes the three-agent AP2 credential chain:
1. ✓ Shopping Agent created IntentMandate (your intent)
2. ✓ Merchant Agent created CartMandate (binding offer)
3. ✓ Credentials Provider created PaymentMandate (payment authorization)
Your donation has been processed securely through our verifiable credential system.
======================================================================
PAYMENTMANDATE CREATED:
======================================================================
Payment Mandate ID: payment_3b4c5d6e7f8a
Linked to Cart: cart_test123
User Consent: True
Amount: USD 50.00
Merchant: Room to Read
Agent Present: True
======================================================================
======================================================================
PAYMENT RESULT:
======================================================================
Transaction ID: txn_a3f7b2c8d9e1f4a2
Status: completed
Amount: USD 50.00
Merchant: Room to Read
Simulation: True
======================================================================
Bước 9: Kiểm thử quy trình hoàn chỉnh gồm 3 tác nhân
Bây giờ, hãy kiểm thử cả 3 tác nhân cùng hoạt động!
👉 Chạy kiểm thử toàn bộ quy trình:
python scripts/test_full_pipeline.py
Kết quả đầu ra dự kiến:
======================================================================
THREE-AGENT PIPELINE TEST (AP2 CREDENTIAL CHAIN)
======================================================================
[1/3] SHOPPING AGENT - Finding charity and creating IntentMandate...
----------------------------------------------------------------------
✓ IntentMandate created
- Intent ID: intent_774799058_1730927536
- Description: Donate $75.00 to Room to Read
- Merchant: Room to Read
- Amount: $75.0
- Expires: 2025-11-07T16:32:16Z
[2/3] MERCHANT AGENT - Reading IntentMandate and creating CartMandate...
----------------------------------------------------------------------
✓ CartMandate created
- ID: cart_3b4c5d6e7f8a
- Expires: 2025-11-07T15:47:16Z
- Signature: SIG_a3f7b2c8d9e1f4a2
[3/3] CREDENTIALS PROVIDER - Creating PaymentMandate and processing...
----------------------------------------------------------------------
NOTE: In the web UI, this would show a confirmation dialog
For this test, consent is automatically granted
✓ Payment processed (SIMULATED)
- Transaction ID: txn_a3f7b2c8d9e1f4a2
- Amount: $75.0
- Status: completed
======================================================================
COMPLETE AP2 CREDENTIAL CHAIN
======================================================================
✓ Credential 1: IntentMandate (User's Intent)
- Intent ID: intent_774799058_1730927536
- Description: Donate $75.00 to Room to Read
- Expiry: 2025-11-07T16:32:16Z
✓ Credential 2: CartMandate (Merchant's Offer)
- Cart ID: cart_3b4c5d6e7f8a
- Cart Expiry: 2025-11-07T15:47:16Z
- Merchant Signature: SIG_a3f7b2c8d9e1f4a2
✓ Credential 3: PaymentMandate (Payment Execution)
- Payment Mandate ID: payment_3b4c5d6e7f8a
- Linked to Cart: cart_3b4c5d6e7f8a
- Agent Present: True
✓ Transaction Result:
- Transaction ID: txn_a3f7b2c8d9e1f4a2
- Simulation: True
======================================================================
✅ COMPLETE PIPELINE TEST PASSED
======================================================================
Đây là chuỗi thông tin đăng nhập AP2 hoàn chỉnh đang hoạt động!
Mỗi nhân viên hỗ trợ:
- Đọc thông tin xác thực từ trạng thái
- Xác thực bằng các mô hình Pydantic (cấu trúc + kiểm tra ngày hết hạn)
- Tạo thông tin đăng nhập tiếp theo bằng các mô hình AP2
- Viết cho trạng thái của nhân viên hỗ trợ tiếp theo
Sản phẩm bạn vừa tạo
Bạn đã hoàn tất thành công chuỗi thông tin xác thực gồm 3 tác nhân AP2 bằng cách xác thực cấu trúc phù hợp bằng các mô hình Pydantic và mô phỏng thanh toán.
Các khái niệm chính đã nắm vững
✅ PaymentMandate (AP2 Credential #3):
- Được tạo bằng các mô hình Pydantic AP2 chính thức
- Thông tin xác thực cuối cùng cho phép thực hiện thanh toán
- Liên kết đến CartMandate thông qua payment_details_id
- Ghi lại sự đồng ý của người dùng và dấu thời gian
- Chứa số tiền thanh toán được trích xuất từ CartMandate
- Bao gồm cờ agent_present cho tính năng có sự tham gia của con người
- Việc xác thực mô hình đảm bảo tuân thủ quy cách
✅ Đọc từ CartMandate:
- Xác thực cấu trúc bằng
CartMandate.model_validate() - Quyền truy cập vào thuộc tính an toàn theo kiểu:
cart_model.contents.payment_request.details.total.amount - Tìm hiểu về sự khác biệt giữa trình bao bọc AP2 và việc tách theo tiêu chuẩn W3C
- Trích xuất merchant_name, amount, currency một cách an toàn từ mô hình
- Pydantic tự động phát hiện các lỗi cấu trúc
✅ Xác thực ngày hết hạn của giỏ hàng:
- Chấp nhận mô hình Pydantic
CartMandateđã được xác thực - Đọc từ
cart.contents.cart_expiry(quyền truy cập vào thuộc tính) - Tính năng bảo mật ngăn chặn việc xử lý giỏ hàng cũ
- Thời lượng ngắn hơn (15 phút) so với ý định (1 giờ)
✅ Mô phỏng thanh toán:
- Mô phỏng mang tính giáo dục về công ty xử lý thanh toán thực
- Tạo mã giao dịch
- Ghi lại payment_result ở trạng thái
- Được đánh dấu rõ ràng là nội dung mô phỏng (cờ mô phỏng: True)
✅ Hoàn tất chuỗi AP2 với các mô hình:
- Ba tác nhân, ba thông tin đăng nhập, ba quy trình xác thực Pydantic
- Mỗi tác nhân sẽ xác thực cấu trúc của thông tin đăng nhập trước đó bằng cách sử dụng các mô hình
- Mỗi thông tin đăng nhập đều liên kết với thông tin đăng nhập trước đó để tạo nhật ký kiểm tra
- Việc chuyển giao dựa trên trạng thái duy trì sự tách biệt vai trò
- An toàn về kiểu trong toàn bộ chuỗi
✅ Phát triển dựa trên mô hình:
- Xác thực thông tin đầu vào qua
model_validate() - Cấu trúc an toàn về kiểu với các mô hình lồng nhau
- Tự động chuyển đổi tuần tự qua
model_dump(mode='json') - Các mẫu sẵn sàng cho sản xuất ngay từ đầu
Tiếp theo là gì?
Trong mô-đun tiếp theo, chúng ta sẽ tạo Orchestrator Agent (Tác nhân điều phối) để điều phối cả 3 tác nhân chuyên trách.
Bạn đã tạo 3 đặc vụ chuyên biệt mạnh mẽ bằng các mô hình AP2 Pydantic. Bây giờ, hãy tạo trình điều phối để sắp xếp các thành phần này thành một trải nghiệm quyên góp liền mạch.
Hãy tạo Orchestrator và xem toàn bộ hệ thống hoạt động.
7. Điều phối – Tổng hợp mọi thứ
Từ chuyên gia đến trải nghiệm liền mạch
Trong các mô-đun trước, bạn đã tạo 3 đặc vụ chuyên biệt:
- Nhân viên hỗ trợ mua sắm: Tìm các tổ chức từ thiện, tạo IntentMandate
- Merchant Agent: Tạo CartMandate từ IntentMandate
- Nhà cung cấp thông tin xác thực: Tạo PaymentMandate, xử lý khoản thanh toán
Các tác nhân này tự nhiên rơi vào 2 giai đoạn:
- Giai đoạn 1 (Mua sắm): Cuộc trò chuyện nhiều lượt để tìm và chọn tổ chức từ thiện
- Giai đoạn 2 (Xử lý): Thực hiện nguyên tử việc tạo ưu đãi và thanh toán
Nhưng hiện tại, bạn sẽ phải tự điều phối các giai đoạn này theo cách thủ công.
Đây là nơi các mẫu điều phối của ADK phát huy tác dụng.
Nguyên tắc AP2: Điều phối việc thực thi ranh giới tin cậy
Tại sao việc điều phối lại quan trọng đối với bảo mật
Điều phối không chỉ mang lại sự thuận tiện mà còn giúp thực thi các ranh giới tin cậy thông qua cấu trúc.
Không có quy trình điều phối:
# User could accidentally skip steps or reorder them
shopping_agent.run("Find charity")
# Oops, forgot to create CartMandate!
credentials_provider.run("Process payment") # No offer to validate!
Có sự sắp đặt:
# Pipeline enforces correct order
donation_processing_pipeline = SequentialAgent(
sub_agents=[
merchant_agent, # Must run first
credentials_provider # Must run second
]
)
# Steps ALWAYS run in order, no skipping allowed
Quy trình tuần tự đảm bảo:
- ✅ IntentMandate được tạo trước CartMandate
- ✅ CartMandate được tạo trước khi xử lý thanh toán
- ✅ Mỗi tác nhân chạy trong bối cảnh riêng biệt
- ✅ Trạng thái chuyển tiếp qua chuỗi thông tin đăng nhập
Sứ mệnh của chúng tôi: Xây dựng hệ thống hoàn chỉnh
Chúng ta sẽ tạo 2 lớp:
Lớp 1: Quy trình xử lý (SequentialAgent)
- Wires together Merchant → Credentials
- Tự động chạy theo trình tự sau khi bạn chọn tổ chức từ thiện
- Thực thi nguyên tử của ưu đãi và khoản thanh toán
Lớp 2: Trình điều phối gốc (Tác nhân hướng đến người dùng)
- Tính cách thân thiện
- Uỷ quyền cho shopping_agent để chọn tổ chức từ thiện
- Uỷ quyền cho quy trình xử lý sau khi IntentMandate được tạo
- Xử lý các cuộc trò chuyện và chuyển đổi giai đoạn
Phương pháp gồm 2 lớp này phù hợp với quy trình tự nhiên:
- Giai đoạn mua sắm: Cuộc trò chuyện nhiều lượt (người dùng duyệt xem, đặt câu hỏi, quyết định)
- Giai đoạn xử lý: Thực thi nguyên tử (đề nghị → thanh toán)
Hãy cùng xây dựng cả hai.
Bước 1: Nhập các thành phần điều phối
Trước tiên, hãy thiết lập tệp điều phối với các lệnh nhập cần thiết.
👉 Mở
charity_advisor/agent.py
Hãy bắt đầu với các lệnh nhập:
👉 Tìm:
# MODULE_7_STEP_1_IMPORT_COMPONENTS
👉 Thay thế dòng đó bằng:
from google.adk.agents import Agent, SequentialAgent
from charity_advisor.shopping_agent.agent import shopping_agent
from charity_advisor.merchant_agent.agent import merchant_agent
from charity_advisor.credentials_provider.agent import credentials_provider
Bước 2: Tạo quy trình xử lý
Bây giờ, hãy tạo quy trình chạy hoạt động tạo ưu đãi và xử lý thanh toán một cách riêng lẻ.
👉 Tìm:
# MODULE_7_STEP_2_CREATE_SEQUENTIAL_PIPELINE
👉 Thay thế hai dòng đó bằng:
# Create the donation processing pipeline
# This runs Merchant → Credentials in sequence AFTER charity is selected
donation_processing_pipeline = SequentialAgent(
name="DonationProcessingPipeline",
description="Creates signed offer and processes payment after charity is selected",
sub_agents=[
merchant_agent,
credentials_provider
]
)
Bước 3A: Tạo chế độ thiết lập tác nhân gốc
Bây giờ, hãy tạo tác nhân hướng đến người dùng để điều phối cả hai giai đoạn. Chúng ta sẽ xây dựng phần này thành 3 phần: thiết lập (3A), hướng dẫn (3B) và các trợ lý phụ (3C).
👉 Tìm:
# MODULE_7_STEP_3A_CREATE_ROOT_AGENT_SETUP
👉 Thay thế dòng đó bằng:
# Create the root orchestrator agent
# This is what users interact with directly
root_agent = Agent(
name="CharityAdvisor",
model="gemini-2.5-pro",
description="A friendly charity giving assistant that helps users donate to verified organizations.",
# MODULE_7_STEP_3B_WRITE_ROOT_AGENT_INSTRUCTION
Bước 3B: Viết chỉ dẫn cho Root Agent
Bây giờ, hãy thêm chỉ dẫn hướng dẫn hành vi của cố vấn từ thiện trong cả hai giai đoạn.
👉 Tìm:
# MODULE_7_STEP_3B_WRITE_ROOT_AGENT_INSTRUCTION
👉 Thay thế dòng đó bằng:
instruction="""You are a helpful and friendly charity giving advisor.
Your workflow has TWO distinct phases:
PHASE 1: CHARITY SELECTION (delegate to shopping_agent)
When a user expresses interest in donating:
1. Delegate to shopping_agent immediately
2. The shopping_agent will:
- Search for charities matching their cause
- Present verified options with ratings
- Engage in conversation (user may ask questions, change their mind)
- Wait for user to select a specific charity and amount
- Create an IntentMandate when user decides
3. Wait for shopping_agent to complete
You'll know Phase 1 is complete when shopping_agent's response includes:
- "IntentMandate created" or "Intent ID: intent_xxx"
- Charity name and donation amount
PHASE 2: PAYMENT PROCESSING (delegate to DonationProcessingPipeline)
After shopping_agent completes:
1. Acknowledge the user's selection naturally:
"Perfect! Let me process your $X donation to [Charity]..."
2. Delegate to DonationProcessingPipeline
3. The pipeline will automatically:
- Create signed cart offer (MerchantAgent)
- Get consent and process payment (CredentialsProvider)
4. After pipeline completes, summarize the transaction
CRITICAL RULES:
- Phase 1 may take multiple conversation turns (this is normal)
- Only proceed to Phase 2 after IntentMandate exists
- Don't rush the user during charity selection
- Don't ask user to "proceed" between phases - transition automatically
EXAMPLE FLOW:
User: "I want to donate to education"
You: [delegate to shopping_agent]
Shopping: "Here are 3 education charities..." [waits]
User: "Tell me more about the first one"
Shopping: "Room to Read focuses on..." [waits]
User: "Great, I'll donate $50 to Room to Read"
Shopping: "IntentMandate created (ID: intent_123)..."
You: "Perfect! Processing your $50 donation to Room to Read..." [delegate to DonationProcessingPipeline]
Pipeline: [creates offer, gets consent, processes payment]
You: "Done! Your donation was processed successfully. Transaction ID: txn_456"
Your personality:
- Warm and encouraging
- Patient during charity selection
- Clear about educational nature
- Smooth transitions between phases""",
# MODULE_7_STEP_3C_ADD_ROOT_AGENT_SUBAGENTS
Bước 3C: Thêm các Đại lý phụ
Cuối cùng, hãy cấp cho cố vấn từ thiện quyền truy cập vào cả tác nhân mua sắm và quy trình xử lý, đồng thời đóng định nghĩa Tác nhân.
👉 Tìm:
# MODULE_7_STEP_3C_ADD_ROOT_AGENT_SUBAGENTS
👉 Thay thế dòng đó bằng:
sub_agents=[
shopping_agent,
donation_processing_pipeline
]
)
Bước 4: Xác minh hệ thống hoàn chỉnh
Hãy xác nhận rằng quy trình điều phối được thiết lập đúng cách.
👉 Thông tin đầy đủ của bạn
charity_advisor/agent.py
hiện sẽ có dạng như sau:
"""
Main orchestration: The donation processing pipeline and root orchestrator agent.
"""
from google.adk.agents import Agent, SequentialAgent
from charity_advisor.shopping_agent.agent import shopping_agent
from charity_advisor.merchant_agent.agent import merchant_agent
from charity_advisor.credentials_provider.agent import credentials_provider
# Create the donation processing pipeline
# This runs Merchant → Credentials in sequence AFTER charity is selected
donation_processing_pipeline = SequentialAgent(
name="DonationProcessingPipeline",
description="Creates signed offer and processes payment after charity is selected",
sub_agents=[
merchant_agent,
credentials_provider
]
)
# Create the root orchestrator agent
# This is what users interact with directly
root_agent = Agent(
name="CharityAdvisor",
model="gemini-2.5-flash",
description="A friendly charity giving assistant that helps users donate to verified organizations.",
instruction="""You are a helpful and friendly charity giving advisor.
Your workflow has TWO distinct phases:
PHASE 1: CHARITY SELECTION (delegate to shopping_agent)
When a user expresses interest in donating:
1. Delegate to shopping_agent immediately
2. The shopping_agent will:
- Search for charities matching their cause
- Present verified options with ratings
- Engage in conversation (user may ask questions, change their mind)
- Wait for user to select a specific charity and amount
- Create an IntentMandate when user decides
3. Wait for shopping_agent to complete
You'll know Phase 1 is complete when shopping_agent's response includes:
- "IntentMandate created" or "Intent ID: intent_xxx"
- Charity name and donation amount
PHASE 2: PAYMENT PROCESSING (delegate to DonationProcessingPipeline)
After shopping_agent completes:
1. Acknowledge the user's selection naturally:
"Perfect! Let me process your $X donation to [Charity]..."
2. Delegate to DonationProcessingPipeline
3. The pipeline will automatically:
- Create signed cart offer (MerchantAgent)
- Get consent and process payment (CredentialsProvider)
4. After pipeline completes, summarize the transaction
CRITICAL RULES:
- Phase 1 may take multiple conversation turns (this is normal)
- Only proceed to Phase 2 after IntentMandate exists
- Don't rush the user during charity selection
- Don't ask user to "proceed" between phases - transition automatically
EXAMPLE FLOW:
User: "I want to donate to education"
You: [delegate to shopping_agent]
Shopping: "Here are 3 education charities..." [waits]
User: "Tell me more about the first one"
Shopping: "Room to Read focuses on..." [waits]
User: "Great, I'll donate $50 to Room to Read"
Shopping: "IntentMandate created (ID: intent_123)..."
You: "Perfect! Processing your $50 donation to Room to Read..." [delegate to DonationProcessingPipeline]
Pipeline: [creates offer, gets consent, processes payment]
You: "Done! Your donation was processed successfully. Transaction ID: txn_456"
Your personality:
- Warm and encouraging
- Patient during charity selection
- Clear about educational nature
- Smooth transitions between phases""",
sub_agents=[
shopping_agent,
donation_processing_pipeline
]
)
Bước 5: Tăng cường bảo mật bằng lệnh gọi lại xác thực (Không bắt buộc, có thể bỏ qua để chuyển đến Bước 7)

SequentialAgent đảm bảo thứ tự thực thi, nhưng nếu:
- Shopping Agent âm thầm thất bại (IntentMandate chưa bao giờ được tạo)
- Một giờ trôi qua giữa Mua sắm và Merchant (ý định hết hạn)
- Trạng thái bị hỏng hoặc bị xoá
- Có người cố gắng gọi trực tiếp cho người bán, bỏ qua Mua sắm
Lệnh gọi lại thêm hoạt động thực thi kiến trúc – các lệnh gọi này xác thực các điều kiện tiên quyết trước khi tác nhân bắt đầu lệnh gọi LLM. Đây là phương pháp phòng thủ chuyên sâu: các công cụ xác thực trong quá trình thực thi, các lệnh gọi lại xác thực trước khi thực thi.
Hãy thêm các lệnh gọi lại xác thực vào các tác nhân Merchant và Credentials Provider.
Bước 5A: Thêm quy trình xác thực người bán – Nhập các loại lệnh gọi lại
Trước tiên, hãy thêm các lệnh nhập cần thiết cho lệnh gọi lại.
👉 Mở
charity_advisor/merchant_agent/agent.py
Ở đầu tệp, sau các lệnh nhập hiện có, hãy thêm:
from typing import Optional
from datetime import datetime, timezone
from google.adk.agents.callback_context import CallbackContext
from google.genai.types import Content, Part
import logging
logger = logging.getLogger(__name__)
Bước 5B: Xây dựng hàm xác thực ý định
Bây giờ, hãy tạo một hàm gọi lại để xác thực IntentMandate trước khi Merchant Agent chạy.
👉 Trong
charity_advisor/merchant_agent/agent.py
, hãy thêm hàm này TRƯỚC
merchant_agent = Agent(...)
định nghĩa:
def validate_intent_before_merchant(
callback_context: CallbackContext,
) -> Optional[Content]:
"""
Validates IntentMandate exists and hasn't expired before Merchant runs.
This callback enforces that the Shopping Agent completed successfully
before the Merchant Agent attempts to create a CartMandate.
Returns:
None: Allow Merchant Agent to proceed normally
Content: Skip Merchant Agent and return error to user
"""
state = callback_context.state
# Check credential exists
if "intent_mandate" not in state:
logger.error("❌ IntentMandate missing - Shopping Agent may have failed")
return Content(parts=[Part(text=(
"Error: Cannot create cart. User intent was not properly recorded. "
"Please restart the donation process."
))])
intent_mandate = state["intent_mandate"]
# Validate expiry (critical security check)
try:
expiry_time = datetime.fromisoformat(
intent_mandate["intent_expiry"].replace('Z', '+00:00')
)
now = datetime.now(timezone.utc)
if expiry_time < now:
logger.error(f"❌ IntentMandate expired at {intent_mandate['intent_expiry']}")
return Content(parts=[Part(text=(
"Error: Your donation intent has expired. "
"Please select a charity again to restart."
))])
time_remaining = expiry_time - now
logger.info(f"✓ IntentMandate validated. Expires in {time_remaining.total_seconds():.0f}s")
except (KeyError, ValueError) as e:
logger.error(f"❌ Invalid IntentMandate structure: {e}")
return Content(parts=[Part(text=(
"Error: Invalid intent data. Please restart the donation."
))])
# All checks passed - allow Merchant Agent to proceed
logger.info(f"✓ Prerequisites met for Merchant Agent: {intent_mandate['intent_id']}")
return None
Bước 5C: Đính kèm lệnh gọi lại vào Merchant Agent
Bây giờ, hãy kết nối lệnh gọi lại với nhân viên hỗ trợ.
👉 Trong
charity_advisor/merchant_agent/agent.py
, sửa đổi
merchant_agent = Agent(...)
định nghĩa:
Tìm dòng này trong định nghĩa về Agent:
merchant_agent = Agent(
name="MerchantAgent",
model="gemini-2.5-flash",
description="Creates formal, signed CartMandates for charity donations following W3C PaymentRequest standards.",
Thêm dòng này ngay sau
description
line:
before_agent_callback=validate_intent_before_merchant,
Định nghĩa về tác nhân của bạn hiện sẽ có dạng như sau:
merchant_agent = Agent(
name="MerchantAgent",
model="gemini-2.5-flash",
description="Creates formal, signed CartMandates for charity donations following W3C PaymentRequest standards.",
before_agent_callback=validate_intent_before_merchant,
tools=[
FunctionTool(func=create_cart_mandate)
],
instruction="""..."""
)
Bước 6: Thêm quy trình xác thực nhà cung cấp thông tin đăng nhập (Không bắt buộc, bạn có thể chuyển sang Bước 7)
Cùng một mẫu – hãy thêm quy trình xác thực cho bước thanh toán.
Bước 6A: Nhập các loại lệnh gọi lại
👉 Mở
charity_advisor/credentials_provider/agent.py
Ở đầu tệp, sau các lệnh nhập hiện có, hãy thêm:
from typing import Optional
from datetime import datetime, timezone
from google.adk.agents.callback_context import CallbackContext
from google.genai.types import Content, Part
import logging
logger = logging.getLogger(__name__)
Bước 6B: Xây dựng hàm xác thực giỏ hàng
👉 Trong
charity_advisor/credentials_provider/agent.py
, hãy thêm hàm này TRƯỚC
credentials_provider = Agent(...)
định nghĩa:
def validate_cart_before_payment(
callback_context: CallbackContext,
) -> Optional[Content]:
"""
Validates CartMandate exists and hasn't expired before payment processing.
This callback enforces that the Merchant Agent completed successfully
before the Credentials Provider attempts to process payment.
Returns:
None: Allow Credentials Provider to proceed
Content: Skip payment processing and return error
"""
state = callback_context.state
# Check credential exists
if "cart_mandate" not in state:
logger.error("❌ CartMandate missing - Merchant Agent may have failed")
return Content(parts=[Part(text=(
"Error: Cannot process payment. Cart was not properly created. "
"Please restart the donation process."
))])
cart_mandate = state["cart_mandate"]
# Validate AP2 structure
if "contents" not in cart_mandate:
logger.error("❌ CartMandate missing AP2 contents wrapper")
return Content(parts=[Part(text=(
"Error: Invalid cart structure. Please restart."
))])
# Validate expiry
try:
contents = cart_mandate["contents"]
expiry_time = datetime.fromisoformat(
contents["cart_expiry"].replace('Z', '+00:00')
)
now = datetime.now(timezone.utc)
if expiry_time < now:
logger.error(f"❌ CartMandate expired at {contents['cart_expiry']}")
return Content(parts=[Part(text=(
"Error: Your cart has expired (15 minute limit). "
"Please restart the donation to get a fresh offer."
))])
time_remaining = expiry_time - now
logger.info(f"✓ CartMandate validated. Expires in {time_remaining.total_seconds():.0f}s")
except (KeyError, ValueError) as e:
logger.error(f"❌ Invalid CartMandate structure: {e}")
return Content(parts=[Part(text=(
"Error: Invalid cart data. Please restart the donation."
))])
# All checks passed - allow payment processing
logger.info(f"✓ Prerequisites met for Credentials Provider: {contents['id']}")
return None
Bước 6C: Đính kèm lệnh gọi lại vào Trình cung cấp thông tin đăng nhập
👉 Trong
charity_advisor/credentials_provider/agent.py
, sửa đổi
credentials_provider = Agent(...)
định nghĩa:
Tìm dòng này trong định nghĩa về Agent:
credentials_provider = Agent(
name="CredentialsProvider",
model="gemini-2.5-flash",
description="Securely processes payments by creating PaymentMandates and executing transactions with user consent.",
Thêm dòng này ngay sau
description
line:
before_agent_callback=validate_cart_before_payment,
Định nghĩa về tác nhân của bạn hiện sẽ có dạng như sau:
credentials_provider = Agent(
name="CredentialsProvider",
model="gemini-2.5-flash",
description="Securely processes payments by creating PaymentMandates and executing transactions with user consent.",
before_agent_callback=validate_cart_before_payment,
tools=[
FunctionTool(func=create_payment_mandate)
],
instruction="""..."""
)
Bước 7: Kiểm thử bằng giao diện người dùng web ADK
Bây giờ, hãy kiểm thử hệ thống hoàn chỉnh đã được tăng cường bảo mật với các lệnh gọi lại xác thực đang hoạt động.
👉 Trong thiết bị đầu cuối Cloud Shell, hãy chạy:
adk web
Bạn sẽ thấy kết quả 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 web 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 (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), sau đó 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ẻ trình duyệt mới hiển thị giao diện người dùng web ADK.

👉 Chọn nhân viên hỗ trợ trong trình đơn thả xuống:
Trong giao diện người dùng web ADK, bạn sẽ thấy một trình đơn thả xuống ở trên cùng. Chọn charity_advisor trong danh sách.

Bạn sẽ thấy giao diện web ADK với:
- Bảng trò chuyện: Bên trái, dùng để trò chuyện
- Bảng điều khiển theo dõi: Bên phải, để quan sát (chúng ta sẽ sử dụng bảng này trong Mô-đun 9)
Thử nghiệm 1: Hoàn tất quy trình quyên góp (Trường hợp bình thường)
👉 Trong giao diện trò chuyện, hãy nhập:
I want to donate to an education charity
Xem toàn bộ quy trình diễn ra:


Điều gì đang xảy ra (hiển thị trong bảng điều khiển theo dõi ở bên phải):
1. Advisor uỷ quyền cho ShoppingAgent:
- ShoppingAgent tìm kiếm các tổ chức từ thiện giáo dục
- Cho bạn thấy 3 lựa chọn đã xác minh kèm theo thông tin chi tiết
2. Bạn tương tác với ShoppingAgent (có thể mất nhiều lượt):
User: "Tell me more about Room to Read"
Shopping: [explains mission and impact]
User: "I'll donate $50 to Room to Read"
3. ShoppingAgent tạo IntentMandate:
- Tạo và ký ý định
- Trả lại thông tin xác nhận kèm theo mã nhận dạng ý định
4. Cố vấn chuyển sang giai đoạn xử lý:
Tuyệt lắm! Đang xử lý khoản quyên góp 50 USD của bạn cho tổ chức Room to Read...
5. DonationProcessingPipeline kích hoạt:
- Lệnh gọi lại của người bán xác thực IntentMandate (✓ đã qua) ← MỚI!
- Merchant Agent tạo CartMandate có chữ ký
- Lệnh gọi lại thông tin xác thực xác thực CartMandate (✓ đã qua) ← MỚI!
- Nhà cung cấp thông tin xác thực chuẩn bị khoản thanh toán
6. Quy trình thanh toán:
- Trình cung cấp thông tin đăng nhập tạo PaymentMandate
- Mô phỏng quá trình xử lý thanh toán
- Mã giao dịch trả lại
7. Advisor tóm tắt:
Tuyệt lắm! Khoản quyên góp của bạn đã được xử lý thành công! 🎉
Thông tin chi tiết:
- Số tiền: 50 USD
- Tổ chức từ thiện: Room to Read (Mã số nhận dạng doanh nghiệp: 77-0479905)
- Mã giao dịch: txn_a3f7b2c8d9e1f4a2
Bài kiểm thử 2: Xác minh các lệnh gọi lại phát hiện lỗi (Bài kiểm thử nâng cao không bắt buộc)
Bạn muốn xem các lệnh gọi lại đang hoạt động để phát hiện lỗi? Bạn cần làm hỏng trạng thái theo cách thủ công (gỡ lỗi nâng cao), nhưng trong quá trình sản xuất, các lệnh gọi lại sẽ bắt được:
- Công cụ Trợ lý mua sắm gặp lỗi → Các lệnh gọi lại của người bán bị chặn: "Lỗi: Không tạo được giỏ hàng..."
- 2 giờ trôi qua → Lệnh gọi lại của người bán bị chặn: "Lỗi: Ý định đã hết hạn..."
- Giỏ hàng hết hạn → Các khối lệnh gọi lại thông tin đăng nhập: "Lỗi: Giỏ hàng hết hạn (giới hạn 15 phút)..."
Giờ đây, các trường hợp đặc biệt này được các lệnh gọi lại xác thực của bạn buộc thực thi về mặt cấu trúc.
Sản phẩm bạn vừa tạo
Bạn đã điều phối thành công 3 tác nhân chuyên biệt thành một hệ thống liền mạch, đáng tin cậy với quy trình xác thực kiến trúc.
Tiếp theo là gì?
Giờ đây, bạn đã hoàn tất phần cốt lõi về kỹ thuật để xây dựng các tác nhân đáng tin cậy:
Bạn đã tạo một hệ thống hoàn chỉnh và đáng tin cậy để thực thi chuỗi thông tin đăng nhập cục bộ. Bây giờ, hãy cung cấp quyền truy cập cho người dùng thực thông qua việc triển khai bản phát hành chính thức và bật nhật ký kiểm toán để có thể thực hiện được Mô-đun 9.
Hãy triển khai tác nhân được tăng cường bảo mật của bạn lên Google Cloud.
8. Triển khai

Hệ thống quyên góp đáng tin cậy của bạn hiện đã hoàn tất với 3 nhân viên chuyên trách làm việc tại địa phương:
Nhưng nó chỉ chạy trên máy phát triển của bạn. Để hệ thống này hữu ích cho người dùng thực và để ghi lại các dấu vết về trách nhiệm giải trình nhằm chứng minh độ tin cậy, bạn cần triển khai hệ thống này cho bản phát hành công khai.
Module này hướng dẫn bạn cách triển khai tác nhân của mình lên Google Cloud với khả năng quan sát được bật ngay từ ngày đầu tiên. Cờ --trace_to_cloud mà bạn sẽ sử dụng trong quá trình triển khai là yếu tố giúp nhật ký trách nhiệm trong Mô-đun 9 có thể thực hiện được.
Tìm hiểu về các lựa chọn triển khai
ADK hỗ trợ nhiều mục tiêu triển khai. Mỗi loại có các đặc điểm khác nhau về độ phức tạp, quản lý phiên, khả năng mở rộng và chi phí:
Yếu tố | Địa phương ( | Agent Engine | Cloud Run |
Độ phức tạp | Tối giản | Thấp | Trung bình |
Tính năng duy trì phiên | Chỉ trong bộ nhớ (mất khi khởi động lại) | Vertex AI được quản lý (tự động) | Cloud SQL (PostgreSQL) hoặc trong bộ nhớ |
Cơ sở hạ tầng | Không có (chỉ dành cho máy phát triển) | Được quản lý đầy đủ | Vùng chứa + cơ sở dữ liệu không bắt buộc |
Khởi động nguội | Không áp dụng | 100 – 500 mili giây | 100 – 2000 mili giây |
Điều chỉnh tỷ lệ | Một phiên bản | Tự động | Tự động (về 0) |
Mô hình chi phí | Miễn phí (tính toán cục bộ) | Dựa trên điện toán | Dựa trên yêu cầu + bậc miễn phí |
Hỗ trợ giao diện người dùng | Có (được tích hợp sẵn) | Không (chỉ có API) | Có (thông qua cờ |
Thiết lập khả năng quan sát | Trình xem dấu vết cục bộ | Tự động bằng | Yêu cầu phải có cờ |
Phù hợp nhất cho | Phát triển và kiểm thử | Production agents | Production agents |
Đề xuất: Đối với hệ thống quyên góp đáng tin cậy này, bạn nên sử dụng Agent Engine làm hoạt động triển khai sản xuất chính vì hệ thống này cung cấp:
- Cơ sở hạ tầng được quản lý toàn diện (không cần quản lý vùng chứa)
- Tính năng duy trì phiên tích hợp thông qua
VertexAiSessionService - Tự động mở rộng quy mô mà không cần khởi động nguội
- Triển khai đơn giản (không cần kiến thức về Docker)
- Tích hợp Cloud Trace ngay từ đầu
Lựa chọn bổ sung: Google Kubernetes Engine (GKE)
Đối với những người dùng nâng cao cần quyền kiểm soát ở cấp độ Kubernetes, mạng tuỳ chỉnh hoặc điều phối nhiều dịch vụ, bạn có thể sử dụng việc triển khai GKE. Lựa chọn này mang lại tính linh hoạt tối đa nhưng đòi hỏi bạn phải có nhiều kinh nghiệm vận hành hơn (quản lý cụm, tệp kê khai, tài khoản dịch vụ).
Việc triển khai GKE không được đề cập trong lớp học lập trình này nhưng được ghi lại đầy đủ trong Hướng dẫn triển khai ADK GKE.
Điều kiện tiên quyết
1. Thiết lập dự án trên Google Cloud
Bạn cần có một dự án trên Google Cloud đã bật tính năng thanh toán. Nếu bạn chưa có:
- Tạo một dự án: Google Cloud Console
- Bật tính năng thanh toán: Bật tính năng thanh toán
- Ghi lại Mã dự án (không phải tên hoặc số dự án)
2. Xác thực lại (Không bắt buộc)
Xác thực bằng Google Cloud:
gcloud auth application-default login
gcloud config set project YOUR_PROJECT_ID
Thay thế YOUR_PROJECT_ID bằng mã dự án thực tế của bạn trên Google Cloud.
Xác minh thông tin xác thực của bạn:
gcloud config get-value project
# Should output: YOUR_PROJECT_ID
3. Biến môi trường
Sử dụng các lệnh sau để tự động điền vào tệp .env:
# Get your current Project ID
PROJECT_ID=$(gcloud config get-value project)
STAGING_BUCKET_VALUE="gs://${PROJECT_ID}-staging"
ENV_FILE=".env"
# Check if STAGING_BUCKET is already set in the .env file
if grep -q "^STAGING_BUCKET=" "${ENV_FILE}"; then
# If it exists, replace the line
# The sed command finds the line starting with STAGING_BUCKET= and replaces the entire line.
# Using | as a delimiter to avoid issues with slashes in the bucket name.
sed -i "s|^STAGING_BUCKET=.*|STAGING_BUCKET=${STAGING_BUCKET_VALUE}|" "${ENV_FILE}"
echo "Updated STAGING_BUCKET in ${ENV_FILE}"
else
# If it doesn't exist, add it to the end of the file
echo "STAGING_BUCKET=${STAGING_BUCKET_VALUE}" >> "${ENV_FILE}"
echo "Added STAGING_BUCKET to ${ENV_FILE}"
fi
# Verify it was added or updated correctly
echo "Current STAGING_BUCKET setting:"
grep "^STAGING_BUCKET=" "${ENV_FILE}"
Bạn sẽ thấy:
STAGING_BUCKET=gs://your-actual-project-id-staging
Lưu ý quan trọng:
- Thay thế
YOUR_PROJECT_IDbằng mã dự án thực tế của bạn (hoặc sử dụng các lệnh ở trên) - Đối với
GOOGLE_CLOUD_LOCATION, hãy sử dụng khu vực được hỗ trợ - Thùng lưu trữ tạm thời sẽ được tạo tự động nếu chưa tồn tại khi bạn chạy tập lệnh triển khai
4. Bật các API bắt buộc
Quá trình triển khai cần bật một số API Google Cloud. Chạy lệnh này để bật các tính năng đó:
gcloud services enable \
aiplatform.googleapis.com \
storage.googleapis.com \
cloudbuild.googleapis.com \
cloudtrace.googleapis.com \
compute.googleapis.com
Lệnh này cho phép:
- AI Platform API – Dành cho Agent Engine và các mô hình Vertex AI
- Cloud Storage API – Đối với vùng lưu trữ tạm thời
- Cloud Build API – Để tạo vùng chứa (Cloud Run)
- Cloud Trace API – Để theo dõi và ghi lại nhật ký hoạt động
- Compute Engine API – Để quản lý tài khoản dịch vụ
Bước 1: Tìm hiểu về Cơ sở hạ tầng triển khai
Dự án của bạn có một tập lệnh triển khai hợp nhất (deploy.sh) xử lý tất cả các chế độ triển khai.
👉 Xem xét tập lệnh triển khai (không bắt buộc):
cat deploy.sh
Tập lệnh này cung cấp 3 chế độ triển khai:
./deploy.sh local– Chạy cục bộ bằng bộ nhớ trong./deploy.sh agent-engine– Triển khai cho Vertex AI Agent Engine (nên dùng)./deploy.sh cloud-run– Triển khai lên Cloud Run bằng giao diện người dùng không bắt buộc
Cách hoạt động của tính năng này:
Đối với việc triển khai Agent Engine, tập lệnh sẽ thực thi:
adk deploy agent_engine \
--project=$GOOGLE_CLOUD_PROJECT \
--region=$GOOGLE_CLOUD_LOCATION \
--staging_bucket=$STAGING_BUCKET \
--display_name="Charity Advisor" \
--trace_to_cloud \
charity_advisor
Đối với việc triển khai Cloud Run, lệnh này sẽ thực thi:
adk deploy cloud_run \
--project=$GOOGLE_CLOUD_PROJECT \
--region=$GOOGLE_CLOUD_LOCATION \
--service_name="charity-advisor" \
--app_name="charity_advisor" \
--with_ui \
--trace_to_cloud \
charity_advisor
Cờ --trace_to_cloud là yếu tố quan trọng đối với cả hai loại triển khai. Cờ này cho phép tích hợp Cloud Trace cho nhật ký hoạt động mà bạn sẽ khám phá trong Mô-đun 9.
Bước 2: Chuẩn bị Trình bao bọc công cụ tác nhân
Agent Engine yêu cầu một điểm truy cập cụ thể bao bọc tác nhân của bạn cho thời gian chạy được quản lý. Tệp này đã được tạo cho bạn.
👉 Xem lại
charity_advisor/agent_engine_app.py
:
"""Agent Engine application wrapper.
This file prepares the Charity Advisor agent for deployment to Vertex AI Agent Engine.
"""
from vertexai import agent_engines
from .agent import root_agent
# Wrap the agent in an AdkApp object for Agent Engine deployment
app = agent_engines.AdkApp(
agent=root_agent,
enable_tracing=True, # Enables Cloud Trace integration automatically
)
Lý do cần có tệp này:
- Agent Engine yêu cầu nhân viên hỗ trợ được gói trong một đối tượng
AdkApp - Tham số
enable_tracing=Truetự động bật chế độ tích hợp Cloud Trace - Trình bao bọc này được ADK CLI tham chiếu trong quá trình triển khai
- Thao tác này định cấu hình
VertexAiSessionServiceđể duy trì phiên tự động
Bước 3: Triển khai cho Agent Engine (NÊN DÙNG)
Agent Engine là quy trình triển khai sản xuất được đề xuất cho hệ thống quyên góp đáng tin cậy của bạn vì quy trình này cung cấp cơ sở hạ tầng được quản lý hoàn toàn với khả năng duy trì phiên tích hợp.
Chạy quá trình triển khai
Từ thư mục gốc của dự án:
chmod +x deploy.sh
./deploy.sh agent-engine
Giai đoạn triển khai
Xem tập lệnh thực thi các giai đoạn sau:
Phase 1: API Enablement
✓ aiplatform.googleapis.com
✓ storage.googleapis.com
✓ cloudbuild.googleapis.com
✓ cloudtrace.googleapis.com
✓ compute.googleapis.com
Phase 2: IAM Setup
✓ Getting project number
✓ Granting Storage Object Admin
✓ Granting Vertex AI User
✓ Granting Cloud Trace Agent
Phase 3: Staging Bucket
✓ Creating gs://your-project-id-staging (if needed)
✓ Setting permissions
Phase 4: Validation
✓ Checking agent.py exists
✓ Verifying root_agent defined
✓ Checking agent_engine_app.py exists
✓ Validating requirements.txt
Phase 5: Build & Deploy
✓ Packaging agent code
✓ Uploading to staging bucket
✓ Creating Agent Engine instance
✓ Configuring session persistence
✓ Setting up Cloud Trace integration
✓ Running health checks
Quá trình này mất 5 đến 10 phút vì quá trình này đóng gói tác nhân và triển khai tác nhân đó vào cơ sở hạ tầng Vertex AI.
Lưu mã nhận dạng công cụ của tác nhân
Sau khi triển khai thành công:
✅ Agent Engine created successfully!
Agent Engine ID: 7917477678498709504
Resource Name: projects/123456789/locations/us-central1/reasoningEngines/7917477678498709504
Endpoint: https://us-central1-aiplatform.googleapis.com/v1/...
⚠️ IMPORTANT: Save the Agent Engine ID from the output above
Add it to your .env file as:
AGENT_ENGINE_ID=7917477678498709504
This ID is required for:
- Testing the deployed agent
- Updating the deployment later
- Accessing logs and traces
Cập nhật ngay tệp .env:
echo "AGENT_ENGINE_ID=7917477678498709504" >> .env
Nội dung đã triển khai
Việc triển khai Agent Engine hiện bao gồm:
✅ Cả 3 tác nhân (Mua sắm, Người bán, Thông tin đăng nhập) đều chạy trong thời gian chạy được quản lý
✅ Hoàn tất logic chuỗi thông tin đăng nhập (Ý định → Giỏ hàng → Yêu cầu thanh toán)
✅ Cơ chế đồng ý của người dùng với quy trình xác nhận
✅ Tính năng duy trì phiên tự động thông qua VertexAiSessionService
✅ Cơ sở hạ tầng tự động mở rộng quy mô do Google quản lý
✅ Tích hợp Cloud Trace để có khả năng quan sát hoàn toàn
Bước 4: Kiểm thử tác nhân đã triển khai
Cập nhật môi trường
Xác minh rằng .env có Mã Agent Engine:
AGENT_ENGINE_ID=7917477678498709504 # From deployment output
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=us-central1
STAGING_BUCKET=gs://your-project-id-staging
Chạy tập lệnh kiểm thử
Dự án của bạn có một tập lệnh kiểm thử dành riêng cho việc triển khai Agent Engine.
👉 Chạy kiểm thử:
python scripts/test_deployed_agent.py
Kết quả đầu ra dự kiến
Testing Agent Engine deployment...
Project: your-project-id
Location: us-central1
Agent Engine ID: 7917477678498709504
Endpoint: https://us-central1-aiplatform.googleapis.com/v1/...
Creating session...
✓ Session created: 4857885913439920384
Sending donation query...
✓ Response received:
Event 1: I'll help you donate $50 to a children's education charity...
Event 2: Here are some highly-rated children's education charities...
Event 3: Which charity would you like to support?...
✅ Test completed successfully!
Session ID: 4857885913439920384
This donation generated a trace in Cloud Trace.
View it in Module 9: Observability
To view traces:
https://console.cloud.google.com/traces/list?project=your-project-id
Danh sách kiểm tra quy trình xác minh
Sau khi kiểm thử, hãy xác minh:
✅ Nhân viên hỗ trợ phản hồi các câu hỏi
✅ Cả 3 nhân viên hỗ trợ đều thực hiện theo trình tự (Mua sắm → Người bán → Thông tin đăng nhập)
✅ Cơ chế đồng ý được kích hoạt (yêu cầu xác nhận)
✅ Phiên vẫn duy trì trong các yêu cầu
✅ Không có lỗi xác thực
✅ Không có lỗi hết thời gian chờ kết nối
Nếu bạn gặp lỗi:
- Kiểm tra để đảm bảo bạn đã thiết lập đúng các biến môi trường
- Xác minh rằng các API đã được bật:
gcloud services list --enabled - Kiểm tra nhật ký Agent Engine trong Bảng điều khiển Vertex AI
- Xác minh rằng tệp
agent_engine_app.pycó trong thư mụccharity_advisor
Bước 5: Triển khai lên Cloud Run (Không bắt buộc)
Mặc dù Agent Engine được đề xuất để đơn giản hoá việc triển khai sản xuất, nhưng Cloud Run mang lại nhiều quyền kiểm soát hơn và hỗ trợ giao diện người dùng web ADK. Phần này là không bắt buộc.
Trường hợp nên dùng Cloud Run
Chọn Cloud Run nếu bạn cần:
- Giao diện người dùng web ADK để người dùng tương tác
- Toàn quyền kiểm soát môi trường vùng chứa
- Cấu hình cơ sở dữ liệu tuỳ chỉnh
- Tích hợp với các dịch vụ Cloud Run hiện có
Chạy quá trình triển khai
chmod +x deploy.sh
./deploy.sh cloud-run
Điểm khác biệt:
Tập lệnh sẽ tự động:
- Tạo một vùng chứa Docker bằng mã tác nhân của bạn
- Tạo cơ sở dữ liệu Cloud SQL PostgreSQL (nếu cần)
- Định cấu hình kết nối cơ sở dữ liệu
- Triển khai khi giao diện người dùng web ADK đang bật
Quá trình triển khai mất 10 đến 15 phút do việc cung cấp Cloud SQL.
Quản lý phiên:
- Sử dụng
DatabaseSessionServicethay vìVertexAiSessionService - Cần có thông tin đăng nhập cơ sở dữ liệu trong
.env(hoặc được tạo tự động) - Trạng thái vẫn duy trì trong cơ sở dữ liệu PostgreSQL
Hỗ trợ giao diện người dùng:
- Giao diện người dùng trên web có tại:
https://charity-advisor-xyz.a.run.app
Kiểm thử việc triển khai Cloud Run
Nếu đã triển khai lên Cloud Run bằng --with_ui, bạn có thể kiểm thử ngay trong trình duyệt:
- Chuyển đến URL dịch vụ (có trong đầu ra triển khai)
- Bạn sẽ thấy giao diện web ADK. Chọn nhân viên hỗ trợ trong trình đơn thả xuống.
- Bắt đầu quy trình quyên góp thử:
I want to donate $50 to a children's education charity
- Quan sát quy trình thực thi:
- ShoppingAgent tìm các tổ chức từ thiện và lưu ý định của bạn
- MerchantAgent tạo giấy uỷ quyền cho giỏ hàng
- CredentialsProvider tạo uỷ quyền thanh toán và yêu cầu xác nhận
- Sau khi bạn xác nhận, giao dịch thanh toán sẽ được xử lý
- Xác minh rằng phản hồi bao gồm:
- Đề xuất về tổ chức từ thiện
- Yêu cầu xác nhận
- Thông báo thành công sau khi phê duyệt
Khắc phục sự cố
Các vấn đề thường gặp
Vấn đề: ERROR: GOOGLE_CLOUD_PROJECT is not set
Giải pháp: Đảm bảo tệp .env của bạn có mã dự án chính xác:
GOOGLE_CLOUD_PROJECT=your-actual-project-id
Vấn đề: Bộ chứa dàn dựng không được tạo tự động
Giải pháp: Tập lệnh sẽ tự động tạo vùng chứa. Nếu không, hãy tạo đối tượng theo cách thủ công:
gsutil mb -p $GOOGLE_CLOUD_PROJECT -l $GOOGLE_CLOUD_LOCATION $STAGING_BUCKET
Tóm tắt
Bạn đã:
✅ Hiểu rõ cơ sở hạ tầng triển khai do deploy.sh
cung cấp ✅ Xem xét cấu hình trình bao bọc Agent Engine
✅ Triển khai hệ thống quyên góp đáng tin cậy của bạn cho Agent Engine (nên dùng)
✅ Bật tính năng tích hợp Cloud Trace với --trace_to_cloud
✅ Xác minh rằng nhân viên hỗ trợ có thể truy cập và hoạt động được
✅ Tạo nền tảng cho nhật ký hoạt động trong Mô-đun 9
Trong mô-đun tiếp theo, bạn sẽ thấy chính xác những gì mà cờ này mở khoá: khả năng hiển thị đầy đủ mọi khoản quyên góp, mọi thời điểm có sự đồng ý và mọi bước trong chuỗi thông tin đăng nhập.
9. Khả năng ghi nhận


Trong Mô-đun 1, bạn đã tìm hiểu về một vấn đề cơ bản: khi một tác nhân AI xử lý tiền, làm cách nào để chứng minh những gì đã xảy ra?
Người dùng có thể xác nhận quyền sở hữu:
- "Tôi chưa bao giờ chọn tổ chức từ thiện đó!"
- "Tôi không cho phép thanh toán khoản đó!"
- "Hệ thống đã tính phí tôi mà tôi không hề đồng ý!"
Trong hệ thống AI hộp đen truyền thống, bạn sẽ không có cách nào để chứng minh điều ngược lại. Nhưng hệ thống quyên góp đáng tin cậy của bạn thì khác. Trong Mô-đun 8, bạn đã triển khai bằng cờ --trace_to_cloud, tức là mọi khoản quyên góp hiện tạo ra một nhật ký kiểm tra đầy đủ, chống giả mạo trong Cloud Trace.
Mô-đun này hướng dẫn bạn cách đọc những dấu vết đó và sử dụng chúng làm bằng chứng. Bạn sẽ tìm hiểu cách:
- Chuyển đến Cloud Trace Explorer để tìm dấu vết sản xuất
- Đọc chế độ xem thác nước để hiểu luồng thực thi
- Tìm chuỗi thông tin đăng nhập (Ý định → Giỏ hàng → Uỷ quyền thanh toán)
- Xác định thời điểm đồng ý bằng bằng chứng có dấu thời gian
- Sử dụng dấu vết để giải quyết tranh chấp
- Xuất dấu vết để tuân thủ và kiểm tra
Đây là điểm phân biệt giữa các hệ thống đáng tin cậy và các hệ thống có khả năng nhưng không minh bạch: khả năng chứng minh những gì đã xảy ra với độ chính xác pháp lý.
Tìm hiểu về dấu vết và khoảng thời gian
Trước khi xem dấu vết trong Cloud Trace, bạn cần hiểu rõ những gì mình đang xem.
Vết tích là gì?
Dấu vết là dòng thời gian hoàn chỉnh về cách mà tác nhân của bạn xử lý một yêu cầu duy nhất. Sự kiện này ghi lại mọi thứ, từ thời điểm người dùng gửi một truy vấn cho đến khi nhận được phản hồi cuối cùng.
Mỗi dấu vết cho thấy:
- Tổng thời lượng của yêu cầu
- Tất cả các thao tác đã thực hiện
- Mối quan hệ giữa các thao tác (mối quan hệ mẹ con)
- Thời điểm bắt đầu và kết thúc mỗi thao tác
- Trạng thái thành công hoặc không thành công
Đối với nhân viên hỗ trợ của tổ chức từ thiện: Một lượt theo dõi = một quy trình quyên góp hoàn chỉnh từ "Tôi muốn quyên góp" đến "Thanh toán thành công".
Khoảng thời gian là gì?
Khoảng thời gian biểu thị một đơn vị công việc trong một dấu vết. Hãy coi khoảng thời gian là các khối dựng của một dấu vết.
Các loại khoảng thời gian phổ biến trong hệ thống quyên góp của bạn:
Loại khoảng | Ý nghĩa | Ví dụ: |
| Thực thi tác nhân |
|
| Yêu cầu đối với mô hình ngôn ngữ |
|
| Thực thi hàm công cụ |
|
| Đọc từ bộ nhớ phiên | Truy xuất |
| Ghi vào bộ nhớ phiên | Lưu trữ |
Mỗi khoảng thời gian chứa:
- Tên: Thao tác mà chỉ số này đại diện
- Thời gian thực hiện (thời gian bắt đầu → thời gian kết thúc)
- Thuộc tính: Siêu dữ liệu như dữ liệu đầu vào của công cụ, câu trả lời của mô hình, số lượng mã thông báo
- Trạng thái: Thành công (
OK) hoặc lỗi (ERROR) - Mối quan hệ mẹ con: Thao tác nào kích hoạt thao tác nào
Cách các khoảng thời gian tạo thành một dấu vết
Các khoảng thời gian lồng vào nhau để cho thấy mối quan hệ nhân quả:
Root Span: CharityAdvisor.run (entire request)
└─ Child: DonationPipeline.run (sequential workflow)
├─ Child: ShoppingAgent.run
│ ├─ Grandchild: call_llm (Gemini processes charity search)
│ ├─ Grandchild: execute_tool (find_charities)
│ └─ Grandchild: execute_tool (save_user_choice)
├─ Child: MerchantAgent.run
│ ├─ Grandchild: call_llm (Gemini generates cart)
│ └─ Grandchild: execute_tool (create_cart_mandate)
└─ Child: CredentialsProvider.run
├─ Grandchild: call_llm (Gemini processes payment)
└─ Grandchild: execute_tool (create_payment_mandate) [CONSENT!]
Hệ thống phân cấp này cho biết chính xác những gì đã xảy ra và theo thứ tự nào. Bạn có thể thấy rằng yêu cầu uỷ quyền thanh toán được tạo sau yêu cầu uỷ quyền giỏ hàng, tức là sau khi người dùng chọn một tổ chức từ thiện.
Bước 1: Truy cập vào Cloud Trace Explorer
Bây giờ, hãy xem các dấu vết thực tế từ tác nhân đã triển khai của bạn.
Chuyển đến Cloud Trace
- Mở Google Cloud Console: console.cloud.google.com
- Chọn dự án của bạn trong trình đơn thả xuống ở trên cùng (sẽ được chọn trước nếu bạn đang làm việc trong dự án đó)
- Chuyển đến Cloud Trace Explorer:
- Trong thanh bên trái, hãy di chuyển đến phần Khả năng quan sát
- Nhấp vào Trace (Theo dõi)
- Hoặc sử dụng đường liên kết trực tiếp: console.cloud.google.com/traces/list
Nội dung bạn đang xem
Trình khám phá dấu vết cho thấy danh sách tất cả dấu vết trong dự án của bạn:
Cột | Nội dung hiển thị |
Yêu cầu | Phương thức và điểm cuối HTTP (đối với các yêu cầu API) |
Thời gian bắt đầu | Thời điểm bắt đầu yêu cầu |
Độ trễ | Tổng thời lượng của yêu cầu |
Khoảng | Số lượng thao tác trong dấu vết |
Mỗi hàng đại diện cho một yêu cầu hoàn chỉnh đối với tác nhân đã triển khai của bạn.
Tạo dấu vết kiểm thử (nếu cần)
Nếu bạn chưa thấy dấu vết nào, thì danh sách có thể trống vì:
- Chưa có yêu cầu nào được gửi đến tác nhân bạn đã triển khai
- Dấu vết mất từ 1 đến 2 phút để xuất hiện sau một yêu cầu
Tạo dấu vết kiểm thử:
Nếu bạn triển khai vào Cloud Run bằng giao diện người dùng, hãy truy cập vào URL dịch vụ của bạn và hoàn tất quy trình quyên góp trong trình duyệt.
Nếu bạn triển khai cho Agent Engine, hãy chạy tập lệnh kiểm thử từ Mô-đun 8:
python scripts/test_deployed_agent.py
Đợi 1 đến 2 phút, sau đó làm mới trang Cloud Trace Explorer. Lúc này, bạn sẽ thấy các dấu vết.
Lọc dấu vết
Sử dụng các lựa chọn lọc ở trên cùng để tìm các dấu vết cụ thể:
- Phạm vi thời gian: Thay đổi từ "Một giờ qua" thành "24 giờ qua" nếu cần
- Độ trễ tối thiểu / Độ trễ tối đa: Lọc các yêu cầu chậm
- Bộ lọc yêu cầu: Tìm kiếm theo các thao tác cụ thể (ví dụ: "DonationPipeline")
Đối với mô-đun này, hãy tập trung vào các dấu vết có thời lượng dài hơn (>5 giây), vì đây là những dấu vết đại diện cho quy trình quyên góp hoàn chỉnh với cả 3 tác nhân đang thực thi.
Bước 2: Kiểm tra quy trình quyên góp hoàn chỉnh
Nhấp vào một dấu vết bất kỳ trong danh sách để mở chế độ xem thác nước. Đây là nơi bạn sẽ dành phần lớn thời gian để phân tích hành vi của nhân viên hỗ trợ.
Tìm hiểu về Chế độ xem thác nước
Chế độ xem thác nước là một biểu đồ Gantt cho thấy toàn bộ dòng thời gian thực thi:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Timeline (horizontal = time) →
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invocation ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 8.2s
agent_run: CharityAdvisor ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 8.1s
agent_run: DonationPipeline ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 7.9s
agent_run: ShoppingAgent ▓▓▓▓▓▓ 2.1s
call_llm: gemini-2.5-flash ▓▓▓▓ 1.2s
execute_tool: find_charities ▓▓ 0.5s
execute_tool: save_user_choice ▓ 0.3s
agent_run: MerchantAgent ▓▓▓ 1.8s
call_llm: gemini-2.5-flash ▓▓ 0.9s
execute_tool: create_cart_mandate ▓ 0.7s
agent_run: CredentialsProvider ▓▓▓▓▓▓▓▓ 4.0s
call_llm: gemini-2.5-flash ▓▓ 0.8s
execute_tool: create_payment_mandate ▓▓▓▓▓ 3.0s [CONSENT]
Đọc biểu đồ
Mỗi thanh đại diện cho một khoảng thời gian:
- Vị trí ngang: Thời điểm bắt đầu
- Độ dài: Thời gian diễn ra
- Thụt lề: Cho biết mối quan hệ chính-phụ
- Màu sắc: Thường là màu xanh dương cho trạng thái bình thường, màu đỏ cho lỗi
Các điểm quan sát chính từ dấu vết ví dụ này:
✅ Tổng thời lượng: 8,2 giây
✅ Thực thi tuần tự: ShoppingAgent hoàn tất trước khi MerchantAgent bắt đầu
✅ MerchantAgent hoàn tất
trước
CredentialsProvider đã bắt đầu
✅ Thao tác lâu nhất là thao tác Đồng ý: 3 giây cho create_payment_mandate (vì thao tác này đợi người dùng xác nhận)
✅ Các lệnh gọi LLM đều hiển thị: Mỗi tác nhân thực hiện một yêu cầu Gemini
✅ Các lệnh gọi công cụ đều được ghi lại: Cả 6 công cụ đều thực thi thành công
Hình ảnh này cho bạn biết ngay thời gian đã dùng ở đâu và thứ tự thực hiện các thao tác.
Nhấp vào một khoảng thời gian để xem thông tin chi tiết
Nhấp vào khoảng thời gian invocation (khoảng thời gian gốc ở trên cùng). Trong bảng điều khiển bên phải, bạn sẽ thấy các thuộc tính chi tiết:
{
"http.method": "POST",
"http.status_code": 200,
"http.url": "https://charity-advisor-xyz.a.run.app/api/run",
"user_id": "test_user_123",
"session_id": "4857885913439920384",
"trace_id": "a1b2c3d4e5f6...",
"span_id": "1234567890abcdef"
}
Các thuộc tính này cung cấp bối cảnh về toàn bộ yêu cầu.
Bước 3: Tìm Chuỗi chứng chỉ
Hệ thống đáng tin cậy của bạn sử dụng một chuỗi thông tin đăng nhập để chứng minh quyền uỷ quyền ở mỗi bước:
IntentMandate (User chose charity)
↓
CartMandate (Merchant created cart, signed IntentMandate)
↓
PaymentMandate (Payment provider created payment, signed CartMandate)
Hãy tìm từng lệnh trong dấu vết.
Tìm IntentMandate
Nhấp vào khoảng execute_tool: save_user_choice (trong ShoppingAgent).
Trong bảng thuộc tính, bạn sẽ thấy:
{
"tool.name": "save_user_choice",
"tool.input.charity_name": "Save the Children",
"tool.input.amount": 50,
"tool.output.status": "success",
"tool.output.intent_mandate": {
"charity_name": "Save the Children",
"amount": 50,
"timestamp": "2024-11-08T15:30:12.345Z",
"signature": "a3f7b9c1d2e4..."
}
}
Điều này chứng minh rằng:
- ✅ Người dùng chọn "Tổ chức Cứu lấy trẻ em"
- ✅ Số tiền là 50 đô la
- ✅ Lựa chọn được ghi lại lúc 15:30:12 UTC
- ✅ Chữ ký đã được tạo (trong thực tế, chữ ký này sẽ được mã hoá)
IntentMandate hiện ở trạng thái phiên và có sẵn cho các tác nhân tiếp theo.
Tìm CartMandate
Nhấp vào khoảng execute_tool: create_cart_mandate (trong MerchantAgent).
Trong bảng thuộc tính:
{
"tool.name": "create_cart_mandate",
"tool.input.intent_mandate": {
"charity_name": "Save the Children",
"amount": 50,
"signature": "a3f7b9c1d2e4..."
},
"tool.output.status": "success",
"tool.output.cart_mandate": {
"cart_id": "cart_7893",
"intent_signature": "a3f7b9c1d2e4...",
"cart_signature": "e8f2a9b3c7d1...",
"timestamp": "2024-11-08T15:30:14.789Z"
}
}
Điều này chứng minh rằng:
- ✅ MerchantAgent đã nhận được IntentMandate (đầu vào cho thấy điều đó)
- ✅ Giỏ hàng đã được tạo với mã "cart_7893"
- ✅ Chữ ký giỏ hàng tham chiếu đến chữ ký IntentMandate (chuỗi liên kết!)
- ✅ Được tạo lúc 15:30:14 UTC (2,4 giây sau ý định)
CartMandate hiện tham chiếu đến IntentMandate, tạo thành chuỗi.
Tìm PaymentMandate
Nhấp vào khoảng execute_tool: create_payment_mandate (trong CredentialsProvider).
Trong bảng thuộc tính:
{
"tool.name": "create_payment_mandate",
"tool.input.cart_mandate": {
"cart_id": "cart_7893",
"intent_signature": "a3f7b9c1d2e4...",
"cart_signature": "e8f2a9b3c7d1..."
},
"tool.confirmation_required": true,
"tool.confirmation_timestamp": "2024-11-08T15:30:17.891Z",
"tool.user_response": "CONFIRMED",
"tool.wait_duration_ms": 29168,
"tool.output.status": "success",
"tool.output.payment_mandate": {
"payment_id": "pay_9821",
"cart_signature": "e8f2a9b3c7d1...",
"payment_signature": "b4c9e2a7f8d3...",
"timestamp": "2024-11-08T15:30:47.059Z"
}
}
Điều này chứng minh toàn bộ chuỗi:
- ✅ CredentialsProvider đã nhận được CartMandate (đầu vào cho thấy điều đó)
- ✅ Khoản thanh toán tham chiếu đến chữ ký CartMandate (chuỗi liên kết!)
- ✅ Cần xác nhận (
confirmation_required: true) - ✅ Người dùng xác nhận lúc 15:30:17 UTC
- ✅ Hệ thống đã chờ 29,2 giây để người dùng đưa ra quyết định
- ✅ Khoản thanh toán được tạo sau khi xác nhận (dấu thời gian: 15:30:47)
Trực quan hoá chuỗi
Dấu vết này chứng minh rằng chuỗi thông tin đăng nhập đã thực thi chính xác:
15:30:12 UTC → IntentMandate created (signature: a3f7...)
↓
15:30:14 UTC → CartMandate created (references: a3f7...)
↓
15:30:17 UTC → User consent requested
↓
15:30:47 UTC → PaymentMandate created (references: e8f2...)
Mỗi uỷ quyền đều tham chiếu chữ ký của uỷ quyền trước đó. Đây là bằng chứng chống giả mạo – bạn có thể xác minh chuỗi bằng cách kiểm tra xem các chữ ký có khớp hay không.
Bước 4: Phân tích hiệu suất và các điểm tắc nghẽn
Cloud Trace không chỉ chứng minh những gì đã xảy ra mà còn cho bạn biết thời gian đã được sử dụng ở đâu để bạn có thể tối ưu hoá.
Xác định đường dẫn quan trọng
Trong chế độ xem thác nước, hãy tìm khoảng thời gian dài nhất trong ngăn xếp dọc. Đây là những nút thắt cổ chai về hiệu suất.
Từ dấu vết ví dụ của chúng tôi:
Total: 8.2 seconds
Breakdown:
- ShoppingAgent: 2.1s (26%)
- MerchantAgent: 1.8s (22%)
- CredentialsProvider: 4.0s (49%) ← Bottleneck
- Other overhead: 0.3s (3%)
Thông tin chi tiết quan trọng: CredentialsProvider chiếm 49% tổng thời gian. Tại sao?
Đi sâu vào khoảng CredentialsProvider:
CredentialsProvider: 4.0s
- call_llm: 0.8s (20%)
- create_payment_mandate: 3.0s (75%) ← User consent wait
- Other: 0.2s (5%)
Độ trễ 3 giây là điều bình thường và chấp nhận được – đó là khoảng thời gian người dùng cân nhắc trước khi xác nhận. Đây không phải là vấn đề về hiệu suất mà là bằng chứng cho thấy người dùng đã cân nhắc kỹ trước khi đồng ý.
Theo dõi chi phí LLM
Nhấp vào bất kỳ khoảng call_llm nào để xem mức sử dụng mã thông báo:
{
"llm.model": "gemini-2.5-flash",
"llm.usage.prompt_tokens": 487,
"llm.usage.completion_tokens": 156,
"llm.usage.total_tokens": 643,
"llm.response_time_ms": 1243
}
Hãy sử dụng API này để:
- Theo dõi chi phí cho mỗi yêu cầu (số lượng mã thông báo × giá mô hình)
- Xác định những câu lệnh dài không cần thiết
- So sánh hiệu suất của mô hình (Flash so với Pro)
- Tối ưu hoá độ trễ so với chất lượng
Ví dụ về cách tính:
Gemini 2.5 Flash pricing (as of Nov 2024):
Input: $0.075 per 1M tokens
Output: $0.30 per 1M tokens
This request:
Input: 487 tokens × $0.075 / 1M = $0.000037
Output: 156 tokens × $0.30 / 1M = $0.000047
Total: = $0.000084 (~$0.00008)
For 10,000 donations/month:
10,000 × 3 agents × $0.00008 = $2.40/month in LLM costs
Thông tin chi tiết này giúp bạn đưa ra quyết định dựa trên dữ liệu về việc chọn mô hình.
So sánh trên nhiều dấu vết
Lọc nhiều dấu vết và so sánh thời lượng:
Trace 1: 8.2s (with consent wait: 3.0s)
Trace 2: 12.5s (with consent wait: 7.8s) ← User took longer
Trace 3: 5.1s (with consent wait: 0.2s) ← User clicked fast
Trace 4: 6.3s (with consent wait: 1.5s)
Thông tin chi tiết: Hầu hết sự khác biệt đến từ thời gian đưa ra quyết định của người dùng, chứ không phải hiệu suất hệ thống. Việc thực thi tác nhân cốt lõi (trừ sự đồng ý) diễn ra nhất quán trong khoảng 5 giây.
Điều này cho biết hệ thống đang hoạt động ổn định.
Đối với các hệ thống sản xuất, hãy thiết lập cảnh báo để phát hiện các vấn đề trước khi người dùng phàn nàn.
Cảnh báo về tỷ lệ lỗi cao
Tạo cảnh báo khi có hơn 5% dấu vết chứa lỗi:
- Chuyển đến Cloud Monitoring
- Nhấp vào "Cảnh báo" → "Tạo chính sách"
- Định cấu hình:
Resource: Cloud Trace Span Metric: Span error count Condition: Rate > 5% over 5 minutes Notification: Email your-team@example.com
Cảnh báo về độ trễ cao
Tạo cảnh báo khi độ trễ p95 vượt quá 15 giây:
Resource: Cloud Trace
Metric: Span duration (95th percentile)
Condition: > 15000ms for 5 minutes
Notification: PagerDuty
Điều này giúp phát hiện tình trạng giảm hiệu suất trước khi ảnh hưởng đến trải nghiệm người dùng.
Cảnh báo khi thiếu sự đồng ý
Tạo cảnh báo nếu có quy trình thanh toán nào không có bước xác nhận:
Resource: Cloud Trace Span
Filter: tool.name="create_payment_mandate" AND tool.confirmation_required!=true
Condition: Any match
Notification: Critical alert to security team
Đây là trình phát hiện vi phạm an toàn – nếu trình này kích hoạt, tức là cơ chế đồng ý của bạn có vấn đề nghiêm trọng.
Kiến thức bạn học được
Thông qua Cloud Trace, giờ đây bạn đã hiểu cách:
✅ Điều hướng Cloud Trace Explorer để tìm dấu vết sản xuất
✅ Đọc chế độ xem thác nước để xem quy trình thực thi hoàn chỉnh
✅ Theo dõi chuỗi thông tin đăng nhập thông qua IntentMandate → CartMandate → PaymentMandate ✅ Sử dụng dấu vết làm bằng chứng để giải quyết tranh chấp
✅ Phân tích hiệu suất để xác định các điểm tắc nghẽn
✅ Theo dõi chi phí LLM ở mức độ chi tiết
Sự khác biệt mà điều này tạo ra
So sánh 2 hệ thống xử lý cùng một khiếu nại "Tôi chưa bao giờ uỷ quyền việc này!":
Hệ thống không có khả năng ghi nhận
User: "I never authorized that $50 donation!"
You: "Our logs show the transaction completed successfully."
User: "But I didn't approve it!"
You: "The system requires confirmation before processing."
User: "I never saw any confirmation!"
You: "..." [no way to prove what happened]
Result: Refund issued, trust lost, user never returns.
Hệ thống có Cloud Trace
User: "I never authorized that $50 donation!"
You: "Let me pull up the trace from your session..."
[Shows waterfall with consent span]
You: "Here's the evidence:
- 15:30:17 UTC: System asked for confirmation
- Message shown: 'You are about to donate $50...'
- 15:30:47 UTC: You clicked 'CONFIRM'
- Wait time: 29.2 seconds
The system waited almost 30 seconds for your decision.
Here's the exact timestamp of your confirmation."
User: "Oh... I remember now. My mistake. Sorry!"
Result: Trust preserved, no refund needed, user continues using service.
Đây là sức mạnh của nhật ký hoạt động. Bạn chuyển từ "tin tưởng chúng tôi" sang "hãy để chúng tôi cho bạn biết chính xác những gì đã xảy ra".
Tiếp theo là gì?
Giờ đây, bạn đã hoàn tất phần cốt lõi về kỹ thuật để xây dựng các tác nhân đáng tin cậy:
✅ Mô-đun 1 – 6: Thiết kế một cấu trúc đáng tin cậy (vai trò, thông tin đăng nhập, sự đồng ý)
✅ Mô-đun 7: Điều phối các quy trình công việc phức tạp (SequentialAgent)
✅ Mô-đun 8: Triển khai với khả năng quan sát được bật
✅ Mô-đun 9: Tìm hiểu cách đọc và sử dụng nhật ký hoạt động
Cấu trúc mà bạn đã xây dựng (phân tách vai trò, chuỗi thông tin đăng nhập, cơ chế đồng ý, khả năng quan sát hoàn chỉnh) sẽ được chuyển trực tiếp sang các hệ thống sản xuất xử lý tiền thật, dữ liệu thực và hậu quả thực.
10. Hành trình tương lai
Những gì bạn đã tạo
Bạn bắt đầu hội thảo này bằng một câu hỏi: "Làm cách nào để tạo các trợ lý AI mà tôi có thể tin tưởng giao phó tiền bạc?"
Giờ thì bạn đã có câu trả lời.
Nơi bạn bắt đầu (Học phần 3):
simple_agent = Agent(
model="gemini-2.5-flash",
instruction="Find charities and donate",
tools=[google_search]
)
Tình hình hiện tại của bạn (Học phần 10):
- ✅ 3 đặc vụ chuyên trách có sự phân tách vai trò
- ✅ 3 thông tin xác thực có thể xác minh (Ý định → Giỏ hàng → Uỷ quyền thanh toán)
- ✅ Hoàn tất chuỗi thông tin đăng nhập bằng quy trình xác thực thời gian hết hạn ở mỗi bước
- ✅ Cơ chế đồng ý rõ ràng có bằng chứng về dấu thời gian
- ✅ Triển khai sản xuất cho Agent Engine có khả năng quan sát
- ✅ Nhật ký đầy đủ về trách nhiệm giải trình trong Cloud Trace
- ✅ Bằng chứng pháp y để giải quyết tranh chấp
Xưởng sản xuất so với sản xuất: Khoảng cách
Hệ thống của bạn minh hoạ cấu trúc và mẫu chính xác, nhưng sử dụng các điểm đơn giản hoá mang tính giáo dục mà bạn phải nâng cấp để sử dụng tiền thật và người dùng thực.
Sau đây là những điểm được đơn giản hoá và những yêu cầu đối với bản phát hành công khai:
Thành phần | Triển khai hội thảo | Yêu cầu về việc sản xuất |
Chữ ký | Hàm băm SHA-256 ( | Chữ ký mã hoá thực bằng PKI hoặc JWT với khoá riêng tư |
Xử lý thanh toán | Trả lại hàng được mô phỏng (cờ | Tích hợp với các API thanh toán thực tế (Stripe, PayPal, Square) |
Xác thực người dùng | Tin tưởng ngầm (không yêu cầu đăng nhập) | OAuth 2.0, WebAuthn hoặc quản lý phiên |
Quản lý khoá bí mật | Biến môi trường trong tệp | Google Secret Manager hoặc Cloud KMS có tính năng mã hoá |
Cơ sở dữ liệu về tổ chức từ thiện | Tệp JSON mô phỏng có 9 tổ chức từ thiện | Tích hợp API Trực tiếp (Tìm kiếm tổ chức miễn thuế của IRS, Charity Navigator API) |
Xử lý lỗi | Thử bắt lỗi cơ bản bằng thông báo lỗi | Logic thử lại với thuật toán thời gian đợi luỹ thừa, bộ ngắt mạch, hàng đợi thư không gửi được |
Kiểm thử | Xác minh thủ công thông qua tập lệnh | Bộ kiểm thử đơn vị/tích hợp/E2E toàn diện với CI/CD |
Tính năng duy trì phiên | Trong bộ nhớ (cục bộ) hoặc tự động (Agent Engine) | Cơ sở dữ liệu sản xuất có bản sao lưu và khả năng khôi phục sau thảm hoạ |
Giới hạn tốc độ | Không có (môi trường giáo dục) | Giới hạn về tốc độ cho mỗi người dùng, điều tiết dựa trên IP, phát hiện hành vi sai trái |
Các mẫu kiến trúc chính mà bạn đã nắm vững
Các mẫu bạn đã học trong hội thảo này là các mẫu sản xuất. Đừng nghi ngờ họ.
Phân tách vai trò (Nguyên tắc AP2 số 1)
Mỗi tác nhân có MỘT công việc rõ ràng và CHỈ thấy những gì cần thiết. Nếu một tác nhân bị xâm phạm, kẻ tấn công sẽ không thể truy cập vào dữ liệu của các tác nhân khác. Điều này giúp hạn chế phạm vi ảnh hưởng.
Các hệ thống sản xuất sử dụng tính năng này: Xử lý thanh toán, quy trình làm việc với tài liệu, chuỗi phê duyệt, biểu mẫu nhiều bước có cổng xác thực.
Thông tin xác thực có thể xác minh (Nguyên tắc AP2 số 2)
Mỗi thông tin xác thực đều có thời gian hết hạn, tham chiếu đến thông tin xác thực trước đó và yêu cầu xác thực trước bước tiếp theo. Điều này tạo ra một chuỗi kiểm tra không giả mạo.
Giá trị sản xuất: Bằng chứng đầy đủ về những gì đã xảy ra, thời điểm và thứ tự xảy ra. Đây là thông tin cần thiết để giải quyết tranh chấp và tuân thủ quy định.
Sự đồng ý rõ ràng (Nguyên tắc 3 của AP2)
Chứng minh bằng dấu thời gian rằng người dùng đã phê duyệt hành động. Không thể khiếu nại.
Giá trị sản xuất: Yêu cầu pháp lý đối với các giao dịch tài chính. Bảo vệ cả người dùng và công ty.
Sắp xếp tuần tự (Mẫu ADK)
Thực thi đúng thứ tự thực hiện. Ngăn việc bỏ qua các bước. Đảm bảo mỗi tác nhân đều thấy được đầu ra của tác nhân trước đó.
Giá trị sản xuất: Phù hợp với các hệ thống có sự tham gia của con người, nơi người dùng mong đợi kết quả ngay lập tức. Đây là mẫu phù hợp cho quy trình quyên góp, quy trình thanh toán và chuỗi phê duyệt.
Khả năng ghi nhận đầy đủ (OpenTelemetry + Cloud Trace)
Mọi quyết định, lệnh gọi công cụ, thời điểm đồng ý và hoạt động chuyển giao thông tin đăng nhập đều được ghi lại tự động.
Giá trị sản xuất: Bằng chứng pháp lý cho các tranh chấp. Dữ liệu tối ưu hoá hiệu suất. Nhật ký kiểm tra việc tuân thủ. Gỡ lỗi các vấn đề về sản xuất một cách chính xác.
Tài nguyên để tiếp tục học tập
Tài liệu về ADK:
AP2 và các tiêu chuẩn liên quan:
Các dịch vụ của Google Cloud:
Tài nguyên dọn dẹp
Để không bị tính phí liên tục, hãy xoá cụm triển khai:
Agent Engine: Làm theo các bước trong tài liệu về Agent Engine
Cloud Run (nếu được triển khai):
gcloud run services delete charity-advisor \
--region=$GOOGLE_CLOUD_LOCATION
Nhóm lưu trữ:
gsutil -m rm -r gs://$GOOGLE_CLOUD_PROJECT-staging
gsutil -m rm -r gs://$GOOGLE_CLOUD_PROJECT-artifacts
Hành trình của bạn vẫn tiếp tục
Bạn bắt đầu bằng một câu hỏi đơn giản và xây dựng một câu trả lời hoàn chỉnh. Bạn đã nắm vững các mẫu cơ bản cho các tác nhân AI đáng tin cậy. Những mẫu này được chuyển sang bất kỳ miền nào mà tác nhân AI xử lý các hoạt động nhạy cảm – giao dịch tài chính, quyết định về chăm sóc sức khoẻ, tài liệu pháp lý, hoạt động của chuỗi cung ứng.
Các nguyên tắc này sẽ được chuyển giao. Mô hình tin cậy hoạt động.
Giờ thì hãy bắt tay vào xây dựng một thứ gì đó đáng tin cậy! ❤️
