1. บทนำ
ภาพรวม
แล็บนี้สอนวิธีจัดระเบียบระบบแบบหลายเอเจนต์ที่ซับซ้อนโดยใช้ Agent Development Kit (Google ADK) ของ Google คุณจะเปลี่ยนจากลำดับชั้นของตัวแทนแบบง่ายๆ ไปเป็นการสร้างเวิร์กโฟลว์อัตโนมัติที่ทำงานร่วมกัน
สิ่งที่คุณจะสร้าง
คุณจะสร้างระบบแบบหลายเอเจนต์ที่แตกต่างกัน 2 ระบบ ได้แก่
- เอเจนต์วางแผนการเดินทางแบบง่ายๆ ที่เรียนรู้การโอนการสนทนาระหว่างเอเจนต์ "ระดมความคิด" กับเอเจนต์ "วางแผนสถานที่ท่องเที่ยว"
- เครื่องมือสร้างพิตช์ภาพยนตร์ขั้นสูงที่ใช้ "ห้องนักเขียน" ของเอเจนต์อัตโนมัติ (เช่น นักวิจัย นักเขียนบท และนักวิจารณ์) เพื่อทำงานร่วมกันในลูปเพื่อสร้างพล็อตภาพยนตร์เต็มรูปแบบ
สิ่งที่คุณจะได้เรียนรู้
- วิธีสร้างความสัมพันธ์ระหว่างเอเจนซีหลักและเอเจนซีย่อย
- วิธีเขียนข้อมูลไปยังเซสชัน
stateจากเครื่องมือ - วิธีอ่านจาก
stateโดยใช้การสร้างเทมเพลตคีย์ (เช่น{my_key?}) - วิธีใช้
SequentialAgentสำหรับเวิร์กโฟลว์แบบทีละขั้นตอน - วิธีใช้
LoopAgentเพื่อสร้างวงจรการปรับแต่งแบบวนซ้ำ - วิธีใช้
ParallelAgentเพื่อเรียกใช้ฟังก์ชันที่ไม่ขึ้นต่อกันพร้อมกัน
2. ระบบหลายเอเจนต์
ชุดพัฒนา Agent (ADK) ช่วยให้นักพัฒนาแอปได้รับลักษณะการทำงานแบบหลายขั้นตอนที่ซับซ้อนและเชื่อถือได้มากขึ้นจากโมเดล Generative ADK ช่วยให้คุณสร้างโฟลว์ของ Agent หลายตัวที่เรียบง่ายกว่าซึ่งทำงานร่วมกันเพื่อแก้ปัญหาด้วยการแบ่งงาน แทนที่จะใช้พรอมต์ที่ซับซ้อนเพียงรายการเดียว
แนวทางนี้มีข้อดีหลายประการเหนือกว่าการใช้พรอมต์แบบโมโนลิธเดียว ดังนี้
- การออกแบบที่ง่ายขึ้น: การออกแบบและจัดระเบียบโฟลว์ของเอเจนต์ขนาดเล็กที่เชี่ยวชาญเฉพาะทางนั้นง่ายกว่าการออกแบบพรอมต์ขนาดใหญ่ที่ซับซ้อน
- ความน่าเชื่อถือ: เอเจนต์เฉพาะทางมีความน่าเชื่อถือมากกว่าเอเจนต์ขนาดใหญ่ที่ซับซ้อนในงานที่เฉพาะเจาะจง
- การบำรุงรักษา: การแก้ไขหรือปรับปรุงเอเจนต์ขนาดเล็กที่เชี่ยวชาญเฉพาะทางจะทำได้ง่ายกว่าโดยไม่กระทบต่อส่วนอื่นๆ ของระบบ
- ความสามารถในการแยกส่วน: คุณสามารถนำเอเจนต์ที่สร้างขึ้นสำหรับเวิร์กโฟลว์หนึ่งไปใช้ซ้ำในเวิร์กโฟลว์อื่นๆ ได้อย่างง่ายดาย
แผนผังตัวแทนแบบลำดับชั้น

ใน ADK คุณจะจัดระเบียบเอเจนต์ในโครงสร้างแบบต้นไม้ ลำดับชั้นนี้เป็นกุญแจสำคัญในการควบคุมลำดับการสนทนา เนื่องจากจะจำกัดว่าตัวแทนคนใดสามารถ "ส่งต่อ" การสนทนาไปยังตัวแทนคนอื่นๆ ได้ ซึ่งจะช่วยให้คาดการณ์พฤติกรรมของระบบได้มากขึ้นและแก้ไขข้อบกพร่องได้ง่ายขึ้น สิทธิประโยชน์มีดังนี้
- การออกแบบที่ใช้งานง่าย: โครงสร้างได้รับแรงบันดาลใจจากทีมในโลกแห่งความเป็นจริง จึงทำให้เข้าใจได้ง่ายขึ้น
- โฟลว์ที่ควบคุมได้: ลำดับชั้นช่วยให้คุณควบคุมการมอบหมายงานได้อย่างแม่นยำ ซึ่งจะช่วยในการแก้ไขข้อบกพร่อง เช่น โครงสร้างแบบต้นไม้จะช่วยให้ระบบเรียกใช้เอเจนต์การเขียนรายงานที่ถูกต้องได้ แม้ว่าคุณจะมีเอเจนต์ 2 รายการที่มีคำอธิบายคล้ายกันก็ตาม
โครงสร้างทั้งหมดเริ่มต้นด้วย root_agent เอเจนต์นี้ทำหน้าที่เป็นเอเจนต์หลักและอาจมีเอเจนต์ย่อยอย่างน้อย 1 ราย ซึ่งเอเจนต์ย่อยเหล่านี้ก็อาจเป็นเอเจนต์หลักของเอเจนต์ย่อยของตนเองได้เช่นกัน ทำให้เกิดโครงสร้างแบบต้นไม้
3. การตั้งค่าโปรเจ็กต์
บัญชี Google
หากยังไม่มีบัญชี Google ส่วนบุคคล คุณต้องสร้างบัญชี Google
ใช้บัญชีส่วนตัวแทนบัญชีงานหรือบัญชีโรงเรียน
ลงชื่อเข้าใช้ Google Cloud Console
ลงชื่อเข้าใช้ Google Cloud Console โดยใช้บัญชี Google ส่วนตัว
เปิดใช้การเรียกเก็บเงิน
แลกรับเครดิต Google Cloud มูลค่า $5 (ไม่บังคับ)
หากต้องการจัดเวิร์กช็อปนี้ คุณต้องมีบัญชีสำหรับการเรียกเก็บเงินที่มีเครดิตอยู่บ้าง หากวางแผนที่จะใช้การเรียกเก็บเงินของคุณเอง ให้ข้ามขั้นตอนนี้
- คลิกลิงก์นี้ แล้วลงชื่อเข้าใช้ด้วยบัญชี Google ส่วนบุคคล คุณจะเห็นข้อความคล้ายกับนี้

