การออกแบบเครื่องมือสำหรับนักพัฒนาเว็บ: การใช้โทเค็นอย่างมีประสิทธิภาพในความช่วยเหลือจาก AI

เผยแพร่: 30 มกราคม 2026

เมื่อสร้างความช่วยเหลือจาก AI สำหรับประสิทธิภาพ ความท้าทายด้านวิศวกรรมหลักคือการทำให้ Gemini ทำงานร่วมกับ การติดตามประสิทธิภาพที่บันทึกไว้ในเครื่องมือสำหรับนักพัฒนาเว็บได้อย่างราบรื่น

โมเดลภาษาขนาดใหญ่ (LLM) ทำงานภายใน "หน้าต่างบริบท" ซึ่งหมายถึง ขีดจำกัดที่เข้มงวดเกี่ยวกับปริมาณข้อมูลที่ประมวลผลได้ในครั้งเดียว ความจุนี้วัดเป็นโทเค็น สำหรับโมเดล Gemini โทเค็น 1 รายการจะประกอบด้วยกลุ่มอักขระประมาณ 4 ตัว

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

เราต้องออกแบบระบบที่เพิ่มปริมาณข้อมูลที่เป็นประโยชน์สำหรับ LLM ให้ได้สูงสุดโดยใช้โทเค็นน้อยที่สุด เพื่อให้ความช่วยเหลือจาก AI สำหรับประสิทธิภาพเป็นไปได้ ในบล็อกนี้ คุณจะได้เรียนรู้เกี่ยวกับเทคนิคที่เราใช้ในการดำเนินการดังกล่าวและนำไปใช้กับโปรเจ็กต์ของคุณเอง

ปรับแต่งบริบทเริ่มต้น

การแก้ไขข้อบกพร่องของประสิทธิภาพเว็บไซต์เป็นงานที่ซับซ้อน นักพัฒนาซอฟต์แวร์สามารถ ดูการติดตามแบบเต็มเพื่อดูบริบท หรือมุ่งเน้นที่ Core Web Vitals และช่วงเวลาที่เกี่ยวข้อง ของการติดตาม หรือแม้แต่เจาะลึกลงไปในรายละเอียดและมุ่งเน้นที่เหตุการณ์แต่ละรายการ เช่น การคลิกหรือการเลื่อน และสแต็กการเรียกที่เกี่ยวข้อง

ความช่วยเหลือจาก AI ของ DevTools ต้องสอดคล้องกับเส้นทางของนักพัฒนาซอฟต์แวร์เหล่านั้น และทำงานร่วมกับข้อมูลที่เกี่ยวข้องเท่านั้น เพื่อให้คำแนะนำที่เจาะจง สำหรับสิ่งที่นักพัฒนาซอฟต์แวร์ให้ความสำคัญ เพื่อช่วยกระบวนการแก้ไขข้อบกพร่อง ดังนั้นเราจึงสร้างความช่วยเหลือจาก AI เพื่อแบ่งข้อมูลตามงานการแก้ไขข้อบกพร่องของคุณแทนที่จะส่งการติดตามแบบเต็มเสมอ

งานการแก้ไขข้อบกพร่อง ข้อมูลที่ส่งไปยังความช่วยเหลือจาก AI ในตอนแรก
แชทเกี่ยวกับการติดตามประสิทธิภาพ ข้อมูลสรุปการติดตาม: รายงานแบบข้อความที่มีข้อมูลระดับสูงจากการติดตามและเซสชันการแก้ไขข้อบกพร่อง ประกอบด้วย URL ของหน้าเว็บ เงื่อนไขการควบคุมอัตรา เมตริกประสิทธิภาพที่สำคัญ (LCP, INP, CLS) รายการข้อมูลเชิงลึกที่มี และสรุป CrUX (หากมี)
แชทเกี่ยวกับข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพ สรุปการติดตาม และชื่อข้อมูลเชิงลึกด้านประสิทธิภาพที่เลือก
แชทเกี่ยวกับงานจากร่องรอย สรุปการติดตาม และแผนภูมิการเรียกที่เรียงตามลำดับซึ่งมีงานที่เลือกอยู่
แชทเกี่ยวกับคำขอเครือข่าย สรุปการติดตาม รวมถึงคีย์คำขอและการประทับเวลาที่เลือก
สร้างคำอธิบายประกอบการติดตาม แผนผังการเรียกที่เรียงลำดับซึ่งมีงานที่เลือกอยู่ แผนผังที่แปลงเป็นอนุกรมจะระบุว่างานใดเป็นงานที่เลือก

