ลดเวลาตอบครั้งแรกของ Claude Code จาก 16 วินาทีเหลือ 10 วินาที และทำให้อาการค้างเหลือศูนย์ — แยกความสูญเปล่า 4 ชนิดออกจากกันด้วยโปรไฟเลอร์

AI Claude Code RAG プロファイリング パフォーマンスチューニング Operations 検証

บทนำ

ผู้ช่วย AI เขียนโค้ดส่วนตัวของฉันมีกลไกหนึ่งฝังอยู่ ที่ฉันเคยเขียนถึงไว้ที่นี่แล้ว มันดักทุกอินพุตของบทสนทนาแล้วแทรกบันทึกในอดีตที่น่าจะเกี่ยวกับหัวข้อปัจจุบันเข้าไปโดยอัตโนมัติ — “ชั้นกระตุ้นความจำ”

ฉีด ‘สิ่งที่ควรนึกถึงตอนนี้’ ให้ AI ทุกเทิร์น — ชั้นกระตุ้นความจำ (Activation Layer) ของ RAG ส่วนตัว

มีประโยชน์ แต่มันก็เป็น ด่านที่ AI ต้องผ่านโดยไม่มีข้อยกเว้น ก่อนจะเริ่มเขียนคำตอบ ความสูญเปล่าใด ๆ ที่ด่านนั้นย้อนกลับมาเป็นความช้าของการตอบครั้งแรกโดยตรง

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


เปลี่ยน “ช้า” ให้เป็นสิ่งที่วัดได้

ถ้าไล่ตามความรู้สึกว่า “ช้า” ตามที่มันเป็น คุณจะอ้อมไปไหนก็ได้ อันที่จริงการสืบสวนครั้งแรกของฉันอ้อมไปวัด “เวลาที่ AI ใช้เสนอทางเลือกให้ยืนยันแล้วรอคำตอบจากคน” นั่นคือเวลาที่ใช้รอมนุษย์ ไม่ใช่ความช้าของตัวผู้ช่วยเอง

วินาทีที่สังเกตเห็นการอ้อม ฉันหดตัวชี้วัดกลับมาเหลือตัวเดียว

A-2: จำนวนวินาทีนับจากผู้ใช้ส่งอินพุตจนถึงเอาต์พุตแรกของ AI กลับมา (มัธยฐาน)

ฉันตรึงวิธีวัดไว้ด้วย สแกนบันทึกเซสชัน (ล็อกรูปแบบ JSON Lines) แล้วเอาผลต่างจากเวลาประทับของเรกคอร์ด “คำพูดของผู้ใช้” ไปยังเวลาประทับของเรกคอร์ด “คำตอบของผู้ช่วย” ที่ตามมาทันที อะไรที่เกิน 600 วินาทีอาจหมายความว่าคนลุกออกไป จึงถูกกันออกจากมัธยฐานปกติและนับแยก

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


แยกส่วนประกอบ — เอาต์พุตของโปรไฟเลอร์

เมื่อตัวชี้วัดยุติแล้ว งานถัดไปคือวัดว่าอะไรกิน 16 วินาทีนั้นไป ฉันรันโปรไฟเลอร์มาตรฐานของ Python (cProfile) ทับกระบวนการค้นหาเอง แล้วเอาส่วนประกอบตามเวลาสะสม การเรียกครั้งหนึ่งหลังอุ่นเครื่องแล้วรวมได้ราว 34.8 วินาที

ส่วนเวลาสะสม (การเรียกหนึ่งครั้งใต้โปรไฟเลอร์)สัดส่วน
การสอบถามตัวตัดสินความเกี่ยวข้อง22.27 วิ64%
การจัดอันดับผลการค้นใหม่ (การกระจายความหลากหลาย)9.29 วิ27%
การคำนวณเอ็มเบดดิง (ในนั้นเป็นการตั้งการเชื่อมต่อ 2.042 วิ)2.08 วิ6%
การคำนวณคะแนน0.82 วิ2%

ทุกตัวเลขในตารางนี้คือค่าของการเรียกหนึ่งครั้งโดยมีโปรไฟเลอร์ติดอยู่ ส่วน “27.399 วินาที” ที่ปรากฏทีหลังคือการวัดคนละครั้งของกระบวนการเดียวกัน (เบนช์มาร์กเฉพาะทางที่ตรึงจำนวนรายการไว้ที่ 120) ภายใต้เงื่อนไขต่างกัน ทั้งสองจึงเทียบกันตรง ๆ ไม่ได้ เมื่อชื่อกระบวนการเดียวกันกลับมาพร้อมจำนวนวินาทีที่ต่างกัน ให้สงสัยก่อนว่าเงื่อนไขการวัดต่างกัน

