▶SUBTHAIแปลไทย · ซับ · พากย์⚙
บทความแปลภาษาไทย · YouTube

Day 4A: Multi-Agent Systems — Roles, Communication, Orchestration

0:000:00
เล่นเสียงต้นฉบับของวิดีโอ พร้อมแสดงซับไทยซิงก์ตามเวลา
กำลังโหลดวิดีโอ…
01

สรุปย่อ

ประเด็นสำคัญจากวิดีโอ

- **ช่อง:** Adspolitan Knowledge Studio · **ความยาว:** ~24 นาที · **ลิงก์:** https://www.youtube.com/watch?v=16QTif1cqoU

# สรุป: Day 4A: Multi-Agent Systems — Roles, Communication, Orchestration

- **ช่อง:** Adspolitan Knowledge Studio · **ความยาว:** ~24 นาที · **ลิงก์:** https://www.youtube.com/watch?v=16QTif1cqoU

## ประเด็นหลัก

- แม้ชื่อวิดีโอจะระบุ Multi-Agent Systems แต่เนื้อหาจริงของ assignment นี้คือ agent quality ที่มีรากฐานอยู่ที่ observability (การสังเกตการทำงานของเอเจนต์)
- เสาหลักของ agent observability มี 3 อย่าง: logs (เกิดอะไรขึ้นตอนไหน) traces (ทำไมผลลัพธ์จึงเป็นแบบนั้น — ลำดับขั้นตอนทั้งหมด) และ metrics (คะแนนว่าเอเจนต์ทำได้ดีแค่ไหน) — อธิบายด้วยอุปมาการทำอาหาร: logs = บันทึกวัตถุดิบ+ขั้นตอน, traces = ทำตามสูตรจริง, metrics = ให้คะแนนอาหาร
- ตัวอย่าง bug จริง: root agent ส่ง list ของ paper เป็น string แทน list ของ string ทำให้นับได้ 1690 paper แทนที่จะเป็น 14 — แก้ด้วยการตรวจ invocations ใน ADK web UI เห็น parameter ที่ LLM รับจริง
- การ debug ด้วย ADK web UI ใช้ได้ในช่วงพัฒนา แต่ production ไม่มีสิทธิ์เข้า web UI และเอเจนต์อาจรันวันละพันครั้ง — ต้องเก็บ observability data ด้วย log statements แทน
- Plugin คือโมดูลโค้ดที่รันอัตโนมัติตามช่วงต่างๆ ของวงจรเอเจนต์ ประกอบด้วย callbacks หลายตัว (before/after agent, before/after model, before/after tool, after error) — callbacks รวมกันเป็น plugin
- ตัวอย่าง CountInvocationPlugin นับจำนวนครั้งที่เอเจนต์และ LLM ถูกเรียก โดยเพิ่มค่าทีละหนึ่งใน before callback แต่ละตัว
- ไดอะแกรม 6 ขั้นตอนอธิบาย flow: user message → runner → plugin (before agent) → research agent → LLM (plugin ก่อน/หลัง model) → response กลับ — plugin ถูกเรียก 2 ครั้งต่อการรันหนึ่งครั้ง
- ADK มี built-in logging plugin ที่เก็บอัตโนมัติ: user messages, agent responses, timing data, LLM request/response, tool calls และ execution traces ทั้งหมด
- การใช้งาน: import plugin แล้วเสียบเข้าตอนสร้าง runner — log ที่ได้อ่านง่ายและอธิบายตัวเองได้ ไล่ดู invocation ID, event ID, token ได้ครบ
- วิดีโอถัดไป (Day 4B) คือ evaluation — การให้คะแนนคุณภาพคำตอบและการใช้ tool ของเอเจนต์

## ความเห็นสรุป

วิดีโอนี้เดินตาม notebook ทีละ cell เหมือนคลิปก่อนๆ ของซีรีส์ จุดเด่นคือการพา debug bug จริง (string แทน list) จนเห็นกันชัดๆ ว่า observability ช่วยหาสาเหตุได้อย่างไร แล้วต่อยอดสู่ logging แบบ plugin สำหรับ production ครับ ข้อควรระวังอีกอย่างคือชื่อวิดีโอกับเนื้อหาจริงไม่ตรงกันอีกครั้ง (ชื่อบอก Multi-Agent แต่สอน Observability/Logging) ผู้เรียนควรอาศัยคำอธิบายในวิดีโอเป็นหลักแทนชื่อคลิปครับ
02

คำแปลเต็ม

แปลตามบทสนทนาต้นฉบับ ปรับเป็นภาษาไทยธรรมชาติ

สวัสดีทุกคนครับ ยินดีต้อนรับเข้าสู่ assignment ของ Day 4 ในคอร์ส 5 วันนี้ครับ ใน assignment นี้เราจะเรียนเรื่อง agent quality หรือคุณภาพของเอเจนต์ครับ รากฐานพื้นฐานของเรื่องนี้คือ observability (ความสามารถในการสังเกตการทำงานของระบบ) ครับ โปรดตรวจสอบให้แน่ใจว่าคุณได้ฟังตอนสรุปพอดแคสต์ที่สร้างโดย NotebookLM และ white paper เรื่อง agent quality ซึ่งเป็นข้อมูลประกอบของพอดแคสต์นี้แล้วนะครับ white paper ฉบับนี้จัดการกับความท้าทายในการรับประกันคุณภาพของ AI agents โดยแนะนำกรอบการประเมินผลแบบ holistic หรือแบบองค์รวมครับ

ใน codelab พวกนี้เราจะเข้าใจคุณภาพของเอเจนต์อย่างครบถ้วน codelab แรกเกี่ยวกับวิธีใช้ logs traces และ metrics ส่วนอันที่สองคือการประเมินเอเจนต์ของเรา เพื่อให้คะแนนคุณภาพคำตอบของเอเจนต์และการใช้ tool ครับ ผมจะคลิกที่ implement ซึ่งจะพาไปที่ notebook แล้วผมจะแก้ไขสำเนาของผมจากตรงนี้ครับ

ตอนต้นของ notebook ให้สรุปว่า agent observability คืออะไร agent observability โดยพื้นฐานคือการเข้าใจ error ต่างๆ ติดตามทุกขั้นตอน และบันทึกรายละเอียดต่างๆ เพื่อ debug เมื่อจำเป็นครับ ตัวอย่างเช่น user สั่งว่าหางานวิจัยเรื่อง quantum computing ให้หน่อย แต่เอเจนต์ตอบว่าฉันช่วยเรื่องนี้ไม่ได้ ตอนนี้เราต้องเข้าใจว่า prompt ผิดตรงไหน มี tool ตัวไหนขาดหายไปหรือเปล่า หรือมี error ใน API ครับ ทางแก้ก็คือ agent observability ครับ มันให้มุมมองแบบครบถ้วนเกี่ยวกับกระบวนการตัดสินใจของเอเจนต์ คุณจะเห็นชัดเจนว่า prompt อะไรถูกส่งไปที่ LLM มี tool อะไรให้ใช้บ้าง โมเดลตอบอย่างไร และความล้มเหลวเกิดขึ้นตรงไหนครับ ตัว debug log จะแสดงให้เห็นว่า request นี้ไม่มี functions เลย ซึ่งหมายความว่าเราต้องแทรก Google Search tool ที่ขาดหายไปตรงนี้ครับ และนั่นคือวิธีแก้ไขครับ

เพื่ออธิบายให้เห็นภาพชัดขึ้น มีตัวอย่างหนึ่งครับ เสาหลักของ agent observability คือ logs traces และ metrics ครับ logs บอกเราว่าเกิดอะไรขึ้นในช่วงเวลาหนึ่งๆ traces แสดงให้เห็นว่าทำไมผลลัพธ์สุดท้ายจึงออกมาแบบนั้น โดยเปิดเผยลำดับขั้นตอนทั้งหมด ส่วน metrics คือคะแนน มันจะบอกว่าเอเจนต์ทำงานได้ดีแค่ไหนโดยรวมครับ ในตัวอย่างนี้มันแสดงให้เห็นว่าอาหารจานหนึ่งถูกปรุงขึ้นมาอย่างไร logs ก็เหมือนบันทึกการเตรียม ที่คุณระบุวัตถุดิบและขั้นตอนต่างๆ traces คือการที่คุณทำตามขั้นตอนเหล่านั้นเพื่อสร้างสูตรอาหารจริงๆ ส่วน metrics คือการให้คะแนนอาหารในด้านต่างๆ เช่น รสชาติ การจัดจาน ความคิดสร้างสรรค์ แล้วสรุปเป็นคะแนนรวมของจานนั้นครับ

ใน notebook นี้เราจะตั้งค่า logging configuration สร้างเอเจนต์ที่มีปัญหาที่เราจะแก้ไข แล้วเรียนรู้วิธี implement logging แบบ production รวมถึงเรียนรู้ว่าเมื่อไหร่ควรใช้ built-in logging เทียบกับโซลูชันที่เขียนเองครับ

ในการเริ่มต้น section แรกเป็นเรื่องตั้งค่า environment เสมอ ซึ่งเราทำกันมาในทุกวิดีโอแล้ว ผมจะรีบผ่านๆ ไปเลยนะครับ อย่างแรกคือตั้งค่า Gemini API วิธีทำคือไปที่ add-ons แล้วเลือก secret ตอนนี้เรายังไม่มี key ผมจะไปที่ Google AI Studio คัดลอก key จากตรงนั้น กลับมาที่ notebook กด add secret ใส่ชื่อ label เป็น Google API โปรดตรวจสอบให้แน่ใจว่าใส่ตรงตามนั้นทุกตัวอักษร เพราะมัน sensitive ต่อตัวพิมพ์ใหญ่เล็ก ต้องเหมือนกับที่ระบุในโค้ดตรงนี้เป๊ะครับ กด save แล้วตรวจว่ามันถูกติ๊กแล้วหรือยัง ติ๊กแล้วครับ ตอนนี้กดรัน เราได้รัน setup เรียบร้อย การยืนยันตัวตนและการตั้งค่าเสร็จสมบูรณ์แล้วครับ

ต่อไปเราจะจัดการไฟล์ logging และ cleanup เราจะตั้งค่ามันกัน import logging และ import os เพื่อล้าง log เดิมที่เหลือจากครั้งก่อน รันอันนี้ได้เลย ถ้ามี log file อยู่ใน logger file ใน web tunnel เราจะเอามันออก โดยใช้ path.exists ถ้าคุณมี log file ซึ่งก็ไฟล์พวกนี้ ก็จะลบไฟล์พวกนี้ทิ้ง แล้วพิมพ์ว่า cleaned up ครับ จากนั้นขั้นต่อไปคือ configure logging แบบ debug logging โดย basicConfig คือใส่ logger ตรงนี้ ใช้ level เป็น logging.DEBUG ส่วน format ประกอบด้วยชื่อไฟล์ เลขบรรทัด ระดับ และข้อความ พอรันก็บอกว่า logging configured ครับ

ขั้นต่อไปคือตั้งค่า proxy และ tunneling อันนี้ก็คือ helper function ที่เราทำกันมาแล้วในวิดีโอก่อนๆ ถ้าคุณใช้สภาพแวดล้อม notebook ของ Kaggle คุณต้องทำขั้นตอนนี้ แต่ถ้ารันนอกสภาพแวดล้อม Kaggle ก็ไม่จำเป็นต้องทำครับ ผมจะรันผ่านๆ ไป helper function ถูกนิยามแล้วครับ