- คลิกปุ่มคลิกที่นี่เพื่อเข้าถึงเครดิต ระบบจะนำคุณไปยังหน้าเพื่อตั้งค่าโปรไฟล์การเรียกเก็บเงิน

- คลิกยืนยัน
ตอนนี้คุณเชื่อมต่อกับบัญชีสำหรับการเรียกเก็บเงินของ Google Cloud Platform เวอร์ชันทดลองใช้งานแล้ว

ตั้งค่าบัญชีสำหรับการเรียกเก็บเงินส่วนตัว
หากตั้งค่าการเรียกเก็บเงินโดยใช้เครดิต Google Cloud คุณจะข้ามขั้นตอนนี้ได้
หากต้องการตั้งค่าบัญชีสำหรับการเรียกเก็บเงินส่วนตัว ให้ไปที่นี่เพื่อเปิดใช้การเรียกเก็บเงินใน Cloud Console
ข้อควรทราบ
- การทำแล็บนี้ควรมีค่าใช้จ่ายน้อยกว่า $1 USD ในทรัพยากรระบบคลาวด์
- คุณสามารถทำตามขั้นตอนที่ส่วนท้ายของแล็บนี้เพื่อลบทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินเพิ่มเติม
- ผู้ใช้ใหม่มีสิทธิ์ใช้ช่วงทดลองใช้ฟรีมูลค่า$300 USD
สร้างโปรเจ็กต์ (ไม่บังคับ)
หากไม่มีโปรเจ็กต์ปัจจุบันที่ต้องการใช้สำหรับ Lab นี้ ให้สร้างโปรเจ็กต์ใหม่ที่นี่
4. เปิดเครื่องมือแก้ไข Cloud Shell
- คลิกลิงก์นี้เพื่อไปยัง Cloud Shell Editor โดยตรง
- หากระบบแจ้งให้ให้สิทธิ์ในวันนี้ ให้คลิกให้สิทธิ์เพื่อดำเนินการต่อ

- หากเทอร์มินัลไม่ปรากฏที่ด้านล่างของหน้าจอ ให้เปิดโดยทำดังนี้
- คลิกดู
- คลิก Terminal

- ในเทอร์มินัล ให้ตั้งค่าโปรเจ็กต์ด้วยคำสั่งนี้
gcloud config set project [PROJECT_ID]- ตัวอย่าง
gcloud config set project lab-project-id-example - หากจำรหัสโปรเจ็กต์ไม่ได้ คุณสามารถแสดงรหัสโปรเจ็กต์ทั้งหมดได้โดยใช้คำสั่งต่อไปนี้
gcloud projects list
- ตัวอย่าง
- คุณควรเห็นข้อความต่อไปนี้
Updated property [core/project].
5. เปิดใช้ API
หากต้องการใช้ Vertex AI API และโต้ตอบกับโมเดล Gemini คุณต้องเปิดใช้ Vertex AI API ในโปรเจ็กต์ Google Cloud
- เปิดใช้ API ในเทอร์มินัลโดยทำดังนี้
gcloud services enable aiplatform.googleapis.com
ต่อไปนี้คือส่วนที่อัปเดตแล้ว ซึ่งจะแทนที่การสร้างไฟล์ด้วยตนเองด้วยวิธีการโคลนที่เก็บ GitHub และติดตั้งการอ้างอิง
ข้อมูลเบื้องต้นเกี่ยวกับ Vertex AI SDK สำหรับ Python
หากต้องการโต้ตอบกับโมเดลที่โฮสต์ใน Vertex AI จากแอปพลิเคชัน Python คุณจะต้องใช้ Vertex AI SDK สำหรับ Python SDK นี้ช่วยลดความซับซ้อนของกระบวนการส่งพรอมต์ การระบุพารามิเตอร์ของโมเดล และการรับคำตอบโดยไม่จำเป็นต้องจัดการความซับซ้อนของการเรียก API พื้นฐานโดยตรง
คุณดูเอกสารประกอบที่ครอบคลุมสำหรับ Vertex AI SDK สำหรับ Python ได้ที่ข้อมูลเบื้องต้นเกี่ยวกับ Vertex AI SDK สำหรับ Python | Google Cloud
6. ตั้งค่าสภาพแวดล้อมของโปรเจ็กต์
โคลนที่เก็บ
- ในเทอร์มินัล ให้โคลนที่เก็บที่มีไฟล์เริ่มต้น
แฟล็กgit clone --depth 1 https://github.com/GoogleCloudPlatform/devrel-demos.git--depth 1จะโคลนเฉพาะเวอร์ชันล่าสุด ซึ่งเร็วกว่า - ในเทอร์มินัล ให้ไปที่ไดเรกทอรีการทำงานที่ถูกต้องสำหรับแล็บนี้
cd devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
เปิดใช้งานสภาพแวดล้อมเสมือน
- ในเทอร์มินัล ให้สร้างและเปิดใช้งานสภาพแวดล้อมเสมือนโดยใช้
uvดังนี้uv venv source .venv/bin/activate - ในเทอร์มินัล ให้ติดตั้ง
google-adkและการอ้างอิงอื่นๆ จากไฟล์requirements.txtโดยใช้คำสั่งต่อไปนี้uv pip install -r requirements.txt
ตรวจสอบโครงสร้างไฟล์
เมื่อสร้างไฟล์ทั้งหมดแล้ว ให้เปิดโฟลเดอร์ adk_multiagent_systems ใน Explorer เพื่อดูโครงสร้างทั้งหมด
- ในเมนู Cloud Shell Editor ให้เลือกไฟล์ > เปิดโฟลเดอร์...