โดยปกติแล้ว ระบบจะส่งข้อมูลสรุปการติดตามเพื่อระบุบริบทเริ่มต้นให้ Gemini ซึ่งเป็นโมเดลพื้นฐานของความช่วยเหลือจาก AI สำหรับคำอธิบายประกอบที่ AI สร้างขึ้น ระบบจะ ละเว้น

การให้เครื่องมือแก่ AI

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

เราได้กำหนดชุดฟังก์ชันแบบละเอียดสำหรับเอเจนต์ตามเส้นทางการแก้ไขข้อบกพร่องที่ระบุไว้ก่อนหน้านี้ ฟังก์ชันเหล่านี้จะเจาะลึกรายละเอียด ที่ถือว่าสำคัญตามบริบทเริ่มต้น ซึ่งคล้ายกับวิธีที่นักพัฒนาซอฟต์แวร์ ที่เป็นมนุษย์จะใช้ในการแก้ไขข้อบกพร่องด้านประสิทธิภาพ ชุดฟังก์ชันมีดังนี้

ฟังก์ชัน คำอธิบาย
getInsightDetails(name) แสดงข้อมูลโดยละเอียดเกี่ยวกับข้อมูลเชิงลึกด้านประสิทธิภาพที่เฉพาะเจาะจง (เช่น รายละเอียดเกี่ยวกับสาเหตุที่ระบบแจ้งว่า LCP ไม่เหมาะสม)
getEventByKey(key) แสดงผลพร็อพเพอร์ตี้โดยละเอียดสำหรับเหตุการณ์เดียวที่เฉพาะเจาะจง
getMainThreadTrackSummary(start, end) แสดงผลสรุปกิจกรรมของเธรดหลักสำหรับขอบเขตที่ระบุ รวมถึงสรุปจากบนลงล่าง จากล่างขึ้นบน และจากบุคคลที่สาม
getNetworkTrackSummary(start, end) แสดงผลข้อมูลสรุปกิจกรรมเครือข่ายสำหรับขอบเขตเวลาที่ระบุ
getDetailedCallTree(event_key) แสดงผลแผนภูมิการเรียกใช้ทั้งหมดสำหรับเหตุการณ์ในเทรดหลักที่เฉพาะเจาะจงในการติดตามประสิทธิภาพ
getFunctionCode(url, line, col) แสดงผลซอร์สโค้ดของฟังก์ชันที่กำหนดในตำแหน่งที่เฉพาะเจาะจงในทรัพยากร โดยมีคำอธิบายประกอบพร้อมข้อมูลประสิทธิภาพรันไทม์จากร่องรอยประสิทธิภาพ
getResourceContent(url) แสดงเนื้อหาของทรัพยากรข้อความที่หน้าเว็บใช้ (เช่น HTML หรือ CSS)

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

ตัวอย่างการดำเนินการของเอเจนต์