มาถึง section สองซึ่งเป็นการ debug แบบลงมือจริงด้วย ADK web UI ครับ อันดับแรกเราจะสร้าง research paper finder agent เอเจนต์หางานวิจัย โดยเป้าหมายคือช่วย user หางานวิจัยวิชาการในหัวข้อใดก็ได้ครับ ตอนนี้คุณจะสังเกตเห็นว่ามันขึ้นว่าโฟลเดอร์ที่ไม่ว่างอยู่แล้ว มันถามว่าจะทับโมเดลที่มีอยู่เดิมของเราไหม y หรือ n คือ yes หรือ no ครับ เหตุผลที่ผมเจอข้อความนี้เพราะผมเคยทำมาแล้วก่อนถ่ายวิดีโอนี้ มันเลยบอกว่าโฟลเดอร์มีอยู่แล้ว ถ้าคุณทำครั้งแรกอาจจะไม่เห็นข้อความนี้ แต่ถ้าทำรอบที่สองเหมือนผมก็จะเจอข้อความนี้ครับ

ตอนนี้คุณเห็นว่ามันยังคง executing อยู่ หมายความว่า notebook กำลังรอ input แบบ interactive แต่เราพิมพ์ y แบบ interactive ภายใน cell ของ notebook ไม่ได้ครับ วิธีแก้คือทำให้มันตอบ yes อัตโนมัติ โดยแก้โค้ดตรงนี้ คือเพิ่ม force flag เข้าไปในคำสั่ง พิมพ์ขีดกลางสองอันแล้วพิมพ์ force ก็จะใช้ได้ครับ ปกติวิธีนี้ใช้ได้ แต่บางครั้งก็ไม่ได้ผล ในกรณีนั้นเราสามารถลบโฟลเดอร์ด้วยตนเองได้ครับ ระหว่างที่มันรันอยู่ ผมจะบอกว่าควรเขียนอะไรไว้ในกรณีที่ใช้ไม่ได้ครับ ให้เขียนว่าเครื่องหมายอัศเจรีย์ตามด้วย rm ครับ แล้วขั้นต่อไปคือรันอันนี้ ขอหยุดอันเดิมก่อนนะครับ โอเค ให้ผมรันอันนี้ก่อน เสร็จแล้ว ตอนนี้ผมจะเอา force ออก ขอโทษทีครับ นี่ไงเห็นไหมครับ

สิ่งที่ผมทำตรงนี้ ผมจะอธิบายให้ฟังนะครับ โค้ดนี้เป็นคำสั่ง shell ที่คุณรันภายใน notebook ของ Kaggle หรือ Jupyter ถ้ารันนอก Kaggle ก็ไม่ต้องมีส่วนนี้ครับ rm ย่อมาจาก remove แล้วก็ recursive กับ force นี่คือชื่อโฟลเดอร์ที่มีอยู่เดิม ผมสั่งให้มันลบ directory ของ research agent ทั้งหมดพร้อมไฟล์ข้างในทั้งหมดทันที ในสภาพแวดล้อม Kaggle หรือสภาพแวดล้อม Jupyter โดยไม่ต้องถามอะไรอีก นี่คือสิ่งที่โค้ดนี้ทำครับ หลังจากนั้นผมรันโค้ดก่อนหน้านี้ซ้ำอีกครั้ง มันจึงสร้าง research agent ใหม่ที่สะอาดเต็มไปหมดครับ

ทีนี้มานิยามเอเจนต์กันที่ตรงนี้ครับ ถ้าดูส่วนประกอบของ ADK ที่เราเคย import แยกในอีก cell หนึ่ง ตอนนี้เรารวมเข้ามาในโค้ดนิยามเอเจนต์เลยครับ ตรงนี้เรากำลัง configure ตัว LlmAgent โดยให้ชื่อ คำอธิบาย และ instructions ครับ ก่อนหน้านั้นขอคุยเรื่องนี้กันก่อน ในการนิยามเอเจนต์แบบนี้ เรามี root agent (เอเจนต์หลัก) ที่มอบหมายงานค้นหาให้ search agent แล้วก็มีอีกเอเจนต์หนึ่งที่ใช้ count_papers ครับ ส่วน import ที่เรียกเข้ามาอันดับแรกคือ agent กับ Gemini แล้วก็ agent tool และ Google Search ครับ ถ้าคุณรู้จักสิ่งเหล่านี้แล้ว เราก็นิยาม retry_config ไว้ในโค้ดเดียวกันนี้เลย แทนที่จะไว้ในส่วน setup ครับ

จากนั้นเราจงใจส่ง data type ที่ผิดพลาด คือส่ง string แทนที่จะเป็น list ของ string ครับ แล้วดูกันว่าจะเกิดอะไรขึ้น นิยาม count_papers โดยรับ papers เป็น string อาร์กิวเมนต์คือ papers ซึ่งเป็น list ของ string โดยแต่ละ string คืองานวิจัยหนึ่งชิ้น มันควรคืนค่าจำนวน paper ใน list นั้น คำสั่งคือ return len(papers) ครับ ต่อไปเรานิยาม Google search agent ให้ชื่อ model description และ instructions ครับ description คือค้นหาข้อมูลโดยใช้ Google Search ส่วน instruction คือให้ใช้เครื่องมือ Google Search ค้นหาข้อมูลในหัวข้อที่กำหนด แล้วคืนผลลัพธ์การค้นหาแบบดิบๆ ถ้า user ขอ list ของ paper ให้ส่ง list งานวิจัยที่เจอให้ ไม่ใช่สรุปย่อครับ เครื่องมือที่เราใช้ตรงนี้คือ Google Search ครับ

ส่วน root agent จะใช้ตัวนี้กับ count_papers ครับ มีชื่อ model และ instructions ว่า ภารกิจของเธอคือหางานวิจัยแล้วนับมัน เธอต้องทำตามขั้นตอนเหล่านี้เสมอ ขั้นแรกหางานวิจัยในหัวข้อที่ user ให้มาโดยใช้ Google search agent ซึ่งเรานิยามไว้ตรงนี้ในส่วน tools จากนั้นส่ง papers ที่ได้ไปที่ count_papers ซึ่งก็เป็น tool ตัวนี้อีกเช่นกัน เพื่อนับจำนวน paper แล้วคืนค่าทั้ง list งานวิจัยและจำนวน paper ทั้งหมดครับ มันต้องคืนผลลัพธ์สองอย่างคือ list กับจำนวน paper ครับ ผมกำลังสร้างเอเจนต์เหล่านี้ เราได้ทับ research agent เดิมแล้ว

ต่อไปเราจะรันเอเจนต์นี้ใน ADK web UI ครับ สำหรับขั้นนี้เราต้องสร้าง proxy ก่อน นี่คือการเข้าถึง URL ของ proxy โดยต้องรันอันนี้ก่อน พอเห็นว่า server เริ่มทำงานแล้ว เราก็พร้อมเริ่มต้นครับ กลับไปที่ section นี้ เปิด ADK web UI โดยคลิกตรงนี้ เห็นไหมครับ ถ้ากลับไปดู มันจะให้คำถามอย่างเช่นให้ทำสิ่งนี้ใน UI คุณต้องเลือก agent ที่ชื่อ research agent แล้วถามใน interface นี้ครับ เราเลือกไว้แล้วโดย default ครับ จะถามว่าหางานวิจัย quantum computing ล่าสุดหน่อย ซึ่งเป็นคำถามที่ระบุไว้ตรงนี้ พิมพ์ลงในช่องแชตครับ แล้วเอเจนต์ควรคืน list งานวิจัยพร้อมจำนวนที่นับได้ครับ

เรากลับมาดูกัน งานวิจัย computing ล่าสุดถูกพบแล้ว ได้ตัวนี้ ตัวนี้ และตัวนี้มา รวมทั้งหมดเป็น 1690 paper ซึ่งดูมหาศาลเกินไปครับ สิ่งที่เราทำคือไปที่ส่วน invocations ทางซ้ายแล้วขยายออก จะเห็นว่าการนับถูกทำอย่างไร นี่คือการเรียกใช้ tool ตัว count_papers ครับ คลิกตรงนี้ มันบอกว่า 1690 ครับ ผู้เขียนคือ research paper finder คุณจะเห็นการเรียก LLM ว่ามันรับ parameter อะไรไปบ้าง ถ้าดูจะเห็นว่ามันรับ text เป็น string แทนที่จะเป็น list นั่นเองครับ นี่จึงเป็นเหตุผลที่เราได้ 1690 paper ครับ

ทีนี้เราจะทำอะไรต่อ ต้องหยุด session ก่อนตรงนี้ครับ มันยังคงพูดเรื่องเดิมอยู่ คือ root agent ส่ง list ของ paper เป็น string แทนที่จะเป็น list ของ string และนั่นคือ bug ที่เราหาเจอครับ สิ่งที่ต้องทำต่อไปคือเปลี่ยน data type ของอาร์กิวเมนต์ papers ใน tool ชื่อ count_papers ให้เป็น list ของ string แล้วรันใหม่ครับ การจะรันใหม่เราต้องหยุดอันเดิมก่อน ถ้าไม่หยุดมันจะรันต่อไปเรื่อยๆ ผมต้องมาตรงนี้แล้วหยุดมันด้วยตนเองครับ โอเค หยุดแล้ว แล้วรันส่วน debug นี้ เราตรวจสอบ log ของ web server เพื่อหาเบาะแสการ debug ครับ

ระหว่างนั้นเราจะอัปเดต data type ของอาร์กิวเมนต์ papers ใน count_papers ให้เป็นแบบนี้กันด้วย กลับไปตรงนี้ นี่คือ count_papers ตรงนี้เดิมเป็น string เราจะเปลี่ยนเป็น list ของ string ครับ ทีนี้รันอันนี้ ทับของเดิม เขียนทับเรียบร้อยแล้ว เรากลับมาแล้วรันส่วนนี้ซ้ำ แล้วเริ่มอันนี้ขึ้นมาใหม่ web server ก็เริ่มทำงานครับ คลิกที่ลิงก์นี้ มันเปิดหน้าเอเจนต์ขึ้นมา สังเกตว่า agent ID กับ session ID ตรงนี้ไม่เหมือนเดิมแล้ว อันก่อนหน้านี้ต่างออกไป เราจึงใช้ตัวใหม่นี้ครับ คัดลอกคำถามเดิมมา ขอกลับไปเอาคำถามนี้ก่อนนะครับ วางแล้วกด enter คุณเห็น output ตรงนี้ไหมครับ ได้ข้อมูลมาแล้ว และอันสุดท้ายคือมี paper รวมทั้งหมด 14 ชิ้น เทียบกับอันก่อนที่บอก 1690 paper ครับ และตรงนี้เราก็สามารถเห็นการ execute ของโค้ดได้อีกเช่นกันครับ

