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

Day 3B: Tool Calling — Complete Function Calling Guide (Gemini)

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

สรุปย่อ

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

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

# สรุป: Day 3B: Tool Calling — Complete Function Calling Guide (Gemini)

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

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

- แม้ชื่อวิดีโอจะระบุเรื่อง Tool Calling แต่เนื้อหาจริงของ codelab นี้คือ memory management (การจัดการหน่วยความจำระยะยาว) ใน ADK — แยกจาก session ซึ่งเป็นหน่วยความจำระยะสั้นแบบบทสนทนาเดียว
- Memory ให้ความสามารถที่ session เดี่ยวๆ ทำไม่ได้: จดจำข้ามบทสนทนา สกัดข้อมูลอย่างชาญฉลาด ค้นหาเชิงความหมาย และเก็บข้อมูลถาวร
- Memory workflow มี 3 ขั้นหลัก: Initialize (สร้าง service ผ่าก runner) → Ingest (ย้ายข้อมูล session ด้วย add_session_to_memory) → Retrieve (ค้นหาด้วย search_memory)
- Notebook ใช้ InMemory memory service (จับคู่คียเวิร์ด ไม่เก็บถาวร) ส่วน production ควรใช้ Vertex AI Memory Bank (กลั่นข้อมูลด้วย LLM + semantic search + คลาวด์ถาวร) ซึ่งจะสอนใน Day 5
- การดึงข้อมูลความจำมี 2 โหมด: load_memory แบบ reactive (ทำงานเมื่อถูกเรียก) และ preload_memory แบบ proactive (เตรียมข้อมูลไว้ล่วงหน้า)
- การค้นหา memory ตั้งอยู่บนข้อเท็จจริงจริงๆ ที่เก็บไว้ เอเจนต์จึง hallucinate ความจำที่ไม่มีอยู่ไม่ได้
- Callbacks ของ ADK เป็นฟังก์ชันที่ทำงานอัตโนมัติตามจังหวะต่างๆ ของเอเจนต์ (before/after agent, before/after model, before/after tool, on model error) เหมาะกับ logging, observability และการบันทึก memory อัตโนมัติ
- ใช้ after_agent_callback + callback_context ทำ autosave บทสนทนาหลังจบทุก turn รวมกับ preload_memory ทำให้การจัดเก็บและดึงข้อมูลเป็นอัตโนมัติทั้งหมด โดยไม่ต้องเรียกด้วยมือเลย
- ความถี่ในการบันทึก memory มี 3 แบบ: ทุก turn (เรียลไทม์), หลังจบบทสนทนา (ลด API calls / batch), เป็นช่วงๆ (บทสนทนายาว)
- เก็บข้อมูลดิบทั้งหมดไม่ scale (50 ข้อความ = 10,000 tokens) — ต้องใช้ memory consolidation สกัดเฉพาะข้อเท็จจริงสำคัญทิ้ง noise ทิ้ง ผลลัพธ์คือเก็บน้อยลง ดึงเร็วขึ้น ตอบแม่นขึ้น
- Consolidation เปลี่ยนภาษาธรรมชาติเป็นข้อมูลมีโครงสร้าง เช่น "แพ้ถั่ว กินอะไรที่มีถั่วไม่ได้" → แพ้ถั่ว/ถั่วต้นไม้/หลีกเลี่ยงอย่างสมบูรณ์ และ managed service อย่าง Vertex AI ทำให้อัตโนมัติโดยใช้ API เดิม

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

วิดีโอนี้เดินตาม notebook ไปทีละขั้นอย่างละเอียด เหมาะกับผู้เริ่มต้นที่อยากเข้าใจว่าระบบความจำระยะยาวของเอเจนต์ทำงานอย่างไร ตั้งแต่ manual workflow ไปจนถึง automation ด้วย callbacks ครับ จุดที่ควรระวังคือชื่อวิดีโอกับเนื้อหาจริงไม่ตรงกัน (Tool Calling แต่สอน Memory) และตัวอย่างทั้งหมดใช้ InMemory service ซึ่งไม่เก็บข้อมูลถาวร ผู้ดูควรต่อยอดไปดู Day 5 เรื่อง Vertex AI Memory Bank ครับ
02

คำแปลเต็ม

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

ในวิดีโอนี้เราจะไปดูกันใน codelab ที่สองของ assignment ใน Day 3 ครับ ผมจะกดที่ Explore เพื่อให้มันพาเราไปที่ notebook แล้วเราจะทำสำเนาไว้เป็น notebook แบบแก้ไขได้ของเราเอง เพื่อใช้เดินผ่าน assignment นี้ไปด้วยกันนะครับ

ใน assignment นี้เราจะคุยกันเรื่อง memory management หรือการจัดการหน่วยความจำครับ เรามีอยู่สองแบบ แบบแรกคือ session (เซสชัน) และอีกแบบคือ memory (หน่วยความจำระยะยาว) session เป็นหน่วยความจำระยะสั้นที่ครอบคลุมแค่บทสนทนาเดียว ส่วนในวิดีโอนี้เราจะโฟกัสที่ memory ซึ่งเป็นความรู้ระยะยาวที่ใช้งานข้ามหลายบทสนทนาครับ ตัวอย่างที่เขาให้มาก็คือให้คิดว่ามันเหมือนกับ software engineer ครับ

ทีนี้ทำไมต้องมี memory ล่ะครับ memory มีความสามารถที่ session อย่างเดียวทำไม่ได้ ไม่ว่าจะเป็นการจดจำข้ามบทสนทนา การสกัดข้อมูลอย่างชาญฉลาด การค้นหาเชิงความหมาย และการเก็บข้อมูลแบบถาวรครับ มีอีกตัวอย่างหนึ่งคือการคุยกับ personal assistant ถ้ามีแค่ session เอเจนต์จะจำได้แค่สิ่งที่เราพูดในช่วงสิบนาทีที่ผ่านมา แต่ถ้ามี memory มันจะจำความชอบและบทสนทนาของเราจากสัปดาห์ที่แล้วได้ด้วยครับ

สิ่งที่เราจะเรียนในแบบฝึกหัดนี้คือ การตั้งค่า memory service และเชื่อมเข้ากับเอเจนต์ การย้ายข้อมูล session ไปเก็บในหน่วยความจำ การค้นหาและดึงข้อมูลความจำกลับมา การทำให้การจัดเก็บและดึงข้อมูลเป็นแบบอัตโนมัติ และการเข้าใจเรื่อง memory consolidation (การกลั่นข้อมูลในหน่วยความจำ) ครับ นี่คือภาพรวมเชิงแนวคิดนะครับ ข้อควรทราบคือ notebook นี้ใช้บริการ InMemory memory service เพื่อการเรียนรู้ แต่ในงานจริงที่ใช้ production สิ่งที่ต้องใช้คือ Vertex AI Memory Bank ซึ่งจะได้เจอกันใน assignment ของ Day 5 ครับ Vertex AI Memory Bank ให้บริการกลั่นข้อมูลด้วย LLM การค้นหาเชิงความหมาย และการจัดเก็บแบบถาวรบนคลาวด์ ส่วน InMemory memory service ทำได้แค่การจับคู่คำคียเวิร์ด และไม่เก็บข้อมูลถาวรครับ

เอาล่ะ เริ่มกันเลย ส่วนของ step หนึ่งผมจะรีบผ่านๆ ไป เพราะเราทำขั้นตอนนี้ซ้ำกันมาในทุกแบบฝึกหัดแล้ว เลือกหนึ่ง เราสร้าง API key สำเร็จแล้ว และตั้งค่าเรียบร้อยแล้ว ต่อไปเราจะ import ส่วนประกอบของ ADK (Agent Development Kit — ชุดเครื่องมือพัฒนาเอเจนต์ของ Google) เรามี load_memory และ preload_memory และมี memory service ด้วย แต่ใน production เราจะใช้ Vertex AI Memory Bank ตามที่บอกไปก่อนหน้านี้ครับ ฉะนั้นตรงนี้เราใช้ InMemory memory service แต่พอขึ้น production ให้ใช้ Vertex Memory Bank ครับ

เยี่ยม import ส่วนประกอบของ ADK สำเร็จแล้ว ขั้นต่อไปคือกำหนด helper function อันนี้ก็ทำเสร็จแล้ว จากนั้นสร้าง retry config ก็เสร็จเรียบร้อย เรามาดู section สองกันต่อเลย ซึ่งก็คือ memory workflow ครับ

ทีนี้ใน section สอง มาทำความเข้าใจ workflow ของ memory กันก่อน การจะเชื่อม memory เข้ากับเอเจนต์ของเรามีอยู่สามขั้นตอนหลักคือ Initialize Ingest และ Retrieve ครับ ขั้น Initialize คือเราสร้าง memory service แล้วส่งให้เอเจนต์ผ่านตัว runner ขั้นที่สองคือ Ingest ที่เราย้ายข้อมูลของ session เข้าสู่ memory โดยใช้ฟังก์ชัน add_session_to_memory ส่วนขั้นที่สามคือ Retrieve ที่เราค้นหาข้อมูลความจำที่เก็บไว้ด้วยฟังก์ชัน search_memory ครับ นี่คือหน้าตาของ memory workflow ของเรา แล้วเดี๋ยวเราจะไล่ดูรายละเอียดทีละขั้น ตั้งแต่ Initialize Ingest ไปจนถึง Retrieve กันครับ

Section สามคือการตั้งค่า memory service ครับ การ initialize memory คืออะไร ตรงนี้เรามีบริการแบบ built-in สำหรับงาน prototyping และ testing เช่นการจับคู่คำคียเวิร์ด แต่ไม่มีการเก็บข้อมูลถาวร ส่วนแบบที่สองคือ Vertex AI Memory Bank ซึ่งเป็นบริการคลาวด์แบบ managed มีการกลั่นข้อมูลด้วย LLM และการค้นหาเชิงความหมาย และแบบที่สามคือการ implement เอง เราสามารถสร้างของตัวเองจากฐานข้อมูลผ่าน managed service ซึ่งเป็นวิธีที่แนะนำครับ โดยสรุป ADK มี memory service implementation ให้เลือกใช้หลายแบบ ผ่าน interface ที่ชื่อ BaseMemoryService ครับ สำหรับ notebook นี้เราจะใช้แบบแรกตามที่บอกไปแล้ว เอาล่ะมาสร้าง memory กัน อันนี้เสร็จแล้ว ต่อไปเป็นการเพิ่ม memory เข้ากับเอเจนต์ตามที่นิยามไว้