“ตัวตัดสินความเกี่ยวข้อง” คือโมเดลเล็กที่บีบสิ่งที่การค้นหาดึงมาให้เหลือเฉพาะสิ่งที่เกี่ยวข้องจริง ฉันเคยเขียนถึงมันไว้แล้วเช่นกัน

วางตัวตัดสินความเกี่ยวข้องขนาดเล็กไว้หน้า RAG — ไม่ส่งทุกอย่างที่ค้นเจอผ่านไปทั้งหมด

“การจัดอันดับผลการค้นใหม่ (การกระจายความหลากหลาย)” คือกระบวนการ (MMR) ที่เรียงผลลัพธ์ใหม่เพื่อไม่ให้เรกคอร์ดที่เกือบเหมือนกันเบียดเต็มด้านบน ส่วนการสร้างการค้นหาเองต่อยอดมาจากการปรับจูนที่ขับด้วยการวัดซึ่งฉันเขียนไว้ในอีกบทความ

RAG ที่มีแค่ vector search “ลืมในตอนที่สำคัญที่สุด” — ทำให้ recall ขึ้นจาก 0.2 เป็น 1.0 ด้วย hybrid search + การวัดผล

การวาดส่วนประกอบนั้นออกมาแสดงให้เห็นว่าอะไรกำลังถูกรออยู่จริง ๆ ก่อนการตอบครั้งแรก

ผู้ใช้ส่ง


[ด่านที่ทุกเทิร์นต้องผ่าน (ฮุกของชั้นกระตุ้นความจำ)]

      ├─▶ เริ่มไคลเอนต์การค้นหา
      │     import                       2.409 วิ
      │     สร้าง HTTP client            1.337 วิ
      │       └─ ในนั้นเป็นการโหลดใบรับรอง SSL อย่างเดียว 0.958 วิ ◀── ไม่จำเป็น: การรับส่งเป็น HTTP ธรรมดา
      │     (รวมราว 3.7 วิ ต่อเทิร์น)

      ├─▶ การจัดอันดับผลการค้นใหม่ (การกระจายความหลากหลาย, MMR)
      │     การเรียงใหม่                  9.29 วิ ◀── การอิมพลีเมนต์เติบโตตามกำลังสองของจำนวนรายการ
      │       └─ ในการวัดเฉพาะทางที่ตรึงจำนวนไว้ 120: 27.399 วิ (คนละตัวเลข คนละเงื่อนไข)

      ├─▶ การสอบถามตัวตัดสินความเกี่ยวข้อง
      │     กิน 22–60 วิ แม้ตอนที่เริ่มไม่สำเร็จ โดยไม่มีใครสังเกต ◀── 64% ของส่วนประกอบใน cProfile
      │        └── เมื่อตรวจพบความล้มเหลวติดกันสองครั้ง ให้เปิดวงจรแล้วผ่านตรงไปเลยจากนั้น
      │              └────────────── ลองใหม่ครั้งเดียวหลัง 1,800 วิ ─────┘


เอาต์พุตแรกของ AI

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


ความสูญเปล่า 4 ชนิดที่พบ และมันกลายเป็นอะไร

ทั้งสี่ถูกปิดทีละข้อ บนหลักฐานของตัวเลขส่วนประกอบ

#สิ่งที่ทำก่อนหลัง
1เปลี่ยนการจัดอันดับใหม่ (การกระจายความหลากหลาย) ไปใช้การอิมพลีเมนต์ด้วยไลบรารีเมทริกซ์ (numpy)27.399 วิ (การวัดเฉพาะทาง อินพุตตรึงที่ 120 รายการ)0.009 วิ (120 รายการเดิม เงื่อนไขเดิม การตรวจสอบไขว้กับการอิมพลีเมนต์เก่าตรงกันทั้ง 15 รายการ)
2ตรึงที่อยู่ของเซิร์ฟเวอร์เอ็มเบดดิงจาก localhost เป็น 127.0.0.12.042 วิ สำหรับการตั้งการเชื่อมต่ออย่างเดียวใกล้ 0
3อิมพลีเมนต์เบรกเกอร์ตัดวงจรบนตัวตัดสินความเกี่ยวข้องกิน 22–60 วิ โดยไม่มีใครสังเกต ทุกครั้งที่เริ่มไม่สำเร็จล้มเหลวติดกันสองครั้งเปิดวงจรแล้วผ่านตรงไปจากนั้น (ลองใหม่หนึ่งครั้งหลัง 1,800 วินาที)
4เปลี่ยนวิธีที่ฮุกด่านสร้างไคลเอนต์การค้นหา ไปใช้การอิมพลีเมนต์แบบเบาที่พูด HTTP โดยตรงด้วยไลบรารีมาตรฐานimport 2.409 วิ + สร้างไคลเอนต์ 1.337 วิ (ในนั้นเป็นการโหลดใบรับรอง SSL อย่างเดียว 0.958 วิ) = ราว 3.7 วิ ต่อเทิร์นประหยัดได้ราว 3.1 วิ ต่อเทิร์น