ทีนี้คือ section สามครับ เราสามารถ debug ความล้มเหลวของเอเจนต์โดยใช้ ADK web UI และ debug log ได้ ปัญหาแรกคือ production development ปัญหาที่สองคือระบบอัตโนมัติครับ มีคนพูดว่า ขอเปิด ADK web UI เพื่อตรวจสอบว่าทำไมเอเจนต์ถึงล้มเหลว ทีม DevOps มักจะตอบว่า นี่คือ production server เข้าถึง web UI ไม่ได้ครับ ตอนนี้เราอยากเข้าใจว่าจะ debug ปัญหา production อย่างไร นี่คือสิ่งที่เราอยากจัดการครับ อีกเรื่องที่อยากจัดการคือ เอเจนต์รันวันละพันครั้งใน pipeline ของเราซึ่งรันช้า อัตราความสำเร็จของเราเป็นเท่าไหร่ แล้วคุณคงต้องไปเช็ค web UI ด้วยตนเองเป็นพันครั้ง ไม่ครับ ผมว่าเราไม่ควรทำแบบนั้นครับ

ดังนั้นเราต้องมีวิธีเก็บข้อมูล observability หรือพูดอีกอย่างคือเพิ่ม log เข้าไปในโค้ดของเราครับ นั่นแหละสิ่งที่เราทำกันอยู่ใช่ไหมครับ สำหรับแต่ละ batch เรามี batch run มีข้อมูล job run ครับ ในทำนองเดียวกันเราก็จะมีอะไรทำนองนี้เช่นกันครับ มันบอกว่าในการพัฒนาซอฟต์แวร์แบบดั้งเดิม เราทำโดยเพิ่ม log statement ในฟังก์ชัน Python และเอเจนต์ก็ไม่ต่างกัน เราต้องเพิ่ม log statement เข้าไปในเอเจนต์ของเราครับ แนวทางที่พบบ่อยคือการเพิ่ม log statement ใน plugin ครับ จะเพิ่ม log สำหรับ production observability อย่างไร เราจะทำด้วย plugin ครับ โดย plugin คือโมดูลโค้ดที่กำหนดเองซึ่งรันอัตโนมัติในหลายช่วงของวงจรชีวิตเอเจนต์ครับ แต่ละ plugin จะมี callback ดังที่เห็นในไดอะแกรมนี้ ซึ่งเป็น hook สำหรับแทรกตัวเข้าไปใน flow ของเอเจนต์ครับ

ตัวอย่างเช่น workflow ของเอเจนต์เป็นแบบนี้ครับ user message เข้ามา เอเจนต์คิด เรียกใช้ tool แล้วตอบกลับครับ เมื่อมี plugin hook สิ่งที่เกิดขึ้นคือ ก่อนเอเจนต์เริ่มทำงาน และหลัง tool รัน หรือหลัง response คุณสามารถวาง hook ได้ทุกจุดเลยครับ แล้ว callback คืออะไรกันแน่ มันคือส่วนประกอบย่อยภายใน plugin ครับ เหมือนมีชิ้นเล็กๆ อยู่ข้างใน plugin ไดอะแกรมนี้เราเคยเห็นใน Day 3 แล้ว มันคือฟังก์ชัน Python ที่รันในจุดเวลา specific ต่างๆ ของวงจรชีวิตเอเจนต์ครับ callback ถูกรวมกันเป็นกลุ่มเพื่อสร้าง plugin ครับ เวลาใช้ callback ก็เหมือนที่เราทำเมื่อวานนี้ มี callback แบบ before กับ after ของเอเจนต์ มี before กับ after ของ tool มี before กับ after ของ model และมี callback เมื่อเกิด error ครับ ทั้งหมดนี้คือ callback ที่คุณเสียบเข้าไปได้ครับ

เพื่อให้เห็นภาพชัดขึ้น มาดูกันว่า plugin หน้าตาเป็นอย่างไรครับ นี่คือตัวอย่าง ในโค้ดนี้มันไม่ได้ทำอะไรจริงจัง เราแค่ดูว่ามันทำงานอย่างไร ผมรันเพื่อดูว่า input เป็นอย่างไรครับ ระหว่างรันผมจะเล่าให้ฟังว่าเกิดอะไรขึ้นตรงนี้ คุณมี BaseAgent และมี callback context มี request และมี BasePlugin ครับ จากนั้นคุณใช้ BasePlugin ตัวนี้ใน count invocation plugin ที่คุณจะนิยามขึ้นครับ แล้วมี callback ตัวที่หนึ่ง คุณเขียนว่า self agent คือ BaseAgent ซึ่งเป็นเอเจนต์แรกที่คุณนิยามไว้ นี่คือ base agent ของคุณ และมี callback context ครับ

ทีนี้ count_agent_returns จะคืนค่าเช่นร้อยครั้ง พันครั้งอะไรทำนองนี้ ถ้าเป็นการบวกหนึ่งทุกครั้ง มันจะสะสมมากกว่าหนึ่งเสมอ ต้องนับมันไปเรื่อยๆ มันจะเพิ่มขึ้นเรื่อยๆ ครับ ตัวที่สอง callback ตัวที่สองรันก่อนที่ model จะถูกเรียก ตรงนี้คุณต้องมี model callback โดย callback context ก็ยังเป็น callback context เหมือนเดิม llm ก็คือ llm request เดิม ทีนี้คุณต้องนับ llm request ซึ่งก็บวกหนึ่งเช่นกันครับ ผมแค่รันอันนี้ ปกติมันไม่กระทบโค้ดของเราเลย พอเสร็จมันจะพิมพ์ว่า example plugin ไม่ทำอะไรเลย เพราะมันไม่ทำอะไร ผมจะกลับมาตรงนี้ คุณสามารถทำตามตัวเลขในไดอะแกรมด้านล่างเพื่อเข้าใจ flow ได้ครับ ไล่ตาม 1 2 แล้ว 3 4 5 ครับ

ขั้นแรกคือหางานวิจัย computing ล่าสุด ตามที่เราใส่ไปใน section ก่อนหน้าผ่านทาง web UI ครับ ตัว runner รันมัน เริ่มทำงาน ไปที่ memory agent ไปที่ agent tool และอื่นๆ ที่ตรงนี้ สิ่งที่เกิดขึ้นคือ count invocation plugin ซึ่งเป็น before agent callback ก่อนหน้านี้ มันไปที่เครื่องมือ research finding ก่อนตัวนั้น count เป็น none ครับ จากนั้นสิ่งที่เกิดขึ้นคือ runner ไปที่ research paper finder เพื่อไปที่โมเดล llm เพื่อหาว่าควรดูหน้าไหนบ้าง ระหว่างกลางมี plugin หนึ่ง นี่คือ before และ after และนี่คือ before model ด้วยเช่นกันครับ ขั้นที่หกคือมันรับกลับมา research agent ส่งต่อให้ runner แล้ว response ก็ออกไปครับ สิ่งที่เกิดขึ้นคือใน count invocation plugin ตัวนี้ถูกเรียกสองครั้ง ที่ขั้นตอนสองมันเรียกก่อนเอเจนต์ เพราะ plugin มี before agent callback ในทำนองเดียวกัน plugin ก็ถูก execute ก่อนการเรียก llm ซึ่งเกิดที่ขั้นตอนสี่ตรงนี้ครับ หวังว่าจะเข้าใจแจ่มชัดแล้วนะครับ

ต่อไปคือ built-in logging plugin ครับ built-in logging plugin คืออะไร ADK มี logging plugin แบบ built-in ซึ่งเก็บกิจกรรมของเอเจนต์โดยอัตโนมัติทั้งหมด เช่น ข้อความของ user และ response ของเอเจนต์ ข้อมูล timing สำหรับวิเคราะห์ประสิทธิภาพ request และ response ของ LLM เพื่อใช้ debug การเรียกใช้ tool และผลลัพธ์ รวมถึง execution trace แบบครบถ้วนครับ เราเคยนิยามเอเจนต์ไปแล้วสำหรับ research paper agent ตรงนี้เราทำคล้ายกันนี้อีกครั้ง โดยรัน research agent พร้อม logging ครับ ทุกอย่างเกือบเหมือนเดิม ตรงนี้ papers ถูกอัปเดตเป็น list ของ string แล้ว ข้อมูลส่วนที่เหลือถูกต้องครับ ต้องคืนค่าทั้งหมด instructions ก็เหมือนเดิมครับ ตรงนี้เราเพิ่ม research agent ด้วย plugin ครับ ผมจะรันตอนนี้เลย มันบอกว่าเอเจนต์ถูกสร้างสำเร็จแล้วครับ

ขั้นที่สามคือการใช้ plugin ใน research agent ด้านบน คลิกเพื่อ import plugin แล้วเพิ่มมันตอน initialize ตัว runner ครับ จาก ADK runners import runner ครับ คุณมี plugin ซึ่งก็คือ log plugin ผมจะรันอันนี้ มันบอกว่า runner ถูก configure แล้ว ใน runner ครับ เสร็จแล้ว ส่วนนี้เพิ่ม plugin เข้าไป มันจัดการ logging แบบ observability มาตรฐานให้กับเอเจนต์ทั้งหมดครับ ตัว runner ถูก configure แล้ว ทีนี้เราจะพิมพ์ statement ต่างๆ แล้วดูว่าได้ผลลัพธ์อะไร เราจะ debug ตอนนี้เลยครับ รันเอเจนต์พร้อม plugin แล้วดู logging output ที่ครอบคลุมครับ

response ตรงนี้คือ user message ได้รับแล้ว มี invocation กำลังใช้ debug ด้วย user ID นี้ มี context ตรงนี้ คือหางานวิจัยล่าสุดเรื่อง quantum computing ครับ แล้ว agent starting อยู่ตรงนี้ มี invocation ID ซึ่งเป็น plugin ID อีกอันหนึ่ง ตรงนี้บอกว่า research paper เริ่มแล้ว ก็มีแบบนี้อีกครับ ทีนี้เธอต้องทำตามขั้นตอนเหล่านี้ ขั้นแรกคือหางานวิจัยในหัวข้อที่ user ให้มาโดยใช้ Google search agent นี่คือ instruction แรกที่เราให้ไว้ใช่ไหมครับ มันบอกว่า tool ที่ใช้ได้คือตัวนี้กับตัวนี้ครับ

ใน LLM response เอเจนต์ research paper finder เรียกใช้ฟังก์ชันนี้ มี token ID มี input มี output เป็น 21 และมี event ID ตรงนี้ ทุก event ที่เกิดขึ้นถูกบันทึกครับ ตอนนี้ tool เริ่มทำงาน มี invocation ID ของ user message นี้ ตอนนี้เริ่ม invocation มีชื่อเอเจนต์ มี invocation ID ตัวนี้อยู่ตรงนี้ครับ ตอนนี้ model เริ่มทำงาน ตอนนี้เธอเป็นเอเจนต์หนึ่ง ชื่อภายในคือ Google search agent คำอธิบาย B ส่วน description เกี่ยวกับการค้นหา ฟิลด์ของ quantum เริ่มเพิ่ม context เข้ามา คุณสามารถไล่ดูได้เลย เรื่องนี้เข้าใจง่ายมาก มันอธิบายตัวเองได้ครับ

ในวิดีโอนี้เราได้ผ่านการ debug ในขั้นพัฒนา observability ระดับ production และ requirement แบบกำหนดเองครับ ในวิดีโอถัดไปซึ่งเป็นส่วนที่สองของ Day 4 เราจะเรียนเรื่อง evaluation คือวิธีประเมินและให้คะแนนคุณภาพคำตอบของเอเจนต์และการใช้ tool ครับ

03

หมายเหตุการแปล