โอเค ตอนนี้เรามี instructions ที่บอกว่าให้ตอบคำถามด้วยคำง่ายๆ เราได้เพิ่ม memory ตรงนี้แล้ว เอเจนต์ถูกสร้างเรียบร้อย ขั้นต่อไปคือสร้าง runner ครับ ตัว runner ต้องการ service ทั้งสองตัวเพื่อเปิดใช้งานฟังก์ชันที่เกี่ยวกับ memory ครับ ตัวแรกคือ session service ที่จัดการเธรดของบทสนทนาและ events และตัวที่สองคือ memory service ที่ให้การจัดเก็บหน่วยความจำระยะยาว ทั้งสอง service ทำงานร่วมกัน session เก็บบทสนทนา ส่วน memory เก็บความรู้เพื่อดึงกลับมาใช้ข้าม session ครับ เรามารันกัน เอเจนต์และ runner ถูกสร้างแล้วพร้อมการรองรับ memory ครับ

ตรงนี้มีโน้ตสำคัญเรื่อง configuration กับ usage ครับ การเพิ่ม memory service เข้ากับ runner ทำให้ memory พร้อมใช้สำหรับเอเจนต์ แต่มันไม่ได้ใช้งานอัตโนมัติ เราต้องกำหนดอย่างชัดเจน คือบอกให้มัน ingest ข้อมูลผ่าน session และเปิดใช้งานการดึงข้อมูลโดยให้ memory tools อย่าง load_memory หรือ preload_memory กับเอเจนต์ ซึ่งเราจะทำในขั้นถัดไปครับ

ทีนี้อีกเรื่องหนึ่งคือเรื่องตัวเลือก implementation ของ memory service ครับ อันนี้เราใช้ InMemory memory service และใน production เราจะใช้แบบที่พูดถึงไปแล้วครับ

Section สี่คือการนำข้อมูล session เข้าสู่ memory ครับ ระหว่างรันโค้ดนี้ สิ่งที่เกิดขึ้นคือในระหว่างการย้ายข้อมูล ตัว session จะทำ intelligent consolidation คือสกัดเอาเฉพาะข้อเท็จจริงสำคัญ แล้วทิ้งส่วนที่เป็นแค่ความยุ่งยากของบทสนทนาทิ้งไปครับ อันนี้เสร็จแล้ว เราได้คำถามว่า my favorite color is blue green ชอบสีน้ำเงินอมเขียว แล้วขอให้เขียนบทกวี haiku (ไฮกู) เกี่ยวกับสีนั้นหน่อย โดยใช้ conversation ID เป็น 01 ครับ แล้วมันตอบว่าเป็นสีที่สวยงามเหมือนมหาสมุทรกับต้นไม้ สงบและกลมกลืนกันดีครับ

ทีนี้เราจะมาตรวจสอบว่าบทสนทนานี้ถูกเก็บจริงหรือเปล่า และมันถูกเก็บอย่างไร ลองดูนะครับ มันบอกว่า session มีข้อความของ user เกี่ยวกับสีที่ชอบ และเรามี event ตรงนี้ที่มีคำว่า beautiful อยู่ เสร็จแล้วครับ ตรงนี้คือ method หลักในการนำบทสนทนาเข้าสู่ memory store เพื่อให้ค้นหาได้ในอนาคต ก็คือการเพิ่ม session เข้าไปใน memory ด้วยวิธีนี้ครับ

ขั้นต่อไปคือการเปิดใช้งานการดึงข้อมูล memory ในเอเจนต์ ครับ มีอยู่สองวิธีคือ load กับ preload โดย load_memory เป็นแบบ reactive คือทำงานเมื่อถูกเรียก ส่วน preload เป็นแบบ proactive คือเตรียมข้อมูลไว้ก่อนครับ ทีนี้เราจะเพิ่ม load_memory tool เข้ากับเอเจนต์ ผมรันอันนี้เลย ใช้ข้อมูลชุดเดิมกัน ตัว tool คือ load_memory และ instruction คือให้ตอบคำถามของ user ด้วยคำง่ายๆ และให้ใช้ load_memory tool เมื่อต้องการนึกถึงบทสนทนาที่ผ่านมา ครับ เราจะอัปเดต runner แล้วทดสอบกัน

User ถามว่าสีที่ฉันชอบคือสีอะไร โมเดลตอบว่าสีที่คุณชอบคือสีน้ำเงินอมเขียวครับ ต่อไปเราจะทดสอบ manual workflow ให้ครบ เรารันอันนี้แล้วบอกว่าวันเกิดของฉันคือวันที่ 15 มีนาคม โดยตั้งชื่อ session เป็น session วันเกิดอันดับหนึ่ง มันตอบว่ารับทราบ ฉันจะจำไว้ครับ ทีนี้เราจะบันทึกข้อมูลนี้แบบ manual อีกครั้ง session วันเกิดถูกบันทึกเข้า memory แล้ว ต่อไปเราจะดึงข้อมูลนี้กลับมาดูว่ามันได้ผลหรือเปล่า ผมใช้ session วันเกิดอันดับสอง ถามว่าวันเกิดของฉันคือเมื่อไหร่ มันตอบว่าวันเกิดของคุณคือวันที่ 15 มีนาคม ครับ

ตรงนี้เอเจนต์ได้รับคำถามว่าวันเกิดของฉันคือเมื่อไหร่ มันรู้ว่าคำถามนี้ต้องใช้บริบทจากบทสนทนาที่ผ่านมา เอเจนต์จึงเรียกใช้ load_memory แล้วมันคืนค่าบทสนทนาก่อนหน้าที่มีวันที่ 15 มีนาคมอยู่ อันนี้เสร็จเรียบร้อยครับ ทีนี้ถ้าอยากลองเล่นดู เรามี load_memory อยู่แล้ว ตอนนี้ลองสลับเป็น preload ดูครับ ในส่วนของ tool ตรงที่เขียนว่า load_memory ให้เปลี่ยนเป็น preload_memory แล้วรันดูว่าจะเกิดอะไรขึ้นครับ

เอาล่ะ มาลองกัน ถ้าต้องการผมจะเอาโค้ดส่วน retrieval มาวางตรงนี้เลย กำลังแทนที่อยู่ครับ อ๊ะขอโทษที ตรงนี้ต้องแก้ด้วย นี่ไง color test ดูดีเลยใช่ไหมครับ ทั้งสอง session ถูกบันทึกแล้ว เรากำลังรันส่วนนี้อยู่ ทุกอย่างเข้าที่ ทุกอย่างสมบูรณ์ครับ แม้จะใช้ preload แต่มันก็ยังค้นหาใน memory ได้เหมือนกันครับ

นอกเหนือจากกฎของเอเจนต์ เรายังเรียกใช้ search memory ตรงๆ ในโค้ดของเราได้ด้วยครับ วิธีนี้มีประโยชน์สำหรับการ debug การสร้าง analytics dashboard และการทำ custom memory management ครับ ตัวฟังก์ชัน search_memory จะรับ text query แล้วคืนค่า SearchMemoryResponse ที่มีรายการ memories ที่ตรงกันครับ โค้ดง่ายมาก มี user ID แล้วก็ print ผลลัพธ์ออกมาดูว่าเราคุยอะไรกันมาแล้วบ้าง ผลออกมามี memories ที่เกี่ยวข้องหกรายการครับ มีสีที่ชอบคือน้ำเงินอมเขียว มี haiku เกี่ยวกับสีนั้น แล้วก็มีวันที่ 15 กับคำว่ารับทราบจะจำไว้ มันแค่แสดงบทสนทนาทั้งหมดให้เราดูครับ

ทีนี้ถ้าอยากลอง ให้ลองเล่น search พวกนี้ดูเพื่อทำความเข้าใจว่าการจับคู่คียเวิร์ดทำงานอย่างไร เราสามารถถามว่า user ชอบสีอะไร และคำถามอื่นๆ ในลักษณะนี้ แล้วดูว่าแชตบอตตอบอย่างไร หรือมัน hallucinate (สร้างความจำเท็จ) หรือเปล่า แต่ประเด็นสำคัญคือการค้นหา memory นั้นตั้งอยู่บนข้อเท็จจริงครับ เอเจนต์จึงไม่สามารถ hallucinate ความจำที่ไม่มีอยู่จริงได้ครับ ส่วนการค้นหาทำงานอย่างไร memory service แบบนี้ทำการจับคู่คียเวิร์ด ส่วนใน Vertex AI Memory Bank ซึ่งเราจะได้ทำในแบบฝึกหัดของ Day 5 จะใช้การค้นหาเชิงความหมายด้วย embeddings ครับ อันนี้เสร็จแล้ว

ต่อไป section หกคือการทำ memory storage ให้อัตโนมัติครับ ตอนนี้เราเรียก add_session_to_memory ด้วยตนเองมาตลอดเพื่อย้ายข้อมูลไปเก็บระยะยาว แต่ระบบ production ต้องการให้เรื่องนี้เกิดขึ้นเองอัตโนมัติ ดังนั้นเราจึงแนะนำ callbacks (ฟังก์ชันเรียกกลับ) ครับ ระบบ callback ของ ADK ให้เรา hook เข้าไปยังจังหวะสำคัญๆ ของการทำงาน callback เป็นฟังก์ชัน Python ที่เรานิยามแล้วผูกเข้ากับเอเจนต์ ADK จะเรียกมันเองโดยอัตโนมัติในแต่ละขั้นตอน ทำหน้าที่เหมือน checkpoint ระหว่างการทำงานของเอเจนต์ครับ จะคิดซะว่า callback เป็น event listener ในวงจรชีวิตของเอเจนต์ก็ได้ครับ เมื่อเอเจนต์ประมวลผลคำขอหนึ่งๆ มันจะผ่านหลายขั้นตอน ตั้งแต่รับ input เรียก LLM เรียกใช้ tools ไปจนถึงสร้างคำตอบ callback ทำให้เราแทรก logic ที่กำหนดเองเข้าไปในแต่ละขั้นตอนเหล่านี้ได้ โดยไม่ต้องแก้โค้ดหลักของเอเจนต์ครับ

callback มีประเภทอะไรบ้าง มี before_agent_callback ที่รันก่อนที่เอเจนต์จะเริ่มประมวลผลคำขอ มี after_agent_callback ที่รันหลังเอเจนต์จบ turn ของตัวเอง แล้วก็มี before และ after ที่อยู่รอบๆ ตำแหน่งการเรียกใช้ tool มี before_model_callback และ after_model_callback ที่อยู่รอบๆ การเรียก LLM และมี on_model_error_callback ที่ทำงานเมื่อเกิด error ครับ use case ที่พบบ่อยคือ logging และ observability (การติดตามการทำงาน) เช่นดูว่าเอเจนต์ทำอะไรบ้าง การบันทึกลง memory การตรวจสอบแบบกำหนดเอง การกรองข้อมูล หรือการเฝ้าดูประสิทธิภาพ ครับ อยากรู้เรื่อง callback เพิ่มเติมไปอ่านได้ที่ documentation นี้ครับ ผมจะใส่ลิงก์ไว้ในคำอธิบายของวิดีโอด้วยเช่นกัน