- ในช่องที่ปรากฏขึ้น ให้เพิ่มข้อมูลโฟลเดอร์ต่อไปนี้หลังชื่อผู้ใช้
devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems/คลิก OK
โดยควรมีลักษณะดังนี้
- แผง Explorer ทางด้านซ้ายจะรีเฟรช ตอนนี้คุณควรเห็นโครงสร้างโปรเจ็กต์ที่สมบูรณ์พร้อมไดเรกทอรีย่อย
parent_and_subagentsและworkflow_agentsซึ่งพร้อมสำหรับขั้นตอนถัดไป
ตั้งค่าตัวแปรสภาพแวดล้อม
- คุณอยู่ในไดเรกทอรี
adk_multiagent_systemsอยู่แล้ว ในเทอร์มินัล ให้สร้างไฟล์.envเพื่อจัดเก็บตัวแปรสภาพแวดล้อมcloudshell edit .env - วางโค้ดต่อไปนี้ลงในไฟล์
.envที่เปิดในเครื่องมือแก้ไขGOOGLE_GENAI_USE_VERTEXAI=TRUE GOOGLE_CLOUD_PROJECT="[YOUR-PROJECT-ID]" GOOGLE_CLOUD_LOCATION=global MODEL="gemini-2.5-flash" - แทนที่
[YOUR-PROJECT-ID]ด้วยรหัสโปรเจ็กต์ Google Cloud จริง (เช่นPROJECT_ID = "google-cloud-labs")
หากจำรหัสโปรเจ็กต์ไม่ได้ ให้เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล โดยจะแสดงรายการโปรเจ็กต์ทั้งหมดและรหัสของโปรเจ็กต์gcloud projects list - ในเทอร์มินัล ให้คัดลอกไฟล์
.envนี้ลงในไดเรกทอรีย่อยของ Agent เพื่อให้ Agent เข้าถึงตัวแปรได้ด้วย ตอนนี้โครงสร้างไฟล์ควรมีลักษณะดังนี้cp .env parent_and_subagents/.env cp .env workflow_agents/.env
7. ดูข้อมูลเกี่ยวกับการโอนระหว่างเอเจนต์หลัก เอเจนต์ย่อย และเอเจนต์ที่เป็นเพียร์
การสนทนาจะเริ่มต้นด้วย root_agent เสมอ โดยค่าเริ่มต้น ตัวแทนหลักจะใช้ description ของตัวแทนย่อยเพื่อตัดสินใจว่าจะโอนการสนทนาเมื่อใด นอกจากนี้ คุณยังแนะนำการโอนเหล่านี้อย่างชัดเจนในinstructionของผู้ปกครองnameได้โดยใช้nameของตัวแทนย่อยname
มาทดสอบกัน
- ใน Cloud Shell Editor ให้เปิด
adk_multiagent_systems/parent_and_subagents/agent.pyสังเกตเอเจนต์ 3 รายในไฟล์agent.pyroot_agent(ชื่อsteering): ถามคำถามผู้ใช้เพื่อตัดสินใจว่าจะโอนไปยังตัวแทนย่อยรายใด ในตอนแรกจะอาศัยเพียงdescriptionของตัวแทนย่อยเท่านั้นtravel_brainstormer: ช่วยผู้ใช้ระดมความคิดเกี่ยวกับจุดหมายปลายทางattractions_planner: ช่วยให้ผู้ใช้แสดงรายการสิ่งที่ต้องทำในประเทศที่เฉพาะเจาะจง
- สร้าง
travel_brainstormerและattractions_plannerเป็น Agent ย่อยของroot_agentโดยเพิ่มบรรทัดต่อไปนี้ในการสร้างroot_agentsub_agents=[travel_brainstormer, attractions_planner] - ในเทอร์มินัล ให้แชทกับเอเจนต์โดยทำดังนี้
cd ~/devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems adk run parent_and_subagents - ที่พรอมต์
[user]:ในเทอร์มินัล ให้พิมพ์ ตัวอย่างเอาต์พุต (ของคุณอาจแตกต่างออกไปเล็กน้อย)hello[steering]: Hi there! Do you already have a country in mind for your trip, or would you like some help deciding where to go?
- ตอนนี้ให้บอกตัวแทนในเทอร์มินัลว่า
ตัวอย่างเอาต์พุต (ของคุณอาจแตกต่างออกไปเล็กน้อย)I could use some help deciding. สังเกตแท็ก[travel_brainstormer]: Okay! To give you the best recommendations, I need to understand what you're looking for in a trip. ...
[travel_brainstormer]root_agentการควบคุมที่โอนจะอิงตาม ของตัวแทนย่อยdescriptionเท่านั้น - ที่พรอมต์
user:ในเทอร์มินัล ให้พิมพ์exitแล้วกด Enter เพื่อสิ้นสุดการสนทนา - ทีนี้มาดูตัวอย่างที่ชัดเจนขึ้นกัน ใน
agent.pyให้เพิ่มรายการต่อไปนี้ลงในinstructionของroot_agentIf they need help deciding, send them to 'travel_brainstormer'. If they know what country they'd like to visit, send them to the 'attractions_planner'. - เรียกใช้ Agent อีกครั้งในเทอร์มินัล
adk run parent_and_subagents - ที่พรอมต์
[user]:ในเทอร์มินัล ให้พิมพ์hello - ให้ตอบว่า
ตัวอย่างเอาต์พุต (ของคุณอาจแตกต่างออกไปเล็กน้อย)I would like to go to Japan. โปรดทราบว่าระบบจะโอนไปยัง[attractions_planner]: Okay, I can help you with that! Here are some popular attractions in Japan: ...
attractions_plannerตามคำแนะนำใหม่ - ตอนนี้ให้ตอบว่า
ตัวอย่างเอาต์พุต (ของคุณอาจแตกต่างออกไปเล็กน้อย)Actually I don't know what country to visit. โปรดทราบว่าระบบได้โอนคุณไปยัง[travel_brainstormer]: Okay! I can help you brainstorm some countries for travel...
travel_brainstormerซึ่งเป็นเพียร์ของattractions_plannerซึ่งจะอนุญาตโดยค่าเริ่มต้น - ที่พรอมต์ผู้ใช้ ให้พิมพ์
exitเพื่อสิ้นสุดเซสชัน
สรุป
ในส่วนนี้ คุณได้เรียนรู้พื้นฐานของลำดับชั้นของตัวแทนและโฟลว์การสนทนาแล้ว
- การสนทนาจะเริ่มต้นด้วย
root_agentเสมอ - เอเจนต์หลักจะโอนสายไปยังเอเจนต์ย่อยโดยอัตโนมัติตาม
description - คุณควบคุมขั้นตอนการทำงานนี้ได้อย่างชัดเจนโดยให้ผู้ปกครองของ
instructionโอนไปยังตัวแทนย่อยตามname - โดยค่าเริ่มต้น ตัวแทนจะโอนสายไปยังตัวแทน
peer(ตัวแทนที่อยู่ในลำดับชั้นเดียวกัน) ได้
8. ใช้สถานะเซสชันเพื่อจัดเก็บและเรียกข้อมูล
การสนทนา ADK ทุกครั้งจะมี Session ซึ่งรวมถึงพจนานุกรมสถานะเซสชัน เอเจนต์ทุกคนสามารถเข้าถึงสถานะนี้ได้ จึงเป็นวิธีที่เหมาะที่สุดในการส่งต่อข้อมูลระหว่างเอเจนต์หรือเก็บรักษาข้อมูล (เช่น รายการ) ตลอดการสนทนา
หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มและการอ่านจากสถานะ ให้ทำดังนี้
- กลับไปที่ไฟล์
adk_multiagent_systems/parent_and_subagents/agent.py - วางคำจำกัดความฟังก์ชันต่อไปนี้หลังส่วนหัว
# Tools ในโค้ดนี้ ให้สังเกตสิ่งต่อไปนี้def save_attractions_to_state( tool_context: ToolContext, attractions: List[str] ) -> dict[str, str]: """Saves the list of attractions to state["attractions"]. Args: attractions [str]: a list of strings to add to the list of attractions Returns: None """ # Load existing attractions from state. If none exist, start an empty list existing_attractions = tool_context.state.get("attractions", []) # Update the 'attractions' key with a combo of old and new lists. # When the tool is run, ADK will create an event and make # corresponding updates in the session's state. tool_context.state["attractions"] = existing_attractions + attractions # A best practice for tools is to return a status message in a return dict return {"status": "success"}- ฟังก์ชันจะได้รับ
tool_context: ToolContextออบเจ็กต์นี้คือเกตเวย์ไปยังเซสชัน - บรรทัด
tool_context.state["attractions"] = ...จะอ่านและเขียนลงในพจนานุกรมสถานะของเซสชันโดยตรง ส่วน ADK จะจัดการที่เหลือให้
- ฟังก์ชันจะได้รับ
- เพิ่มเครื่องมือลงใน
attractions_plannerAgent โดยเพิ่มพารามิเตอร์toolsดังนี้tools=[save_attractions_to_state] - เพิ่มหัวข้อย่อยต่อไปนี้ลงใน
attractions_plannerinstructionที่มีอยู่ของตัวแทน- When they reply, use your tool to save their selected attraction and then provide more possible attractions. - If they ask to view the list, provide a bulleted list of { attractions? } and then suggest some more. - เปิดใช้ UI บนเว็บของ Agent Development Kit ด้วยคำสั่งต่อไปนี้ในเทอร์มินัล
เอาต์พุตadk webINFO: Started server process [2434] INFO: Waiting for application startup. +-------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://localhost:8000. | +-------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) - ในเทอร์มินัล Cloud Shell ให้คลิกหากต้องการดูอินเทอร์เฟซเว็บในแท็บใหม่ ให้คลิกปุ่มตัวอย่างเว็บ แล้วเลือกเปลี่ยนพอร์ต