ความโปร่งใสเกี่ยวกับความไม่แน่นอนในต้นฉบับ

  • ไม่มีการใช้สัญลักษณ์ระบุเสียงไม่ชัดเจน (0 จุด) — ทุก segment เข้าใจความหมายได้ครบ
04

อภิธานศัพท์เทคนิค

คำศัพท์และชื่อผลิตภัณฑ์ที่คงรูปภาษาอังกฤษ

ศัพท์คำแปล / คำอธิบาย
agent qualityคุณภาพของเอเจนต์
observabilityความสามารถในการสังเกต/ติดตามการทำงานภายในของระบบ
logsบันทึกเหตุการณ์ — บอกว่าเกิดอะไรขึ้นในช่วงเวลาหนึ่งๆ
tracesการติดตามเส้นทาง — แสดงลำดับขั้นตอนทั้งหมดว่าทำไมผลลัพธ์จึงเป็นเช่นนั้น
metricsตัวชี้วัด — คะแนนว่าเอเจนต์ทำงานได้ดีแค่ไหนโดยรวม
white paperเอกสารทางการเชิงเทคนิค
holistic evaluation frameworkกรอบการประเมินผลแบบองค์รวม
notebook LM / NotebookLMเครื่องมือสร้างสรุปเนื้อหา/พอดแคสต์จากเอกสารของ Google
debug logบันทึกข้อผิดพลาดใช้หาสาเหตุปัญหา
root agentเอเจนต์หลักที่มอบหมายงานให้เอเจนต์อื่น
search agentเอเจนต์ค้นหาข้อมูล
LlmAgentคลาสเอเจนต์ที่ขับเคลื่อนด้วย LLM ใน ADK
count_papersชื่อ tool ในตัวอย่าง ใช้นับจำนวนงานวิจัย
ADK web UIหน้าจอเว็บสำหรับรันและ debug เอเจนต์ของ ADK
proxyตัวกลางส่งต่อคำขอเครือข่าย ใช้เปิด web UI จาก notebook
tunnelingการเจาะทางผ่านเครือข่ายเพื่อเข้าถึง service ภายในจากภายนอก
invocationการเรียกใช้งานหนึ่งครั้งของเอเจนต์/โมเดล
productionสภาพแวดล้อมระบบจริงที่ใช้งานจริง
pipelineสายการผลิตกระบวนการทำงานอัตโนมัติ
pluginโมดูลโค้ดที่กำหนดเอง รันอัตโนมัติตามช่วงของวงจรเอเจนต์
callbackฟังก์ชันเรียกกลับที่รันในจุดเวลา specific ของวงจรเอเจนต์
BasePluginคลาสหลักสำหรับสร้าง plugin ใน ADK
BaseAgentคลาสหลักของเอเจนต์ใน ADK
hookจุดเกาะสำหรับแทรกโค้ดเข้าไปใน flow การทำงาน
built-in logging pluginplugin บันทึก log สำเร็จรูปที่ ADK ให้มา
logging configurationการตั้งค่าการบันทึก log
force flagตัวเลือกคำสั่ง (--force) บังคับดำเนินการโดยไม่ถามยืนยัน
rm -rfคำสั่ง shell ลบโฟลเดอร์/ไฟล์แบบ recursive + force
case sensitivesensitive ต่อตัวพิมพ์ใหญ่-เล็ก ต้องพิมพ์ตรงตาม
Google AI Studioเครื่องมือของ Google สำหรับสร้าง/จัดการ API key
Kaggleแพลตฟอร์มการแข่งขันและ notebook วิทยาศาสตร์ข้อมูล
Jupyter notebookสมุดบันทึกโค้ดแบบโต้ตอบ
sessionเซสชัน — หน่วยบทสนทนาหนึ่งครั้งกับเอเจนต์
eventเหตุการณ์หนึ่งๆ ที่เกิดระหว่างการทำงานของเอเจนต์
tokenหน่วยนับข้อความที่โมเดลใช้
evaluationการประเมินผลการทำงาน
data typeชนิดข้อมูล เช่น string หรือ list
string / listข้อความ / รายการหลายค่า
05

ซับไตเติ้ลภาษาไทย

ดาวน์โหลดหรือดูซับทั้งหมด

1
00:00:00,000 --> 00:00:04,283
สวัสดีทุกคนครับ ยินดีต้อนรับเข้าสู่ assignment

2
00:00:04,283 --> 00:00:08,379
ของ Day 4 ในคอร์ส 5 วันนี้ครับ ใน assignment

3
00:00:08,379 --> 00:00:11,452
นี้เราจะเรียนเรื่อง agent quality

4
00:00:11,452 --> 00:00:13,686
หรือคุณภาพของเอเจนต์ครับ
thai-subtitles.srt
SubRip — ใช้กับเครื่องเล่นวิดีโอส่วนใหญ่
↓ ดาวน์โหลด
thai-subtitles.vtt
WebVTT — ใช้กับเว็บ / YouTube
↓ ดาวน์โหลด
เปิดดูซับไตเติ้ลทั้งหมด (416 segments)
1
00:00:00,000 --> 00:00:04,283
สวัสดีทุกคนครับ ยินดีต้อนรับเข้าสู่ assignment

2
00:00:04,283 --> 00:00:08,379
ของ Day 4 ในคอร์ส 5 วันนี้ครับ ใน assignment

3
00:00:08,379 --> 00:00:11,452
นี้เราจะเรียนเรื่อง agent quality

4
00:00:11,452 --> 00:00:13,686
หรือคุณภาพของเอเจนต์ครับ

5
00:00:13,686 --> 00:00:17,597
รากฐานพื้นฐานของเรื่องนี้คือ observability

6
00:00:17,597 --> 00:00:21,600
(ความสามารถในการสังเกตการทำงานของระบบ) ครับ

7
00:00:21,600 --> 00:00:26,907
โปรดตรวจสอบให้แน่ใจว่าคุณได้ฟังตอนสรุปพอดแคสต์ที่สร้างโดย

8
00:00:26,907 --> 00:00:30,539
NotebookLM และ white paper เรื่อง agent

9
00:00:30,539 --> 00:00:31,636
quality

10
00:00:31,636 --> 00:00:35,732
ซึ่งเป็นข้อมูลประกอบของพอดแคสต์นี้แล้วนะครับ

11
00:00:35,732 --> 00:00:36,829
white paper

12
00:00:36,829 --> 00:00:41,392
ฉบับนี้จัดการกับความท้าทายในการรับประกันคุณภาพของ

13
00:00:41,392 --> 00:00:45,674
AI agents โดยแนะนำกรอบการประเมินผลแบบ holistic

14
00:00:45,674 --> 00:00:48,375
หรือแบบองค์รวมครับ ใน codelab

15
00:00:48,375 --> 00:00:52,564
พวกนี้เราจะเข้าใจคุณภาพของเอเจนต์อย่างครบถ้วน

16
00:00:52,564 --> 00:00:56,568
codelab แรกเกี่ยวกับวิธีใช้ logs traces และ

17
00:00:56,568 --> 00:00:57,665
metrics

18
00:00:57,665 --> 00:01:01,296
ส่วนอันที่สองคือการประเมินเอเจนต์ของเรา

19
00:01:01,296 --> 00:01:05,300
เพื่อให้คะแนนคุณภาพคำตอบของเอเจนต์และการใช้

20
00:01:05,300 --> 00:01:09,489
tool ครับ ผมจะคลิกที่ implement ซึ่งจะพาไปที่

21
00:01:09,489 --> 00:01:13,679
notebook แล้วผมจะแก้ไขสำเนาของผมจากตรงนี้ครับ

22
00:01:13,679 --> 00:01:16,938
ตอนต้นของ notebook ให้สรุปว่า agent

23
00:01:16,938 --> 00:01:20,755
observability คืออะไร agent observability

24
00:01:20,755 --> 00:01:23,921
โดยพื้นฐานคือการเข้าใจ error ต่างๆ

25
00:01:23,921 --> 00:01:27,738
ติดตามทุกขั้นตอน และบันทึกรายละเอียดต่างๆ

26
00:01:27,738 --> 00:01:31,928
เพื่อ debug เมื่อจำเป็นครับ ตัวอย่างเช่น user

27
00:01:31,928 --> 00:01:35,745
สั่งว่าหางานวิจัยเรื่อง quantum computing

28
00:01:35,745 --> 00:01:36,842
ให้หน่อย

29
00:01:36,842 --> 00:01:40,380
แต่เอเจนต์ตอบว่าฉันช่วยเรื่องนี้ไม่ได้

30
00:01:40,380 --> 00:01:44,291
ตอนนี้เราต้องเข้าใจว่า prompt ผิดตรงไหน มี

31
00:01:44,291 --> 00:01:48,387
tool ตัวไหนขาดหายไปหรือเปล่า หรือมี error ใน

32
00:01:48,387 --> 00:01:52,577
API ครับ ทางแก้ก็คือ agent observability ครับ

33
00:01:52,577 --> 00:01:57,977
มันให้มุมมองแบบครบถ้วนเกี่ยวกับกระบวนการตัดสินใจของเอเจนต์

34
00:01:57,977 --> 00:02:02,167
คุณจะเห็นชัดเจนว่า prompt อะไรถูกส่งไปที่ LLM

35
00:02:02,167 --> 00:02:05,705
มี tool อะไรให้ใช้บ้าง โมเดลตอบอย่างไร

36
00:02:05,705 --> 00:02:09,988
และความล้มเหลวเกิดขึ้นตรงไหนครับ ตัว debug log

37
00:02:09,988 --> 00:02:13,991
จะแสดงให้เห็นว่า request นี้ไม่มี functions

38
00:02:13,991 --> 00:02:18,088
เลย ซึ่งหมายความว่าเราต้องแทรก Google Search

39
00:02:18,088 --> 00:02:20,508
tool ที่ขาดหายไปตรงนี้ครับ

40
00:02:20,508 --> 00:02:22,650
และนั่นคือวิธีแก้ไขครับ

41
00:02:22,650 --> 00:02:25,257
เพื่ออธิบายให้เห็นภาพชัดขึ้น

42
00:02:25,257 --> 00:02:28,609
มีตัวอย่างหนึ่งครับ เสาหลักของ agent

43
00:02:28,609 --> 00:02:32,891
observability คือ logs traces และ metrics ครับ

44
00:02:32,891 --> 00:02:36,802
logs บอกเราว่าเกิดอะไรขึ้นในช่วงเวลาหนึ่งๆ

45
00:02:36,802 --> 00:02:37,899
traces

46
00:02:37,899 --> 00:02:42,275
แสดงให้เห็นว่าทำไมผลลัพธ์สุดท้ายจึงออกมาแบบนั้น

47
00:02:42,275 --> 00:02:46,185
โดยเปิดเผยลำดับขั้นตอนทั้งหมด ส่วน metrics

48
00:02:46,185 --> 00:02:47,283
คือคะแนน

49
00:02:47,283 --> 00:02:51,379
มันจะบอกว่าเอเจนต์ทำงานได้ดีแค่ไหนโดยรวมครับ

50
00:02:51,379 --> 00:02:57,245
ในตัวอย่างนี้มันแสดงให้เห็นว่าอาหารจานหนึ่งถูกปรุงขึ้นมาอย่างไร

51
00:02:57,245 --> 00:02:59,852
logs ก็เหมือนบันทึกการเตรียม