มาดูตัวอย่างการใช้งานจริงของความช่วยเหลือจาก AI ที่ใช้การเรียกใช้ฟังก์ชันเพื่อ ดึงข้อมูลเพิ่มเติมกัน หลังจากได้รับข้อความแจ้งเริ่มต้นว่า "ทำไมคำขอนี้จึงช้า" ความช่วยเหลือจาก AI สามารถเรียกใช้ฟังก์ชันต่อไปนี้ได้ทีละรายการ

  1. getEventByKey: ดึงข้อมูลรายละเอียดการแบ่งเวลา (TTFB, เวลาในการดาวน์โหลด) ของคำขอที่ผู้ใช้เลือก
  2. getMainThreadTrackSummary: ตรวจสอบว่าเทรดหลักทำงานหนัก (ถูกบล็อก) หรือไม่ เมื่อควรเริ่มคำขอ
  3. getNetworkTrackSummary: วิเคราะห์ว่าทรัพยากรอื่นๆ แข่งขันกันใช้ แบนด์วิดท์ในเวลาเดียวกันหรือไม่
  4. getInsightDetails: ตรวจสอบว่าสรุปการติดตามได้กล่าวถึงข้อมูลเชิงลึกที่เกี่ยวข้องกับคำขอนี้ว่าเป็นคอขวดแล้วหรือไม่

การรวมผลลัพธ์ของการเรียกเหล่านี้จะช่วยให้ความช่วยเหลือจาก AI สามารถให้การวินิจฉัยและเสนอขั้นตอนที่ทําได้จริง เช่น การแนะนําการปรับปรุงโค้ดโดยใช้ getFunctionCode หรือการเพิ่มประสิทธิภาพการโหลดทรัพยากรตาม getResourceContent

อย่างไรก็ตาม การดึงข้อมูลที่เกี่ยวข้องเป็นเพียงครึ่งหนึ่งของความท้าทายเท่านั้น แม้ว่าฟังก์ชันจะให้ข้อมูลแบบละเอียด แต่ข้อมูลที่ฟังก์ชันเหล่านั้นแสดงผลก็อาจมีขนาดใหญ่ อีกตัวอย่างหนึ่งคือ getDetailedCallTree สามารถแสดงผล โครงสร้างที่มีโหนดหลายร้อยรายการ ใน JSON มาตรฐาน การทำเช่นนี้จะต้องใช้ { และ } หลายรายการเพื่อการซ้อนเท่านั้น

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

ทำให้ข้อมูลเป็นอนุกรม

มาดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีที่เราจัดการกับความท้าทายนี้กันต่อโดยใช้ ตัวอย่างแผนผังการเรียก เนื่องจากแผนผังการเรียกเป็นข้อมูลส่วนใหญ่ใน Performance Trace ตัวอย่างต่อไปนี้แสดงงานเดียวใน Call Stack ใน JSON เพื่อเป็นข้อมูลอ้างอิง

{
  "id": 2,
  "name": "animate",
  "selected": true,
  "duration": 150,
  "selfTime": 20,
  "children": [3, 5, 6, 7, 10, 11, 12]
}

การติดตามประสิทธิภาพ 1 รายการอาจมีข้อมูลดังกล่าวหลายพันรายการ ดังที่แสดงใน ภาพหน้าจอต่อไปนี้ กล่องสีเล็กๆ ทุกกล่องจะแสดงโดยใช้โครงสร้างออบเจ็กต์นี้

สแต็กการเรียกในร่องรอยประสิทธิภาพที่บันทึกไว้ในเครื่องมือสำหรับนักพัฒนาเว็บ

รูปแบบนี้เหมาะสำหรับการทำงานแบบเป็นโปรแกรมใน DevTools แต่ไม่เหมาะสำหรับ LLM เนื่องจากเหตุผลต่อไปนี้

  1. คีย์ที่ซ้ำกัน: สตริง เช่น "duration", "selfTime" และ "children" จะซ้ำกันสำหรับทุกโหนดในแผนผังการเรียก ดังนั้น ต้นไม้ ที่มี 500 โหนดที่ส่งไปยังโมเดลจะใช้โทเค็นสำหรับแต่ละคีย์ 500 ครั้ง
  2. รายการแบบละเอียด: การแสดงรหัสย่อยทุกรายการทีละรายการผ่าน children จะใช้โทเค็นจํานวนมาก โดยเฉพาะอย่างยิ่งสําหรับงานที่ทําให้เกิดเหตุการณ์ปลายทางจํานวนมาก