- ป้อนหมายเลขพอร์ต 8000 แล้วคลิกเปลี่ยนและแสดงตัวอย่าง แท็บใหม่ของเบราว์เซอร์จะเปิดขึ้นพร้อมกับ UI สำหรับนักพัฒนา ADK

- จากเมนูแบบเลื่อนลงเลือกตัวแทนทางด้านซ้าย ให้เลือก
parent_and_subagents - เริ่มการสนทนาด้วยข้อความต่อไปนี้
hello - หลังจากที่ตัวแทนกล่าวทักทายแล้ว ให้ตอบกลับด้วยข้อความต่อไปนี้
ระบบจะโอนสายไปยังI'd like to go to Egypt.attractions_plannerและแสดงรายการสถานที่ท่องเที่ยวให้คุณ - เลือกสถานที่ท่องเที่ยว เช่น
I'll go to the Sphinx - คุณควรได้รับคำตอบเช่น โอเค ฉันบันทึกสฟิงซ์ลงในลิสต์ของคุณแล้ว...
- คลิกกล่องเครื่องมือตอบกลับ (ทำเครื่องหมายด้วยเครื่องหมายถูก) เพื่อดูกิจกรรมที่สร้างขึ้นจากการตอบกลับของเครื่องมือ
โปรดทราบว่ามีฟิลด์ actions ซึ่งมีstateDeltaที่อธิบายการเปลี่ยนแปลงสถานะ - ตอบกลับด้วยสถานที่ท่องเที่ยวอื่นจากรายการของตัวแทน
- ในเมนูการนำทางด้านซ้าย ให้คลิก "X" เพื่อออกจากโฟกัสในเหตุการณ์ที่คุณตรวจสอบก่อนหน้านี้
- คลิกแท็บสถานะในแถบด้านข้างทางซ้าย ตอนนี้คุณจะเห็นอาร์เรย์
attractionsในสถานะของเซสชัน ซึ่งควรมีทั้ง 2 รายการที่คุณเลือก
- ส่งข้อความนี้ถึงตัวแทน
ตอนนี้เอเจนต์ควรอ่านจากสถานะและแสดงรายการของคุณWhat is on my list? - เมื่อทดสอบเอเจนต์เสร็จแล้ว ให้ปิดแท็บเว็บเบราว์เซอร์และกด CTRL + C ในเทอร์มินัล Cloud Shell เพื่อหยุดเซิร์ฟเวอร์
สรุปส่วน
ในส่วนนี้ คุณได้เรียนรู้วิธีใช้สถานะ Session เพื่อแชร์ข้อมูล ดังนี้
- หากต้องการเขียนสถานะ: คุณจะเขียนไปยังพจนานุกรมสถานะจากภายในเครื่องมือได้โดยใช้ออบเจ็กต์
tool_context.state(เช่นtool_context.state["my_list"] = [...]) - หากต้องการอ่านสถานะ: คุณจะแทรกข้อมูลสถานะลงใน
instructionของเอเจนต์โดยตรงได้โดยใช้การสร้างเทมเพลตคีย์ (เช่นHere is your list: {my_list?}) - หากต้องการตรวจสอบสถานะ คุณสามารถตรวจสอบสถานะเซสชันแบบเรียลไทม์ใน ADK Dev UI ได้โดยใช้แท็บสถานะ
9. Agent เวิร์กโฟลว์
ที่ผ่านมา คุณได้เห็นวิธีที่เอเจนต์หลักโอนสายไปยังเอเจนต์ย่อยแล้วรอผู้ใช้ เอเจนต์เวิร์กโฟลว์จะแตกต่างออกไป โดยจะเรียกใช้เอเจนต์ย่อยทีละตัวในโฟลว์อัตโนมัติโดยไม่ต้องรออินพุตจากผู้ใช้
ซึ่งเหมาะอย่างยิ่งสำหรับงานแบบหลายขั้นตอนที่ทำงานอัตโนมัติ เช่น ไปป์ไลน์ "วางแผนและดำเนินการ" หรือ "ร่างและแก้ไข" ADK มี Agent เวิร์กโฟลว์ในตัว 3 รายการเพื่อจัดการเรื่องนี้ ได้แก่
SequentialAgentLoopAgentParallelAgent
ส่วนที่เหลือของแล็บนี้จะมุ่งเน้นที่การสร้างระบบหลายเอเจนต์โดยใช้เอเจนต์เวิร์กโฟลว์ทั้ง 3 รายการนี้
คุณจะสร้างเอเจนต์ที่พัฒนาเอกสารการเสนอขายสำหรับภาพยนตร์เรื่องใหม่เกี่ยวกับบุคคลในประวัติศาสตร์ เอเจนต์จะจัดการการค้นคว้า การเขียนแบบวนซ้ำ และการสร้างรายงาน
ในท้ายที่สุด ระบบของคุณจะมีลักษณะดังนี้

