บทที่ 31
บทที่ 31 — Loop และ Goal (`/loop`, `/goal`)
สองคำสั่งสำหรับงานที่ต้องใช้มากกว่าหนึ่ง turn
/loop เป็นตัวส่งซ้ำแบบโง่ ๆ คือส่งข้อความเดิมซ้ำตามเวลาที่ตั้งไว้
จนกว่าคุณจะสั่งหยุด ส่วน /goal เป็นเป้าหมายที่ engine คอยติดตามให้ —
มีงบประมาณ มีวินัยในการ audit และมีเพดานแข็งที่หยุดสิ่งที่วิ่งหลุด
ทั้งคู่ใช้ร่วมกันได้ผลดีที่สุด goal บอกว่า อะไร และเงื่อนไขหยุด ส่วน loop
บอกว่า ทำต่อไป แต่แต่ละตัวก็ใช้เดี่ยว ๆ ได้ และ /goal --auto ก็ตัดความ
จำเป็นของ loop ออกไปเลย
/loop — ส่งซ้ำตามเวลา
❯ /loop 30s check whether the build finished and summarise any new errors
loop started (every 30s): check whether the build finished and summarise any new errors
token แรกคือช่วงเวลา (30s, 5m, 2h, 1d) ที่เหลือทั้งหมดคือข้อความที่
จะถูกส่งซ้ำ ถ้าไม่ใส่ช่วงเวลา ทั้งบรรทัดจะกลายเป็นเนื้อความ แล้วยิงทุก
5 นาที
❯ /loop /goal continue
loop started (self-paced (5min default)): /goal continue
การจัดการ
| คำสั่ง | ทำอะไร |
|---|---|
/loop <interval> <body> |
เริ่ม — ช่วงเวลาต้องมาก่อนเท่านั้นถึงจะถูกอ่านว่าเป็นช่วงเวลา |
/loop หรือ /loop status (หรือ list) |
แสดงเนื้อความของ loop ที่ทำงานอยู่ |
/loop stop (หรือ cancel / kill / off) |
หยุด |
หนึ่ง loop ต่อหนึ่งครั้ง การเริ่มตัวที่สองขณะที่ตัวแรกยังทำงานจะขึ้นว่า
loop already running — /loop stop first แทนที่จะซ้อนกัน
เนื้อความถูกส่งตรงตามที่พิมพ์ จะเป็น prompt, slash command หรืออะไรก็ได้ที่ คุณพิมพ์เองได้ และ loop ไม่ได้รอ ให้ turn ก่อนหน้าจบก่อนที่ช่วงเวลา ถัดไปจะมาถึง — มันเป็นตัวจับเวลา ไม่ใช่คิว
/goal — เป้าหมายที่ engine ติดตามให้
❯ /goal start "migrate every test file to the new fixture" --budget-tokens 400000
goal หนึ่งตัวมีทั้งเป้าหมาย งบประมาณ (ถ้าตั้ง) จำนวนโทเคนและรอบที่ใช้ไป และ
สถานะ มันถูกเก็บอยู่ใน session จึงอยู่รอดข้าม /load
ตัวที่น่าสนใจคือ /goal continue มันไม่ได้แค่ prompt ซ้ำ แต่สร้าง
audit prompt จากสถานะปัจจุบัน ซึ่งสั่งให้โมเดล
- แปลงเป้าหมายกลับมาเป็นสิ่งส่งมอบที่จับต้องได้
- ทำ checklist จาก prompt ไปถึง artifact
- ตรวจหลักฐานจริง — ไฟล์ ผลลัพธ์เทส ผลของคำสั่ง
- ห้าม รับสัญญาณตัวแทนว่าเป็นการเสร็จสิ้น
- ถือว่าความไม่แน่ใจ = ยังทำไม่สำเร็จ
สองข้อสุดท้ายคือหัวใจ โมเดลที่ถูกถามว่า “เสร็จหรือยัง” มักตอบว่าเสร็จ ส่วน โมเดลที่ถูกสั่งว่า “ไปตรวจ artifact และถือว่าความไม่แน่ใจคือยังไม่สำเร็จ” จะไปดูจริง
คำสั่งย่อย
| คำสั่ง | ทำอะไร |
|---|---|
/goal start <objective> [flags] (หรือ set / new) |
เริ่ม ใส่เครื่องหมายคำพูดครอบเป้าหมายถ้ามีคำที่ขึ้นต้นด้วย -- |
/goal หรือ /goal status |
สถานะบรรทัดเดียว |
/goal show (หรือ info) |
สถานะเต็ม: งบประมาณ โทเคนที่ใช้ จำนวนรอบ audit ล่าสุด |
/goal continue (หรือ next) |
ยิง audit หนึ่งรอบ |
/goal complete [reason] (หรือ done) |
ปิดเองว่าเสร็จแล้ว |
/goal abandon [reason] (หรือ stop / cancel) |
ยอมแพ้ |
Flag ของ /goal start
| Flag | ผล |
|---|---|
--budget-tokens N (หรือ --tokens) |
เพดานโทเคนแบบอ่อน ที่ 1.0× โมเดลจะถูกเตือนให้สรุปงาน ที่ 1.5× engine หยุดให้ (ดูข้างล่าง) |
--budget-time T (หรือ --time) |
เหมือนกัน แต่เป็นเวลาจริง เช่น 30m, 2h |
--auto (หรือ --auto-continue) |
เดินต่อเองโดยไม่ต้องมี /loop ครอบ (ดูข้างล่าง) |
--require <path> |
ไฟล์ที่ต้องมีอยู่จริงก่อนจะปิด goal ได้ ใส่ซ้ำได้หลายตัว (ดูข้างล่าง) |
การรัน goal จนจบ
ทำได้สองแบบ
แบบมี loop — เขียนออกมาชัด ๆ
❯ /goal start "get the integration suite green" --budget-time 2h
❯ /loop 2m /goal continue
ทุกสองนาทีจะ audit หนึ่งรอบ เมื่อ goal ไปถึงสถานะปลายทาง loop จะ หยุดตัวเอง
loop auto-stopped (goal complete)
แบบ --auto — ไม่ต้องมี loop เลย
❯ /goal start "get the integration suite green" --budget-time 2h --auto
หลังจบทุก turn ที่มีการเรียก tool engine จะเข้าคิว /goal continue ตัวถัดไป
ทันที ไม่ต้องรอครบช่วงเวลา แบบนี้มักเป็นสิ่งที่คุณต้องการ เพราะเร็วกว่า และ
ยิงซ้อนไม่ได้
อย่าใช้ทั้งสองพร้อมกัน --auto จะถอยให้โดยเจตนาเมื่อมี /loop ทำงานอยู่
เพื่อไม่ให้ทั้งคู่เข้าคิวรอบใหม่พร้อมกัน
กลไกความปลอดภัย
ส่วนนี้ควรอ่านก่อนปล่อย goal ให้ทำงานโดยไม่มีคนเฝ้า มีจุดหยุดที่เป็นอิสระ จากกันสี่ชั้น และมันมีอยู่เพราะ “ให้โมเดลตัดสินเองว่าเสร็จเมื่อไร” ไม่ใช่ ดีไซน์ที่ปลอดภัยถ้ามีอยู่ลำพัง
1. งบอ่อน แล้วตามด้วยเพดานแข็ง
การใช้เกินงบโทเคนหรือเวลาที่ 1.0× จะสลับ prompt เป็นแบบให้สรุปงาน โมเดล จะถูกบอกว่าหมดงบแล้วและควรรวบให้จบ
ส่วนการเกิน 1.5× เป็นเรื่องของ engine ไม่ใช่ของโมเดล goal จะถูกบังคับให้
เป็น blocked ตัว loop ถูก abort และคุณจะได้รู้เหตุผล
/goal continue — hard limit: token budget overrun (612000 used ≥ 1.5× 400000 budget).
Auto-blocking goal + stopping loop.
ช่วงผ่อนผัน 1.5× มีไว้เพื่อไม่ให้โมเดลที่เหลืออีกก้าวเดียวจะจบถูกตัดกลางคัน ขณะเดียวกันโมเดลที่เลิกลู่เข้าหาคำตอบแล้วก็ใช้เงินต่อไปไม่ได้
2. เพดานจำนวนรอบ
100 ครั้งของ /goal continue ไม่ว่าจะตั้งงบไว้หรือไม่ การ audit จริง ๆ
ลู่เข้าได้ต่ำกว่านี้มาก เพดานนี้มีไว้จับตัวที่วิ่งหลุดเท่านั้น และเป็นเหตุผล
ที่ goal ซึ่งไม่ตั้งงบอะไรเลยก็ยังมีขอบเขต
3. ตัวกันรอบที่ว่างเปล่า
ถ้า turn ที่อยู่ใน loop ไม่มีการเรียก tool เลย — โมเดลพูดคนเดียวโดยไม่ได้ทำ อะไร — รอบถัดไปจะถูกข้ามหนึ่งครั้ง
(/goal continue suppressed: prior turn made no tool calls — model just
monologued. Will retry next /loop firing.)
ข้ามครั้งเดียว ไม่ใช่ถาวร ตัวกันจะรีเซ็ตตัวเอง turn ที่ครุ่นคิดหนึ่งครั้งจึง ไม่ทำให้ loop ตาย
4. สถานะปลายทางหยุดทุกอย่าง
complete, abandoned และ blocked เป็นสถานะปลายทาง การไปถึงสถานะใด
สถานะหนึ่งจะ abort loop ที่ทำงานอยู่และปฏิเสธ /goal continue ต่อไป ส่วน
goal ที่ blocked คือถูก พัก ไม่ใช่ตาย แก้ตัวติดขัดแล้วสั่ง /goal continue
เองได้ หรือจะ /goal abandon ก็ได้
--require — ประตูที่โมเดลพูดผ่านไม่ได้
audit prompt สั่งให้โมเดลตรวจ artifact ส่วน --require ให้ engine เป็น
คนตรวจแทน
❯ /goal start "write the migration guide" \
--require docs/migration.md \
--require docs/migration-th.md \
--auto
ตอนนี้ MarkGoalComplete จะ ถูกปฏิเสธ ตราบใดที่ยังมีไฟล์ไหนหายไป พร้อม
ระบุชื่อไฟล์ที่ขาด goal จะยังเป็น active ต่อไป loop แบบ --auto จึงทำงาน
ต่อแทนที่จะประกาศชัยชนะ
นี่คือการเปลี่ยนข้อตกลงระดับ prompt ให้กลายเป็นข้อเท็จจริงที่แข็ง โมเดลถูก ทำให้เชื่อได้ว่ามันเขียนไฟล์ไปแล้ว แต่มันทำให้ไฟล์มีอยู่จริงไม่ได้ ใช้ flag นี้ทุกครั้งที่ผลลัพธ์ของ goal เป็นไฟล์ที่คุณระบุชื่อได้ล่วงหน้า — มันเป็น สิ่งที่ได้ผลที่สุดในบทนี้
path อ้างอิงจาก working directory และใส่ซ้ำได้หลายตัว
โมเดลทำอะไรกับ goal ได้บ้าง
มีสาม tool ที่ถูกแยกออกจากกันโดยเจตนา เพื่อให้ “บันทึกความคืบหน้า” กับ “ประกาศชัยชนะ” เป็นคนละการกระทำ
| Tool | ผล |
|---|---|
RecordGoalProgress |
จุดตรวจกลางทาง สถานะยังเป็น active รอบต่อไปยังยิง ส่วนสรุปจะถูกพกไปให้รอบหลัง ๆ เป็น hint prior_audit เพื่อไม่ต้อง audit ใหม่ตั้งแต่ต้น |
MarkGoalComplete |
ปลายทาง complete ต้องมีสรุป audit ว่าตรวจอะไรไปบ้างและหลักฐานคืออะไร ถูกปฏิเสธถ้ายังมี path ใน --require ขาดอยู่ |
MarkGoalBlocked |
ปลายทาง blocked ต้องมี reason เช่น ไม่มี API key, สเปกกำกวม, หรือมีเรื่องที่คุณเท่านั้นตัดสินใจได้ |
การแยกนี้สำคัญ ก่อนหน้านี้มี tool ตัวเดียวทำทั้งสามอย่าง และทางที่ถูกที่สุด
สำหรับโมเดลที่ไม่แน่ใจคือประกาศว่าเสร็จ ตอนนี้ทางของความไม่แน่ใจคือ
RecordGoalProgress ซึ่งทำให้ loop เดินต่อ — คำอธิบายของ tool เขียนไว้ตรง ๆ
ว่า “การจบ loop ด้วยหลักฐานที่ไม่พอคือ failure mode ที่แย่ที่สุด”
เมื่อไหร่ที่ไม่ควรใช้
- งานเดี่ยวที่ระบุชัดอยู่แล้ว สั่งไปตรง ๆ เลย goal จะเพิ่มงานบันทึกและ รอบ audit ที่คุณไม่ต้องการ
- งานที่กระจายออกไปหลายไฟล์ นั่นคือ Workflows ซึ่ง deterministic ขนานได้ และ resume ได้ ส่วน goal คืองานเส้นเดียวที่เดินต่อไป เรื่อย ๆ ไม่ใช่หลายเส้นพร้อมกัน
- อะไรที่อิงตารางเวลามากกว่าช่วงเวลา
/loopตายไปพร้อม session ถ้าอยาก ได้ “ทุกวันทำงาน 08:30” ให้ใช้ Scheduling ซึ่งอยู่รอด ข้าม restart และรันจาก daemon ได้
การแก้ปัญหา
| อาการ | สาเหตุ | วิธีแก้ |
|---|---|---|
loop already running |
หนึ่ง loop ต่อหนึ่ง session | /loop stop ก่อน |
| loop ยิงแต่ไม่มีอะไรเกิดขึ้น | เนื้อความถูกตัวกันรอบว่างเปล่าระงับไว้ | มองหาข้อความแจ้งการระงับ รอบถัดไปจะลองใหม่ |
goal กลายเป็น blocked เอง |
ชนเพดานแข็ง — 1.5× ของงบ หรือครบ 100 รอบ | /goal show จะบอกเหตุผล ตั้งงบใหม่ใน goal ตัวใหม่ หรือทำเป้าหมายให้แคบลง |
| โมเดลบอกว่าเสร็จแล้วทั้งที่ยังไม่เสร็จ | ไม่มีอะไรบังคับให้มันพิสูจน์ | เริ่ม goal ใหม่พร้อม --require <path> สำหรับทุก artifact |
--auto ไม่ยอมยิง |
มี /loop ทำงานอยู่ หรือ turn ล่าสุดไม่ได้เรียก tool |
/loop stop แล้วปล่อยให้ --auto เป็นคนขับ |
| goal อยู่รอดข้าม restart ทั้งที่ไม่อยากให้อยู่ | goal ถูกเก็บไว้ใน session | /goal abandon หรือเริ่ม session ใหม่ |