การใช้รูปแบบที่ประหยัดโทเค็นสำหรับข้อมูลทั้งหมดที่ใช้ร่วมกับความช่วยเหลือจาก AI เพื่อประสิทธิภาพเป็นกระบวนการแบบทีละขั้นตอน

การทำซ้ำครั้งแรก

เมื่อเริ่มพัฒนาความช่วยเหลือจาก AI สำหรับประสิทธิภาพ เราได้เพิ่มประสิทธิภาพเพื่อความเร็วในการจัดส่ง แนวทางในการเพิ่มประสิทธิภาพโทเค็นของเรานั้นเป็นพื้นฐาน และเราได้นำ JSON ต้นฉบับออกจากวงเล็บปีกกาและคอมมา ซึ่งส่งผลให้รูปแบบเป็นดังนี้

allUrls = [...]

Node: 1 - update
Selected: false
Duration: 200
Self Time: 50
Children:
   2 - animate

Node: 2 - animate
Selected: true
Duration: 150
Self Time: 20
URL: 0
Children:
   3 - calculatePosition
   5 - applyStyles
   6 - applyStyles
   7 - calculateLayout
   10 - applyStyles
   11 - applyStyles
   12 - applyStyles

Node: 3 - calculatePosition
Selected: false
Duration: 15
Self Time: 2
URL: 0
Children:
   4 - getBoundingClientRect

...

แต่เวอร์ชันแรกนี้ปรับปรุงจาก JSON ดิบเพียงเล็กน้อยเท่านั้น โดยยังคง แสดงรายการโหนดลูกที่มีรหัสและชื่ออย่างชัดเจน และเพิ่ม คีย์ที่ซ้ำกันซึ่งอธิบายได้ (Node:, Selected:, Duration:, …) ไว้หน้า แต่ละบรรทัด

เพิ่มประสิทธิภาพรายการโหนดย่อย

ขั้นตอนถัดไปในการเพิ่มประสิทธิภาพเพิ่มเติมคือ เราได้นำชื่อของโหนดย่อยออก (calculatePosition, applyStyles, … ในตัวอย่างก่อนหน้า) เนื่องจากความช่วยเหลือจาก AI มีสิทธิ์เข้าถึงโหนดทั้งหมดผ่านการเรียกใช้ฟังก์ชันและข้อมูลนี้ อยู่ในส่วนหัวของโหนด (Node: 3 - calculatePosition) อยู่แล้ว จึงไม่จำเป็นต้อง ระบุข้อมูลนี้ซ้ำ ซึ่งช่วยให้เราย่อ Children เป็นรายการจำนวนเต็ม แบบง่ายๆ ได้

Node: 2 - animate
Selected: true
Duration: 150
Self Time: 20
URL: 0
Children: 3, 5, 6, 7, 10, 11, 12

..

แม้ว่าการปรับปรุงนี้จะดีขึ้นอย่างเห็นได้ชัดจากก่อนหน้านี้ แต่ก็ยังสามารถ เพิ่มประสิทธิภาพได้อีก เมื่อดูตัวอย่างก่อนหน้า คุณอาจสังเกตเห็นว่า Children แทบจะเป็นลำดับต่อเนื่อง โดยมีเพียง 4, 8 และ 9 ที่ขาดหายไป

เนื่องจากในความพยายามครั้งแรก เราใช้อัลกอริทึม Depth-First Search (DFS) เพื่อจัดลำดับข้อมูลแบบต้นไม้จากร่องรอยประสิทธิภาพ ซึ่งส่งผลให้ โหนดระดับเดียวกันมีรหัสที่ไม่ต่อเนื่องกัน เราจึงต้องแสดงรหัสทุกรายการ แยกกัน