52
00:02:59,852 --> 00:03:02,924
ที่คุณระบุวัตถุดิบและขั้นตอนต่างๆ

53
00:03:02,924 --> 00:03:08,883
traces คือการที่คุณทำตามขั้นตอนเหล่านั้นเพื่อสร้างสูตรอาหารจริงๆ

54
00:03:08,883 --> 00:03:12,887
ส่วน metrics คือการให้คะแนนอาหารในด้านต่างๆ

55
00:03:12,887 --> 00:03:16,518
เช่น รสชาติ การจัดจาน ความคิดสร้างสรรค์

56
00:03:16,518 --> 00:03:20,800
แล้วสรุปเป็นคะแนนรวมของจานนั้นครับ ใน notebook

57
00:03:20,800 --> 00:03:24,245
นี้เราจะตั้งค่า logging configuration

58
00:03:24,245 --> 00:03:27,504
สร้างเอเจนต์ที่มีปัญหาที่เราจะแก้ไข

59
00:03:27,504 --> 00:03:31,042
แล้วเรียนรู้วิธี implement logging แบบ

60
00:03:31,042 --> 00:03:35,046
production รวมถึงเรียนรู้ว่าเมื่อไหร่ควรใช้

61
00:03:35,046 --> 00:03:36,535
built-in logging

62
00:03:36,535 --> 00:03:40,632
เทียบกับโซลูชันที่เขียนเองครับ ในการเริ่มต้น

63
00:03:40,632 --> 00:03:44,822
section แรกเป็นเรื่องตั้งค่า environment เสมอ

64
00:03:44,822 --> 00:03:48,732
ซึ่งเราทำกันมาในทุกวิดีโอแล้ว ผมจะรีบผ่านๆ

65
00:03:48,732 --> 00:03:52,549
ไปเลยนะครับ อย่างแรกคือตั้งค่า Gemini API

66
00:03:52,549 --> 00:03:56,180
วิธีทำคือไปที่ add-ons แล้วเลือก secret

67
00:03:56,180 --> 00:03:59,998
ตอนนี้เรายังไม่มี key ผมจะไปที่ Google AI

68
00:03:59,998 --> 00:04:03,536
Studio คัดลอก key จากตรงนั้น กลับมาที่

69
00:04:03,536 --> 00:04:07,353
notebook กด add secret ใส่ชื่อ label เป็น

70
00:04:07,353 --> 00:04:08,450
Google API

71
00:04:08,450 --> 00:04:12,733
โปรดตรวจสอบให้แน่ใจว่าใส่ตรงตามนั้นทุกตัวอักษร

72
00:04:12,733 --> 00:04:16,271
เพราะมัน sensitive ต่อตัวพิมพ์ใหญ่เล็ก

73
00:04:16,271 --> 00:04:20,275
ต้องเหมือนกับที่ระบุในโค้ดตรงนี้เป๊ะครับ กด

74
00:04:20,275 --> 00:04:23,719
save แล้วตรวจว่ามันถูกติ๊กแล้วหรือยัง

75
00:04:23,719 --> 00:04:27,444
ติ๊กแล้วครับ ตอนนี้กดรัน เราได้รัน setup

76
00:04:27,444 --> 00:04:28,541
เรียบร้อย

77
00:04:28,541 --> 00:04:32,917
การยืนยันตัวตนและการตั้งค่าเสร็จสมบูรณ์แล้วครับ

78
00:04:32,917 --> 00:04:36,641
ต่อไปเราจะจัดการไฟล์ logging และ cleanup

79
00:04:36,641 --> 00:04:40,738
เราจะตั้งค่ามันกัน import logging และ import

80
00:04:40,738 --> 00:04:44,555
os เพื่อล้าง log เดิมที่เหลือจากครั้งก่อน

81
00:04:44,555 --> 00:04:48,652
รันอันนี้ได้เลย ถ้ามี log file อยู่ใน logger

82
00:04:48,652 --> 00:04:52,376
file ใน web tunnel เราจะเอามันออก โดยใช้

83
00:04:52,376 --> 00:04:56,659
path.exists ถ้าคุณมี log file ซึ่งก็ไฟล์พวกนี้

84
00:04:56,659 --> 00:05:00,755
ก็จะลบไฟล์พวกนี้ทิ้ง แล้วพิมพ์ว่า cleaned up

85
00:05:00,755 --> 00:05:05,038
ครับ จากนั้นขั้นต่อไปคือ configure logging แบบ

86
00:05:05,038 --> 00:05:09,042
debug logging โดย basicConfig คือใส่ logger

87
00:05:09,042 --> 00:05:12,766
ตรงนี้ ใช้ level เป็น logging.DEBUG ส่วน

88
00:05:12,766 --> 00:05:16,583
format ประกอบด้วยชื่อไฟล์ เลขบรรทัด ระดับ

89
00:05:16,583 --> 00:05:20,587
และข้อความ พอรันก็บอกว่า logging configured

90
00:05:20,587 --> 00:05:24,683
ครับ ขั้นต่อไปคือตั้งค่า proxy และ tunneling

91
00:05:24,683 --> 00:05:27,197
อันนี้ก็คือ helper function

92
00:05:27,197 --> 00:05:29,990
ที่เราทำกันมาแล้วในวิดีโอก่อนๆ

93
00:05:29,990 --> 00:05:33,715
ถ้าคุณใช้สภาพแวดล้อม notebook ของ Kaggle

94
00:05:33,715 --> 00:05:37,718
คุณต้องทำขั้นตอนนี้ แต่ถ้ารันนอกสภาพแวดล้อม

95
00:05:37,718 --> 00:05:41,815
Kaggle ก็ไม่จำเป็นต้องทำครับ ผมจะรันผ่านๆ ไป

96
00:05:41,815 --> 00:05:46,098
helper function ถูกนิยามแล้วครับ มาถึง section

97
00:05:46,098 --> 00:05:50,287
สองซึ่งเป็นการ debug แบบลงมือจริงด้วย ADK web

98
00:05:50,287 --> 00:05:54,198
UI ครับ อันดับแรกเราจะสร้าง research paper

99
00:05:54,198 --> 00:05:56,991
finder agent เอเจนต์หางานวิจัย

100
00:05:56,991 --> 00:05:59,132
โดยเป้าหมายคือช่วย user

101
00:05:59,132 --> 00:06:02,484
หางานวิจัยวิชาการในหัวข้อใดก็ได้ครับ

102
00:06:02,484 --> 00:06:08,070
ตอนนี้คุณจะสังเกตเห็นว่ามันขึ้นว่าโฟลเดอร์ที่ไม่ว่างอยู่แล้ว

103
00:06:08,070 --> 00:06:12,074
มันถามว่าจะทับโมเดลที่มีอยู่เดิมของเราไหม y

104
00:06:12,074 --> 00:06:14,588
หรือ n คือ yes หรือ no ครับ

105
00:06:14,588 --> 00:06:20,081
เหตุผลที่ผมเจอข้อความนี้เพราะผมเคยทำมาแล้วก่อนถ่ายวิดีโอนี้

106
00:06:20,081 --> 00:06:22,874
มันเลยบอกว่าโฟลเดอร์มีอยู่แล้ว

107
00:06:22,874 --> 00:06:26,412
ถ้าคุณทำครั้งแรกอาจจะไม่เห็นข้อความนี้

108
00:06:26,412 --> 00:06:30,695
แต่ถ้าทำรอบที่สองเหมือนผมก็จะเจอข้อความนี้ครับ

109
00:06:30,695 --> 00:06:34,326
ตอนนี้คุณเห็นว่ามันยังคง executing อยู่

110
00:06:34,326 --> 00:06:37,864
หมายความว่า notebook กำลังรอ input แบบ

111
00:06:37,864 --> 00:06:41,681
interactive แต่เราพิมพ์ y แบบ interactive

112
00:06:41,681 --> 00:06:44,847
ภายใน cell ของ notebook ไม่ได้ครับ

113
00:06:44,847 --> 00:06:48,106
วิธีแก้คือทำให้มันตอบ yes อัตโนมัติ

114
00:06:48,106 --> 00:06:51,457
โดยแก้โค้ดตรงนี้ คือเพิ่ม force flag

115
00:06:51,457 --> 00:06:55,368
เข้าไปในคำสั่ง พิมพ์ขีดกลางสองอันแล้วพิมพ์

116
00:06:55,368 --> 00:06:58,906
force ก็จะใช้ได้ครับ ปกติวิธีนี้ใช้ได้

117
00:06:58,906 --> 00:07:00,861
แต่บางครั้งก็ไม่ได้ผล

118
00:07:00,861 --> 00:07:05,051
ในกรณีนั้นเราสามารถลบโฟลเดอร์ด้วยตนเองได้ครับ

119
00:07:05,051 --> 00:07:06,913
ระหว่างที่มันรันอยู่

120
00:07:06,913 --> 00:07:11,289
ผมจะบอกว่าควรเขียนอะไรไว้ในกรณีที่ใช้ไม่ได้ครับ

121
00:07:11,289 --> 00:07:15,572
ให้เขียนว่าเครื่องหมายอัศเจรีย์ตามด้วย rm ครับ

122
00:07:15,572 --> 00:07:17,899
แล้วขั้นต่อไปคือรันอันนี้

123
00:07:17,899 --> 00:07:20,506
ขอหยุดอันเดิมก่อนนะครับ โอเค

124
00:07:20,506 --> 00:07:24,417
ให้ผมรันอันนี้ก่อน เสร็จแล้ว ตอนนี้ผมจะเอา

125
00:07:24,417 --> 00:07:27,955
force ออก ขอโทษทีครับ นี่ไงเห็นไหมครับ

126
00:07:27,955 --> 00:07:31,679
สิ่งที่ผมทำตรงนี้ ผมจะอธิบายให้ฟังนะครับ

127
00:07:31,679 --> 00:07:35,217
โค้ดนี้เป็นคำสั่ง shell ที่คุณรันภายใน

128
00:07:35,217 --> 00:07:39,127
notebook ของ Kaggle หรือ Jupyter ถ้ารันนอก

129
00:07:39,127 --> 00:07:42,945
Kaggle ก็ไม่ต้องมีส่วนนี้ครับ rm ย่อมาจาก

130
00:07:42,945 --> 00:07:46,017
remove แล้วก็ recursive กับ force

131
00:07:46,017 --> 00:07:50,300
นี่คือชื่อโฟลเดอร์ที่มีอยู่เดิม ผมสั่งให้มันลบ

132
00:07:50,300 --> 00:07:52,907
directory ของ research agent

133
00:07:52,907 --> 00:07:56,072
ทั้งหมดพร้อมไฟล์ข้างในทั้งหมดทันที

134
00:07:56,072 --> 00:08:00,169
ในสภาพแวดล้อม Kaggle หรือสภาพแวดล้อม Jupyter

135
00:08:00,169 --> 00:08:02,031
โดยไม่ต้องถามอะไรอีก

136
00:08:02,031 --> 00:08:04,452
นี่คือสิ่งที่โค้ดนี้ทำครับ

137
00:08:04,452 --> 00:08:08,362
หลังจากนั้นผมรันโค้ดก่อนหน้านี้ซ้ำอีกครั้ง

138
00:08:08,362 --> 00:08:10,783
มันจึงสร้าง research agent

139
00:08:10,783 --> 00:08:13,111
ใหม่ที่สะอาดเต็มไปหมดครับ