สาเหตุที่ 2 “ตรึงที่อยู่” ดูไม่หวือหวาแต่มีเหตุผล การแปลงชื่อ localhost ในบางสภาพแวดล้อมจะลองเชื่อมต่อไปยังที่อยู่ IPv6 ก่อนแล้วล้มเหลว ทำให้เสียเวลารอจนกว่ามันจะถอยกลับไปใช้ IPv4 ถ้าข้ามการแปลงชื่อแล้วระบุที่อยู่ที่จะใช้โดยตรงตั้งแต่ต้น การรอนั้นก็หายไปทั้งหมด

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

สองในสี่เป็นการเปลี่ยนที่สลับการอิมพลีเมนต์ออกไปเป็นอย่างอื่นทั้งก้อน ทั้งสองกรณีฉันยืนยันก่อนว่าตัวใหม่คืนอินพุตและเอาต์พุตเดียวกันกับตัวเก่าก่อนจะสลับ #1 (การจัดอันดับใหม่ด้วย numpy) รวมได้ 15 การตรวจ — ยืนยันความตรงกันของลำดับที่จำนวนรายการต่างกัน 4 แบบ บวกกับเงื่อนไขขอบเขต: ลิสต์ว่าง, รายการเดียว, เวกเตอร์เหมือนกันทั้งหมด (ค่าเสมอ), เวกเตอร์ศูนย์ และสหสัมพันธ์เชิงลบ #4 (การสลับไปใช้ไคลเอนต์แบบเบา) รวมได้ 24 การตรวจ — ยืนยันว่าค่าเอ็มเบดดิงตรงกับการอิมพลีเมนต์เก่าเป๊ะ (ผลต่างสัมบูรณ์สูงสุด 0) และผลการจำแนกตรงกันทั้งกรณีปกติและผิดปกติ ยิ่งการเปลี่ยนแปลงมุ่งไปที่การทำให้ตัวเลขดีขึ้นเท่าไหร่ ก็ยิ่งต้องยืนยันว่ามันไม่ได้ทำอะไรพังก่อนจะใส่เข้าไป


วันที่ผลไม่ยอมโผล่ ทั้งที่ควรจะปิดมันไปแล้ว

ในวันที่ฉันใส่สองข้อแรกจากสี่ (การจัดอันดับใหม่ที่เร็วขึ้นและการตรึงที่อยู่) ฉันวัดตัวชี้วัด A-2 ใหม่ ในช่วงสองสัปดาห์ก่อนหน้า 13 วันของการใช้งานปกติ (n=680) มัธยฐานอยู่ที่ 16.04 วินาที มัธยฐานของวันนั้นคือ 15.85 วินาที แทบไม่ขยับ

เผิน ๆ ดูเหมือนไม่มีผลอะไร ฉันเกือบสรุปว่า “มันไม่ได้ผล” — แล้วก็ย้อนกลับไปตั้งคำถามกับวิธีที่ตัวเองวัดแทน


การเปลี่ยนความละเอียดของการรวมยอดพลิกข้อสรุป

มัธยฐานรายวันผสม “บทสนทนาจากก่อนการแก้จะเข้า” กับ “บทสนทนาจากหลังจากนั้น” เข้าเป็นค่าเฉลี่ยเดียวภายในวันเดียวกัน ฉันใส่การแก้ทั้งสี่ทีละส่วนตลอดวันนั้น การรวมยอดรายวันจึงเจือจางการปรับปรุงจนมองไม่เห็น

ฉันจึงตัดวันนั้นใหม่ที่เวลาที่คอมมิตการแก้เข้าไปจริง แล้ววัด A-2 ใหม่ทีละช่วง

วันนั้น (ล็อกหนึ่งวัน)
 00:00 ────────────────────────────────────────── 24:00
   │           │              │              │
 ยังไม่แก้   #1・#2 เข้า      #3 เข้า        #4 เข้า (สะท้อนครบ)