เราตระหนักว่าหากจัดทำดัชนีโครงสร้างใหม่โดยใช้การค้นหาแบบกว้างก่อน (BFS) เราจะได้รับรหัสตามลำดับแทน ซึ่งจะทำให้การเพิ่มประสิทธิภาพอีกอย่างเป็นไปได้ ตอนนี้เราสามารถแสดงข้อมูลของเด็กหลายร้อยคนได้ด้วยช่วงเดียวที่กะทัดรัด เช่น 3-9 สำหรับตัวอย่างเดิม แทนที่จะแสดงรหัสแต่ละรายการ

สัญกรณ์โหนดสุดท้ายที่มีChildrenรายการที่เพิ่มประสิทธิภาพจะมีลักษณะดังนี้

allUrls = [...]

Node: 2 - animate
Selected: true
Duration: 150
Self Time: 20
URL: 0
Children: 3-9

ลดจำนวนคีย์

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

allUrls = [...]

2;animate;150;20;0;3-10

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

...
Each call frame is presented in the following format:

'id;name;duration;selfTime;urlIndex;childRange;[S]'

Key definitions:

*   id: A unique numerical identifier for the call frame.
*   name: A concise string describing the call frame (e.g., 'Evaluate Script', 'render', 'fetchData').
*   duration: The total execution time of the call frame, including its children.
*   selfTime: The time spent directly within the call frame, excluding its children's execution.
*   urlIndex: Index referencing the "All URLs" list. Empty if no specific script URL is associated.
*   childRange: Specifies the direct children of this node using their IDs. If empty ('' or 'S' at the end), the node has no children. If a single number (e.g., '4'), the node has one child with that ID. If in the format 'firstId-lastId' (e.g., '4-5'), it indicates a consecutive range of child IDs from 'firstId' to 'lastId', inclusive.
*   S: **Optional marker.** The letter 'S' appears at the end of the line **only** for the single call frame selected by the user.

....

แม้ว่าคำอธิบายรูปแบบนี้จะมีค่าใช้จ่ายโทเค็น แต่ก็เป็นค่าใช้จ่ายคงที่ที่ชำระเพียงครั้งเดียว สำหรับการสนทนาทั้งหมด ค่าใช้จ่ายดังกล่าวมีมูลค่าต่ำกว่าการประหยัดที่ได้รับ จากการเพิ่มประสิทธิภาพก่อนหน้านี้

บทสรุป

การเพิ่มประสิทธิภาพการใช้โทเค็นเป็นข้อควรพิจารณาที่สำคัญเมื่อสร้างด้วย AI การเปลี่ยนจาก JSON ดิบเป็นรูปแบบที่กำหนดเองเฉพาะทาง การจัดทำดัชนีใหม่ของทรีด้วย Breadth-First Search และการใช้การเรียกเครื่องมือเพื่อดึงข้อมูลตามต้องการช่วยให้เรา ลดจำนวนโทเค็นที่ความช่วยเหลือจาก AI ในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ใช้ได้อย่างมาก

การเพิ่มประสิทธิภาพเหล่านี้เป็นข้อกำหนดเบื้องต้นในการเปิดใช้ความช่วยเหลือจาก AI สำหรับ การติดตามประสิทธิภาพ เนื่องจากมีหน้าต่างบริบทที่จำกัด จึงไม่สามารถจัดการข้อมูลจำนวนมหาศาลได้ แต่รูปแบบที่ได้รับการเพิ่มประสิทธิภาพจะช่วยให้ตัวแทนประสิทธิภาพ สามารถรักษาประวัติการสนทนาได้นานขึ้นและให้คำตอบที่แม่นยำยิ่งขึ้น ซึ่งรับรู้บริบทได้โดยไม่ถูกรบกวนจากสิ่งที่ไม่เกี่ยวข้อง

เราหวังว่าเทคนิคเหล่านี้จะเป็นแรงบันดาลใจให้คุณพิจารณาโครงสร้างข้อมูลของตัวเองอีกครั้ง เมื่อออกแบบเพื่อ AI หากต้องการเริ่มต้นใช้งาน AI ในเว็บแอปพลิเคชัน โปรดสำรวจ Learn AI on web.dev