คุณจะสร้างระบบนี้ทีละขั้นตอน โดยเริ่มจากเวิร์กโฟลว์ที่ง่ายที่สุด
10. สร้างระบบหลายเอเจนต์ด้วย SequentialAgent
SequentialAgent คือเอเจนต์เวิร์กโฟลว์ที่เรียกใช้เอเจนต์ย่อยตามลำดับเชิงเส้นอย่างง่าย ระบบจะเรียกใช้เอเจนต์แต่ละตัวในsub_agentsรายการตามลำดับ ซึ่งเหมาะอย่างยิ่งสำหรับไปป์ไลน์ที่ต้องทำงานตามลำดับที่เฉพาะเจาะจง เช่น เอเจนต์เสนอภาพยนตร์ที่คุณจะสร้างในตอนนี้
เวอร์ชันแรกนี้จะมีโครงสร้างดังนี้

root_agent(greeter) จะต้อนรับผู้ใช้และรับหัวข้อภาพยนตร์- จากนั้นระบบจะโอนไปยัง
SequentialAgentชื่อfilm_concept_teamซึ่งจะดำเนินการต่อไปนี้- เรียกใช้เอเจนต์
researcherเพื่อดูข้อเท็จจริงจาก Wikipedia - เรียกใช้เอเจนต์
screenwriterเพื่อใช้ข้อเท็จจริงเหล่านั้นในการเขียนพล็อต - เรียกใช้เอเจนต์
file_writerเพื่อบันทึกพล็อตสุดท้ายลงในไฟล์
- เรียกใช้เอเจนต์
มาเริ่มกันเลย
- เปิด
adk_multiagent_systems/workflow_agents/agent.pyใน Cloud Shell Editor
อ่านไฟล์คำจำกัดความของเอเจนต์นี้ เนื่องจากต้องกำหนดเอเจนต์ย่อยก่อนจึงจะกำหนดให้กับเอเจนต์หลักได้ หากต้องการอ่านไฟล์ตามลำดับของโฟลว์การสนทนา คุณสามารถอ่านเอเจนต์จากด้านล่างของไฟล์ขึ้นไปด้านบนได้ - สังเกตเครื่องมือ
append_to_stateฟังก์ชันตัวช่วยนี้ช่วยให้ Agent สามารถผนวกข้อมูลลงในรายการในสถานะเซสชัน ซึ่งเป็นวิธีที่researcherและscreenwriterจะส่งต่องานของตน - ลองใช้ Agent ในเทอร์มินัล ให้เปิดอินเทอร์เฟซเว็บโดยเปิดใช้การโหลดซ้ำแบบเรียลไทม์
cd ~/devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems adk web --reload_agents - ในเทอร์มินัล Cloud Shell ให้คลิกหากต้องการดูอินเทอร์เฟซเว็บในแท็บใหม่ ให้คลิกปุ่มตัวอย่างเว็บ แล้วเลือกเปลี่ยนพอร์ต

- ป้อนหมายเลขพอร์ต 8000 แล้วคลิกเปลี่ยนและแสดงตัวอย่าง แท็บใหม่ของเบราว์เซอร์จะเปิดขึ้นพร้อมกับ UI สำหรับนักพัฒนา ADK

