
ซอฟต์แวร์ที่นิ่ง: กำจัดปุ่มสวิตช์ที่กะพริบ และสอนแชตให้บอกว่ากำลังอยู่ในโหมดไหน
GeekBye ปล่อยอัปเดตเล็ก ๆ สองเวอร์ชัน ไม่มีฟีเจอร์เด่นอะไรเลย มีแค่ปุ่มสวิตช์ในหน้าตั้งค่าที่เลิกกะพริบ กับผู้ช่วยแชตที่ในที่สุดก็บอกคุณได้แล้วว่ามันตอบในโหมดประชุมหรือโหมดเขียนโค้ด นี่คือราคาที่แท้จริงของคำว่า "ซอฟต์แวร์ที่นิ่ง" ทีละรายละเอียด
ไม่ใช่ทุกอัปเดตจะเป็นเรื่องราวการต่อสู้อันยิ่งใหญ่ บางครั้งมันก็เป็นแค่รายการของสิ่งเล็ก ๆ ที่แทบมองไม่เห็น ซึ่งค่อย ๆ ผิดเพี้ยนอยู่เงียบ ๆ สิ่งที่ไม่ได้ทำให้อะไรพังลง แต่ทำให้แอปรู้สึกน่าเชื่อถือน้อยลงนิดหน่อย กระตุกนิดหน่อย เป็นของเราน้อยลงนิดหน่อย GeekBye v2.0.3 และ v2.0.5 คือสองอัปเดตแบบนั้น ไม่มีฟีเจอร์ใหม่ มีแค่ความนิ่ง
"ซอฟต์แวร์ที่นิ่ง" ฟังดูเหมือนอารมณ์อย่างหนึ่ง แต่จริง ๆ แล้วมันคือกองการตัดสินใจที่เจาะจงต่างหาก นี่คือสามอย่างในนั้น
ปุ่มสวิตช์ที่ตัดสินใจอะไรไม่ได้สักที
มีปุ่มสวิตช์ในหน้าตั้งค่าอยู่ตัวหนึ่ง ตัวที่ควบคุมการกู้คืนเสียง มันกะพริบทุกครั้งที่คุณกด แตะเปิดปุ๊บ ในเสี้ยววินาทีมันจะแสดงเป็น เปิด แล้วเด้งกลับไปเป็น ปิด แล้วค่อยนิ่ง เป็นอาการสะดุดทางสายตาเล็ก ๆ แต่ตาคุณจับได้ และมันสื่อความหมายว่า แอปไม่แน่ใจว่าตัวเองกำลังทำอะไรอยู่
สาเหตุคือ race ของ UI แบบคลาสสิกที่เรียกว่า optimistic update เมื่อคุณกดปุ่มสวิตช์ แอปมีสองทางเลือก จะรอให้ค่าตั้งค่าถูกบันทึกจริงก่อนแล้วค่อยอัปเดตปุ่ม (ถูกต้อง แต่รู้สึกหน่วง) หรือสลับปุ่มทันทีแล้วค่อยบันทึกเบื้องหลัง (รู้สึกฉับไว) GeekBye เลือกทางที่สอง สลับทันที แต่มัน ยัง อ่านค่าที่บันทึกไว้ซ้ำอีกครั้งเมื่อค่านั้นกลับมา ลำดับเหตุการณ์จึงเป็นแบบนี้ คุณกด ปุ่มสลับเป็นเปิดแบบ optimistic ค่าจริงที่บันทึกไว้ตามมาช้ากว่านั้นหนึ่งจังหวะ และในหนึ่งเฟรมนั้นทั้งสองค่าขัดแย้งกันจนปุ่มเด้งให้เห็น
การแก้คือทำให้ค่า optimistic กับค่าที่ยืนยันแล้วตรงกันอย่างสะอาด ปุ่มจะยึดกับสถานะที่คุณเลือกและเลิกกลับมาสงสัยตัวเองเมื่อการบันทึกยืนยันกลับมา นอกจากนั้น v2.0.3 ยังทำงานเก็บงานถ้อยคำที่ไม่หวือหวาอีกรอบ คำอธิบายของปุ่มกู้คืนเสียงถูกตัดให้สั้นลงเพื่อให้ยาวเท่ากับแถวข้าง ๆ และถ้อยคำในหน้าตั้งค่าก็ถูกเขียนให้เป็นภาษาคนมากขึ้น ไม่มีอะไรในนี้เป็นฟีเจอร์ แต่ทั้งหมดนี้คือความต่างระหว่างหน้าตั้งค่าที่รู้สึกว่า ถูกประกอบขึ้นมา กับหน้าที่รู้สึกว่า ถูกใส่ใจดูแล
ทัวร์ที่ไม่ยอมไปไหน
ทัวร์สำหรับผู้ใช้ใหม่มีประโยชน์เพียงครั้งเดียวเป๊ะ ๆ ปัญหาอยู่ที่ความ "ครั้งเดียว" นั่นแหละ หลังจากคุณดูมันจบแล้ว โอเวอร์เลย์แนะนำการใช้งานที่ปิดไม่ได้ก็กลายเป็นความรกที่ส่งสัญญาณว่า แอปนี้ยังคิดว่าคุณเป็นมือใหม่อยู่ v2.0.3 แก้ทั้งสองด้านของเรื่องนี้ ทัวร์แนะนำผลิตภัณฑ์ตอนนี้ ซ่อนได้ แล้ว และถ้าคุณอยากให้มันกลับมาจริง ๆ ก็มีปุ่ม เล่นทัวร์ซ้ำ แสดงมันตอนที่มันช่วยได้ หลบทางตอนที่มันไม่ช่วย และปล่อยให้ผู้ใช้เรียกมันขึ้นมาตามเงื่อนไขของตัวเอง การเคารพว่าผู้ใช้ไม่ใช่มือใหม่แล้วก็เป็นความนิ่งอีกรูปแบบหนึ่งในตัวมันเอง
ผู้ช่วยที่ไม่ยอมบอกว่าตัวเองกำลังคิดแบบไหน
อันนี้คือเรื่องที่สำคัญจริง ๆ และมันเชื่อมโยงกับปัญหาที่ลึกกว่านั้นซึ่งเราไล่ตามมาสักพักแล้ว
ผู้ช่วยของ GeekBye ตอบต่างกันขึ้นอยู่กับบริบท ในการประชุม คำถามว่า "คุณคิดยังไงกับเรื่องนี้?" ควรได้คำตอบเชิงสนทนาที่เข้าใจบริบทการประชุม ส่วนในเซสชันเขียนโค้ด คำเดียวกันควรได้คำตอบเชิงเทคนิค ดังนั้นเซิร์ฟเวอร์จึงส่งคำถามผ่านกรอบที่เหมาะสม เรียกมันว่า โหมดประชุม หรือ โหมดเขียนโค้ด และการตีกรอบนั้นเปลี่ยนคำตอบที่คุณได้จริง ๆ
ปัญหาคือแอปไม่เคยบอกคุณว่าโหมดไหนเป็นคนตอบ ดังนั้นเวลาผู้ช่วยตอบคำถามเชิงสนทนาด้วยคำตอบที่ออกแนวโค้ด หรือตอบคำถามโค้ดเหมือนคุณกำลังคุยเล่น มันดูเหมือน AI แค่ ตอบผิด เฉย ๆ แต่มันไม่ได้ผิด มันอยู่ในอีกโหมดหนึ่งต่างหาก และคุณไม่มีทางเห็นสิ่งนั้นเลย สถานะที่ถูกซ่อนไว้ทำให้พฤติกรรมที่ถูกต้องดูเหมือนพังอยู่ (ตัวตรรกะของโหมดเองเป็นงานชิ้นใหญ่กว่านั้น ตัวออร์เคสเทรเตอร์ที่ตัดสินใจว่าจะตอบคำถามที่ไม่เกี่ยวกับโค้ดอย่างไรระหว่างเซสชันเขียนโค้ด แต่ทั้งหมดนั้นไม่มีประโยชน์กับคุณเลยถ้าคุณ มองไม่เห็น การตัดสินใจที่มันทำ)
v2.0.5 เพิ่ม ป้ายโหมดแบบอ่านอย่างเดียว เข้าไปในแชต เป็นป้ายเล็ก ๆ ที่แสดงว่าผู้ช่วยตอบในโหมดประชุมหรือโหมดเขียนโค้ด ความเป็นอ่านอย่างเดียวคือหัวใจทั้งหมด มันไม่ใช่ปุ่มควบคุมที่คุณตั้งค่าได้ มันคือ หน้าต่างที่มองเข้าไปเห็นการตัดสินใจที่ระบบทำไปแล้ว คุณเลิกเดาว่าทำไมคำตอบถึงรู้สึกไม่เข้าท่า เพราะคุณเห็นกรอบที่มันมาได้
รายละเอียดที่ทำให้ป้ายนี้ซื่อตรง
นี่คือการตัดสินใจเชิงวิศวกรรมที่ควรค่าแก่การส่งต่อ เพราะมันคือสิ่งที่แยกตัวบ่งชี้ที่แปะเข้ามาแบบขอไปที ออกจากตัวบ่งชี้ที่ไว้ใจได้
ข้อมูลโหมดมาจากเซิร์ฟเวอร์ในฐานะส่วนหนึ่งของคำตอบที่สตรีมมา เป็นเฟรม mode เล็ก ๆ ในสตรีมของ server-sent event แต่ไคลเอนต์รุ่นเก่าที่มีมาก่อนฟีเจอร์นี้จะไม่รู้จักว่าเฟรม mode คืออะไร อย่างดีที่สุดมันก็เพิกเฉย อย่างแย่ที่สุดมันก็เรนเดอร์อะไรออกมาเละเทะ ไคลเอนต์จึงประกาศความสามารถของตัวเอง มันส่ง request header บอกว่า ฉันรู้วิธีแสดงป้ายโหมด และเซิร์ฟเวอร์จะส่งเฟรม mode เฉพาะไคลเอนต์ที่ส่ง header นั้นมาเท่านั้น ไคลเอนต์เก่าจะไม่มีวันได้รับสัญญาณที่มันจัดการไม่ได้ ส่วนไคลเอนต์ใหม่ก็ได้รับเฟรมที่มันขอมาพอดี
มันคือการจับมือกันด้วย header เพียงตัวเดียว และมันคือความต่างระหว่าง "เราเพิ่มฟีเจอร์" กับ "เราเพิ่มฟีเจอร์โดยไม่ทำให้คนที่ยังไม่ได้อัปเดตพังไปด้วย" การรีวิวรอบเดียวกันนี้ยังทำให้พฤติกรรมที่เหลือรัดกุมขึ้น ป้ายจะเคลียร์ตัวเองเมื่อรีเซ็ตและเมื่อบริบทของการสนทนาเปลี่ยนไป (ป้ายโหมดที่ค้างเก่าก็เป็นการโกหกเล็ก ๆ ในตัวมันเอง) และมันจะแสดงเฉพาะในหน้าแชตซึ่งเป็นที่ของมันเท่านั้น
สิ่งที่อัปเดตแบบ "ไม่มีฟีเจอร์" สองตัวนี้สอนเรา
- การกระตุกคือสัญญาณของความน่าเชื่อถือ ปุ่มสวิตช์ที่กะพริบ ปุ่มที่เด้งไปมา ป้ายที่ค้างอยู่นานเกินไปหนึ่งเฟรม ไม่มีอันไหนเป็นบั๊กในความหมายของการทำให้แอปพัง แต่ทุกอันกระซิบว่า แอปนี้ยังคุมตัวเองได้ไม่ค่อยอยู่ ความนิ่งคือการไม่มีเสียงกระซิบเหล่านั้น และคุณได้มันมาทีละ race condition
- โหมดที่ถูกซ่อนไว้ทำให้พฤติกรรมที่ถูกต้องดูเหมือนบั๊ก ผู้ช่วยทำสิ่งที่ถูกต้องแต่กลับโดนตำหนิ ล้วนเพราะผู้ใช้มองไม่เห็นกรอบ เมื่อระบบของคุณตัดสินใจอย่างมองไม่เห็นที่ไปเปลี่ยนผลลัพธ์ จงแสดงการตัดสินใจนั้น ป้ายแบบอ่านอย่างเดียวมักเป็นทางแก้ทั้งหมดในตัวมันเอง
- ฟีเจอร์ใหม่ควรมองไม่เห็นสำหรับไคลเอนต์ที่ใช้มันไม่ได้ การจับมือด้วย capability header ทำให้สัญญาณโหมดไปถึงเฉพาะไคลเอนต์ที่เรนเดอร์มันได้ ความเข้ากันได้ย้อนหลังไม่ใช่การเช็กเวอร์ชันที่แปะเข้ามาทีหลัง มันคือไคลเอนต์ที่บอกว่าตัวเองเข้าใจอะไร และเซิร์ฟเวอร์ที่เคารพคำตอบนั้น
นี่คืออัปเดตที่ไม่มีใครเอาไปเขียนพาดหัว changelog และมันคือส่วนสำคัญที่ทำให้ GeekBye v2 รู้สึกเป็นแบบที่มันเป็น สำหรับอัปเดตที่ความนิ่งนี้ถูกสร้างขึ้นมาบนนั้น อ่านได้ที่ เวอร์ชันสองต้องแลกมาด้วยอะไรบ้าง (v2.0.0) สำหรับงานด้านความเสถียรที่ทำควบคู่กันไป อ่าน วันที่แอปของเรา DDoS ใส่ตัวเอง (v2.0.1) และ ทำไมโปรแกรมจดประชุม AI ของคุณถึงหยุดอัดกลางคัน (v2.0.9)