Tool: computer — ควบคุมหน้าจอ เมาส์ คีย์บอร์ดแบบมีการ์ดกันพลาดในทุกขั้นตอน

computer เป็น tool เดียวใน Endeavor Hands ที่ควบคุมแอปบน Mac แบบเดียวกับที่คนใช้เมาส์และคีย์บอร์ดจริง — เห็นภาพหน้าจอ คลิก พิมพ์ scroll ลาก เปิดแอป เปิด URL ต้องมีสิทธิ์ macOS Accessibility ก่อนถึงจะเห็นหรือควบคุมอะไรได้เลย
Observe → act → verify คือ loop บังคับ ไม่ใช่ทางเลือก
Docstring วางกฎเป็น control loop ชัดเจน: เริ่มด้วย action="see" เมื่อยังไม่รู้สถานะหน้าจอ จะได้ screenshot กลับมาพร้อม [OBS obs_N] รายการ element (eN) ให้เลือกกระทำต่อ ทุกการเรียกที่เข้าถึงหน้าจอจะแนบภาพล่าสุดกลับมา พร้อมรายการ Accessibility/OCR element แบบข้อความ ([OBS]) — โมเดลต้อง “ดู” ผลก่อนตัดสินใจขั้นถัดไป ห้ามเดาต่อจากภาพเก่า
ระบบแนะนำให้ใช้ element_id="eN" + observation_id="obs_N" แทนการเล็ง target ด้วยข้อความหรือพิกัด (coord ถูกปิดใช้งานไปแล้ว) เพราะแม่นยำกว่าการ match ข้อความบนจอที่อาจซ้ำกันหลายจุด
หลัง action ระบบเทียบทั้ง semantic AX/OCR signal และ compact visual change จึงไม่ถือว่า “ไม่มีข้อความเปลี่ยน” แปลว่า action ล้มเหลวเสมอไป หากภาพเปลี่ยนอย่างมีหลักฐานก็ใช้เป็นสัญญาณสำเร็จได้ และ see/inspect มี observation budget แยกจาก mutation ceiling ทำให้ตรวจซ้ำเพื่อวินิจฉัยได้โดยไม่เผาโควตา action
Silent failure ต้องถูกตรวจจับ ไม่ใช่สมมติว่าสำเร็จ
หลักการที่ย้ำซ้ำในหลายจุดของ docstring: ห้ามเรียกซ้ำหรืออ้างว่าสำเร็จโดยไม่ตรวจสอบ ถ้าคลิกแล้วไม่มีอะไรเปลี่ยน (no_visible_change) ให้ see/inspect ก่อนเพื่อดูว่าเกิดอะไรขึ้นจริง แล้วค่อยลองอีกครั้งด้วย target/element ที่ต่างออกไป — วนซ้ำแบบเดิมโดยไม่ตรวจสอบก่อนคือพฤติกรรมที่ระบบออกแบบมาป้องกันโดยตรง
expect=<kind>:<value> ช่วยให้ตรวจสถานะหลัง action อัตโนมัติแทนการอ่านภาพด้วยตาเอง มี 4 kind: focus:<label> (element นี้ focus อยู่จริงไหม ผ่าน Accessibility), app:<name> (แอปนี้ frontmost อยู่ไหม), window:<text> (ชื่อหน้าต่างมีข้อความนี้ไหม), text:<text> (ข้อความนี้ปรากฏบนจอไหม) — ผลลัพธ์ต่อท้ายด้วย +verified, +expectation_not_met, หรือ +expect_unknown (เมื่อ Accessibility เช็คตอนนั้นไม่ได้ — ระบบเลือกตอบ “ไม่รู้” แทนที่จะโกหกว่าเช็คผ่านแล้ว)
ข้อจำกัดที่รู้ตัวและบอกไว้ตรงๆ: ใน Chrome/Chromium, expect="focus:<label>" ใช้ได้แม่นกับ control ของตัว browser เอง (address bar, ปุ่ม) แต่ใช้ไม่ได้กับ field ภายในหน้าเว็บที่โหลดมา เพราะ Chrome สร้าง accessibility tree ของเนื้อหาเว็บก็ต่อเมื่อตรวจพบ assistive-technology client แบบต่อเนื่อง ซึ่ง tool นี้ไม่ใช่ — สำหรับ field ในหน้าเว็บ ต้องใช้ expect="text:<value>" แทน
Destructive-action guard: สองระดับ ไม่ใช่ระดับเดียว
ระบบมี marker คำที่เข้าข่ายทำลาย/ลบสองชุด — SUPERVISED (ค่าเริ่มต้นของ turn ปกติ): delete, ลบ, remove, เอาออก, uninstall, empty trash, move to trash และ UNSUPERVISED (turn ที่ไม่มีใครเฝ้าดูโดยตรง) เพิ่ม trash, erase, format, wipe เข้าไปอีก
เหตุผลที่แยกสองระดับ จากคอมเมนต์ในซอร์สโค้ดจริง: รายการเดียวที่กว้างเกินไปเคยจับ “Format” (เมนูจัดรูปแบบข้อความ ไม่ใช่การล้างดิสก์) และ “Trash” (ไอคอนถังขยะใน Finder sidebar — แค่เปิดดูไม่ได้แปลว่ากำลังจะ empty) ผิดพลาดโดยไม่ตั้งใจในทุก turn ปกติที่มีมนุษย์เฝ้าดูอยู่แล้ว คำเหล่านี้เป็นอันตรายจริงเฉพาะในบริบทแคบๆ (ปุ่ม “Format…” ใน Disk Utility, “Empty Trash”) ที่ substring matching ธรรมดาแยกไม่ออก — turn แบบ supervised จึงตัดคำกำกวมพวกนี้ออก ส่วน turn แบบ unsupervised (เช่นงานที่ตั้งเวลาให้ทำงานเองโดยไม่มีคนเฝ้า) ยอมรับ false positive ที่สูงกว่าเพื่อความระมัดระวังสูงสุด
ปฏิเสธ password field แบบไม่บล็อกทั้งหน้าจอเกินจำเป็น
จุดออกแบบที่ละเอียดมาก: การตรวจ password field ไม่ได้สแกนข้อความทั้งหน้าจอหา marker อย่าง “password”/“รหัสผ่าน” — เพราะแบบนั้นจะบล็อกการพิมพ์ปกติในทุกหน้าจอที่มีคำว่า “Password” ปรากฏอยู่ที่ไหนสักแห่ง (เช่น label ของช่อง username ข้างๆ ช่อง password ที่กำลังจะกรอกจริง) ระบบใช้ target ที่โมเดลเพิ่งคลิกไปเอง เป็นตัวแทนที่แม่นยำกว่ามากว่า “field ที่กำลังจะรับข้อความ” คืออันไหน — ถ้า field ที่เพิ่งคลิกมี label ที่ match password marker การพิมพ์ต่อจะถูกปฏิเสธด้วยข้อความ “refusing to type into what looks like a password field — enter credentials manually”
Hotkey อันตรายถูกปฏิเสธโดยตรง ไม่สนบริบท
cmd+delete, cmd+backspace, shift+delete, cmd+shift+delete (คีย์ผสมที่มีความหมาย “ลบถาวร” ใน Finder/macOS) ถูกปฏิเสธเสมอไม่ว่ากรณีใด — แยกจากการตรวจจับคำในข้อความเป้าหมายข้างต้นโดยสิ้นเชิง เพราะการกดปุ่ม Backspace/Delete ธรรมดาระหว่างพิมพ์ข้อความเป็นเรื่องปกติมาก จึงต้อง normalize คีย์ผสมเฉพาะที่มีความหมาย “ลบถาวร” จริงๆ เท่านั้น ไม่ใช่บล็อกการแก้ไขข้อความทั่วไป
open_url ปฏิเสธ URL ที่มี credential ฝังอยู่
ถ้า URL ที่ขอเปิดมีรูปแบบ https://user:pass@host (credential ฝังในตัว URL) จะถูกปฏิเสธทันทีด้วย ValueError("open_url refuses URLs containing credentials") — ป้องกันไม่ให้ credential รั่วผ่านการเปิดลิงก์โดยไม่ตั้งใจ
ทำไมเรื่องนี้ถึงสำคัญ
computer คือ tool ที่ควบคุมสิ่งที่เห็นได้บนจอโดยตรงและกระทบแอปที่ผู้ใช้อาจใช้งานอยู่พร้อมกัน — guardrail จึงต้องละเอียดกว่า tool อื่นในหลายมิติพร้อมกัน: ระดับความเฝ้าระวังของ turn, target ที่แม่นยำสำหรับ password, hotkey ที่อันตรายเฉพาะทาง และ verification แบบ expect ที่ตอบ “ไม่รู้” อย่างตรงไปตรงมาเมื่อเช็คไม่ได้จริง แทนที่จะเดา
ความคิดเห็น
กำลังโหลดความคิดเห็น...