(15.68 วิ)   01:31            09:22          14:07
              │                │              │
              ▼                ▼              ▼
           12.03 วิ          14.18 วิ       10.48 วิ ★

  "การดูแค่มัธยฐานรายวัน" ทำให้สี่ช่วงนี้แบนเป็น
  ค่าเฉลี่ยเดียว (15.85 วิ) แล้วการปรับปรุงก็หายไป
ช่วงการแก้ที่สะท้อนอยู่nมัธยฐานp75p90
การใช้งานปกติ (13 วัน)ไม่มี68016.04 วิ26.9341.10
วันนั้น 00:00–01:31ไม่มี1415.68 วิ21.9731.05
วันนั้น 01:31–09:22#1, #2812.03 วิ15.9129.38
วันนั้น 09:22–14:07#1, #2, #33414.18 วิ22.0935.58
วันนั้น 14:07–#1–#4 ครบ1910.48 วิ11.6331.14

จาก 16.04 วินาทีในการใช้งานปกติ เหลือ 10.48 วินาทีในช่วงที่ทั้งสี่เข้าที่แล้ว: −35% ที่มัธยฐาน และที่ p75 (เส้นแบ่งของหนึ่งในสี่ที่ช้าที่สุด) จาก 26.93 วินาทีเหลือ 11.63 คือ −57% การที่ p75 ตกลงมากกว่ามัธยฐานแสดงว่าการแก้ทั้งสี่กัดแรงกว่ากับ “กรณีที่นาน ๆ ทีจะช้าผิดปกติ”

และอีกเรื่อง: ฉันนับ “การไม่ตอบสนองสนิทที่เกิน 600 วินาที (10 นาที)” ที่ถูกกันออกจากการรวมยอด A-2 ใหม่

วันจำนวนที่เกิน 600 วิสูงสุด
08-117828.0 วิ
08-122728.9 วิ
08-211612.5 วิ
08-223645.7 วิ
08-237971.3 วิ
วันนั้น0

การไม่ตอบสนองเกินสิบนาทีที่เกิดขึ้นแทบทุกวันมาสองสัปดาห์ กลายเป็นศูนย์ในวันที่การแก้ทั้งสี่เข้าไป ตัวตนของ “ไม่รู้ทำไมมันช้า” ส่วนใหญ่คือความสูญเปล่าภายในด่านนี้ แต่สำหรับ “หยุดสนิท” หนึ่งในนั้น — การรอความล้มเหลวในการเริ่มของตัวตัดสินความเกี่ยวข้องอย่างขยันขันแข็งทุกครั้ง — น่าจะเป็นตัวการหลัก

ที่ว่ามานั้น ช่วงในวันนั้นเล็กที่ n=19 และตัวอย่างเอียงไปทางช่วงงานต่อเนื่องช่วงเดียว การหายไปของกรณีที่เกิน 600 วินาทีเป็นการสังเกตของวันเดียว อันที่จริง การไม่ตอบสนองในผู้ช่วย AI เขียนโค้ดเคยเกิดผ่านเส้นทางอื่นนอกจากด่านนี้ด้วย (เช่นการรองานลูกที่เปิดขนานกัน) และการแก้ทั้งสี่นี้ไม่ได้ปิดฝั่งนั้น ฉันพูดได้ว่ามันดีขึ้น แต่สิ่งที่ฉันซ่อมคือส่วนหนึ่งของภายในด่านนี้ — นั่นคือคำกล่าวที่แม่นยำ และคราวหน้าที่ไล่ล็อก ฉันต้องเพิ่ม n แล้วยืนยัน


ผลพลอยได้ — กลไกการตรวจติดธงใส่ตัวเอง

แยกจากการแก้ทั้งสี่ ฉันทำการเปลี่ยนอีกอย่างหนึ่ง จากคำขอ — “การสับสนเรื่องหมายเลขพอร์ตการเชื่อมต่อและการเข้ารหัสอักขระเกิดขึ้นซ้ำ ๆ ช่วยสร้างอะไรที่ตรวจด้วยเครื่องจักรก่อนการทำงาน” — ฉันสร้างการ์ดที่เข้าไปตัดทันทีก่อนคำสั่งทำงานแล้วตรวจว่าค่าของมันมาจากไหน เรื่องนี้ต่อยอดจากแนวคิด “จากคำแนะนำสู่การบังคับ” ที่ฉันเขียนไว้ก่อนหน้า

สร้างกลไก “ไม่ให้ทำ” สำหรับผู้ช่วย AI เขียนโค้ด — จากคำแนะนำสู่การบังคับ แล้วพบว่าประตูนั้นเองก็มีช่องโหว่ข้าง

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