นี่คือวิธีที่มันทำงานครับ ถ้าอยากเข้าใจประเภทของ callback เหล่านี้ before callback รันก่อนที่เอเจนต์จะประมวลผลคำขอ after ตัวหลังจะรันหลังเอเจนต์จบ turn ของตัวเอง แล้วก็ before_tool_callback กับ after_tool_callback ตรงนี้เลยครับ อันนี้อยู่รอบๆ การเรียกใช้ tool และตัว model แบบ before และ after ก็คืออยู่รอบๆ การเรียก LLM ครับ ไดอะแกรมนี้อธิบายประเภทของ callback และการทำงานของมันให้เราเข้าใจครับ นี่คือก่อนเอเจนต์ประมวลผล นี่คือหลังเอเจนต์ทำเสร็จ ส่วนนี้คือการเรียกใช้ tool และส่วนนี้คือการล้อมรอบการเรียก LLM ครับ

ต่อไปคือการจัดเก็บ memory อัตโนมัติด้วย callbacks ครับ สำหรับการจัดเก็บอัตโนมัติเราจะใช้ after_agent_callback ครับ ฟังก์ชันนี้จะทำงานทุกครั้งที่เอเจนต์จบ turn แล้วเรียก add_session เพื่อเรียก add_session_to_memory เพื่อบันทึกบทสนทนาโดยอัตโนมัติครับ แต่ความท้าทายคือฟังก์ชัน callback จะเข้าถึง memory service และ session ปัจจุบันได้อย่างไร สำหรับเรื่องนั้นเรามี callback context ครับ เมื่อเรานิยามฟังก์ชัน callback ขึ้นมา ADK จะส่งพารามิเตอร์พิเศษที่เรียกว่า callback_context เข้ามาให้อัตโนมัติ ตัว callback context นี้ให้การเข้าถึง memory service และส่วนประกอบ runtime อื่นๆ ครับ เราจะใช้มันใน callback ของเราเพื่อเข้าถึง memory service และ session ปัจจุบัน เพื่อบันทึกบทสนทนาอัตโนมัติหลังจบทุก turn ครับ เราไม่ต้องสร้าง context นี้เอง ADK เป็นคนสร้างแล้วส่งเข้า callback ให้อัตโนมัติเมื่อมันทำงาน เราไม่ต้องห่วงว่ามันทำงานอย่างไรครับ

ขั้นต่อไปคือสร้างเอเจนต์ที่รวมการจัดเก็บอัตโนมัติเข้ากับ preload_memory ครับ สำหรับการจัดเก็บอัตโนมัติ เราต้องสร้างเอเจนต์ที่ผสมการจัดเก็บอัตโนมัติกับการดึงข้อมูลอัตโนมัติ การจัดเก็บอัตโนมัติก็คือ after_agent_callback ที่บันทึกบทสนทนา ส่วน preload_memory จะโหลดข้อมูลความจำครับ ทำอย่างไรล่ะครับ มีเอเจนต์ตรงนี้ instruction คือตอบคำถามของ user เครื่องมือคือ preload_memory และ callback คือ autosave_memory ซึ่งบันทึกหลังจบทุก turn ครับ เรามารันกัน สิ่งที่เกิดขึ้นโดยอัตโนมัติคือหลังจากเอเจนต์ตอบกลับทุกครั้ง callback จะทำงาน และข้อมูลของ session จะถูกย้ายเข้า memory โดยไม่ต้องเรียก add_session_to_memory ด้วยตนเองเลยครับ

ต่อไปสร้าง runner แล้วทดสอบเอเจนต์ครับ เราสร้าง runner เสร็จแล้ว ทีนี้มาทดสอบเอเจนต์กัน เรามี test หนึ่งกับ test สอง อันแรกคือผมให้ของขวัญเป็นของเล่นใหม่แก่หลานชายในวันเกิดปีแรกของเขา มันตอบว่าเยี่ยมมาก หวังว่าหลานชายของคุณจะสนุกกับของเล่นนะครับ อันที่สองคือผมให้อะไรหลานชายไป มันตอบว่าคุณให้ของเล่นใหม่แก่หลานชายในวันเกิดปีแรกของเขาครับ

แล้วเพิ่งเกิดอะไรขึ้นล่ะครับ บทสนทนาแรกพูดถึงของขวัญให้หลานชาย ดังนั้น callback จึงบันทึกลง memory โดยอัตโนมัติ ส่วนบทสนทนาที่สองเป็น session ใหม่ ถามเรื่องของขวัญ preload_memory จึงดึงข้อมูลความจำกลับมาอัตโนมัติ แล้วเอเจนต์ก็ตอบถูกต้องครับ ดังนั้นจึงมีการเรียกใช้ memory ด้วยมือเป็นศูนย์ครั้ง นี่คือการจัดการหน่วยความจำแบบอัตโนมัติครับ

ควรบันทึก memory บ่อยแค่ไหน คือควรบันทึก session ลง memory บ่อยแค่ไหน มีตัวเลือกอยู่ดังนี้ครับ คือหลังจบทุก turn หลังจบบทสนทนา และเป็นช่วงๆ ตามระยะเวลา ควรบันทึกหลังจบทุก turn เมื่อต้องการอัปเดต memory แบบเรียลไทม์ ส่วนแบบหลังจบบทสนทนาเหมาะเมื่อทำ batch processing หรือต้องการลดจำนวน API calls และแบบเป็นช่วงๆ เหมาะกับบทสนทนาที่ยาวๆ ครับ เรารู้กันมาแล้วนะครับ

ต่อไปคือ section เจ็ดเรื่อง memory consolidation ครับ ในส่วนนี้เราจะเข้าใจข้อจำกัดของการเก็บข้อมูลดิบ สิ่งที่เราเก็บมาตลอดคือทุกข้อความของ user ทุกคำตอบของเอเจนต์ และทุก tool call ปัญหาคือถ้ามี 50 ข้อความในหนึ่ง session มันจะเท่ากับ 10,000 tokens แล้วทั้ง 50 ข้อความก็ถูกเก็บลง memory หมดเลย ตัวค้นหาจะคืนค่าทั้ง 50 ข้อความ และเอเจนต์ต้องประมวลผล 10,000 tokens ซึ่งมัน scale ไม่ไหวครับ เราจำเป็นต้องมี consolidation ดังนั้น memory consolidation จึงเข้ามามีบทบาทตรงนี้ครับ หมายความคือสกัดเอาเฉพาะข้อเท็จจริงสำคัญ แล้วทิ้ง noise ของบทสนทนาทิ้งไปครับ

การเก็บข้อมูลดิบจะหน้าตาประมาณนี้ครับ จากตัวอย่างก่อนหน้าของเรา มันเก็บข้อความทั้งสี่ที่ซ้ำซ้อนและยืดยาว เพราะเห็นได้ว่ามันพูดซ้ำกัน หลังทำ consolidation ข้อมูลที่สกัดได้คือ user ชอบสีน้ำเงินอมเขียว หมายความว่ามันเก็บเพียงข้อเท็จจริงเดียวที่กระชับจากข้อมูลดิบทั้งก้อนครับ ประโยชน์คือใช้พื้นที่จัดเก็บน้อยลง ดึงข้อมูลเร็วขึ้น และคำตอบแม่นยำขึ้นครับ จากตัวอย่าง session ของเรา สิ่งที่ได้ก็คือแบบนี้ครับ

subsection ถัดไปคือ consolidation ทำงานอย่างไร ในส่วนของแนวคิด เราจะไม่เขียนโค้ดส่วนนี้กันนะครับ เริ่มจาก event ดิบของ session ตัว language model จะวิเคราะห์บทสนทนา สกัดข้อเท็จจริงสำคัญ จัดเก็บความจำที่กระชับ และผสานเข้ากับความจำเดิมที่มีอยู่ โดยขจัดข้อมูลที่ซ้ำกันออกครับ ตัวอย่างของการแปลงข้อมูลเช่น ผมแพ้ถั่ว กินอะไรที่มีถั่วไม่ได้เลย ผลลัพธ์ที่ได้คือความจำแบบมีโครงสร้างว่า แพ้ถั่ว ถั่วต้นไม้ ระดับความรุนแรง หลีกเลี่ยงอย่างสมบูรณ์ ครับ ภาษาธรรมชาติจึงถูกแปลงเป็นข้อมูลที่มีโครงสร้างและนำไปใช้ได้จริงครับ

ส่วนถัดไปพูดถึงขั้นต่อไปของ memory consolidation ครับ ประเด็นสำคัญที่ต้องจำคือ managed memory service จัดการ consolidation ให้อัตโนมัติ ตรงนี้เราใช้ API เดิม ใช้ method ของ memory ตัวเดิม สิ่งที่ต่างคือสิ่งที่เกิดขึ้นเบื้องหลังครับ memory service แบบนี้เก็บ event ดิบๆ ส่วน Vertex AI Memory Bank จะกลั่นข้อมูลอย่างชาญฉลาดก่อนจัดเก็บครับ ถ้าอยากเรียนรู้เพิ่มเติมเรื่อง memory consolidation ซึ่งเราจะได้ศึกษาต่อในห้าวันถัดไป สามารถไปอ่านหน้า guide นี้ได้ครับ

นี่คือสรุปสิ่งที่เราทำในแบบฝึกหัดนี้ครับ เราได้เรียนรู้การเพิ่ม memory การจัดเก็บข้อมูล การค้นหา memory การดึงข้อมูลในเอเจนต์ และ memory consolidation ครับ หวังว่าแนวคิดจะชัดเจนสำหรับคุณนะครับ ถ้ายังไม่ชัดก็ลองดูวิดีโออีกหนึ่งหรือสองรอบ แล้วจะเข้าใจง่ายขึ้นในทุกครั้งที่ดูครับ และเมื่อจบ Day 3 แล้ว โปรดไปดูวิดีโอของ Day 4 ซึ่งพูดถึงการ implement observability และ evaluation ของเอเจนต์ ซึ่งสำคัญมาก เพราะมันช่วยให้มั่นใจว่าเอเจนต์ทำงานตามที่ตั้งใจไว้จริงๆ ใน production ครับ ขอบคุณครับ

03

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

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

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

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

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