- เลือก
workflow_agentsจากเมนูแบบเลื่อนลงเลือกตัวแทน - เริ่มการสนทนาด้วย
helloตัวแทนgreeterจะตอบกลับ - เมื่อได้รับข้อความแจ้ง ให้ป้อนบุคคลในประวัติศาสตร์ คุณใช้ตัวเลือกใดตัวเลือกหนึ่งต่อไปนี้หรือใช้ตัวเลือกของคุณเองก็ได้
- จางจงจิ่ง
- Ada Lovelace
- มาร์คัส ออเรลิอัส
- ตอนนี้
SequentialAgentจะเป็นผู้รับช่วงต่อ คุณจะไม่เห็นข้อความใดๆ ที่อยู่ระหว่างกลางresearcher,screenwriterและfile_writerจะทำงานต่อกัน เอเจนต์จะตอบกลับเมื่อลำดับทั้งหมดเสร็จสมบูรณ์แล้วเท่านั้น
หากไม่สำเร็จ ให้คลิก + เซสชันใหม่ที่ด้านขวาบน แล้วลองอีกครั้ง - เมื่อตัวแทนยืนยันว่าได้เขียนไฟล์แล้ว ให้ค้นหาและเปิดไฟล์
.txtใหม่ในไดเรกทอรีmovie_pitchesใน Cloud Shell Editor เพื่อดูเอาต์พุต - ใน UI ของ ADK Dev ให้คลิกไอคอนตัวแทนสุดท้ายในประวัติการแชทเพื่อเปิดมุมมองเหตุการณ์
- มุมมองเหตุการณ์จะแสดงกราฟภาพของโครงสร้าง Agent คุณจะเห็นว่า
greeterเรียกใช้film_concept_teamอย่างไร ซึ่งจะเรียกใช้ตัวแทนย่อยแต่ละรายตามลำดับ
- คุณสามารถคลิกแท็บคำขอและการตอบกลับสำหรับเอเจนต์ใดก็ได้ในกราฟเพื่อตรวจสอบข้อมูลที่ส่งผ่านอย่างละเอียด รวมถึงสถานะเซสชัน
สรุปส่วน
ในส่วนนี้ คุณได้เรียนรู้วิธีใช้เอเจนต์เวิร์กโฟลว์แล้ว ดังนี้
SequentialAgentจะเรียกใช้เอเจนต์ย่อยทีละตัวตามลำดับโดยไม่ต้องรออินพุตจากผู้ใช้ระหว่างขั้นตอน- นี่คือ "เวิร์กโฟลว์" เนื่องจากผู้ใช้พูดคุยกับ
root_agentซึ่งจะส่งงานให้SequentialAgentทำต่อให้เสร็จ - ตัวแทนย่อยในลำดับจะใช้สถานะเซสชัน (เช่น
{ PLOT_OUTLINE? }) เพื่อเข้าถึงงานของตัวแทนก่อนหน้า - คุณสามารถใช้กราฟเหตุการณ์ใน UI สำหรับนักพัฒนาซอฟต์แวร์เพื่อแสดงภาพและแก้ไขข้อบกพร่องของเวิร์กโฟลว์ทั้งหมดจากเอเจนต์หนึ่งไปยังอีกเอเจนต์หนึ่ง
11. เพิ่ม LoopAgent สำหรับงานที่ต้องทำซ้ำ
LoopAgent คือ Agent เวิร์กโฟลว์ที่เรียกใช้ Agent ย่อยตามลำดับแล้วทำซ้ำโดยเริ่มจากจุดเริ่มต้น "ลูป" นี้จะทำงานต่อไปจนกว่าจะตรงตามเงื่อนไข เช่น ถึงmax_iterations หรือเอเจนต์ย่อยเรียกใช้เครื่องมือ exit_loop ในตัว
ซึ่งมีประโยชน์สำหรับงานที่ต้องมีการปรับแต่งซ้ำๆ คุณจะเพิ่ม LoopAgent นี้เพื่อสร้าง "ห้องนักเขียน" สำหรับเอเจนต์ที่รับเสนอขายภาพยนตร์ ซึ่งจะช่วยให้ researcher, screenwriter และเอเจนต์ critic รายใหม่ทำงานเป็นวงจรได้ โดยจะปรับปรุงพล็อตในแต่ละรอบจนกว่า critic จะตัดสินใจว่าพร้อมแล้ว นอกจากนี้ยังช่วยให้เอเจนต์จัดการกับข้อมูลจากผู้ใช้ที่คลุมเครือมากขึ้น (เช่น "หมอโบราณ") ได้ด้วยการให้เอเจนต์ค้นคว้าและปรับแต่งไอเดีย

