หน้าแรก / บทความ / Dev Tools
Dev Tools สรุปและวิเคราะห์จากข่าวต้นทาง

วิเคราะห์และรีวิว: Codex CLI ติดตั้งเดมอนเบื้องหลังที่ทำงานถาวรและอัปเดตตัวเองเป็นค่าเริ่มต้น

วิเคราะห์ปัญหา daemon_auto_start ใน Codex CLI 0.157.0 ซึ่งอาจทำให้เดมอนทำงานต่อเนื่อง อัปเดตตัวเอง และใช้สภาพแวดล้อมจากเซสชันแรก

วิเคราะห์และรีวิว: Codex CLI ติดตั้งเดมอนเบื้องหลังที่ทำงานถาวรและอัปเดตตัวเองเป็นค่าเริ่มต้น

ตั้งแต่ Codex CLI 0.157.0 การเปิด interactive session อาจทำให้ app-server daemon ทำงานเบื้องหลังและอัปเดตตัวเอง โดย auto-update อาจ force-kill active turns หลัง drain budget 60s ได้ด้วย

ปัญหาไม่ได้มีแค่ session ถูกตัด แต่ daemon ยังยึดค่า HTTPS_PROXY, cwd และ environment จาก session แรก ทำให้ session ถัดไปทำงานไม่ตรงกับที่ผู้ใช้ตั้งใจ อีกจุดคือ CLI ที่ติดตั้งกับ daemon อาจเป็นคนละ binary หรือคนละเวอร์ชัน พูดตรงๆ พฤติกรรมแบบนี้เหมาะกับ Remote Control หรือ desktop app มากกว่า CLI ที่ควรอยู่และจบพร้อมหน้าต่างนั้นๆ

เมื่อเปิด Codex แล้วมีโปรเซสอื่นเริ่มทำงานตามมา

ภาพประกอบ Codex CLI กับ daemon เบื้องหลังที่เริ่มทำงานโดยอัตโนมัติ

ผู้ใช้แค่เปิด interactive session บน Codex CLI 0.157.0 แต่กลับมี app-server daemon เริ่มทำงานเบื้องหลัง พร้อมระบบ auto-update ที่อาจ force-kill active turns หลังช่วง drain 60 วินาที งานที่กำลังพิมพ์หรือรันอยู่จึงถูกตัดกลางทางได้

ผลกระทบไม่ได้จำกัดแค่ความรำคาญ เพราะมีรายงานว่า CLI ใช้งานไม่ได้บน Windows และ Codex 0.157.0 ไม่เริ่มทำงานกับแพ็กเกจ Arch Linux หากไม่ใช้ --no-daemon สำหรับคนที่ต้องการเปิด CLI แล้วทำงานทันที โปรเซสที่โผล่มาเองแบบนี้ทำให้ workflow สะดุดชัดเจน.

Codex CLI กำลังถูกวางให้เป็นเครื่องมือแบบไหน

Codex CLI ควรทำงานตามอายุของหน้าต่างที่เปิดอยู่ ใช้ binary ที่ติดตั้งไว้ และหยุดพร้อม session โดยไม่อัปเดตตัวเองอยู่เบื้องหลัง แบบนี้ตัวโปรแกรมกับสภาพแวดล้อมที่ผู้ใช้ตั้งใจเรียกใช้จะตรงกันกว่า

ส่วน shared self-updating daemon เหมาะกับ Remote Control หรือ desktop app มากกว่า เพราะออกแบบมาให้มี service ทำงานต่อเนื่อง หากต้องใช้กับ CLI ก็ควรเปิดเมื่อผู้ใช้สั่งเองผ่าน codex app-server daemon start หรือ bootstrap ครับ

จาก CLI ที่ผูกกับ session สู่ daemon ที่อยู่ข้าม session

ภาพประกอบเปรียบเทียบ CLI ที่ผูกกับ session เดียวกับ daemon ที่ทำงานข้าม session

ตั้งแต่ Codex CLI 0.157.0 การเปิด TUI สามารถเริ่ม daemon เบื้องหลัง ซึ่งทำให้ backend ไม่ได้ผูกกับ session เดียวอีกต่อไป ผลคือ environment และ binary ของ session แรกอาจส่งผลกับ session ถัดไป

Factor CLI แบบผูกกับ sessionCodex CLI 0.157.0
เปิด TUI ไม่เริ่ม daemon ข้าม sessionเริ่ม daemon อัตโนมัติ
อายุ backend อยู่และจบพร้อมหน้าต่างทำงานต่อเบื้องหลัง
binary ที่ให้บริการ binary ที่ติดตั้งและเรียกใช้สำเนาใน managed release directory
อัปเดตเบื้องหลัง ไม่อัปเดตตัวเองอัปเดตตัวเองได้
environment ใช้ของ session ปัจจุบันอาจยึดค่าจาก session แรก
ปิด daemon_auto_start ไม่ต้องปิดTUI ใหม่ไม่ spawn daemon

ปัญหาเดียวกันปรากฏในสถานการณ์ใช้งานจริงอย่างไร

เปิด Codex CLI แล้วทำงานต่ออยู่ดีๆ auto-update อาจ force-kill active turns หลังช่วง drain 60 วินาที ทำให้งานที่กำลังรันถูกตัดกลางทาง ส่วนคนที่สลับ session พร้อมตั้งค่า HTTPS_PROXY ต่างกัน อาจเจอ daemon ใช้ค่าจาก session แรกต่อไป