ศัพท์คำแปล / คำอธิบาย
memory managementการจัดการหน่วยความจำระยะยาวของเอเจนต์
sessionเซสชัน — หน่วยความจำระยะสั้น ครอบคลุมบทสนทนาเดียว
memoryหน่วยความจำระยะยาว ใช้ข้ามหลายบทสนทนา
ADK (Agent Development Kit)ชุดเครื่องมือพัฒนาเอเจนต์ของ Google
notebookสมุดบันทึกโค้ดแบบโต้ตอบได้ (เช่นของ Kaggle/Colab)
codelabห้องปฏิบัติการโค้ด แบบฝึกหัดปฏิบัติจริง
InMemory memory serviceบริการความจำชั่วคราวเก็บในหน่วยความจำโปรแกรม ใช้จับคู่คียเวิร์ด ไม่เก็บถาวร เหมาะกับการเรียน/ทดลอง
Vertex AI Memory Bankบริการความจำระยะยาวบนคลาวด์ของ Google มีกลั่นข้อมูลด้วย LLM การค้นหาเชิงความหมาย และเก็บข้อมูลถาวร
semantic searchการค้นหาเชิงความหมาย ต่างจากการจับคู่คียเวิร์ดทั่วไป
embeddingsเวกเตอร์แทนความหมายของข้อความ ใช้สำหรับค้นหาเชิงความหมาย
consolidationการกลั่นข้อมูล สกัดเฉพาะข้อเท็จจริงสำคัญจากบทสนทนา ทิ้งส่วนที่ซ้ำซ้อน
runnerตัวขับเคลื่อนการทำงานของเอเจนต์ จัดการ session service และ memory service
session serviceบริการจัดการเธรดบทสนทนาและ events
add_session_to_memoryฟังก์ชันย้ายข้อมูล session เข้าสู่หน่วยความจำระยะยาว
search_memoryฟังก์ชันค้นหาความจำที่เก็บไว้
load_memoryเครื่องมือดึงข้อมูลความจำแบบ reactive (ทำงานเมื่อถูกเรียก)
preload_memoryเครื่องมือดึงข้อมูลความจำแบบ proactive (เตรียมไว้ล่วงหน้า)
callbackฟังก์ชันเรียกกลับที่ ADK เรียกอัตโนมัติตามจังหวะการทำงานของเอเจนต์
callback contextบริบทพิเศษที่ ADK ส่งให้ callback ใช้เข้าถึง memory service และ runtime
after_agent_callbackcallback ที่ทำงานหลังเอเจนต์จบ turn
before_agent_callbackcallback ที่ทำงานก่อนเอเจนต์เริ่มประมวลผลคำขอ
before/after_model_callbackcallback รอบๆ การเรียก LLM
before/after_tool_callbackcallback รอบๆ การเรียกใช้ tool
on_model_error_callbackcallback ที่ทำงานเมื่อโมเดลเกิด error
observabilityความสามารถในการติดตามดูการทำงานของระบบ
evaluationการประเมินผลการทำงานของเอเจนต์
hallucinate / hallucinationอาการโมเดลสร้างข้อมูลเท็จที่ไม่มีอยู่จริง
productionสภาพแวดล้อมจริงที่ระบบใช้งานจริง (ต่างจากการทดลอง)
prototypingการสร้างต้นแบบเพื่อทดลอง
haikuไฮกู — บทกวีสั้นญี่ปุ่น ใช้เป็นตัวอย่างในแบบฝึกหัด
BaseMemoryServiceinterface หลักของ memory service ใน ADK
SearchMemoryResponseชนิดผลลัพธ์ที่ได้จากการค้นหา memory
loggingการบันทึก log การทำงานของระบบ
tokenหน่วยนับข้อความที่โมเดลประมวลผล
05

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

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

1
00:00:00,000 --> 00:00:03,652
ในวิดีโอนี้เราจะไปดูกันใน codelab ที่สองของ

2
00:00:03,652 --> 00:00:07,218
assignment ใน Day 3 ครับ ผมจะกดที่ Explore

3
00:00:07,218 --> 00:00:09,766
เพื่อให้มันพาเราไปที่ notebook

4
00:00:09,766 --> 00:00:12,483
แล้วเราจะทำสำเนาไว้เป็น notebook
thai-subtitles.srt
SubRip — ใช้กับเครื่องเล่นวิดีโอส่วนใหญ่
↓ ดาวน์โหลด
thai-subtitles.vtt
WebVTT — ใช้กับเว็บ / YouTube
↓ ดาวน์โหลด
เปิดดูซับไตเติ้ลทั้งหมด (388 segments)
1
00:00:00,000 --> 00:00:03,652
ในวิดีโอนี้เราจะไปดูกันใน codelab ที่สองของ

2
00:00:03,652 --> 00:00:07,218
assignment ใน Day 3 ครับ ผมจะกดที่ Explore

3
00:00:07,218 --> 00:00:09,766
เพื่อให้มันพาเราไปที่ notebook

4
00:00:09,766 --> 00:00:12,483
แล้วเราจะทำสำเนาไว้เป็น notebook

5
00:00:12,483 --> 00:00:15,625
แบบแก้ไขได้ของเราเอง เพื่อใช้เดินผ่าน

6
00:00:15,625 --> 00:00:19,277
assignment นี้ไปด้วยกันนะครับ ใน assignment

7
00:00:19,277 --> 00:00:22,504
นี้เราจะคุยกันเรื่อง memory management

8
00:00:22,504 --> 00:00:26,241
หรือการจัดการหน่วยความจำครับ เรามีอยู่สองแบบ

9
00:00:26,241 --> 00:00:30,147
แบบแรกคือ session (เซสชัน) และอีกแบบคือ memory

10
00:00:30,147 --> 00:00:32,525
(หน่วยความจำระยะยาว) session

11
00:00:32,525 --> 00:00:36,686
เป็นหน่วยความจำระยะสั้นที่ครอบคลุมแค่บทสนทนาเดียว

12
00:00:36,686 --> 00:00:39,658
ส่วนในวิดีโอนี้เราจะโฟกัสที่ memory

13
00:00:39,658 --> 00:00:43,904
ซึ่งเป็นความรู้ระยะยาวที่ใช้งานข้ามหลายบทสนทนาครับ

14
00:00:43,904 --> 00:00:47,725
ตัวอย่างที่เขาให้มาก็คือให้คิดว่ามันเหมือนกับ

15
00:00:47,725 --> 00:00:51,547
software engineer ครับ ทีนี้ทำไมต้องมี memory

16
00:00:51,547 --> 00:00:54,774
ล่ะครับ memory มีความสามารถที่ session

17
00:00:54,774 --> 00:00:56,302
อย่างเดียวทำไม่ได้

18
00:00:56,302 --> 00:00:58,850
ไม่ว่าจะเป็นการจดจำข้ามบทสนทนา

19
00:00:58,850 --> 00:01:02,756
การสกัดข้อมูลอย่างชาญฉลาด การค้นหาเชิงความหมาย

20
00:01:02,756 --> 00:01:05,049
และการเก็บข้อมูลแบบถาวรครับ

21
00:01:05,049 --> 00:01:08,361
มีอีกตัวอย่างหนึ่งคือการคุยกับ personal

22
00:01:08,361 --> 00:01:10,569
assistant ถ้ามีแค่ session

23
00:01:10,569 --> 00:01:14,985
เอเจนต์จะจำได้แค่สิ่งที่เราพูดในช่วงสิบนาทีที่ผ่านมา

24
00:01:14,985 --> 00:01:16,259
แต่ถ้ามี memory

25
00:01:16,259 --> 00:01:21,184
มันจะจำความชอบและบทสนทนาของเราจากสัปดาห์ที่แล้วได้ด้วยครับ

26
00:01:21,184 --> 00:01:25,006
สิ่งที่เราจะเรียนในแบบฝึกหัดนี้คือ การตั้งค่า

27
00:01:25,006 --> 00:01:28,233
memory service และเชื่อมเข้ากับเอเจนต์

28
00:01:28,233 --> 00:01:31,714
การย้ายข้อมูล session ไปเก็บในหน่วยความจำ

29
00:01:31,714 --> 00:01:34,432
การค้นหาและดึงข้อมูลความจำกลับมา

30
00:01:34,432 --> 00:01:38,338
การทำให้การจัดเก็บและดึงข้อมูลเป็นแบบอัตโนมัติ

31
00:01:38,338 --> 00:01:41,650
และการเข้าใจเรื่อง memory consolidation

32
00:01:41,650 --> 00:01:44,537
(การกลั่นข้อมูลในหน่วยความจำ) ครับ

33
00:01:44,537 --> 00:01:48,104
นี่คือภาพรวมเชิงแนวคิดนะครับ ข้อควรทราบคือ

34
00:01:48,104 --> 00:01:51,926
notebook นี้ใช้บริการ InMemory memory service

35
00:01:51,926 --> 00:01:55,832
เพื่อการเรียนรู้ แต่ในงานจริงที่ใช้ production

36
00:01:55,832 --> 00:01:59,144
สิ่งที่ต้องใช้คือ Vertex AI Memory Bank

37
00:01:59,144 --> 00:02:02,795
ซึ่งจะได้เจอกันใน assignment ของ Day 5 ครับ

38
00:02:02,795 --> 00:02:06,702
Vertex AI Memory Bank ให้บริการกลั่นข้อมูลด้วย

39
00:02:06,702 --> 00:02:08,740
LLM การค้นหาเชิงความหมาย

40
00:02:08,740 --> 00:02:12,307
และการจัดเก็บแบบถาวรบนคลาวด์ ส่วน InMemory

41
00:02:12,307 --> 00:02:15,958
memory service ทำได้แค่การจับคู่คำคียเวิร์ด

42
00:02:15,958 --> 00:02:19,610
และไม่เก็บข้อมูลถาวรครับ เอาล่ะ เริ่มกันเลย

43
00:02:19,610 --> 00:02:22,412
ส่วนของ step หนึ่งผมจะรีบผ่านๆ ไป

44
00:02:22,412 --> 00:02:26,318
เพราะเราทำขั้นตอนนี้ซ้ำกันมาในทุกแบบฝึกหัดแล้ว

45
00:02:26,318 --> 00:02:29,545
เลือกหนึ่ง เราสร้าง API key สำเร็จแล้ว

46
00:02:29,545 --> 00:02:33,027
และตั้งค่าเรียบร้อยแล้ว ต่อไปเราจะ import

47
00:02:33,027 --> 00:02:36,594
ส่วนประกอบของ ADK (Agent Development Kit —

48
00:02:36,594 --> 00:02:40,161
ชุดเครื่องมือพัฒนาเอเจนต์ของ Google) เรามี