วิธีทำการเปลี่ยนแปลงเหล่านี้
- ใน
adk_multiagent_systems/workflow_agents/agent.pyให้เพิ่มการนำเข้าสำหรับexit_loop(ใกล้กับการนำเข้าgoogle.adkอื่นๆ) ดังนี้from google.adk.tools import exit_loop - เพิ่มเอเจนต์
criticใหม่ ตัวแทนจะตรวจสอบเนื้อเรื่อง หากเป็นค่าที่ดี ฟังก์ชันจะเรียกใช้exit_loopหากไม่ ระบบจะเพิ่มความคิดเห็นลงในสถานะสำหรับลูปถัดไป
วางคำจำกัดความของ Agent ต่อไปนี้ในส่วน# Agentscritic = Agent( name="critic", model=model_name, description="Reviews the outline so that it can be improved.", instruction=""" INSTRUCTIONS: Consider these questions about the PLOT_OUTLINE: - Does it meet a satisfying three-act cinematic structure? - Do the characters' struggles seem engaging? - Does it feel grounded in a real time period in history? - Does it sufficiently incorporate historical details from the RESEARCH? If the PLOT_OUTLINE does a good job with these questions, exit the writing loop with your 'exit_loop' tool. If significant improvements can be made, use the 'append_to_state' tool to add your feedback to the field 'CRITICAL_FEEDBACK'. Explain your decision and briefly summarize the feedback you have provided. PLOT_OUTLINE: { PLOT_OUTLINE? } RESEARCH: { research? } """, before_model_callback=log_query_to_model, after_model_callback=log_model_response, tools=[append_to_state, exit_loop] ) - สร้าง
writers_roomLoopAgentซึ่งจะมีเอเจนต์ 3 รายที่จะทำงานในลูป
วางโค้ดต่อไปนี้เหนือคำจำกัดความของเอเจนต์film_concept_teamwriters_room = LoopAgent( name="writers_room", description="Iterates through research and writing to improve a movie plot outline.", sub_agents=[ researcher, screenwriter, critic ], max_iterations=5, ) - อัปเดต
film_concept_teamSequentialAgentเพื่อใช้ลูปwriters_roomใหม่ แทนที่researcherและscreenwriterด้วยเอเจนต์writers_roomรายเดียวแทนที่คำจำกัดความfilm_concept_teamที่มีอยู่ด้วยคำจำกัดความนี้film_concept_team = SequentialAgent( name="film_concept_team", description="Write a film plot outline and save it as a text file.", sub_agents=[ writers_room, file_writer ], ) - กลับไปที่แท็บ UI สำหรับนักพัฒนา ADK แล้วคลิก + เซสชันใหม่ที่ด้านขวาบน
- เริ่มการสนทนาใหม่กับ
hello - เมื่อระบบแจ้ง ให้ระบุหัวข้อที่กว้างขึ้นแก่ตัวแทนในครั้งนี้ ตัวอย่างบางส่วนมีดังนี้
- นักออกแบบอุตสาหกรรมที่สร้างผลิตภัณฑ์สำหรับมวลชน
- นักเขียนแผนที่
- ชายคนนั้นที่ทำให้พืชผลผลิตอาหารได้มากขึ้น
- เมื่อลูปเสร็จสมบูรณ์แล้ว เอเจนต์จะเขียนไฟล์ ตรวจสอบไฟล์ที่สร้างขึ้นในไดเรกทอรี
adk_multiagent_systems/movie_pitches - ตรวจสอบกราฟเหตุการณ์ใน UI สำหรับนักพัฒนาซอฟต์แวร์เพื่อดูโครงสร้างลูป
สรุปส่วน
ในส่วนนี้ คุณได้เรียนรู้วิธีใช้LoopAgent
LoopAgentคือเอเจนต์เวิร์กโฟลว์ที่ทำซ้ำลำดับของเอเจนต์ย่อย ซึ่งสร้าง "ลูปด้านใน" สำหรับงานที่ต้องทำซ้ำ- Agent ภายในลูปใช้สถานะเซสชันเพื่อส่งต่องาน (เช่น
PLOT_OUTLINE) และความคิดเห็น (เช่นCRITICAL_FEEDBACK) ในการส่งต่อครั้งต่อๆ ไป - คุณหยุดลูปได้โดยกด
max_iterationsขีดจำกัดหรือโดยตัวแทนที่เรียกใช้เครื่องมือexit_loop
12. ใช้ ParallelAgent สำหรับ "fan out and gather"
ParallelAgent คือเอเจนต์เวิร์กโฟลว์ที่เรียกใช้เอเจนต์ย่อยทั้งหมดพร้อมกัน (พร้อมกัน) ซึ่งมีประโยชน์สำหรับงานที่แบ่งออกเป็นงานย่อยที่ไม่ขึ้นต่อกันได้ เช่น การเรียกใช้งานงานวิจัย 2 งานที่แตกต่างกัน
คุณจะใช้ ParallelAgent เพื่อสร้าง "ทีมก่อนการผลิต" ที่ทำงานควบคู่กันไป ตัวแทนคนหนึ่งจะค้นหาศักยภาพของบ็อกซ์ออฟฟิศ ขณะที่ตัวแทนอีกคนจะระดมความคิดเรื่องการคัดเลือกนักแสดงไปพร้อมๆ กัน ซึ่งมักเรียกว่ารูปแบบ "กระจายและรวบรวม" โดย ParallelAgent จะ "กระจาย" งาน และเอเจนต์ในภายหลัง (file_writer ของเรา) จะ "รวบรวม" ผลลัพธ์