140
00:08:13,111 --> 00:08:16,369
ทีนี้มานิยามเอเจนต์กันที่ตรงนี้ครับ

141
00:08:16,369 --> 00:08:20,000
ถ้าดูส่วนประกอบของ ADK ที่เราเคย import

142
00:08:20,000 --> 00:08:21,769
แยกในอีก cell หนึ่ง

143
00:08:21,769 --> 00:08:25,773
ตอนนี้เรารวมเข้ามาในโค้ดนิยามเอเจนต์เลยครับ

144
00:08:25,773 --> 00:08:29,218
ตรงนี้เรากำลัง configure ตัว LlmAgent

145
00:08:29,218 --> 00:08:33,035
โดยให้ชื่อ คำอธิบาย และ instructions ครับ

146
00:08:33,035 --> 00:08:36,108
ก่อนหน้านั้นขอคุยเรื่องนี้กันก่อน

147
00:08:36,108 --> 00:08:39,832
ในการนิยามเอเจนต์แบบนี้ เรามี root agent

148
00:08:39,832 --> 00:08:43,742
(เอเจนต์หลัก) ที่มอบหมายงานค้นหาให้ search

149
00:08:43,742 --> 00:08:47,001
agent แล้วก็มีอีกเอเจนต์หนึ่งที่ใช้

150
00:08:47,001 --> 00:08:49,701
count_papers ครับ ส่วน import

151
00:08:49,701 --> 00:08:53,705
ที่เรียกเข้ามาอันดับแรกคือ agent กับ Gemini

152
00:08:53,705 --> 00:08:57,429
แล้วก็ agent tool และ Google Search ครับ

153
00:08:57,429 --> 00:09:01,060
ถ้าคุณรู้จักสิ่งเหล่านี้แล้ว เราก็นิยาม

154
00:09:01,060 --> 00:09:04,412
retry_config ไว้ในโค้ดเดียวกันนี้เลย

155
00:09:04,412 --> 00:09:08,694
แทนที่จะไว้ในส่วน setup ครับ จากนั้นเราจงใจส่ง

156
00:09:08,694 --> 00:09:11,860
data type ที่ผิดพลาด คือส่ง string

157
00:09:11,860 --> 00:09:14,933
แทนที่จะเป็น list ของ string ครับ

158
00:09:14,933 --> 00:09:19,122
แล้วดูกันว่าจะเกิดอะไรขึ้น นิยาม count_papers

159
00:09:19,122 --> 00:09:22,940
โดยรับ papers เป็น string อาร์กิวเมนต์คือ

160
00:09:22,940 --> 00:09:26,664
papers ซึ่งเป็น list ของ string โดยแต่ละ

161
00:09:26,664 --> 00:09:30,854
string คืองานวิจัยหนึ่งชิ้น มันควรคืนค่าจำนวน

162
00:09:30,854 --> 00:09:34,112
paper ใน list นั้น คำสั่งคือ return

163
00:09:34,112 --> 00:09:38,209
len(papers) ครับ ต่อไปเรานิยาม Google search

164
00:09:38,209 --> 00:09:41,468
agent ให้ชื่อ model description และ

165
00:09:41,468 --> 00:09:44,168
instructions ครับ description

166
00:09:44,168 --> 00:09:47,799
คือค้นหาข้อมูลโดยใช้ Google Search ส่วน

167
00:09:47,799 --> 00:09:51,988
instruction คือให้ใช้เครื่องมือ Google Search

168
00:09:51,988 --> 00:09:54,502
ค้นหาข้อมูลในหัวข้อที่กำหนด

169
00:09:54,502 --> 00:09:58,785
แล้วคืนผลลัพธ์การค้นหาแบบดิบๆ ถ้า user ขอ list

170
00:09:58,785 --> 00:10:02,416
ของ paper ให้ส่ง list งานวิจัยที่เจอให้

171
00:10:02,416 --> 00:10:06,699
ไม่ใช่สรุปย่อครับ เครื่องมือที่เราใช้ตรงนี้คือ

172
00:10:06,699 --> 00:10:09,865
Google Search ครับ ส่วน root agent

173
00:10:09,865 --> 00:10:14,054
จะใช้ตัวนี้กับ count_papers ครับ มีชื่อ model

174
00:10:14,054 --> 00:10:15,916
และ instructions ว่า

175
00:10:15,916 --> 00:10:19,175
ภารกิจของเธอคือหางานวิจัยแล้วนับมัน

176
00:10:19,175 --> 00:10:22,061
เธอต้องทำตามขั้นตอนเหล่านี้เสมอ

177
00:10:22,061 --> 00:10:26,251
ขั้นแรกหางานวิจัยในหัวข้อที่ user ให้มาโดยใช้

178
00:10:26,251 --> 00:10:28,020
Google search agent

179
00:10:28,020 --> 00:10:32,117
ซึ่งเรานิยามไว้ตรงนี้ในส่วน tools จากนั้นส่ง

180
00:10:32,117 --> 00:10:36,027
papers ที่ได้ไปที่ count_papers ซึ่งก็เป็น

181
00:10:36,027 --> 00:10:39,844
tool ตัวนี้อีกเช่นกัน เพื่อนับจำนวน paper

182
00:10:39,844 --> 00:10:43,755
แล้วคืนค่าทั้ง list งานวิจัยและจำนวน paper

183
00:10:43,755 --> 00:10:47,945
ทั้งหมดครับ มันต้องคืนผลลัพธ์สองอย่างคือ list

184
00:10:47,945 --> 00:10:49,714
กับจำนวน paper ครับ

185
00:10:49,714 --> 00:10:53,996
ผมกำลังสร้างเอเจนต์เหล่านี้ เราได้ทับ research

186
00:10:53,996 --> 00:10:58,093
agent เดิมแล้ว ต่อไปเราจะรันเอเจนต์นี้ใน ADK

187
00:10:58,093 --> 00:11:02,097
web UI ครับ สำหรับขั้นนี้เราต้องสร้าง proxy

188
00:11:02,097 --> 00:11:05,355
ก่อน นี่คือการเข้าถึง URL ของ proxy

189
00:11:05,355 --> 00:11:08,800
โดยต้องรันอันนี้ก่อน พอเห็นว่า server

190
00:11:08,800 --> 00:11:12,245
เริ่มทำงานแล้ว เราก็พร้อมเริ่มต้นครับ

191
00:11:12,245 --> 00:11:15,690
กลับไปที่ section นี้ เปิด ADK web UI

192
00:11:15,690 --> 00:11:19,135
โดยคลิกตรงนี้ เห็นไหมครับ ถ้ากลับไปดู

193
00:11:19,135 --> 00:11:22,766
มันจะให้คำถามอย่างเช่นให้ทำสิ่งนี้ใน UI

194
00:11:22,766 --> 00:11:26,583
คุณต้องเลือก agent ที่ชื่อ research agent

195
00:11:26,583 --> 00:11:30,866
แล้วถามใน interface นี้ครับ เราเลือกไว้แล้วโดย

196
00:11:30,866 --> 00:11:34,497
default ครับ จะถามว่าหางานวิจัย quantum

197
00:11:34,497 --> 00:11:36,452
computing ล่าสุดหน่อย

198
00:11:36,452 --> 00:11:39,153
ซึ่งเป็นคำถามที่ระบุไว้ตรงนี้

199
00:11:39,153 --> 00:11:43,156
พิมพ์ลงในช่องแชตครับ แล้วเอเจนต์ควรคืน list

200
00:11:43,156 --> 00:11:47,439
งานวิจัยพร้อมจำนวนที่นับได้ครับ เรากลับมาดูกัน

201
00:11:47,439 --> 00:11:51,536
งานวิจัย computing ล่าสุดถูกพบแล้ว ได้ตัวนี้

202
00:11:51,536 --> 00:11:55,632
ตัวนี้ และตัวนี้มา รวมทั้งหมดเป็น 1690 paper

203
00:11:55,632 --> 00:11:57,680
ซึ่งดูมหาศาลเกินไปครับ

204
00:11:57,680 --> 00:12:01,032
สิ่งที่เราทำคือไปที่ส่วน invocations

205
00:12:01,032 --> 00:12:05,315
ทางซ้ายแล้วขยายออก จะเห็นว่าการนับถูกทำอย่างไร

206
00:12:05,315 --> 00:12:09,412
นี่คือการเรียกใช้ tool ตัว count_papers ครับ

207
00:12:09,412 --> 00:12:13,322
คลิกตรงนี้ มันบอกว่า 1690 ครับ ผู้เขียนคือ

208
00:12:13,322 --> 00:12:17,326
research paper finder คุณจะเห็นการเรียก LLM

209
00:12:17,326 --> 00:12:20,119
ว่ามันรับ parameter อะไรไปบ้าง

210
00:12:20,119 --> 00:12:23,564
ถ้าดูจะเห็นว่ามันรับ text เป็น string

211
00:12:23,564 --> 00:12:26,264
แทนที่จะเป็น list นั่นเองครับ

212
00:12:26,264 --> 00:12:30,081
นี่จึงเป็นเหตุผลที่เราได้ 1690 paper ครับ

213
00:12:30,081 --> 00:12:33,433
ทีนี้เราจะทำอะไรต่อ ต้องหยุด session

214
00:12:33,433 --> 00:12:37,529
ก่อนตรงนี้ครับ มันยังคงพูดเรื่องเดิมอยู่ คือ

215
00:12:37,529 --> 00:12:41,347
root agent ส่ง list ของ paper เป็น string

216
00:12:41,347 --> 00:12:45,350
แทนที่จะเป็น list ของ string และนั่นคือ bug

217
00:12:45,350 --> 00:12:49,447
ที่เราหาเจอครับ สิ่งที่ต้องทำต่อไปคือเปลี่ยน

218
00:12:49,447 --> 00:12:53,637
data type ของอาร์กิวเมนต์ papers ใน tool ชื่อ

219
00:12:53,637 --> 00:12:56,988
count_papers ให้เป็น list ของ string

220
00:12:56,988 --> 00:12:58,385
แล้วรันใหม่ครับ

221
00:12:58,385 --> 00:13:01,551
การจะรันใหม่เราต้องหยุดอันเดิมก่อน

222
00:13:01,551 --> 00:13:04,344
ถ้าไม่หยุดมันจะรันต่อไปเรื่อยๆ

223
00:13:04,344 --> 00:13:08,347
ผมต้องมาตรงนี้แล้วหยุดมันด้วยตนเองครับ โอเค

224
00:13:08,347 --> 00:13:12,537
หยุดแล้ว แล้วรันส่วน debug นี้ เราตรวจสอบ log

225
00:13:12,537 --> 00:13:16,447
ของ web server เพื่อหาเบาะแสการ debug ครับ

226
00:13:16,447 --> 00:13:19,427
ระหว่างนั้นเราจะอัปเดต data type

227
00:13:19,427 --> 00:13:22,965
ของอาร์กิวเมนต์ papers ใน count_papers

228
00:13:22,965 --> 00:13:26,689
ให้เป็นแบบนี้กันด้วย กลับไปตรงนี้ นี่คือ

229
00:13:26,689 --> 00:13:29,855
count_papers ตรงนี้เดิมเป็น string

230
00:13:29,855 --> 00:13:33,300
เราจะเปลี่ยนเป็น list ของ string ครับ

231
00:13:33,300 --> 00:13:35,627
ทีนี้รันอันนี้ ทับของเดิม