49
00:02:40,161 --> 00:02:43,812
load_memory และ preload_memory และมี memory

50
00:02:43,812 --> 00:02:47,634
service ด้วย แต่ใน production เราจะใช้ Vertex

51
00:02:47,634 --> 00:02:51,115
AI Memory Bank ตามที่บอกไปก่อนหน้านี้ครับ

52
00:02:51,115 --> 00:02:54,682
ฉะนั้นตรงนี้เราใช้ InMemory memory service

53
00:02:54,682 --> 00:02:58,588
แต่พอขึ้น production ให้ใช้ Vertex Memory Bank

54
00:02:58,588 --> 00:03:01,645
ครับ เยี่ยม import ส่วนประกอบของ ADK

55
00:03:01,645 --> 00:03:05,382
สำเร็จแล้ว ขั้นต่อไปคือกำหนด helper function

56
00:03:05,382 --> 00:03:09,203
อันนี้ก็ทำเสร็จแล้ว จากนั้นสร้าง retry config

57
00:03:09,203 --> 00:03:13,025
ก็เสร็จเรียบร้อย เรามาดู section สองกันต่อเลย

58
00:03:13,025 --> 00:03:16,931
ซึ่งก็คือ memory workflow ครับ ทีนี้ใน section

59
00:03:16,931 --> 00:03:20,838
สอง มาทำความเข้าใจ workflow ของ memory กันก่อน

60
00:03:20,838 --> 00:03:22,366
การจะเชื่อม memory

61
00:03:22,366 --> 00:03:26,018
เข้ากับเอเจนต์ของเรามีอยู่สามขั้นตอนหลักคือ

62
00:03:26,018 --> 00:03:29,415
Initialize Ingest และ Retrieve ครับ ขั้น

63
00:03:29,415 --> 00:03:32,557
Initialize คือเราสร้าง memory service

64
00:03:32,557 --> 00:03:36,378
แล้วส่งให้เอเจนต์ผ่านตัว runner ขั้นที่สองคือ

65
00:03:36,378 --> 00:03:39,945
Ingest ที่เราย้ายข้อมูลของ session เข้าสู่

66
00:03:39,945 --> 00:03:43,596
memory โดยใช้ฟังก์ชัน add_session_to_memory

67
00:03:43,596 --> 00:03:45,804
ส่วนขั้นที่สามคือ Retrieve

68
00:03:45,804 --> 00:03:49,626
ที่เราค้นหาข้อมูลความจำที่เก็บไว้ด้วยฟังก์ชัน

69
00:03:49,626 --> 00:03:53,107
search_memory ครับ นี่คือหน้าตาของ memory

70
00:03:53,107 --> 00:03:54,381
workflow ของเรา

71
00:03:54,381 --> 00:03:58,288
แล้วเดี๋ยวเราจะไล่ดูรายละเอียดทีละขั้น ตั้งแต่

72
00:03:58,288 --> 00:04:01,854
Initialize Ingest ไปจนถึง Retrieve กันครับ

73
00:04:01,854 --> 00:04:05,591
Section สามคือการตั้งค่า memory service ครับ

74
00:04:05,591 --> 00:04:08,054
การ initialize memory คืออะไร

75
00:04:08,054 --> 00:04:11,365
ตรงนี้เรามีบริการแบบ built-in สำหรับงาน

76
00:04:11,365 --> 00:04:13,319
prototyping และ testing

77
00:04:13,319 --> 00:04:15,357
เช่นการจับคู่คำคียเวิร์ด

78
00:04:15,357 --> 00:04:18,923
แต่ไม่มีการเก็บข้อมูลถาวร ส่วนแบบที่สองคือ

79
00:04:18,923 --> 00:04:22,745
Vertex AI Memory Bank ซึ่งเป็นบริการคลาวด์แบบ

80
00:04:22,745 --> 00:04:25,462
managed มีการกลั่นข้อมูลด้วย LLM

81
00:04:25,462 --> 00:04:29,029
และการค้นหาเชิงความหมาย และแบบที่สามคือการ

82
00:04:29,029 --> 00:04:30,133
implement เอง

83
00:04:30,133 --> 00:04:33,445
เราสามารถสร้างของตัวเองจากฐานข้อมูลผ่าน

84
00:04:33,445 --> 00:04:36,842
managed service ซึ่งเป็นวิธีที่แนะนำครับ

85
00:04:36,842 --> 00:04:40,578
โดยสรุป ADK มี memory service implementation

86
00:04:40,578 --> 00:04:44,060
ให้เลือกใช้หลายแบบ ผ่าน interface ที่ชื่อ

87
00:04:44,060 --> 00:04:47,287
BaseMemoryService ครับ สำหรับ notebook

88
00:04:47,287 --> 00:04:51,193
นี้เราจะใช้แบบแรกตามที่บอกไปแล้ว เอาล่ะมาสร้าง

89
00:04:51,193 --> 00:04:54,930
memory กัน อันนี้เสร็จแล้ว ต่อไปเป็นการเพิ่ม

90
00:04:54,930 --> 00:04:58,327
memory เข้ากับเอเจนต์ตามที่นิยามไว้ โอเค

91
00:04:58,327 --> 00:05:00,365
ตอนนี้เรามี instructions

92
00:05:00,365 --> 00:05:04,016
ที่บอกว่าให้ตอบคำถามด้วยคำง่ายๆ เราได้เพิ่ม

93
00:05:04,016 --> 00:05:07,583
memory ตรงนี้แล้ว เอเจนต์ถูกสร้างเรียบร้อย

94
00:05:07,583 --> 00:05:10,980
ขั้นต่อไปคือสร้าง runner ครับ ตัว runner

95
00:05:10,980 --> 00:05:12,254
ต้องการ service

96
00:05:12,254 --> 00:05:16,075
ทั้งสองตัวเพื่อเปิดใช้งานฟังก์ชันที่เกี่ยวกับ

97
00:05:16,075 --> 00:05:19,217
memory ครับ ตัวแรกคือ session service

98
00:05:19,217 --> 00:05:22,019
ที่จัดการเธรดของบทสนทนาและ events

99
00:05:22,019 --> 00:05:24,567
และตัวที่สองคือ memory service

100
00:05:24,567 --> 00:05:28,134
ที่ให้การจัดเก็บหน่วยความจำระยะยาว ทั้งสอง

101
00:05:28,134 --> 00:05:31,955
service ทำงานร่วมกัน session เก็บบทสนทนา ส่วน

102
00:05:31,955 --> 00:05:35,267
memory เก็บความรู้เพื่อดึงกลับมาใช้ข้าม

103
00:05:35,267 --> 00:05:38,834
session ครับ เรามารันกัน เอเจนต์และ runner

104
00:05:38,834 --> 00:05:42,061
ถูกสร้างแล้วพร้อมการรองรับ memory ครับ

105
00:05:42,061 --> 00:05:45,543
ตรงนี้มีโน้ตสำคัญเรื่อง configuration กับ

106
00:05:45,543 --> 00:05:49,109
usage ครับ การเพิ่ม memory service เข้ากับ

107
00:05:49,109 --> 00:05:52,591
runner ทำให้ memory พร้อมใช้สำหรับเอเจนต์

108
00:05:52,591 --> 00:05:54,884
แต่มันไม่ได้ใช้งานอัตโนมัติ

109
00:05:54,884 --> 00:05:58,535
เราต้องกำหนดอย่างชัดเจน คือบอกให้มัน ingest

110
00:05:58,535 --> 00:06:00,064
ข้อมูลผ่าน session

111
00:06:00,064 --> 00:06:03,800
และเปิดใช้งานการดึงข้อมูลโดยให้ memory tools

112
00:06:03,800 --> 00:06:06,943
อย่าง load_memory หรือ preload_memory

113
00:06:06,943 --> 00:06:10,085
กับเอเจนต์ ซึ่งเราจะทำในขั้นถัดไปครับ

114
00:06:10,085 --> 00:06:13,142
ทีนี้อีกเรื่องหนึ่งคือเรื่องตัวเลือก

115
00:06:13,142 --> 00:06:16,369
implementation ของ memory service ครับ

116
00:06:16,369 --> 00:06:19,935
อันนี้เราใช้ InMemory memory service และใน

117
00:06:19,935 --> 00:06:23,417
production เราจะใช้แบบที่พูดถึงไปแล้วครับ

118
00:06:23,417 --> 00:06:26,899
Section สี่คือการนำข้อมูล session เข้าสู่

119
00:06:26,899 --> 00:06:29,362
memory ครับ ระหว่างรันโค้ดนี้

120
00:06:29,362 --> 00:06:33,098
สิ่งที่เกิดขึ้นคือในระหว่างการย้ายข้อมูล ตัว

121
00:06:33,098 --> 00:06:36,325
session จะทำ intelligent consolidation

122
00:06:36,325 --> 00:06:38,958
คือสกัดเอาเฉพาะข้อเท็จจริงสำคัญ

123
00:06:38,958 --> 00:06:43,458
แล้วทิ้งส่วนที่เป็นแค่ความยุ่งยากของบทสนทนาทิ้งไปครับ

124
00:06:43,458 --> 00:06:47,025
อันนี้เสร็จแล้ว เราได้คำถามว่า my favorite

125
00:06:47,025 --> 00:06:50,337
color is blue green ชอบสีน้ำเงินอมเขียว

126
00:06:50,337 --> 00:06:53,055
แล้วขอให้เขียนบทกวี haiku (ไฮกู)

127
00:06:53,055 --> 00:06:56,706
เกี่ยวกับสีนั้นหน่อย โดยใช้ conversation ID

128
00:06:56,706 --> 00:06:57,805
เป็น 01 ครับ

129
00:06:57,805 --> 00:07:02,136
แล้วมันตอบว่าเป็นสีที่สวยงามเหมือนมหาสมุทรกับต้นไม้

130
00:07:02,136 --> 00:07:04,005
สงบและกลมกลืนกันดีครับ

131
00:07:04,005 --> 00:07:08,420
ทีนี้เราจะมาตรวจสอบว่าบทสนทนานี้ถูกเก็บจริงหรือเปล่า

132
00:07:08,420 --> 00:07:11,987
และมันถูกเก็บอย่างไร ลองดูนะครับ มันบอกว่า

133
00:07:11,987 --> 00:07:15,639
session มีข้อความของ user เกี่ยวกับสีที่ชอบ

134
00:07:15,639 --> 00:07:19,545
และเรามี event ตรงนี้ที่มีคำว่า beautiful อยู่

135
00:07:19,545 --> 00:07:22,093
เสร็จแล้วครับ ตรงนี้คือ method