ในโหมด --remote hooks อาจได้ cwd ของ daemon แทน cwd ของ session และระบุ terminal ของ client ไม่ได้ จึงกระทบงานที่ต้องรู้ตำแหน่งหรือหน้าต่างต้นทาง นอกจากนี้ npm update อาจไม่เปลี่ยน daemon ที่ยังใช้ binary รุ่นเก่า และแพ็กเกจบน Arch Linux อาจเริ่มไม่ได้หากไม่ใช้ --no-daemon

ทางเลือกที่ source ระบุว่าเหมาะกับงานต่างกัน

รูปแบบที่เหมาะขึ้นอยู่กับว่าใครเป็นคนควบคุมอายุของ backend และต้องการให้ daemon แชร์ข้าม session หรือไม่

Factor CLIRemote Control / desktop app
อายุ backend อยู่และจบพร้อมหน้าต่างเปิดเป็น daemon แบบแชร์
การเปิด daemon ผู้ใช้สั่ง start หรือ bootstrap เองเหมาะกับการเปิดอัตโนมัติ
รูปแบบการใช้งาน ใช้ binary ที่ติดตั้งและไม่อัปเดตเบื้องหลังรองรับ daemon ที่ทำงานต่อเนื่อง

คำสั่ง codex app-server daemon start หรือ bootstrap เหมาะเมื่อผู้ใช้ต้องการเปิด daemon เอง ส่วน source ไม่ได้ให้ข้อมูลเกี่ยวกับคู่แข่งหรือเครื่องมือทางเลือกอื่นนอกระบบ Codex.

สิ่งที่ทำได้ดี และสิ่งที่ทำให้ผู้ใช้เสียการควบคุม

daemon เหมาะกับ Remote Control และ desktop app เพราะทำงานต่อเนื่องได้ ส่วน CLI เปิดเองผ่าน codex app-server daemon start หรือ bootstrap ได้เมื่อจำเป็น

ข้อดี

  • +เหมาะกับ Remote Control และ desktop app
  • +เปิด daemon เองได้เมื่อผู้ใช้ต้องการ

ข้อเสีย

  • −เปลี่ยนพฤติกรรมโดยไม่แจ้งเตือน
  • −ยึด environment จาก session แรก
  • −อาจทำงานบน binary ที่ไม่ตรงกับตัวที่ติดตั้ง
  • −สั่งหยุด daemon แล้ว updater ยังทำงานต่อ

ราคาที่ไม่ได้อยู่ในคำสั่งติดตั้ง

ภาพประกอบ daemon และ updater ที่ยังทำงานต่อเบื้องหลังหลังสั่งปิด

ต้นทุนไม่ได้จบที่ npm install -g เพราะ daemon อาจ force-kill active turn หลังหมดเวลา drain 60s และคำสั่ง daemon stop ยังทิ้ง pid-update-loop ให้ทำงานต่อ ต้องตาม kill เองแม้ผ่านไป 70 s

ปัญหายังลามถึง environment: daemon จำ HTTPS_PROXY จาก session แรก และ hooks อาจได้ cwd ของ daemon แทน session จริง ทำให้ตรวจสอบยากว่าใครเป็นผู้ให้บริการงานอยู่

ด้าน compatibility ก็มีเคส Codex CLI 0.157.0 เปิดไม่ได้กับแพ็กเกจ Arch Linux หากไม่ใช้ --no-daemon ภาระจึงตกอยู่กับผู้ใช้ที่ต้องเช็กทั้ง binary, daemon generation และ environment ว่าตรงกับตัวที่เรียกใช้งานจริงหรือไม่

สิ่งที่ควรเปลี่ยนเพื่อให้ CLI คาดเดาได้มากขึ้น

ทางที่ตรงที่สุดคือให้ daemon_auto_start เป็น opt-in โดยค่าเริ่มต้นเป็น false หรือถามผู้ใช้ครั้งแรกก่อนเปิดใช้งาน เพราะการเปิด CLI ไม่ควรสร้าง daemon ที่ทำงานต่อเองโดยไม่แจ้งล่วงหน้า

ควรรองรับ externally managed daemon executables เพื่อให้ผู้ใช้ควบคุม binary เองได้ และคำสั่ง daemon stop ต้องหยุด updater ที่เกี่ยวข้องทั้งหมดด้วย ไม่ใช่หยุดแค่ app-server แล้วปล่อย pid-update-loop ทำงานต่อ

อีกแนวคิดที่ช่วยตรวจสอบได้ชัดคือ execution receipt ตอนเชื่อมต่อ โดยแสดง CLI version, daemon binary digest, daemon generation, updater state และ inherited environment generation ผู้ใช้จะเห็นทันทีว่า turn นั้นกำลังใช้ daemon ตัวไหนและ environment ชุดใด.

จาก “ปิด daemon ได้” สู่ “รู้ว่าใครกำลังรันงานแทนเรา”

การตั้งค่า daemon_auto_start = false ช่วยให้ TUI session ใหม่ไม่สร้าง daemon ตามข้อมูลใน source แต่ยังตอบไม่ได้ว่า session ที่กำลังใช้อยู่เชื่อมกับ daemon รุ่นไหน

จึงควรมี execution receipt ตอนเชื่อมต่อ แสดง CLI version, daemon binary digest, daemon generation, updater state และ inherited environment generation ผู้ใช้จะตรวจสอบได้ว่า turn นี้ใช้ binary ตัวใด และรับ environment มาจาก session ไหน.