232
00:13:35,627 --> 00:13:37,582
เขียนทับเรียบร้อยแล้ว

233
00:13:37,582 --> 00:13:40,003
เรากลับมาแล้วรันส่วนนี้ซ้ำ

234
00:13:40,003 --> 00:13:43,355
แล้วเริ่มอันนี้ขึ้นมาใหม่ web server

235
00:13:43,355 --> 00:13:46,334
ก็เริ่มทำงานครับ คลิกที่ลิงก์นี้

236
00:13:46,334 --> 00:13:50,338
มันเปิดหน้าเอเจนต์ขึ้นมา สังเกตว่า agent ID

237
00:13:50,338 --> 00:13:53,876
กับ session ID ตรงนี้ไม่เหมือนเดิมแล้ว

238
00:13:53,876 --> 00:13:56,017
อันก่อนหน้านี้ต่างออกไป

239
00:13:56,017 --> 00:13:59,835
เราจึงใช้ตัวใหม่นี้ครับ คัดลอกคำถามเดิมมา

240
00:13:59,835 --> 00:14:04,024
ขอกลับไปเอาคำถามนี้ก่อนนะครับ วางแล้วกด enter

241
00:14:04,024 --> 00:14:08,121
คุณเห็น output ตรงนี้ไหมครับ ได้ข้อมูลมาแล้ว

242
00:14:08,121 --> 00:14:12,124
และอันสุดท้ายคือมี paper รวมทั้งหมด 14 ชิ้น

243
00:14:12,124 --> 00:14:15,569
เทียบกับอันก่อนที่บอก 1690 paper ครับ

244
00:14:15,569 --> 00:14:18,828
และตรงนี้เราก็สามารถเห็นการ execute

245
00:14:18,828 --> 00:14:22,645
ของโค้ดได้อีกเช่นกันครับ ทีนี้คือ section

246
00:14:22,645 --> 00:14:24,787
สามครับ เราสามารถ debug

247
00:14:24,787 --> 00:14:28,697
ความล้มเหลวของเอเจนต์โดยใช้ ADK web UI และ

248
00:14:28,697 --> 00:14:32,049
debug log ได้ ปัญหาแรกคือ production

249
00:14:32,049 --> 00:14:36,052
development ปัญหาที่สองคือระบบอัตโนมัติครับ

250
00:14:36,052 --> 00:14:38,659
มีคนพูดว่า ขอเปิด ADK web UI

251
00:14:38,659 --> 00:14:42,384
เพื่อตรวจสอบว่าทำไมเอเจนต์ถึงล้มเหลว ทีม

252
00:14:42,384 --> 00:14:46,387
DevOps มักจะตอบว่า นี่คือ production server

253
00:14:46,387 --> 00:14:48,715
เข้าถึง web UI ไม่ได้ครับ

254
00:14:48,715 --> 00:14:52,067
ตอนนี้เราอยากเข้าใจว่าจะ debug ปัญหา

255
00:14:52,067 --> 00:14:53,742
production อย่างไร

256
00:14:53,742 --> 00:14:56,536
นี่คือสิ่งที่เราอยากจัดการครับ

257
00:14:56,536 --> 00:14:58,863
อีกเรื่องที่อยากจัดการคือ

258
00:14:58,863 --> 00:15:02,029
เอเจนต์รันวันละพันครั้งใน pipeline

259
00:15:02,029 --> 00:15:03,518
ของเราซึ่งรันช้า

260
00:15:03,518 --> 00:15:06,591
อัตราความสำเร็จของเราเป็นเท่าไหร่

261
00:15:06,591 --> 00:15:09,012
แล้วคุณคงต้องไปเช็ค web UI

262
00:15:09,012 --> 00:15:11,712
ด้วยตนเองเป็นพันครั้ง ไม่ครับ

263
00:15:11,712 --> 00:15:14,226
ผมว่าเราไม่ควรทำแบบนั้นครับ

264
00:15:14,226 --> 00:15:18,322
ดังนั้นเราต้องมีวิธีเก็บข้อมูล observability

265
00:15:18,322 --> 00:15:20,836
หรือพูดอีกอย่างคือเพิ่ม log

266
00:15:20,836 --> 00:15:22,884
เข้าไปในโค้ดของเราครับ

267
00:15:22,884 --> 00:15:26,329
นั่นแหละสิ่งที่เราทำกันอยู่ใช่ไหมครับ

268
00:15:26,329 --> 00:15:30,612
สำหรับแต่ละ batch เรามี batch run มีข้อมูล job

269
00:15:30,612 --> 00:15:31,709
run ครับ

270
00:15:31,709 --> 00:15:36,085
ในทำนองเดียวกันเราก็จะมีอะไรทำนองนี้เช่นกันครับ

271
00:15:36,085 --> 00:15:39,716
มันบอกว่าในการพัฒนาซอฟต์แวร์แบบดั้งเดิม

272
00:15:39,716 --> 00:15:43,906
เราทำโดยเพิ่ม log statement ในฟังก์ชัน Python

273
00:15:43,906 --> 00:15:47,537
และเอเจนต์ก็ไม่ต่างกัน เราต้องเพิ่ม log

274
00:15:47,537 --> 00:15:50,796
statement เข้าไปในเอเจนต์ของเราครับ

275
00:15:50,796 --> 00:15:54,799
แนวทางที่พบบ่อยคือการเพิ่ม log statement ใน

276
00:15:54,799 --> 00:15:58,617
plugin ครับ จะเพิ่ม log สำหรับ production

277
00:15:58,617 --> 00:16:02,806
observability อย่างไร เราจะทำด้วย plugin ครับ

278
00:16:02,806 --> 00:16:03,904
โดย plugin

279
00:16:03,904 --> 00:16:10,607
คือโมดูลโค้ดที่กำหนดเองซึ่งรันอัตโนมัติในหลายช่วงของวงจรชีวิตเอเจนต์ครับ

280
00:16:10,607 --> 00:16:13,028
แต่ละ plugin จะมี callback

281
00:16:13,028 --> 00:16:16,473
ดังที่เห็นในไดอะแกรมนี้ ซึ่งเป็น hook

282
00:16:16,473 --> 00:16:20,290
สำหรับแทรกตัวเข้าไปใน flow ของเอเจนต์ครับ

283
00:16:20,290 --> 00:16:24,573
ตัวอย่างเช่น workflow ของเอเจนต์เป็นแบบนี้ครับ

284
00:16:24,573 --> 00:16:28,670
user message เข้ามา เอเจนต์คิด เรียกใช้ tool

285
00:16:28,670 --> 00:16:31,928
แล้วตอบกลับครับ เมื่อมี plugin hook

286
00:16:31,928 --> 00:16:35,652
สิ่งที่เกิดขึ้นคือ ก่อนเอเจนต์เริ่มทำงาน

287
00:16:35,652 --> 00:16:38,818
และหลัง tool รัน หรือหลัง response

288
00:16:38,818 --> 00:16:42,449
คุณสามารถวาง hook ได้ทุกจุดเลยครับ แล้ว

289
00:16:42,449 --> 00:16:44,497
callback คืออะไรกันแน่

290
00:16:44,497 --> 00:16:47,942
มันคือส่วนประกอบย่อยภายใน plugin ครับ

291
00:16:47,942 --> 00:16:51,201
เหมือนมีชิ้นเล็กๆ อยู่ข้างใน plugin

292
00:16:51,201 --> 00:16:54,367
ไดอะแกรมนี้เราเคยเห็นใน Day 3 แล้ว

293
00:16:54,367 --> 00:16:58,649
มันคือฟังก์ชัน Python ที่รันในจุดเวลา specific

294
00:16:58,649 --> 00:17:02,187
ต่างๆ ของวงจรชีวิตเอเจนต์ครับ callback

295
00:17:02,187 --> 00:17:05,912
ถูกรวมกันเป็นกลุ่มเพื่อสร้าง plugin ครับ

296
00:17:05,912 --> 00:17:10,008
เวลาใช้ callback ก็เหมือนที่เราทำเมื่อวานนี้

297
00:17:10,008 --> 00:17:14,291
มี callback แบบ before กับ after ของเอเจนต์ มี

298
00:17:14,291 --> 00:17:18,481
before กับ after ของ tool มี before กับ after

299
00:17:18,481 --> 00:17:22,671
ของ model และมี callback เมื่อเกิด error ครับ

300
00:17:22,671 --> 00:17:24,719
ทั้งหมดนี้คือ callback

301
00:17:24,719 --> 00:17:26,953
ที่คุณเสียบเข้าไปได้ครับ

302
00:17:26,953 --> 00:17:30,678
เพื่อให้เห็นภาพชัดขึ้น มาดูกันว่า plugin

303
00:17:30,678 --> 00:17:34,029
หน้าตาเป็นอย่างไรครับ นี่คือตัวอย่าง

304
00:17:34,029 --> 00:17:36,916
ในโค้ดนี้มันไม่ได้ทำอะไรจริงจัง

305
00:17:36,916 --> 00:17:40,826
เราแค่ดูว่ามันทำงานอย่างไร ผมรันเพื่อดูว่า

306
00:17:40,826 --> 00:17:42,781
input เป็นอย่างไรครับ

307
00:17:42,781 --> 00:17:46,971
ระหว่างรันผมจะเล่าให้ฟังว่าเกิดอะไรขึ้นตรงนี้

308
00:17:46,971 --> 00:17:50,788
คุณมี BaseAgent และมี callback context มี

309
00:17:50,788 --> 00:17:54,792
request และมี BasePlugin ครับ จากนั้นคุณใช้

310
00:17:54,792 --> 00:17:58,795
BasePlugin ตัวนี้ใน count invocation plugin

311
00:17:58,795 --> 00:18:02,240
ที่คุณจะนิยามขึ้นครับ แล้วมี callback

312
00:18:02,240 --> 00:18:05,778
ตัวที่หนึ่ง คุณเขียนว่า self agent คือ

313
00:18:05,778 --> 00:18:09,689
BaseAgent ซึ่งเป็นเอเจนต์แรกที่คุณนิยามไว้

314
00:18:09,689 --> 00:18:13,320
นี่คือ base agent ของคุณ และมี callback

315
00:18:13,320 --> 00:18:16,858
context ครับ ทีนี้ count_agent_returns

316
00:18:16,858 --> 00:18:20,768
จะคืนค่าเช่นร้อยครั้ง พันครั้งอะไรทำนองนี้

317
00:18:20,768 --> 00:18:23,189
ถ้าเป็นการบวกหนึ่งทุกครั้ง

318
00:18:23,189 --> 00:18:27,379
มันจะสะสมมากกว่าหนึ่งเสมอ ต้องนับมันไปเรื่อยๆ

319
00:18:27,379 --> 00:18:31,568
มันจะเพิ่มขึ้นเรื่อยๆ ครับ ตัวที่สอง callback

320
00:18:31,568 --> 00:18:34,920
ตัวที่สองรันก่อนที่ model จะถูกเรียก

321
00:18:34,920 --> 00:18:38,924
ตรงนี้คุณต้องมี model callback โดย callback

322
00:18:38,924 --> 00:18:43,114
context ก็ยังเป็น callback context เหมือนเดิม

323
00:18:43,114 --> 00:18:47,396
llm ก็คือ llm request เดิม ทีนี้คุณต้องนับ llm

