เครื่องมือ · เอเจนต์ AI · วิธีทำงาน
ทำไมเราถึงสร้างเครื่องมือใช้เอง
Helm เริ่มจากความยุ่งยากในการใช้เอเจนต์ AI เขียนโค้ดหลายตัวพร้อมกัน พอสร้างขึ้นมาใช้เอง เราก็เริ่มเห็นชัดขึ้นว่างานแต่ละชิ้นเดินไปถึงไหน ใช้ต้นทุนเท่าไร และมีอะไรยืนยันได้บ้างก่อนส่งมอบ
ทุกวันนี้ งานวิศวกรรมซอฟต์แวร์ส่วนใหญ่ของเรามีเอเจนต์ AI ช่วยเขียนโค้ด และมักใช้หลายตัวพร้อมกัน ตัวหนึ่งเขียน migration ฐานข้อมูล อีกตัวเขียนเทสต์สำหรับตรวจ migration นั้น อีกตัวอ่านเอกสารของ vendor ขณะที่ข้างๆ ก็มี dev server เปิดค้างไว้
ช่วงแรก เราทำทั้งหมดนี้ผ่าน terminal หลายแท็บ งานเดินได้ แต่พอเปิดหลายงานพร้อมกันก็เริ่มตามไม่ทันว่าใครกำลังทำอะไร คล้ายครัวร้านอาหารที่ไม่มีที่เรียงใบออเดอร์ ทุกคนทำงานอยู่ อาหารทยอยออก แต่ตอบยากว่าโต๊ะไหนยังรอ
เราเลยสร้าง Helm เป็นแอปเดสก์ท็อปที่รวมงานเหล่านี้ไว้ในหน้าต่างเดียว เอเจนต์แต่ละตัวอยู่ใน pane หรือช่องทำงานของตัวเอง และเรียงให้มองเห็นพร้อมกันได้ ตอนนี้เป็นเครื่องมือที่เราใช้เขียนโค้ดทุกวัน
เราไม่ได้ขาย Helm ครับ บทความนี้อยากเล่าว่าทำไมถึงยอมใช้เวลาสร้างมัน และการมีเครื่องมือที่เข้ากับวิธีทำงานของตัวเองช่วยอะไรบ้าง ตั้งแต่ตกลงขอบเขตงานไปจนถึงส่งมอบให้ลูกค้า
ปัญหาที่อยู่รอบเอเจนต์
เอเจนต์อย่าง Claude Code, Codex และเครื่องมืออื่นๆ ช่วยงานได้มาก ถ้าอธิบายโจทย์และให้ข้อมูลพอ งานอย่างการเขียน migration ก็ทำออกมาได้ดี แต่พอใช้หลายตัวพร้อมกัน เราพบว่าปัญหาหลายอย่างเกิดขึ้นระหว่างทาง
ผมต้องไล่เปิดทีละหน้าต่างถึงจะรู้ว่าเอเจนต์ทั้งสี่ตัวทำอะไรอยู่ บางตัวกำลังทำงาน บางตัวรอผมตอบ การส่งงานต่อก็อาศัย copy แล้ว paste พอจบวันจึงรู้เพียงคร่าวๆ ว่าใช้เงินไปเท่าไร และยังต้องย้อนดูอีกทีว่างานไหนตรวจแล้ว งานไหนแค่มีข้อความบอกว่าเสร็จ
ถ้าเป็นงานที่จะส่งให้ลูกค้า เราต้องรู้รายละเอียดมากกว่านั้น
เครื่องมือสำเร็จรูปช่วยได้บางส่วน แต่ตัวที่เราลองยังไม่เข้ากับวิธีทำงานของเรา พอปัญหาเดิมเกิดขึ้นแทบทุกวัน เราจึงมองว่าการสร้างเครื่องมือขึ้นมาเองคุ้มกับเวลาที่ต้องใช้พัฒนาและดูแล
มองทีเดียว เห็นทั้งทีม
Helm วาง pane ทั้งหมดไว้บน rack เดียวกัน เราออกแบบให้แต่ละ pane มีบริบทการทำงานแยกกัน และให้การส่งงานข้าม pane เป็นขั้นตอนที่มองเห็นและติดตามได้
รายละเอียดเล็กๆ บางอย่างมีผลกับการใช้งานมากกว่าที่คิด ช่วงแรก pane ใหม่ใช้ชื่อ engine เป็นชื่อของตัวเอง หัว pane จึงขึ้นประมาณ “Claude Code, Opus, high” อ่านแล้วรู้ว่าใช้โมเดลอะไร แต่พอจะเรียกกลับลำบาก โดยเฉพาะเวลามีหลายตัวเหมือนกัน
ลองสั่งงานว่า “Claude ตัวที่สอง ไม่ใช่ อีกตัวหนึ่ง” ดูครับ
เราเลยให้แต่ละ pane มี call-sign ตั้งแต่สร้าง เป็นคำสั้นๆ ที่พูดออกเสียงได้ และพิมพ์ต่อท้าย @ เพื่อเรียกมันได้ เช่น Atlas ดูแลงาน migration ส่วน Vega เขียนเทสต์ เวลาส่งงานต่อจึงระบุชื่อได้ตรงๆ โดยไม่ต้องอธิบายตำแหน่งบนหน้าจอ
กระดิ่งแจ้งเตือนก็ใช้หลักเดียวกัน เราอยากให้ตัวเลขบน badge ตอบคำถามเดียวว่า มีเอเจนต์กี่ตัวที่รอคนตอบอยู่ จึงเลือกคำนวณจากสถานะของ pane ตอนอ่าน แทนการเก็บตัวนับอีกชุดแล้วคอยเพิ่มหรือลดแยกกัน
วิธีนี้ลดโอกาสที่ตัวนับกับสถานะงานจะไม่ตรงกัน แต่ยังต้องอาศัยข้อมูลสถานะของแต่ละ pane ที่ถูกต้องด้วย ความหมายที่เราอยากให้ชัดคือ ถ้า badge ขึ้นเลขสอง ผู้ใช้ควรหาเจอว่าเอเจนต์สองตัวไหนกำลังรออยู่
ส่งต่องานแบบสืบย้อนได้
ตอนเอเจนต์ส่งงานให้กันเป็นอีกจุดที่ต้องดูแล ข้อความอาจไปผิด pane หรือบทสนทนาอาจต่อกันยาวจนไม่ชัดว่าใครเป็นคนเริ่มและกำลังตอบโจทย์อะไรอยู่
เราเลยวางกฎการส่งข้อความใน Helm โดยยึดหลักว่า ต้องตามกลับไปหาคำสั่งของคนที่เริ่มงานได้
- pane ที่ทำงานตามคำสั่งของคน เรียก pane อื่นในทีมได้ด้วย call-sign
- pane ที่กำลังตอบงานจากเพื่อน ส่งคำตอบกลับไปยัง pane ที่เรียกมาได้เท่านั้น
- ไม่ให้ pane คุยกับตัวเอง ส่วนการกระจายงานให้ทั้งทีมเป็นหน้าที่ของคนหรือ orchestrator
orchestrator ของเราชื่อ Vesper มีหนึ่งตัวต่อหนึ่ง workspace ทำหน้าที่ช่วยจัดและส่งงานภายในพื้นที่นั้น
เราแยกพฤติกรรมของคำสั่งที่พิมพ์กับคำสั่งเสียงไว้ชัดเจน ถ้าผมพิมพ์สั่ง Vesper จะเสนอแผนให้ดูก่อน และรอให้ผมโอเคจึงค่อยพิมพ์คำสั่งลงใน pane ส่วนคำสั่งเสียงจะส่งงานเข้า pane ทันที
สองแบบนี้จึงมีจังหวะให้ตรวจทานต่างกัน คนใช้ต้องรู้ก่อนว่าแบบไหนจะรออนุมัติ และแบบไหนจะเริ่มทำงานเลย เราถือว่าเรื่องนี้เป็นส่วนหนึ่งของพฤติกรรมเครื่องมือที่ต้องกำหนดให้ชัดตั้งแต่ต้น
เห็นต้นทุนระหว่างทำงาน
เราให้แต่ละ pane แสดงตัวเลขค่าใช้จ่ายไว้บนหน้าจอหลัก เพื่อให้ดูต้นทุนระหว่างทำงานได้ โดยไม่ต้องเปิดหน้าตั้งค่าหรือรอไปดูยอดรวมตอนสิ้นเดือน
ตัวเลขที่มีระหว่างรันช่วยให้เราเห็นแนวโน้มและเปรียบเทียบงานแต่ละแบบได้ ส่วนยอดเรียกเก็บจริงยังต้องตรวจจากข้อมูลของผู้ให้บริการอีกครั้ง
การเห็นตัวเลขข้างงานทำให้เรากลับมาดูวิธีสั่งงานของตัวเองด้วย เช่น ถ้าเอเจนต์ที่หาข้อมูลใช้เงินมากกว่าตัวที่เขียนฟีเจอร์ เราจะถามต่อว่า brief กว้างเกินไปไหม ต้องอ่านเอกสารมากขนาดนั้นจริงหรือเปล่า หรือเราระบุแหล่งข้อมูลที่ต้องการให้ชัดกว่านี้ได้
ค่าใช้จ่ายสูงไม่ได้บอกว่างานไม่ดีเสมอไป บางงานก็ต้องค้นคว้ามาก แต่เป็นจุดให้กลับไปดูว่าทรัพยากรถูกใช้กับอะไร และได้ผลที่ต้องการหรือยัง พอเก็บประสบการณ์จากงานหลายแบบ เราก็มีข้อมูลประกอบการประเมินงานครั้งต่อไปมากขึ้น
receipt: สีเขียวต้องอธิบายได้
ถ้าต้องเลือกส่วนหนึ่งของ Helm ที่ผมให้ความสำคัญที่สุด ผมเลือก receipt ครับ
receipt คือบันทึกที่มีโครงสร้าง บอกว่างานนั้นทำอะไรไปแล้ว รันอะไร มีข้อมูลค่าใช้จ่ายเท่าไร ตรวจอะไรได้บ้าง และข้อสรุปแต่ละข้อมาจากหลักฐานไหน เราใช้มันประกอบการอ่านสรุปของเอเจนต์ เพื่อดูว่าข้อความที่บอกว่าสำเร็จมีอะไรยืนยันอยู่บ้าง
หลักที่เราวางไว้สำหรับสถานะสีเขียวคือ ต้องผูกกับผลตรวจที่ระบุได้ เช่น เทสต์ชุดใดผ่านบนโค้ดเวอร์ชันไหน เครื่องมือตรวจความปลอดภัยตรวจอะไรแล้วไม่พบปัญหา หรือการ build ซ้ำได้ผลตรงกันภายใต้เงื่อนไขใด
ผลแต่ละอย่างยืนยันได้เฉพาะสิ่งที่ตรวจ เทสต์ผ่านไม่ได้ครอบคลุมทุกพฤติกรรมของระบบ การตรวจความปลอดภัยไม่พบปัญหาก็ยังมีขอบเขตตามเครื่องมือและวิธีตรวจที่ใช้ เราจึงต้องอ่านรายละเอียดใน receipt ด้วย ไม่หยุดอยู่แค่สีของสถานะ
ถ้ายังไม่มีหลักฐานรองรับ เราก็ควรเห็นว่างานส่วนนั้นยังต้องตรวจ แม้เอเจนต์จะสรุปด้วยน้ำเสียงมั่นใจแล้วก็ตาม
เรื่องนี้สำคัญขึ้นเมื่อเปิดเอเจนต์หลายตัวพร้อมกัน เพราะเราจะได้รับทั้งโค้ดและข้อความสรุปจำนวนมาก อ่านเพียงสรุปแล้วเข้าใจว่างานพร้อมใช้งานได้ง่าย ทั้งที่บางขั้นตอนอาจยังไม่ได้รันจริง การมี receipt ช่วยให้ย้อนดูได้ว่าอะไรทำแล้ว อะไรยังไม่ได้ทำ และต้องตรวจอะไรต่อ
ตอนส่งมอบโปรเจกต์ เราก็ใช้บันทึกเหล่านี้เป็นส่วนหนึ่งของข้อมูลที่ให้ลูกค้า เพื่อให้เขาตรวจดูสิ่งที่เราทำและผลที่ได้ด้วยตัวเอง
สิ่งที่เปลี่ยนไปในโปรเจกต์
ก่อนมี Helm การเพิ่มเอเจนต์ตัวที่สองหรือตัวที่สามทำให้ผมมีหน้าต่างและข้อความต้องตามมากขึ้น บางช่วงเวลาที่ประหยัดได้จากการเขียนโค้ดก็กลับไปหมดกับการไล่ดูสถานะและส่งงานต่อ
พอรวมงานไว้ในที่เดียว เราจัดงานคู่ขนานได้เป็นระเบียบขึ้น เห็นว่าแต่ละสายมีเจ้าของเป็นใคร และต้องรออะไรจากกันบ้าง วิธีทำงานที่เราวางไว้คือ ให้แต่ละสายมีสำเนา repository แยกกัน และนำงานมา review ก่อน merge โดยตั้งใจมองหาจุดผิดและผลกระทบกับส่วนอื่น
เครื่องมือช่วยให้ตามขั้นตอนเหล่านี้ได้ง่ายขึ้น แต่เรายังต้องตรวจว่างานแต่ละชิ้นผ่านอะไรมาแล้ว และมีอะไรค้างอยู่ก่อนรวมโค้ดหรือส่งมอบ
ข้อมูลที่ส่งให้ลูกค้าจึงมีมากกว่าไฟล์โค้ด เราสามารถแนบร่องรอยของงานได้ว่า เริ่มจากคำขออะไร ใครหรือเอเจนต์ตัวไหนทำ มีข้อมูลต้นทุนเท่าไร และตรวจการทำงานด้วยวิธีไหน ข้อมูลเหล่านี้ช่วยทั้งตอนรับมอบงานและตอนที่ต้องกลับมาแก้ต่อภายหลัง
ทำไมสร้างเอง ไม่ซื้อ
มีคนถามว่าการสร้างเครื่องมือใช้เองทำให้เสียโฟกัสไหม บางทีก็ใช่ครับ เพราะต้องใช้เวลาพัฒนา แก้บั๊ก และดูแลต่อเหมือนซอฟต์แวร์ชิ้นอื่น
เราเลยใช้เกณฑ์ค่อนข้างง่าย ถ้าเครื่องมือนั้นเกี่ยวข้องกับงานที่เราส่งมอบแทบทุกชิ้น และตัวเลือกที่มีอยู่ยังไม่เข้ากับวิธีทำงานมากพอ เราจะพิจารณาว่าคุ้มที่จะสร้างเองหรือไม่ สำหรับเรา Helm ผ่านเกณฑ์นี้ เช่นเดียวกับเครื่องมือเสียงและเครื่องมือจับภาพหน้าจอที่ใช้ควบคู่กัน
อีกอย่างที่ได้จากการใช้ของที่ตัวเองสร้างทุกวัน คือเราเห็นจุดติดขัดของมันตลอด เวลาเรียกชื่อ pane ลำบาก ดูสถานะไม่เข้าใจ หรือส่งงานต่อแล้วตามไม่เจอ เราเจอปัญหานั้นเองและต้องกลับมาแก้
การอยู่กับรายละเอียดเหล่านี้ทำให้เราใส่ใจจุดเล็กๆ ในซอฟต์แวร์มากขึ้น และความใส่ใจแบบเดียวกันก็ติดไปกับงานที่ทำให้ลูกค้าด้วย นี่เป็นอีกเหตุผลที่เรายังเลือกสร้างและใช้เครื่องมือของตัวเองครับ