136
00:07:22,093 --> 00:07:25,320
หลักในการนำบทสนทนาเข้าสู่ memory store

137
00:07:25,320 --> 00:07:29,141
เพื่อให้ค้นหาได้ในอนาคต ก็คือการเพิ่ม session

138
00:07:29,141 --> 00:07:31,774
เข้าไปใน memory ด้วยวิธีนี้ครับ

139
00:07:31,774 --> 00:07:35,510
ขั้นต่อไปคือการเปิดใช้งานการดึงข้อมูล memory

140
00:07:35,510 --> 00:07:38,907
ในเอเจนต์ ครับ มีอยู่สองวิธีคือ load กับ

141
00:07:38,907 --> 00:07:42,304
preload โดย load_memory เป็นแบบ reactive

142
00:07:42,304 --> 00:07:45,871
คือทำงานเมื่อถูกเรียก ส่วน preload เป็นแบบ

143
00:07:45,871 --> 00:07:48,928
proactive คือเตรียมข้อมูลไว้ก่อนครับ

144
00:07:48,928 --> 00:07:51,645
ทีนี้เราจะเพิ่ม load_memory tool

145
00:07:51,645 --> 00:07:54,108
เข้ากับเอเจนต์ ผมรันอันนี้เลย

146
00:07:54,108 --> 00:07:57,844
ใช้ข้อมูลชุดเดิมกัน ตัว tool คือ load_memory

147
00:07:57,844 --> 00:08:01,071
และ instruction คือให้ตอบคำถามของ user

148
00:08:01,071 --> 00:08:04,298
ด้วยคำง่ายๆ และให้ใช้ load_memory tool

149
00:08:04,298 --> 00:08:07,610
เมื่อต้องการนึกถึงบทสนทนาที่ผ่านมา ครับ

150
00:08:07,610 --> 00:08:10,667
เราจะอัปเดต runner แล้วทดสอบกัน User

151
00:08:10,667 --> 00:08:12,875
ถามว่าสีที่ฉันชอบคือสีอะไร

152
00:08:12,875 --> 00:08:16,697
โมเดลตอบว่าสีที่คุณชอบคือสีน้ำเงินอมเขียวครับ

153
00:08:16,697 --> 00:08:19,924
ต่อไปเราจะทดสอบ manual workflow ให้ครบ

154
00:08:19,924 --> 00:08:23,660
เรารันอันนี้แล้วบอกว่าวันเกิดของฉันคือวันที่

155
00:08:23,660 --> 00:08:27,227
15 มีนาคม โดยตั้งชื่อ session เป็น session

156
00:08:27,227 --> 00:08:30,199
วันเกิดอันดับหนึ่ง มันตอบว่ารับทราบ

157
00:08:30,199 --> 00:08:33,851
ฉันจะจำไว้ครับ ทีนี้เราจะบันทึกข้อมูลนี้แบบ

158
00:08:33,851 --> 00:08:37,587
manual อีกครั้ง session วันเกิดถูกบันทึกเข้า

159
00:08:37,587 --> 00:08:38,687
memory แล้ว

160
00:08:38,687 --> 00:08:42,933
ต่อไปเราจะดึงข้อมูลนี้กลับมาดูว่ามันได้ผลหรือเปล่า

161
00:08:42,933 --> 00:08:45,480
ผมใช้ session วันเกิดอันดับสอง

162
00:08:45,480 --> 00:08:48,113
ถามว่าวันเกิดของฉันคือเมื่อไหร่

163
00:08:48,113 --> 00:08:52,019
มันตอบว่าวันเกิดของคุณคือวันที่ 15 มีนาคม ครับ

164
00:08:52,019 --> 00:08:56,435
ตรงนี้เอเจนต์ได้รับคำถามว่าวันเกิดของฉันคือเมื่อไหร่

165
00:08:56,435 --> 00:09:00,511
มันรู้ว่าคำถามนี้ต้องใช้บริบทจากบทสนทนาที่ผ่านมา

166
00:09:00,511 --> 00:09:03,059
เอเจนต์จึงเรียกใช้ load_memory

167
00:09:03,059 --> 00:09:06,625
แล้วมันคืนค่าบทสนทนาก่อนหน้าที่มีวันที่ 15

168
00:09:06,625 --> 00:09:09,598
มีนาคมอยู่ อันนี้เสร็จเรียบร้อยครับ

169
00:09:09,598 --> 00:09:12,910
ทีนี้ถ้าอยากลองเล่นดู เรามี load_memory

170
00:09:12,910 --> 00:09:16,391
อยู่แล้ว ตอนนี้ลองสลับเป็น preload ดูครับ

171
00:09:16,391 --> 00:09:19,873
ในส่วนของ tool ตรงที่เขียนว่า load_memory

172
00:09:19,873 --> 00:09:22,336
ให้เปลี่ยนเป็น preload_memory

173
00:09:22,336 --> 00:09:26,242
แล้วรันดูว่าจะเกิดอะไรขึ้นครับ เอาล่ะ มาลองกัน

174
00:09:26,242 --> 00:09:29,214
ถ้าต้องการผมจะเอาโค้ดส่วน retrieval

175
00:09:29,214 --> 00:09:33,036
มาวางตรงนี้เลย กำลังแทนที่อยู่ครับ อ๊ะขอโทษที

176
00:09:33,036 --> 00:09:35,923
ตรงนี้ต้องแก้ด้วย นี่ไง color test

177
00:09:35,923 --> 00:09:38,725
ดูดีเลยใช่ไหมครับ ทั้งสอง session

178
00:09:38,725 --> 00:09:41,783
ถูกบันทึกแล้ว เรากำลังรันส่วนนี้อยู่

179
00:09:41,783 --> 00:09:45,519
ทุกอย่างเข้าที่ ทุกอย่างสมบูรณ์ครับ แม้จะใช้

180
00:09:45,519 --> 00:09:48,322
preload แต่มันก็ยังค้นหาใน memory

181
00:09:48,322 --> 00:09:51,718
ได้เหมือนกันครับ นอกเหนือจากกฎของเอเจนต์

182
00:09:51,718 --> 00:09:54,521
เรายังเรียกใช้ search memory ตรงๆ

183
00:09:54,521 --> 00:09:56,474
ในโค้ดของเราได้ด้วยครับ

184
00:09:56,474 --> 00:09:59,956
วิธีนี้มีประโยชน์สำหรับการ debug การสร้าง

185
00:09:59,956 --> 00:10:03,522
analytics dashboard และการทำ custom memory

186
00:10:03,522 --> 00:10:07,004
management ครับ ตัวฟังก์ชัน search_memory

187
00:10:07,004 --> 00:10:09,297
จะรับ text query แล้วคืนค่า

188
00:10:09,297 --> 00:10:12,779
SearchMemoryResponse ที่มีรายการ memories

189
00:10:12,779 --> 00:10:16,430
ที่ตรงกันครับ โค้ดง่ายมาก มี user ID แล้วก็

190
00:10:16,430 --> 00:10:20,337
print ผลลัพธ์ออกมาดูว่าเราคุยอะไรกันมาแล้วบ้าง

191
00:10:20,337 --> 00:10:24,073
ผลออกมามี memories ที่เกี่ยวข้องหกรายการครับ

192
00:10:24,073 --> 00:10:27,130
มีสีที่ชอบคือน้ำเงินอมเขียว มี haiku

193
00:10:27,130 --> 00:10:29,933
เกี่ยวกับสีนั้น แล้วก็มีวันที่ 15

194
00:10:29,933 --> 00:10:31,801
กับคำว่ารับทราบจะจำไว้

195
00:10:31,801 --> 00:10:34,858
มันแค่แสดงบทสนทนาทั้งหมดให้เราดูครับ

196
00:10:34,858 --> 00:10:37,660
ทีนี้ถ้าอยากลอง ให้ลองเล่น search

197
00:10:37,660 --> 00:10:42,586
พวกนี้ดูเพื่อทำความเข้าใจว่าการจับคู่คียเวิร์ดทำงานอย่างไร

198
00:10:42,586 --> 00:10:46,322
เราสามารถถามว่า user ชอบสีอะไร และคำถามอื่นๆ

199
00:10:46,322 --> 00:10:50,144
ในลักษณะนี้ แล้วดูว่าแชตบอตตอบอย่างไร หรือมัน

200
00:10:50,144 --> 00:10:53,456
hallucinate (สร้างความจำเท็จ) หรือเปล่า

201
00:10:53,456 --> 00:10:56,258
แต่ประเด็นสำคัญคือการค้นหา memory

202
00:10:56,258 --> 00:10:58,721
นั้นตั้งอยู่บนข้อเท็จจริงครับ

203
00:10:58,721 --> 00:11:01,353
เอเจนต์จึงไม่สามารถ hallucinate

204
00:11:01,353 --> 00:11:03,816
ความจำที่ไม่มีอยู่จริงได้ครับ

205
00:11:03,816 --> 00:11:07,128
ส่วนการค้นหาทำงานอย่างไร memory service

206
00:11:07,128 --> 00:11:10,780
แบบนี้ทำการจับคู่คียเวิร์ด ส่วนใน Vertex AI

207
00:11:10,780 --> 00:11:14,686
Memory Bank ซึ่งเราจะได้ทำในแบบฝึกหัดของ Day 5

208
00:11:14,686 --> 00:11:18,507
จะใช้การค้นหาเชิงความหมายด้วย embeddings ครับ

209
00:11:18,507 --> 00:11:21,904
อันนี้เสร็จแล้ว ต่อไป section หกคือการทำ

210
00:11:21,904 --> 00:11:25,811
memory storage ให้อัตโนมัติครับ ตอนนี้เราเรียก

211
00:11:25,811 --> 00:11:27,594
add_session_to_memory

212
00:11:27,594 --> 00:11:31,245
ด้วยตนเองมาตลอดเพื่อย้ายข้อมูลไปเก็บระยะยาว

213
00:11:31,245 --> 00:11:32,774
แต่ระบบ production

214
00:11:32,774 --> 00:11:36,086
ต้องการให้เรื่องนี้เกิดขึ้นเองอัตโนมัติ

215
00:11:36,086 --> 00:11:38,464
ดังนั้นเราจึงแนะนำ callbacks

216
00:11:38,464 --> 00:11:42,370
(ฟังก์ชันเรียกกลับ) ครับ ระบบ callback ของ ADK

217
00:11:42,370 --> 00:11:46,192
ให้เรา hook เข้าไปยังจังหวะสำคัญๆ ของการทำงาน

218
00:11:46,192 --> 00:11:48,569
callback เป็นฟังก์ชัน Python