การ์ดที่ตรวจว่าค่ามาจากไหน

   ├─▶ ตรวจเนื้อหาของคำสั่งที่กำลังจะรัน
   │     └─ ลงเอยด้วยการตรวจเนื้อหาของไวยากรณ์ที่
   │         "ส่งบรรทัดต่อไปนี้ผ่านไปในฐานะข้อมูล" (heredoc) ด้วย
   │           └─ เข้าใจข้อความอธิบายในข้อความคอมมิตที่เขียนอยู่ข้างใน
   │               ผิดว่าเป็น "โค้ดที่จะถูกรัน" แล้วหยุด ①

   └─▶ ตรวจจับ "ค่าที่ไม่รู้ที่มา" ด้วยการ grep ทั้งรีโป
         └─ ลงเอยด้วยการรวมโค้ดเทสต์ที่ใช้ตรวจสอบเข้าไปในขอบเขตด้วย
               └─ grep ของตัวมันเองไปโดน "ค่าที่จงใจไม่ใส่ที่มาเพื่อการตรวจสอบ"
                   ที่เขียนอยู่ในโค้ดเทสต์นั้น แล้วถือว่าเทสต์ล้มเหลวเสมอ ②

① คือการเข้าใจเนื้อหาของไวยากรณ์ข้อมูลหลายบรรทัดผิดว่าเป็นโค้ดที่จะถูกรัน สิ่งที่ถูกส่งผ่านไม่ใช่ “คำสั่งที่จะถูกรัน” แต่คือ “ข้อมูลธรรมดาที่ส่งให้เชลล์” ฉันจึงกันเนื้อหาของไวยากรณ์นั้นออกจากขอบเขตการตรวจ ② คือภายในโค้ดเทสต์ที่เขียนขึ้นเพื่อยืนยันความถูกต้องของการ์ด ฉันจงใจวาง “ค่าที่ไม่รู้ที่มา” ไว้ และ grep ของการ์ดเองก็ไปโดนโค้ดเทสต์นั้นด้วย ทำให้ตัวเทสต์เองใช้ไม่ได้ ฉันแก้ด้วยการกันไดเรกทอรีที่เทสต์อยู่ออกจากขอบเขตการตรวจ

ทั้งคู่มีรากเดียวกัน: ฉันลากเส้นแบ่งระหว่าง “ผู้ตรวจ” กับ “สิ่งที่ถูกตรวจ” ด้วยพาธและไดเรกทอรีล้วน ๆ โดยไม่ดูธรรมชาติของเนื้อหา (ข้อมูลหรือโค้ด, โปรดักชันหรือเทสต์) ฉันเขียนการตรวจ 24 รายการใหม่โดยสมมติอินพุตเชิงปฏิปักษ์ แล้วยืนยันว่ามันผ่านทั้งหมดในสภาพแวดล้อมที่ติดตั้งใช้งานจริงก่อนจะเริ่มใช้มัน (จำนวนเท่ากันคือ 24 กับ #4 ข้างบน แต่นี่เป็นชุดเทสต์คนละชุดที่เฉพาะกับการ์ด ไม่เกี่ยวกันในเชิงเนื้อหา)


ส่วนของ 16 วินาทีที่ฉันยังไม่ได้วัด

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

วัดเฉพาะกระบวนการค้นหา (5 รอบ, แยกโปรเซส)
import                2.02 วิ
รอบ 1                 72.38 วิ   ← รอบแรก รวมการโหลดโมเดลของตัวตัดสิน
รอบ 2                 13.48 วิ
รอบ 3                  4.83 วิ
รอบ 4                  5.04 วิ
รอบ 5                  3.99 วิ
มัธยฐาน 5.04 วิ  ต่ำสุด 3.99 วิ  สูงสุด 72.38 วิ  เฉลี่ย 19.94 วิ

ในประวัติก่อนการแก้ (การวัด 256 ครั้ง) มัธยฐานของกระบวนการค้นหาอย่างเดียวนี้อยู่ที่ 65.93 วินาที โดย p90 อยู่ที่ 117.14 อ่านแค่นั้นก็ดูเหมือนว่า “ยิ่งซ่อมการค้นหา มันก็ยิ่งเร็ว” แต่พอเรียงการตอบครั้งแรกที่วัดได้ (10.48 วินาที) ไว้ข้างการค้นหาอย่างเดียว (มัธยฐาน 5.04 วินาที) การอ่านก็กลายเป็นว่า การทำให้การค้นหาเร็วขึ้นอีกจะมีผลจำกัดต่อการตอบครั้งแรกโดยรวม เลยด่านออกไป ยังมีส่วนที่ฉันยังไม่ได้วัด

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

ส่งข้อความได้ตามสบาย

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