16 KiB
| read_when | summary | title | x-i18n | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
โหมดคิวการตอบกลับอัตโนมัติ ค่าเริ่มต้น และการแทนที่ต่อเซสชัน | คิวคำสั่ง |
|
เราทำให้การรันการตอบกลับอัตโนมัติขาเข้า (ทุกช่องทาง) ผ่านคิวขนาดเล็กในโปรเซสแบบเรียงลำดับ เพื่อป้องกันไม่ให้การรันเอเจนต์หลายรายการชนกัน ขณะเดียวกันยังอนุญาตให้ทำงานแบบขนานอย่างปลอดภัยข้ามเซสชันได้
เหตุผล
- การรันการตอบกลับอัตโนมัติอาจมีค่าใช้จ่ายสูง (การเรียก LLM) และอาจชนกันเมื่อมีข้อความขาเข้าหลายข้อความมาถึงในเวลาใกล้กัน
- การจัดลำดับช่วยหลีกเลี่ยงการแย่งใช้ทรัพยากรที่แชร์กัน (ไฟล์เซสชัน, บันทึก, CLI stdin) และลดโอกาสเจอขีดจำกัดอัตราจาก upstream
วิธีทำงาน
- คิว FIFO ที่รับรู้ lane จะระบายแต่ละ lane ด้วยเพดาน concurrency ที่กำหนดค่าได้ (ค่าเริ่มต้น 1 สำหรับ lane ที่ไม่ได้กำหนดค่า; main มีค่าเริ่มต้นเป็น 4, subagent เป็น 8)
runEmbeddedPiAgentเข้าคิวตาม คีย์เซสชัน (lanesession:<key>) เพื่อรับประกันว่ามีการรันที่ทำงานอยู่ได้เพียงรายการเดียวต่อเซสชัน- จากนั้นการรันแต่ละเซสชันจะถูกเข้าคิวใน lane ส่วนกลาง (
mainโดยค่าเริ่มต้น) เพื่อให้ parallelism โดยรวมถูกจำกัดด้วยagents.defaults.maxConcurrent - เมื่อเปิดใช้การบันทึกแบบละเอียด การรันที่อยู่ในคิวจะแสดงข้อความแจ้งสั้น ๆ หากต้องรอนานกว่า ~2 วินาทีก่อนเริ่ม
- ตัวบ่งชี้การพิมพ์ยังส่งทันทีเมื่อเข้าคิว (เมื่อช่องทางรองรับ) ดังนั้นประสบการณ์ผู้ใช้จึงไม่เปลี่ยนขณะรอถึงลำดับของเรา
ค่าเริ่มต้น
เมื่อไม่ได้ตั้งค่า พื้นผิวช่องทางขาเข้าทั้งหมดจะใช้:
mode: "steer"debounceMs: 500cap: 20drop: "summarize"
steer เป็นค่าเริ่มต้นเพราะช่วยให้รอบของโมเดลที่กำลังทำงานตอบสนองได้ดี โดยไม่เริ่มการรันเซสชันที่สอง ระบบจะระบายข้อความ steering ทั้งหมดที่มาถึงก่อน boundary ของโมเดลถัดไป หากการรันปัจจุบันรับ steering ไม่ได้ OpenClaw จะ fallback ไปยังรายการคิว followup
โหมดคิว
ข้อความขาเข้าสามารถ steer การรันปัจจุบัน, รอรอบ followup หรือทำทั้งสองอย่างได้:
steer: เข้าคิวข้อความ steering เข้าไปใน runtime ที่กำลังทำงานอยู่ Pi จะส่งข้อความ steering ที่รออยู่ทั้งหมด หลังจากรอบ assistant ปัจจุบันเรียกใช้เครื่องมือเสร็จสิ้นแล้ว ก่อนการเรียก LLM ครั้งถัดไป; Codex app-server จะได้รับturn/steerแบบแบตช์หนึ่งรายการ หากการรันไม่ได้ streaming อยู่จริงหรือ steering ไม่พร้อมใช้งาน OpenClaw จะ fallback ไปยังรายการคิว followupqueue(เดิม): steering แบบทีละรายการเก่า Pi จะส่งข้อความ steering ที่เข้าคิวไว้หนึ่งข้อความที่แต่ละ boundary ของโมเดล; Codex app-server จะได้รับคำขอturn/steerแยกกัน ควรใช้steerเว้นแต่คุณต้องการพฤติกรรมแบบเรียงลำดับเดิมfollowup: เข้าคิวแต่ละข้อความสำหรับรอบเอเจนต์ภายหลังหลังจากการรันปัจจุบันสิ้นสุดcollect: รวมข้อความที่เข้าคิวไว้เป็นรอบ followup เดียว หลังช่วงเวลาที่เงียบลง หากข้อความชี้ไปยังช่องทาง/เธรดต่างกัน จะระบายแยกกันเพื่อรักษาการกำหนดเส้นทางsteer-backlog(หรือsteer+backlog): steer ทันที และ เก็บข้อความเดียวกันไว้สำหรับรอบ followupinterrupt(เดิม): ยกเลิกการรันที่กำลังทำงานอยู่สำหรับเซสชันนั้น แล้วรันข้อความล่าสุด
Steer-backlog หมายความว่าคุณอาจได้รับการตอบกลับ followup หลังการรันที่ถูก steer ดังนั้นพื้นผิว streaming อาจดูเหมือนมีรายการซ้ำ ควรใช้ collect/steer หากคุณต้องการการตอบกลับหนึ่งรายการต่อข้อความขาเข้าหนึ่งข้อความ
สำหรับ timing และพฤติกรรม dependency เฉพาะ runtime โปรดดู คิว Steering สำหรับคำสั่ง /steer <message> แบบชัดเจน โปรดดู Steer
กำหนดค่าแบบส่วนกลางหรือต่อช่องทางผ่าน messages.queue:
{
messages: {
queue: {
mode: "steer",
debounceMs: 500,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" },
},
},
}
ตัวเลือกคิว
ตัวเลือกใช้กับ followup, collect และ steer-backlog (และกับ steer หรือ queue เดิมเมื่อ steering fallback ไปเป็น followup):
debounceMs: ช่วงเวลาที่เงียบลงก่อนระบาย followup ที่เข้าคิวไว้ ตัวเลขล้วนคือมิลลิวินาที; ตัวเลือก/queueรับหน่วยms,s,m,hและdcap: จำนวนข้อความสูงสุดที่เข้าคิวได้ต่อเซสชัน ค่าต่ำกว่า1จะถูกละเว้นdrop: "summarize": ค่าเริ่มต้น ทิ้งรายการที่เข้าคิวเก่าที่สุดตามจำเป็น เก็บสรุปแบบย่อไว้ และฉีดเข้าไปเป็นพรอมป์ followup สังเคราะห์drop: "old": ทิ้งรายการที่เข้าคิวเก่าที่สุดตามจำเป็น โดยไม่เก็บสรุปไว้drop: "new": ปฏิเสธข้อความล่าสุดเมื่อคิวเต็มอยู่แล้ว
ค่าเริ่มต้น: debounceMs: 500, cap: 20, drop: summarize
ลำดับความสำคัญ
สำหรับการเลือกโหมด OpenClaw จะ resolve ตามลำดับ:
- override
/queueแบบ inline หรือที่จัดเก็บไว้ต่อเซสชัน messages.queue.byChannel.<channel>messages.queue.mode- ค่าเริ่มต้น
steer
สำหรับตัวเลือก ตัวเลือก /queue แบบ inline หรือที่จัดเก็บไว้จะชนะ config จากนั้นจะใช้ debounce เฉพาะช่องทาง (messages.queue.debounceMsByChannel), ค่าเริ่มต้น debounce ของ Plugin, ตัวเลือก messages.queue ส่วนกลาง และค่าเริ่มต้นในตัว ระบบจะใช้ cap และ drop เป็นตัวเลือกส่วนกลาง/เซสชัน ไม่ใช่คีย์ config ต่อช่องทาง
override ต่อเซสชัน
- ส่ง
/queue <mode>เป็นคำสั่งเดี่ยวเพื่อจัดเก็บโหมดสำหรับเซสชันปัจจุบัน - สามารถรวมตัวเลือกได้:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaultหรือ/queue resetจะล้าง override ของเซสชัน
ขอบเขตและการรับประกัน
- ใช้กับการรันเอเจนต์การตอบกลับอัตโนมัติในทุกช่องทางขาเข้าที่ใช้ไปป์ไลน์ตอบกลับของ Gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat ฯลฯ)
- lane เริ่มต้น (
main) มีผลทั่วทั้งโปรเซสสำหรับขาเข้า + Heartbeat หลัก; ตั้งค่าagents.defaults.maxConcurrentเพื่ออนุญาตให้หลายเซสชันทำงานพร้อมกันได้ - อาจมี lane เพิ่มเติม (เช่น
cron,cron-nested,nested,subagent) เพื่อให้งานพื้นหลังทำงานพร้อมกันได้โดยไม่บล็อกการตอบกลับขาเข้า รอบเอเจนต์ cron แบบแยกจะถือ slotcronไว้ ขณะที่การทำงานเอเจนต์ภายในใช้cron-nested; ทั้งสองใช้cron.maxConcurrentRunsโฟลว์nestedที่แชร์และไม่ใช่ cron จะคงพฤติกรรม lane ของตัวเอง การรันแบบแยกเหล่านี้ถูกติดตามเป็น งานพื้นหลัง - lane ต่อเซสชันรับประกันว่ามีการรันเอเจนต์เพียงรายการเดียวที่แตะเซสชันหนึ่ง ๆ ในเวลาเดียวกัน
- ไม่มี dependency ภายนอกหรือเธรด worker พื้นหลัง; เป็น TypeScript + promise ล้วน
การแก้ไขปัญหา
- หากคำสั่งดูเหมือนค้าง ให้เปิดใช้บันทึกแบบละเอียดแล้วมองหาบรรทัด “queued for …ms” เพื่อยืนยันว่าคิวกำลังระบาย
- หากคุณต้องการความลึกของคิว ให้เปิดใช้บันทึกแบบละเอียดแล้วดูบรรทัด timing ของคิว
- การรัน Codex app-server ที่รับ turn แล้วหยุดส่ง progress จะถูก interrupt โดย Codex adapter เพื่อให้ lane ของเซสชันที่กำลังทำงานอยู่ปล่อยได้ แทนที่จะรอ timeout ของการรันชั้นนอก
- เมื่อเปิดใช้ diagnostics เซสชันที่ยังอยู่ใน
processingเกินdiagnostics.stuckSessionWarnMsโดยไม่พบ reply, tool, status, block หรือ progress ของ ACP จะถูกจัดประเภทตามกิจกรรมปัจจุบัน งานที่ยัง active จะบันทึกเป็นsession.long_running; งานที่ยัง active แต่ไม่มี progress ล่าสุดจะบันทึกเป็นsession.stalled;session.stuckสงวนไว้สำหรับ bookkeeping ของเซสชันที่ค้างเก่าโดยไม่มีงาน active และมีเพียงเส้นทางนั้นเท่านั้นที่ปล่อย lane ของเซสชันที่ได้รับผลกระทบได้ เพื่อให้งานที่เข้าคิวไว้ระบายต่อ diagnosticssession.stuckที่เกิดซ้ำจะ back off ขณะที่เซสชันยังไม่เปลี่ยนแปลง