219
00:11:48,569 --> 00:11:51,626
ที่เรานิยามแล้วผูกเข้ากับเอเจนต์ ADK

220
00:11:51,626 --> 00:11:54,938
จะเรียกมันเองโดยอัตโนมัติในแต่ละขั้นตอน

221
00:11:54,938 --> 00:11:57,146
ทำหน้าที่เหมือน checkpoint

222
00:11:57,146 --> 00:12:00,543
ระหว่างการทำงานของเอเจนต์ครับ จะคิดซะว่า

223
00:12:00,543 --> 00:12:02,921
callback เป็น event listener

224
00:12:02,921 --> 00:12:05,469
ในวงจรชีวิตของเอเจนต์ก็ได้ครับ

225
00:12:05,469 --> 00:12:08,016
เมื่อเอเจนต์ประมวลผลคำขอหนึ่งๆ

226
00:12:08,016 --> 00:12:11,668
มันจะผ่านหลายขั้นตอน ตั้งแต่รับ input เรียก

227
00:12:11,668 --> 00:12:15,489
LLM เรียกใช้ tools ไปจนถึงสร้างคำตอบ callback

228
00:12:15,489 --> 00:12:17,018
ทำให้เราแทรก logic

229
00:12:17,018 --> 00:12:20,584
ที่กำหนดเองเข้าไปในแต่ละขั้นตอนเหล่านี้ได้

230
00:12:20,584 --> 00:12:24,321
โดยไม่ต้องแก้โค้ดหลักของเอเจนต์ครับ callback

231
00:12:24,321 --> 00:12:27,803
มีประเภทอะไรบ้าง มี before_agent_callback

232
00:12:27,803 --> 00:12:31,369
ที่รันก่อนที่เอเจนต์จะเริ่มประมวลผลคำขอ มี

233
00:12:31,369 --> 00:12:35,191
after_agent_callback ที่รันหลังเอเจนต์จบ turn

234
00:12:35,191 --> 00:12:38,163
ของตัวเอง แล้วก็มี before และ after

235
00:12:38,163 --> 00:12:39,262
ที่อยู่รอบๆ

236
00:12:39,262 --> 00:12:46,481
ตำแหน่งการเรียกใช้ tool มี before_model_callback และ after_model_callback ที่อยู่รอบๆ

237
00:12:46,481 --> 00:12:50,047
การเรียก LLM และมี on_model_error_callback

238
00:12:50,047 --> 00:12:53,189
ที่ทำงานเมื่อเกิด error ครับ use case

239
00:12:53,189 --> 00:12:56,416
ที่พบบ่อยคือ logging และ observability

240
00:12:56,416 --> 00:13:00,323
(การติดตามการทำงาน) เช่นดูว่าเอเจนต์ทำอะไรบ้าง

241
00:13:00,323 --> 00:13:03,719
การบันทึกลง memory การตรวจสอบแบบกำหนดเอง

242
00:13:03,719 --> 00:13:07,371
การกรองข้อมูล หรือการเฝ้าดูประสิทธิภาพ ครับ

243
00:13:07,371 --> 00:13:11,108
อยากรู้เรื่อง callback เพิ่มเติมไปอ่านได้ที่

244
00:13:11,108 --> 00:13:12,891
documentation นี้ครับ

245
00:13:12,891 --> 00:13:16,712
ผมจะใส่ลิงก์ไว้ในคำอธิบายของวิดีโอด้วยเช่นกัน

246
00:13:16,712 --> 00:13:18,835
นี่คือวิธีที่มันทำงานครับ

247
00:13:18,835 --> 00:13:22,232
ถ้าอยากเข้าใจประเภทของ callback เหล่านี้

248
00:13:22,232 --> 00:13:23,506
before callback

249
00:13:23,506 --> 00:13:26,648
รันก่อนที่เอเจนต์จะประมวลผลคำขอ after

250
00:13:26,648 --> 00:13:30,045
ตัวหลังจะรันหลังเอเจนต์จบ turn ของตัวเอง

251
00:13:30,045 --> 00:13:32,677
แล้วก็ before_tool_callback กับ

252
00:13:32,677 --> 00:13:35,480
after_tool_callback ตรงนี้เลยครับ

253
00:13:35,480 --> 00:13:36,669
อันนี้อยู่รอบๆ

254
00:13:36,669 --> 00:13:42,104
การเรียกใช้ tool และตัว model แบบ before และ after ก็คืออยู่รอบๆ

255
00:13:42,104 --> 00:13:45,840
การเรียก LLM ครับ ไดอะแกรมนี้อธิบายประเภทของ

256
00:13:45,840 --> 00:13:49,407
callback และการทำงานของมันให้เราเข้าใจครับ

257
00:13:49,407 --> 00:13:51,530
นี่คือก่อนเอเจนต์ประมวลผล

258
00:13:51,530 --> 00:13:55,436
นี่คือหลังเอเจนต์ทำเสร็จ ส่วนนี้คือการเรียกใช้

259
00:13:55,436 --> 00:13:59,258
tool และส่วนนี้คือการล้อมรอบการเรียก LLM ครับ

260
00:13:59,258 --> 00:14:02,570
ต่อไปคือการจัดเก็บ memory อัตโนมัติด้วย

261
00:14:02,570 --> 00:14:03,758
callbacks ครับ

262
00:14:03,758 --> 00:14:06,561
สำหรับการจัดเก็บอัตโนมัติเราจะใช้

263
00:14:06,561 --> 00:14:08,684
after_agent_callback ครับ

264
00:14:08,684 --> 00:14:12,335
ฟังก์ชันนี้จะทำงานทุกครั้งที่เอเจนต์จบ turn

265
00:14:12,335 --> 00:14:15,053
แล้วเรียก add_session เพื่อเรียก

266
00:14:15,053 --> 00:14:16,836
add_session_to_memory

267
00:14:16,836 --> 00:14:19,724
เพื่อบันทึกบทสนทนาโดยอัตโนมัติครับ

268
00:14:19,724 --> 00:14:23,375
แต่ความท้าทายคือฟังก์ชัน callback จะเข้าถึง

269
00:14:23,375 --> 00:14:27,197
memory service และ session ปัจจุบันได้อย่างไร

270
00:14:27,197 --> 00:14:30,848
สำหรับเรื่องนั้นเรามี callback context ครับ

271
00:14:30,848 --> 00:14:34,330
เมื่อเรานิยามฟังก์ชัน callback ขึ้นมา ADK

272
00:14:34,330 --> 00:14:37,047
จะส่งพารามิเตอร์พิเศษที่เรียกว่า

273
00:14:37,047 --> 00:14:40,359
callback_context เข้ามาให้อัตโนมัติ ตัว

274
00:14:40,359 --> 00:14:43,756
callback context นี้ให้การเข้าถึง memory

275
00:14:43,756 --> 00:14:47,153
service และส่วนประกอบ runtime อื่นๆ ครับ

276
00:14:47,153 --> 00:14:50,635
เราจะใช้มันใน callback ของเราเพื่อเข้าถึง

277
00:14:50,635 --> 00:14:53,607
memory service และ session ปัจจุบัน

278
00:14:53,607 --> 00:14:57,513
เพื่อบันทึกบทสนทนาอัตโนมัติหลังจบทุก turn ครับ

279
00:14:57,513 --> 00:15:00,401
เราไม่ต้องสร้าง context นี้เอง ADK

280
00:15:00,401 --> 00:15:03,033
เป็นคนสร้างแล้วส่งเข้า callback

281
00:15:03,033 --> 00:15:05,156
ให้อัตโนมัติเมื่อมันทำงาน

282
00:15:05,156 --> 00:15:08,213
เราไม่ต้องห่วงว่ามันทำงานอย่างไรครับ

283
00:15:08,213 --> 00:15:12,969
ขั้นต่อไปคือสร้างเอเจนต์ที่รวมการจัดเก็บอัตโนมัติเข้ากับ

284
00:15:12,969 --> 00:15:16,790
preload_memory ครับ สำหรับการจัดเก็บอัตโนมัติ

285
00:15:16,790 --> 00:15:22,565
เราต้องสร้างเอเจนต์ที่ผสมการจัดเก็บอัตโนมัติกับการดึงข้อมูลอัตโนมัติ

286
00:15:22,565 --> 00:15:26,386
การจัดเก็บอัตโนมัติก็คือ after_agent_callback

287
00:15:26,386 --> 00:15:29,443
ที่บันทึกบทสนทนา ส่วน preload_memory

288
00:15:29,443 --> 00:15:32,755
จะโหลดข้อมูลความจำครับ ทำอย่างไรล่ะครับ

289
00:15:32,755 --> 00:15:36,322
มีเอเจนต์ตรงนี้ instruction คือตอบคำถามของ

290
00:15:36,322 --> 00:15:40,228
user เครื่องมือคือ preload_memory และ callback

291
00:15:40,228 --> 00:15:43,965
คือ autosave_memory ซึ่งบันทึกหลังจบทุก turn

292
00:15:43,965 --> 00:15:45,324
ครับ เรามารันกัน

293
00:15:45,324 --> 00:15:50,334
สิ่งที่เกิดขึ้นโดยอัตโนมัติคือหลังจากเอเจนต์ตอบกลับทุกครั้ง

294
00:15:50,334 --> 00:15:53,476
callback จะทำงาน และข้อมูลของ session

295
00:15:53,476 --> 00:15:56,533
จะถูกย้ายเข้า memory โดยไม่ต้องเรียก

296
00:15:56,533 --> 00:15:59,760
add_session_to_memory ด้วยตนเองเลยครับ

297
00:15:59,760 --> 00:16:02,987
ต่อไปสร้าง runner แล้วทดสอบเอเจนต์ครับ

298
00:16:02,987 --> 00:16:05,110
เราสร้าง runner เสร็จแล้ว

299
00:16:05,110 --> 00:16:08,677
ทีนี้มาทดสอบเอเจนต์กัน เรามี test หนึ่งกับ

300
00:16:08,677 --> 00:16:09,776
test สอง

301
00:16:09,776 --> 00:16:15,381
อันแรกคือผมให้ของขวัญเป็นของเล่นใหม่แก่หลานชายในวันเกิดปีแรกของเขา

302
00:16:15,381 --> 00:16:16,909
มันตอบว่าเยี่ยมมาก

303
00:16:16,909 --> 00:16:20,476
หวังว่าหลานชายของคุณจะสนุกกับของเล่นนะครับ

304
00:16:20,476 --> 00:16:23,024
อันที่สองคือผมให้อะไรหลานชายไป