ขั้นตอนสุดท้ายของ Agent จะเป็นดังนี้
greeter(รูท) จะเริ่มแชท- โดยจะโอนไปยัง
film_concept_team(SequentialAgent) ซึ่งจะทำงานดังนี้writers_room(LoopAgent) เพื่อสร้างพล็อตpreproduction_teamใหม่ (ParallelAgent) เพื่อค้นหารายได้และรายชื่อนักแสดงพร้อมกันfile_writerเพื่อรวบรวมผลลัพธ์ทั้งหมดและบันทึกไฟล์
วิธีทำการเปลี่ยนแปลงเหล่านี้
- ใน
adk_multiagent_systems/workflow_agents/agent.pyให้วางParallelAgentใหม่และตัวแทนย่อยภายใต้ส่วนหัว# Agentsbox_office_researcher = Agent( name="box_office_researcher", model=model_name, description="Considers the box office potential of this film", instruction=""" PLOT_OUTLINE: { PLOT_OUTLINE? } INSTRUCTIONS: Write a report on the box office potential of a movie like that described in PLOT_OUTLINE based on the reported box office performance of other recent films. """, output_key="box_office_report" ) casting_agent = Agent( name="casting_agent", model=model_name, description="Generates casting ideas for this film", instruction=""" PLOT_OUTLINE: { PLOT_OUTLINE? } INSTRUCTIONS: Generate ideas for casting for the characters described in PLOT_OUTLINE by suggesting actors who have received positive feedback from critics and/or fans when they have played similar roles. """, output_key="casting_report" ) preproduction_team = ParallelAgent( name="preproduction_team", sub_agents=[ box_office_researcher, casting_agent ] ) - อัปเดตรายการ
sub_agentsของfilm_concept_teamSequentialAgentให้มีpreproduction_teamใหม่ (ระหว่างwriters_roomกับfile_writer) แทนที่คำจำกัดความfilm_concept_teamที่มีอยู่ด้วยคำจำกัดความนี้film_concept_team = SequentialAgent( name="film_concept_team", description="Write a film plot outline and save it as a text file.", sub_agents=[ writers_room, preproduction_team, file_writer ], ) - อัปเดต
file_writerinstructionของเอเจนต์เพื่อให้ "รวบรวม" รายงานใหม่จากรัฐและเพิ่มลงในไฟล์
แทนที่สตริงinstructionสำหรับfile_writerด้วยสตริงนี้instruction=""" INSTRUCTIONS: - Create a marketable, contemporary movie title suggestion for the movie described in the PLOT_OUTLINE. If a title has been suggested in PLOT_OUTLINE, you can use it, or replace it with a better one. - Use your 'write_file' tool to create a new txt file with the following arguments: - for a filename, use the movie title - Write to the 'movie_pitches' directory. - For the 'content' to write, include: - The PLOT_OUTLINE - The BOX_OFFICE_REPORT - The CASTING_REPORT PLOT_OUTLINE: { PLOT_OUTLINE? } BOX_OFFICE_REPORT: { box_office_report? } CASTING_REPORT: { casting_report? } """, - กลับไปที่แท็บ UI สำหรับนักพัฒนา ADK แล้วคลิก + เซสชันใหม่
- ป้อน
helloเพื่อเริ่มการสนทนา - เมื่อได้รับข้อความแจ้ง ให้ป้อนไอเดียตัวละครใหม่ ตัวอย่างบางส่วนมีดังนี้
- นักแสดงหญิงที่คิดค้นเทคโนโลยีสำหรับ Wi-Fi
- เชฟที่น่าตื่นเต้น
- ผู้เล่นหลักในนิทรรศการเวิลด์แฟร์
- เมื่อตัวแทนทำงานเสร็จแล้ว ให้ตรวจสอบไฟล์สุดท้ายในไดเรกทอรี
adk_multiagent_systems/movie_pitchesตอนนี้เอกสารควรมีเนื้อเรื่อง รายงานรายได้ และรายงานการคัดเลือกนักแสดงทั้งหมดในเอกสารเดียว
สรุปส่วน
ในส่วนนี้ คุณได้เรียนรู้วิธีใช้ParallelAgent
ParallelAgent"แฟนเอาต์" ทำงานโดยเรียกใช้ตัวแทนย่อยทั้งหมดพร้อมกันแทนที่จะเรียกใช้ตามลำดับ- ซึ่งมีประสิทธิภาพสูงสำหรับงานที่ไม่ขึ้นต่อกัน (เช่น การค้นคว้า 2 หัวข้อที่แตกต่างกัน)
- Agent ที่ทำงานแบบคู่ขนานจะ "รวบรวม" ผลลัพธ์โดย Agent ที่ทำงานในภายหลัง โดยทำได้ด้วยการให้เอเจนต์แบบคู่ขนานบันทึกงานของตนลงในสถานะเซสชัน (ใช้
output_key) และให้เอเจนต์สุดท้าย (เช่นfile_writer) อ่านคีย์เหล่านั้น
13. Agent เวิร์กโฟลว์ที่กำหนดเอง
เมื่อเอเจนต์เวิร์กโฟลว์ที่กำหนดไว้ล่วงหน้าของ SequentialAgent, LoopAgent และ ParallelAgent ไม่เพียงพอต่อความต้องการของคุณ CustomAgent จะช่วยให้คุณมีความยืดหยุ่นในการใช้ตรรกะเวิร์กโฟลว์ใหม่
คุณสามารถกำหนดรูปแบบสำหรับการควบคุมโฟลว์ การดำเนินการแบบมีเงื่อนไข หรือการจัดการสถานะระหว่างเอเจนต์ย่อย ซึ่งจะเป็นประโยชน์สำหรับเวิร์กโฟลว์ที่ซับซ้อน การจัดระเบียบแบบมีสถานะ หรือการผสานรวมตรรกะทางธุรกิจที่กำหนดเองเข้ากับเลเยอร์การจัดระเบียบของเฟรมเวิร์ก
การสร้าง CustomAgent อยู่นอกขอบเขตของแล็บนี้ แต่คุณควรทราบว่ามีฟีเจอร์นี้อยู่หากต้องการใช้
14. ยินดีด้วย
คุณสร้างระบบแบบหลายเอเจนต์ที่ซับซ้อนโดยใช้ Google Agent Development Kit (ADK) ได้สำเร็จแล้ว คุณได้พัฒนาจากความสัมพันธ์แบบ Agent หลักกับ Agent ย่อยอย่างง่ายไปสู่การประสานงานเวิร์กโฟลว์ที่ซับซ้อนและอัตโนมัติ ซึ่งสามารถค้นคว้า เขียน และปรับแต่งโปรเจ็กต์ครีเอทีฟโฆษณาได้
สรุป
ในแล็บนี้ คุณได้ทำสิ่งต่อไปนี้
- ตัวแทนที่จัดระเบียบในแผนผังลำดับชั้นที่มีความสัมพันธ์ระหว่างตัวแทนหลักและตัวแทนย่อย
- การโอนจากตัวแทนไปยังตัวแทนที่ควบคุม ทั้งโดยอัตโนมัติ (ใช้
description) และโดยชัดแจ้ง (ใช้instruction) - ใช้เครื่องมือเพื่อเขียนข้อมูลลงในพจนานุกรม
tool_context.state - ใช้การสร้างเทมเพลตคีย์ (เช่น
{ PLOT_OUTLINE? }) เพื่ออ่านจากสถานะเซสชันและแนะนำพรอมต์ของ Agent - ใช้
SequentialAgentเพื่อสร้างเวิร์กโฟลว์แบบทีละขั้นตอนง่ายๆ (ค้นคว้า -> เขียน -> บันทึก) - ใช้
LoopAgentกับเอเจนต์criticและเครื่องมือexit_loopเพื่อสร้างวงจรการปรับแต่งแบบวนซ้ำ - ใช้
ParallelAgentเพื่อ "กระจาย" งานอิสระ (เช่น การแคสต์และการวิจัยรายได้จากภาพยนตร์) ให้ทำงานพร้อมกัน
การทดสอบอย่างต่อเนื่อง
คุณสามารถนำสิ่งที่ได้เรียนรู้ไปต่อยอดได้หลายวิธี ลองดูแนวคิดบางส่วนกัน
- เพิ่มตัวแทน: ลองเพิ่มตัวแทนใหม่ลงใน
preproduction_teamParallelAgentเช่น คุณอาจสร้างmarketing_agentที่เขียนสโลแกนสำหรับภาพยนตร์โดยอิงตามPLOT_OUTLINE - เพิ่มเครื่องมือ: มอบเครื่องมือเพิ่มเติมให้
researcherAgent คุณอาจสร้างเครื่องมือที่ใช้ Google Search API เพื่อค้นหาข้อมูลที่ไม่มีใน Wikipedia - สำรวจ
CustomAgent: ห้องทดลองได้กล่าวถึงCustomAgentสำหรับเวิร์กโฟลว์ที่ไม่เหมาะกับเทมเพลตมาตรฐาน ลองสร้างตัวแทนที่เรียกใช้แบบมีเงื่อนไขเฉพาะในกรณีที่มีคีย์ที่เฉพาะเจาะจงในสถานะเซสชัน เป็นต้น