324
00:18:47,396 --> 00:18:50,469
request ซึ่งก็บวกหนึ่งเช่นกันครับ

325
00:18:50,469 --> 00:18:54,472
ผมแค่รันอันนี้ ปกติมันไม่กระทบโค้ดของเราเลย

326
00:18:54,472 --> 00:18:57,731
พอเสร็จมันจะพิมพ์ว่า example plugin

327
00:18:57,731 --> 00:19:00,524
ไม่ทำอะไรเลย เพราะมันไม่ทำอะไร

328
00:19:00,524 --> 00:19:02,014
ผมจะกลับมาตรงนี้

329
00:19:02,014 --> 00:19:06,576
คุณสามารถทำตามตัวเลขในไดอะแกรมด้านล่างเพื่อเข้าใจ

330
00:19:06,576 --> 00:19:10,207
flow ได้ครับ ไล่ตาม 1 2 แล้ว 3 4 5 ครับ

331
00:19:10,207 --> 00:19:13,652
ขั้นแรกคือหางานวิจัย computing ล่าสุด

332
00:19:13,652 --> 00:19:17,749
ตามที่เราใส่ไปใน section ก่อนหน้าผ่านทาง web

333
00:19:17,749 --> 00:19:21,659
UI ครับ ตัว runner รันมัน เริ่มทำงาน ไปที่

334
00:19:21,659 --> 00:19:25,197
memory agent ไปที่ agent tool และอื่นๆ

335
00:19:25,197 --> 00:19:29,387
ที่ตรงนี้ สิ่งที่เกิดขึ้นคือ count invocation

336
00:19:29,387 --> 00:19:32,832
plugin ซึ่งเป็น before agent callback

337
00:19:32,832 --> 00:19:36,463
ก่อนหน้านี้ มันไปที่เครื่องมือ research

338
00:19:36,463 --> 00:19:40,187
finding ก่อนตัวนั้น count เป็น none ครับ

339
00:19:40,187 --> 00:19:43,725
จากนั้นสิ่งที่เกิดขึ้นคือ runner ไปที่

340
00:19:43,725 --> 00:19:47,542
research paper finder เพื่อไปที่โมเดล llm

341
00:19:47,542 --> 00:19:51,267
เพื่อหาว่าควรดูหน้าไหนบ้าง ระหว่างกลางมี

342
00:19:51,267 --> 00:19:55,549
plugin หนึ่ง นี่คือ before และ after และนี่คือ

343
00:19:55,549 --> 00:19:58,156
before model ด้วยเช่นกันครับ

344
00:19:58,156 --> 00:20:01,787
ขั้นที่หกคือมันรับกลับมา research agent

345
00:20:01,787 --> 00:20:05,698
ส่งต่อให้ runner แล้ว response ก็ออกไปครับ

346
00:20:05,698 --> 00:20:09,794
สิ่งที่เกิดขึ้นคือใน count invocation plugin

347
00:20:09,794 --> 00:20:11,843
ตัวนี้ถูกเรียกสองครั้ง

348
00:20:11,843 --> 00:20:16,033
ที่ขั้นตอนสองมันเรียกก่อนเอเจนต์ เพราะ plugin

349
00:20:16,033 --> 00:20:19,757
มี before agent callback ในทำนองเดียวกัน

350
00:20:19,757 --> 00:20:23,202
plugin ก็ถูก execute ก่อนการเรียก llm

351
00:20:23,202 --> 00:20:26,088
ซึ่งเกิดที่ขั้นตอนสี่ตรงนี้ครับ

352
00:20:26,088 --> 00:20:29,905
หวังว่าจะเข้าใจแจ่มชัดแล้วนะครับ ต่อไปคือ

353
00:20:29,905 --> 00:20:34,095
built-in logging plugin ครับ built-in logging

354
00:20:34,095 --> 00:20:37,819
plugin คืออะไร ADK มี logging plugin แบบ

355
00:20:37,819 --> 00:20:38,916
built-in

356
00:20:38,916 --> 00:20:43,013
ซึ่งเก็บกิจกรรมของเอเจนต์โดยอัตโนมัติทั้งหมด

357
00:20:43,013 --> 00:20:47,110
เช่น ข้อความของ user และ response ของเอเจนต์

358
00:20:47,110 --> 00:20:50,834
ข้อมูล timing สำหรับวิเคราะห์ประสิทธิภาพ

359
00:20:50,834 --> 00:20:54,837
request และ response ของ LLM เพื่อใช้ debug

360
00:20:54,837 --> 00:20:58,934
การเรียกใช้ tool และผลลัพธ์ รวมถึง execution

361
00:20:58,934 --> 00:21:00,796
trace แบบครบถ้วนครับ

362
00:21:00,796 --> 00:21:04,986
เราเคยนิยามเอเจนต์ไปแล้วสำหรับ research paper

363
00:21:04,986 --> 00:21:08,989
agent ตรงนี้เราทำคล้ายกันนี้อีกครั้ง โดยรัน

364
00:21:08,989 --> 00:21:12,062
research agent พร้อม logging ครับ

365
00:21:12,062 --> 00:21:15,507
ทุกอย่างเกือบเหมือนเดิม ตรงนี้ papers

366
00:21:15,507 --> 00:21:18,672
ถูกอัปเดตเป็น list ของ string แล้ว

367
00:21:18,672 --> 00:21:21,372
ข้อมูลส่วนที่เหลือถูกต้องครับ

368
00:21:21,372 --> 00:21:24,165
ต้องคืนค่าทั้งหมด instructions

369
00:21:24,165 --> 00:21:28,448
ก็เหมือนเดิมครับ ตรงนี้เราเพิ่ม research agent

370
00:21:28,448 --> 00:21:31,521
ด้วย plugin ครับ ผมจะรันตอนนี้เลย

371
00:21:31,521 --> 00:21:35,059
มันบอกว่าเอเจนต์ถูกสร้างสำเร็จแล้วครับ

372
00:21:35,059 --> 00:21:39,155
ขั้นที่สามคือการใช้ plugin ใน research agent

373
00:21:39,155 --> 00:21:43,438
ด้านบน คลิกเพื่อ import plugin แล้วเพิ่มมันตอน

374
00:21:43,438 --> 00:21:47,349
initialize ตัว runner ครับ จาก ADK runners

375
00:21:47,349 --> 00:21:51,538
import runner ครับ คุณมี plugin ซึ่งก็คือ log

376
00:21:51,538 --> 00:21:55,356
plugin ผมจะรันอันนี้ มันบอกว่า runner ถูก

377
00:21:55,356 --> 00:21:58,987
configure แล้ว ใน runner ครับ เสร็จแล้ว

378
00:21:58,987 --> 00:22:03,083
ส่วนนี้เพิ่ม plugin เข้าไป มันจัดการ logging

379
00:22:03,083 --> 00:22:04,666
แบบ observability

380
00:22:04,666 --> 00:22:08,949
มาตรฐานให้กับเอเจนต์ทั้งหมดครับ ตัว runner ถูก

381
00:22:08,949 --> 00:22:13,232
configure แล้ว ทีนี้เราจะพิมพ์ statement ต่างๆ

382
00:22:13,232 --> 00:22:16,491
แล้วดูว่าได้ผลลัพธ์อะไร เราจะ debug

383
00:22:16,491 --> 00:22:20,494
ตอนนี้เลยครับ รันเอเจนต์พร้อม plugin แล้วดู

384
00:22:20,494 --> 00:22:24,125
logging output ที่ครอบคลุมครับ response

385
00:22:24,125 --> 00:22:27,477
ตรงนี้คือ user message ได้รับแล้ว มี

386
00:22:27,477 --> 00:22:31,667
invocation กำลังใช้ debug ด้วย user ID นี้ มี

387
00:22:31,667 --> 00:22:35,391
context ตรงนี้ คือหางานวิจัยล่าสุดเรื่อง

388
00:22:35,391 --> 00:22:39,301
quantum computing ครับ แล้ว agent starting

389
00:22:39,301 --> 00:22:43,584
อยู่ตรงนี้ มี invocation ID ซึ่งเป็น plugin ID

390
00:22:43,584 --> 00:22:47,215
อีกอันหนึ่ง ตรงนี้บอกว่า research paper

391
00:22:47,215 --> 00:22:49,729
เริ่มแล้ว ก็มีแบบนี้อีกครับ

392
00:22:49,729 --> 00:22:52,709
ทีนี้เธอต้องทำตามขั้นตอนเหล่านี้

393
00:22:52,709 --> 00:22:56,060
ขั้นแรกคือหางานวิจัยในหัวข้อที่ user

394
00:22:56,060 --> 00:22:59,598
ให้มาโดยใช้ Google search agent นี่คือ

395
00:22:59,598 --> 00:23:03,043
instruction แรกที่เราให้ไว้ใช่ไหมครับ

396
00:23:03,043 --> 00:23:07,326
มันบอกว่า tool ที่ใช้ได้คือตัวนี้กับตัวนี้ครับ

397
00:23:07,326 --> 00:23:11,516
ใน LLM response เอเจนต์ research paper finder

398
00:23:11,516 --> 00:23:15,519
เรียกใช้ฟังก์ชันนี้ มี token ID มี input มี

399
00:23:15,519 --> 00:23:19,802
output เป็น 21 และมี event ID ตรงนี้ ทุก event

400
00:23:19,802 --> 00:23:23,154
ที่เกิดขึ้นถูกบันทึกครับ ตอนนี้ tool

401
00:23:23,154 --> 00:23:27,251
เริ่มทำงาน มี invocation ID ของ user message

402
00:23:27,251 --> 00:23:31,254
นี้ ตอนนี้เริ่ม invocation มีชื่อเอเจนต์ มี

403
00:23:31,254 --> 00:23:35,071
invocation ID ตัวนี้อยู่ตรงนี้ครับ ตอนนี้

404
00:23:35,071 --> 00:23:38,982
model เริ่มทำงาน ตอนนี้เธอเป็นเอเจนต์หนึ่ง

405
00:23:38,982 --> 00:23:42,985
ชื่อภายในคือ Google search agent คำอธิบาย B

406
00:23:42,985 --> 00:23:46,989
ส่วน description เกี่ยวกับการค้นหา ฟิลด์ของ

407
00:23:46,989 --> 00:23:50,061
quantum เริ่มเพิ่ม context เข้ามา

408
00:23:50,061 --> 00:23:54,065
คุณสามารถไล่ดูได้เลย เรื่องนี้เข้าใจง่ายมาก

409
00:23:54,065 --> 00:23:56,113
มันอธิบายตัวเองได้ครับ

410
00:23:56,113 --> 00:24:00,024
ในวิดีโอนี้เราได้ผ่านการ debug ในขั้นพัฒนา

411
00:24:00,024 --> 00:24:04,306
observability ระดับ production และ requirement

412
00:24:04,306 --> 00:24:05,703
แบบกำหนดเองครับ

413
00:24:05,703 --> 00:24:09,427
ในวิดีโอถัดไปซึ่งเป็นส่วนที่สองของ Day 4

414
00:24:09,427 --> 00:24:11,941
เราจะเรียนเรื่อง evaluation

415
00:24:11,941 --> 00:24:17,062
คือวิธีประเมินและให้คะแนนคุณภาพคำตอบของเอเจนต์และการใช้

416
00:24:17,062 --> 00:24:18,159
tool ครับ