305
00:16:23,024 --> 00:16:28,119
มันตอบว่าคุณให้ของเล่นใหม่แก่หลานชายในวันเกิดปีแรกของเขาครับ

306
00:16:28,119 --> 00:16:30,497
แล้วเพิ่งเกิดอะไรขึ้นล่ะครับ

307
00:16:30,497 --> 00:16:33,979
บทสนทนาแรกพูดถึงของขวัญให้หลานชาย ดังนั้น

308
00:16:33,979 --> 00:16:37,375
callback จึงบันทึกลง memory โดยอัตโนมัติ

309
00:16:37,375 --> 00:16:40,263
ส่วนบทสนทนาที่สองเป็น session ใหม่

310
00:16:40,263 --> 00:16:42,895
ถามเรื่องของขวัญ preload_memory

311
00:16:42,895 --> 00:16:45,698
จึงดึงข้อมูลความจำกลับมาอัตโนมัติ

312
00:16:45,698 --> 00:16:47,990
แล้วเอเจนต์ก็ตอบถูกต้องครับ

313
00:16:47,990 --> 00:16:50,538
ดังนั้นจึงมีการเรียกใช้ memory

314
00:16:50,538 --> 00:16:52,321
ด้วยมือเป็นศูนย์ครั้ง

315
00:16:52,321 --> 00:16:55,888
นี่คือการจัดการหน่วยความจำแบบอัตโนมัติครับ

316
00:16:55,888 --> 00:16:59,285
ควรบันทึก memory บ่อยแค่ไหน คือควรบันทึก

317
00:16:59,285 --> 00:17:01,663
session ลง memory บ่อยแค่ไหน

318
00:17:01,663 --> 00:17:05,229
มีตัวเลือกอยู่ดังนี้ครับ คือหลังจบทุก turn

319
00:17:05,229 --> 00:17:08,456
หลังจบบทสนทนา และเป็นช่วงๆ ตามระยะเวลา

320
00:17:08,456 --> 00:17:12,023
ควรบันทึกหลังจบทุก turn เมื่อต้องการอัปเดต

321
00:17:12,023 --> 00:17:13,637
memory แบบเรียลไทม์

322
00:17:13,637 --> 00:17:16,864
ส่วนแบบหลังจบบทสนทนาเหมาะเมื่อทำ batch

323
00:17:16,864 --> 00:17:20,175
processing หรือต้องการลดจำนวน API calls

324
00:17:20,175 --> 00:17:23,827
และแบบเป็นช่วงๆ เหมาะกับบทสนทนาที่ยาวๆ ครับ

325
00:17:23,827 --> 00:17:27,054
เรารู้กันมาแล้วนะครับ ต่อไปคือ section

326
00:17:27,054 --> 00:17:30,111
เจ็ดเรื่อง memory consolidation ครับ

327
00:17:30,111 --> 00:17:34,102
ในส่วนนี้เราจะเข้าใจข้อจำกัดของการเก็บข้อมูลดิบ

328
00:17:34,102 --> 00:17:37,584
สิ่งที่เราเก็บมาตลอดคือทุกข้อความของ user

329
00:17:37,584 --> 00:17:40,556
ทุกคำตอบของเอเจนต์ และทุก tool call

330
00:17:40,556 --> 00:17:43,868
ปัญหาคือถ้ามี 50 ข้อความในหนึ่ง session

331
00:17:43,868 --> 00:17:47,095
มันจะเท่ากับ 10,000 tokens แล้วทั้ง 50

332
00:17:47,095 --> 00:17:49,813
ข้อความก็ถูกเก็บลง memory หมดเลย

333
00:17:49,813 --> 00:17:52,445
ตัวค้นหาจะคืนค่าทั้ง 50 ข้อความ

334
00:17:52,445 --> 00:17:56,182
และเอเจนต์ต้องประมวลผล 10,000 tokens ซึ่งมัน

335
00:17:56,182 --> 00:18:00,088
scale ไม่ไหวครับ เราจำเป็นต้องมี consolidation

336
00:18:00,088 --> 00:18:02,466
ดังนั้น memory consolidation

337
00:18:02,466 --> 00:18:04,674
จึงเข้ามามีบทบาทตรงนี้ครับ

338
00:18:04,674 --> 00:18:07,986
หมายความคือสกัดเอาเฉพาะข้อเท็จจริงสำคัญ

339
00:18:07,986 --> 00:18:10,958
แล้วทิ้ง noise ของบทสนทนาทิ้งไปครับ

340
00:18:10,958 --> 00:18:14,100
การเก็บข้อมูลดิบจะหน้าตาประมาณนี้ครับ

341
00:18:14,100 --> 00:18:16,223
จากตัวอย่างก่อนหน้าของเรา

342
00:18:16,223 --> 00:18:19,620
มันเก็บข้อความทั้งสี่ที่ซ้ำซ้อนและยืดยาว

343
00:18:19,620 --> 00:18:22,507
เพราะเห็นได้ว่ามันพูดซ้ำกัน หลังทำ

344
00:18:22,507 --> 00:18:25,734
consolidation ข้อมูลที่สกัดได้คือ user

345
00:18:25,734 --> 00:18:27,348
ชอบสีน้ำเงินอมเขียว

346
00:18:27,348 --> 00:18:33,462
หมายความว่ามันเก็บเพียงข้อเท็จจริงเดียวที่กระชับจากข้อมูลดิบทั้งก้อนครับ

347
00:18:33,462 --> 00:18:36,349
ประโยชน์คือใช้พื้นที่จัดเก็บน้อยลง

348
00:18:36,349 --> 00:18:39,746
ดึงข้อมูลเร็วขึ้น และคำตอบแม่นยำขึ้นครับ

349
00:18:39,746 --> 00:18:41,954
จากตัวอย่าง session ของเรา

350
00:18:41,954 --> 00:18:45,776
สิ่งที่ได้ก็คือแบบนี้ครับ subsection ถัดไปคือ

351
00:18:45,776 --> 00:18:49,342
consolidation ทำงานอย่างไร ในส่วนของแนวคิด

352
00:18:49,342 --> 00:18:52,909
เราจะไม่เขียนโค้ดส่วนนี้กันนะครับ เริ่มจาก

353
00:18:52,909 --> 00:18:56,221
event ดิบของ session ตัว language model

354
00:18:56,221 --> 00:18:59,533
จะวิเคราะห์บทสนทนา สกัดข้อเท็จจริงสำคัญ

355
00:18:59,533 --> 00:19:01,401
จัดเก็บความจำที่กระชับ

356
00:19:01,401 --> 00:19:04,203
และผสานเข้ากับความจำเดิมที่มีอยู่

357
00:19:04,203 --> 00:19:06,666
โดยขจัดข้อมูลที่ซ้ำกันออกครับ

358
00:19:06,666 --> 00:19:09,893
ตัวอย่างของการแปลงข้อมูลเช่น ผมแพ้ถั่ว

359
00:19:09,893 --> 00:19:12,016
กินอะไรที่มีถั่วไม่ได้เลย

360
00:19:12,016 --> 00:19:15,328
ผลลัพธ์ที่ได้คือความจำแบบมีโครงสร้างว่า

361
00:19:15,328 --> 00:19:18,215
แพ้ถั่ว ถั่วต้นไม้ ระดับความรุนแรง

362
00:19:18,215 --> 00:19:20,508
หลีกเลี่ยงอย่างสมบูรณ์ ครับ

363
00:19:20,508 --> 00:19:26,198
ภาษาธรรมชาติจึงถูกแปลงเป็นข้อมูลที่มีโครงสร้างและนำไปใช้ได้จริงครับ

364
00:19:26,198 --> 00:19:29,085
ส่วนถัดไปพูดถึงขั้นต่อไปของ memory

365
00:19:29,085 --> 00:19:32,737
consolidation ครับ ประเด็นสำคัญที่ต้องจำคือ

366
00:19:32,737 --> 00:19:36,388
managed memory service จัดการ consolidation

367
00:19:36,388 --> 00:19:40,210
ให้อัตโนมัติ ตรงนี้เราใช้ API เดิม ใช้ method

368
00:19:40,210 --> 00:19:41,738
ของ memory ตัวเดิม

369
00:19:41,738 --> 00:19:45,390
สิ่งที่ต่างคือสิ่งที่เกิดขึ้นเบื้องหลังครับ

370
00:19:45,390 --> 00:19:48,872
memory service แบบนี้เก็บ event ดิบๆ ส่วน

371
00:19:48,872 --> 00:19:50,655
Vertex AI Memory Bank

372
00:19:50,655 --> 00:19:54,052
จะกลั่นข้อมูลอย่างชาญฉลาดก่อนจัดเก็บครับ

373
00:19:54,052 --> 00:19:57,194
ถ้าอยากเรียนรู้เพิ่มเติมเรื่อง memory

374
00:19:57,194 --> 00:19:58,298
consolidation

375
00:19:58,298 --> 00:20:01,100
ซึ่งเราจะได้ศึกษาต่อในห้าวันถัดไป

376
00:20:01,100 --> 00:20:03,903
สามารถไปอ่านหน้า guide นี้ได้ครับ

377
00:20:03,903 --> 00:20:07,299
นี่คือสรุปสิ่งที่เราทำในแบบฝึกหัดนี้ครับ

378
00:20:07,299 --> 00:20:11,206
เราได้เรียนรู้การเพิ่ม memory การจัดเก็บข้อมูล

379
00:20:11,206 --> 00:20:14,688
การค้นหา memory การดึงข้อมูลในเอเจนต์ และ

380
00:20:14,688 --> 00:20:16,811
memory consolidation ครับ

381
00:20:16,811 --> 00:20:19,868
หวังว่าแนวคิดจะชัดเจนสำหรับคุณนะครับ

382
00:20:19,868 --> 00:20:23,519
ถ้ายังไม่ชัดก็ลองดูวิดีโออีกหนึ่งหรือสองรอบ

383
00:20:23,519 --> 00:20:26,831
แล้วจะเข้าใจง่ายขึ้นในทุกครั้งที่ดูครับ

384
00:20:26,831 --> 00:20:30,653
และเมื่อจบ Day 3 แล้ว โปรดไปดูวิดีโอของ Day 4

385
00:20:30,653 --> 00:20:34,134
ซึ่งพูดถึงการ implement observability และ

386
00:20:34,134 --> 00:20:37,022
evaluation ของเอเจนต์ ซึ่งสำคัญมาก

387
00:20:37,022 --> 00:20:41,777
เพราะมันช่วยให้มั่นใจว่าเอเจนต์ทำงานตามที่ตั้งใจไว้จริงๆ

388
00:20:41,777 --> 00:20:44,240
ใน production ครับ ขอบคุณครับ