เอเจนต์ย่อยคือการรันเอเจนต์เบื้องหลังที่สร้างจากการรันเอเจนต์ที่มีอยู่ เอเจนต์ย่อยจะทำงานในเซสชันของตนเอง (Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
agent:<agentId>:subagent:<uuid>) และ
เมื่อเสร็จแล้วจะประกาศผลลัพธ์กลับไปยังช่องแชตของผู้ร้องขอ
การรันเอเจนต์ย่อยแต่ละครั้งจะถูกติดตามเป็น
งานเบื้องหลัง
เป้าหมายหลัก:
- ทำงาน “วิจัย / งานยาว / เครื่องมือช้า” แบบขนานโดยไม่บล็อกการรันหลัก
- แยกเอเจนต์ย่อยออกจากกันโดยค่าเริ่มต้น (การแยกเซสชัน + การ sandbox แบบเลือกใช้ได้)
- ทำให้พื้นผิวเครื่องมือใช้งานผิดได้ยาก: เอเจนต์ย่อยจะไม่ได้รับเครื่องมือเซสชันโดยค่าเริ่มต้น
- รองรับความลึกของการซ้อนที่กำหนดค่าได้สำหรับรูปแบบตัวประสานงาน
หมายเหตุเรื่องค่าใช้จ่าย: เอเจนต์ย่อยแต่ละตัวมีบริบทและการใช้โทเค็นของตนเองโดย
ค่าเริ่มต้น สำหรับงานหนักหรืองานที่ทำซ้ำ ให้ตั้งค่าโมเดลที่ถูกกว่าสำหรับเอเจนต์ย่อย
และให้เอเจนต์หลักใช้โมเดลคุณภาพสูงกว่า กำหนดค่าผ่าน
agents.defaults.subagents.model หรือการแทนที่รายเอเจนต์ เมื่อเอเจนต์ลูก
จำเป็นต้องใช้ทรานสคริปต์ปัจจุบันของผู้ร้องขอจริงๆ เอเจนต์สามารถร้องขอ
context: "fork" สำหรับการสร้างครั้งนั้นได้ เซสชันเอเจนต์ย่อยที่ผูกกับเธรดจะมีค่าเริ่มต้นเป็น
context: "fork" เพราะเซสชันเหล่านั้นแตกสาขาการสนทนาปัจจุบันไปยัง
เธรดติดตามผลคำสั่งสแลช
ใช้/subagents เพื่อตรวจสอบหรือควบคุมการรันเอเจนต์ย่อยสำหรับเซสชันปัจจุบัน:
/steer <message> ระดับบนสุดเพื่อบังคับทิศทางการรันที่ใช้งานอยู่ของเซสชันผู้ร้องขอปัจจุบัน ใช้ /subagents steer <id|#> <message> เมื่อเป้าหมายเป็นการรันลูก
/subagents info แสดงเมตาดาต้าการรัน (สถานะ, ประทับเวลา, id เซสชัน,
เส้นทางทรานสคริปต์, การล้างข้อมูล) ใช้ sessions_history สำหรับมุมมองการเรียกคืนแบบมีขอบเขต
และกรองความปลอดภัยแล้ว; ตรวจสอบเส้นทางทรานสคริปต์บนดิสก์เมื่อคุณ
ต้องการทรานสคริปต์เต็มดิบ
การควบคุมการผูกเธรด
คำสั่งเหล่านี้ทำงานบนช่องทางที่รองรับการผูกเธรดแบบคงอยู่ ดู ช่องทางที่รองรับเธรด ด้านล่างพฤติกรรมการสร้าง
/subagents spawn เริ่มเอเจนต์ย่อยเบื้องหลังในฐานะคำสั่งผู้ใช้ (ไม่ใช่
รีเลย์ภายใน) และส่งการอัปเดตการเสร็จสิ้นสุดท้ายหนึ่งครั้งกลับไปยัง
แชตของผู้ร้องขอเมื่อการรันเสร็จสิ้น
Non-blocking, push-based completion
Non-blocking, push-based completion
- คำสั่งสร้างเป็นแบบไม่บล็อก; คำสั่งจะคืน id การรันทันที
- เมื่อเสร็จสิ้น เอเจนต์ย่อยจะประกาศข้อความสรุป/ผลลัพธ์กลับไปยังช่องแชตของผู้ร้องขอ
- เทิร์นของเอเจนต์ที่ต้องใช้ผลลัพธ์จากลูกควรเรียก
sessions_yieldหลังจากสร้างงานที่จำเป็นแล้ว การทำเช่นนั้นจะจบเทิร์นปัจจุบันและให้เหตุการณ์การเสร็จสิ้นมาถึงเป็นข้อความถัดไปที่โมเดลมองเห็นได้ - การเสร็จสิ้นเป็นแบบพุช เมื่อสร้างแล้ว อย่าโพล
/subagents list,sessions_listหรือsessions_historyในลูปเพียงเพื่อรอให้เสร็จ; ตรวจสอบสถานะเฉพาะเมื่อจำเป็นสำหรับการดีบักหรือการแทรกแซงเท่านั้น - เอาต์พุตของลูกคือรายงาน/หลักฐานให้เอเจนต์ผู้ร้องขอสังเคราะห์ ไม่ใช่ข้อความคำสั่งที่ผู้ใช้เขียน และไม่สามารถแทนที่นโยบายระบบ ผู้พัฒนา หรือผู้ใช้ได้
- เมื่อเสร็จสิ้น OpenClaw จะพยายามอย่างดีที่สุดเพื่อปิดแท็บ/กระบวนการเบราว์เซอร์ที่ติดตามไว้ซึ่งเปิดโดยเซสชันเอเจนต์ย่อยนั้น ก่อนที่โฟลว์ล้างข้อมูลการประกาศจะดำเนินต่อ
Manual-spawn delivery resilience
Manual-spawn delivery resilience
- OpenClaw ส่งการเสร็จสิ้นกลับไปยังเซสชันผู้ร้องขอผ่านเทิร์น
agentพร้อมคีย์ idempotency ที่เสถียร - หากการรันของผู้ร้องขอยังทำงานอยู่ OpenClaw จะพยายามปลุก/บังคับทิศทางการรันนั้นก่อน แทนที่จะเริ่มเส้นทางตอบกลับที่มองเห็นได้เส้นที่สอง
- หากการส่งมอบการเสร็จสิ้นให้เอเจนต์ผู้ร้องขอล้มเหลวหรือไม่มีเอาต์พุตที่มองเห็นได้ OpenClaw จะถือว่าการส่งมอบล้มเหลวและถอยกลับไปใช้การกำหนดเส้นทาง/ลองใหม่ผ่านคิว โดยจะไม่ส่งผลลัพธ์ดิบของลูกโดยตรงไปยังแชตภายนอก
- หากไม่สามารถใช้การส่งมอบโดยตรงได้ จะถอยกลับไปใช้การกำหนดเส้นทางผ่านคิว
- หากการกำหนดเส้นทางผ่านคิวยังไม่พร้อมใช้งาน การประกาศจะถูกลองใหม่ด้วย exponential backoff สั้นๆ ก่อนยอมแพ้ในที่สุด
- การส่งมอบการเสร็จสิ้นจะคงเส้นทางผู้ร้องขอที่แก้ไขแล้วไว้: เส้นทางการเสร็จสิ้นที่ผูกกับเธรดหรือผูกกับการสนทนาจะชนะเมื่อพร้อมใช้งาน; หากต้นทางการเสร็จสิ้นให้มาเพียงช่องทาง OpenClaw จะเติมเป้าหมาย/บัญชีที่ขาดหายจากเส้นทางที่แก้ไขแล้วของเซสชันผู้ร้องขอ (
lastChannel/lastTo/lastAccountId) เพื่อให้การส่งมอบโดยตรงยังทำงานได้
Completion handoff metadata
Completion handoff metadata
การส่งต่อการเสร็จสิ้นไปยังเซสชันผู้ร้องขอเป็นบริบทภายในที่สร้างโดยรันไทม์
(ไม่ใช่ข้อความที่ผู้ใช้เขียน) และประกอบด้วย:
Result— ข้อความตอบกลับassistantที่มองเห็นได้ล่าสุด หรือมิฉะนั้นเป็นข้อความเครื่องมือ/toolResult ล่าสุดที่ทำให้ปลอดภัยแล้ว การรันที่ล้มเหลวแบบสิ้นสุดจะไม่นำข้อความตอบกลับที่จับไว้กลับมาใช้Status—completed successfully/failed/timed out/unknown- สถิติรันไทม์/โทเค็นแบบย่อ
- คำสั่งการส่งมอบที่บอกเอเจนต์ผู้ร้องขอให้เขียนใหม่ด้วยเสียงผู้ช่วยปกติ (ไม่ส่งต่อเมตาดาต้าภายในดิบ)
Modes and ACP runtime
Modes and ACP runtime
--modelและ--thinkingแทนที่ค่าเริ่มต้นสำหรับการรันนั้นโดยเฉพาะ- ใช้
info/logเพื่อตรวจสอบรายละเอียดและเอาต์พุตหลังเสร็จสิ้น /subagents spawnเป็นโหมดครั้งเดียว (mode: "run") สำหรับเซสชันแบบคงอยู่ที่ผูกกับเธรด ให้ใช้sessions_spawnพร้อมthread: trueและmode: "session"- สำหรับเซสชันชุดทดสอบ ACP (Claude Code, Gemini CLI, OpenCode หรือ Codex ACP/acpx แบบชัดเจน) ให้ใช้
sessions_spawnพร้อมruntime: "acp"เมื่อเครื่องมือประกาศรันไทม์นั้น ดู โมเดลการส่งมอบ ACP เมื่อดีบักการเสร็จสิ้นหรือลูปเอเจนต์ต่อเอเจนต์ เมื่อเปิดใช้งาน Plugincodexการควบคุมแชต/เธรดของ Codex ควรเลือกใช้/codex ...แทน ACP เว้นแต่ผู้ใช้จะขอ ACP/acpx อย่างชัดเจน - OpenClaw ซ่อน
runtime: "acp"จนกว่าจะเปิดใช้งาน ACP, ผู้ร้องขอไม่ได้อยู่ใน sandbox และมีการโหลด Plugin แบ็กเอนด์ เช่นacpxแล้วruntime: "acp"คาดหวัง id ชุดทดสอบ ACP ภายนอก หรือรายการagents.list[]ที่มีruntime.type="acp"; ใช้รันไทม์เอเจนต์ย่อยเริ่มต้นสำหรับเอเจนต์การกำหนดค่า OpenClaw ปกติจากagents_list
โหมดบริบท
เอเจนต์ย่อยแบบเนทีฟจะเริ่มแบบแยกส่วน เว้นแต่ผู้เรียกจะขอ fork ทรานสคริปต์ปัจจุบันอย่างชัดเจน| โหมด | เมื่อใดควรใช้ | พฤติกรรม |
|---|---|---|
isolated | การวิจัยใหม่, การใช้งานอิสระ, งานเครื่องมือช้า หรือสิ่งใดก็ตามที่สามารถบรีฟในข้อความงานได้ | สร้างทรานสคริปต์ลูกที่สะอาด นี่เป็นค่าเริ่มต้นและช่วยลดการใช้โทเค็น |
fork | งานที่ขึ้นอยู่กับการสนทนาปัจจุบัน, ผลลัพธ์เครื่องมือก่อนหน้า หรือคำสั่งที่มีความละเอียดอ่อนซึ่งมีอยู่แล้วในทรานสคริปต์ของผู้ร้องขอ | แตกสาขาทรานสคริปต์ของผู้ร้องขอเข้าไปยังเซสชันลูกก่อนที่ลูกจะเริ่ม |
fork เท่าที่จำเป็น ใช้สำหรับการมอบหมายงานที่ไวต่อบริบท ไม่ใช่
สิ่งทดแทนการเขียนพรอมต์งานให้ชัดเจน
เครื่องมือ: sessions_spawn
เริ่มการรันเอเจนต์ย่อยด้วย deliver: false บนเลน subagent ส่วนกลาง
จากนั้นรันขั้นตอนประกาศและโพสต์คำตอบประกาศไปยังช่องแชตของผู้ร้องขอ
ความพร้อมใช้งานขึ้นอยู่กับนโยบายเครื่องมือที่มีผลจริงของผู้เรียก โปรไฟล์ coding และ
full เปิดเผย sessions_spawn โดยค่าเริ่มต้น โปรไฟล์ messaging
ไม่เปิดเผย; เพิ่ม tools.alsoAllow: ["sessions_spawn", "sessions_yield", "subagents"] หรือใช้ tools.profile: "coding" สำหรับเอเจนต์ที่ควรมอบหมาย
งาน นโยบายอนุญาต/ปฏิเสธของช่องทาง/กลุ่ม, provider, sandbox และรายเอเจนต์
ยังสามารถลบเครื่องมือหลังขั้นตอนโปรไฟล์ได้ ใช้ /tools จาก
เซสชันเดียวกันเพื่อยืนยันรายการเครื่องมือที่มีผลจริง
ค่าเริ่มต้น:
- โมเดล: สืบทอดจากผู้เรียก เว้นแต่คุณตั้งค่า
agents.defaults.subagents.model(หรือagents.list[].subagents.modelรายเอเจนต์);sessions_spawn.modelที่ระบุอย่างชัดเจนยังคงมีผลเหนือกว่า - Thinking: สืบทอดจากผู้เรียก เว้นแต่คุณตั้งค่า
agents.defaults.subagents.thinking(หรือagents.list[].subagents.thinkingรายเอเจนต์);sessions_spawn.thinkingที่ระบุอย่างชัดเจนยังคงมีผลเหนือกว่า - หมดเวลาการรัน: หากละ
sessions_spawn.runTimeoutSecondsไว้ OpenClaw จะใช้agents.defaults.subagents.runTimeoutSecondsเมื่อมีการตั้งค่า; มิฉะนั้นจะถอยกลับเป็น0(ไม่หมดเวลา)
โหมดพรอมต์การมอบหมายงาน
agents.defaults.subagents.delegationMode ควบคุมเฉพาะแนวทางพรอมต์เท่านั้น; ไม่เปลี่ยนนโยบายเครื่องมือหรือบังคับใช้การมอบหมายงาน
suggest(ค่าเริ่มต้น): คงการกระตุ้นในพรอมต์มาตรฐานให้ใช้เอเจนต์ย่อยสำหรับงานที่ใหญ่กว่าหรือช้ากว่าprefer: บอกเอเจนต์หลักให้ตอบสนองต่อเนื่องและมอบหมายสิ่งใดก็ตามที่ซับซ้อนกว่าการตอบกลับโดยตรงผ่านsessions_spawn
agents.list[].subagents.delegationMode
พารามิเตอร์เครื่องมือ
คำอธิบายงานสำหรับเอเจนต์ย่อย
ตัวระบุเสถียรแบบเลือกได้สำหรับการกำหนดเป้าหมาย
subagents ในภายหลัง ต้องตรงกับ [a-z][a-z0-9_]{0,63} และต้องไม่เป็นเป้าหมายที่สงวนไว้ เช่น last หรือ all ควรใช้เมื่อผู้ประสานงานอาจต้องควบคุม หยุด หรือระบุ child เฉพาะหลังจากสร้าง children หลายตัวป้ายกำกับแบบมนุษย์อ่านได้ที่ระบุได้ตามต้องการ
สร้างภายใต้ id ของเอเจนต์อื่นเมื่อ
subagents.allowAgents อนุญาตacp ใช้เฉพาะสำหรับ ACP harness ภายนอก (claude, droid, gemini, opencode หรือ Codex ACP/acpx ที่ร้องขออย่างชัดเจน) และสำหรับรายการ agents.list[] ที่ runtime.type เป็น acpเฉพาะ ACP ดำเนินการต่อจากเซสชัน ACP harness ที่มีอยู่เมื่อ
runtime: "acp"; จะถูกละเว้นสำหรับการสร้างเอเจนต์ย่อยแบบเนทีฟเฉพาะ ACP สตรีมเอาต์พุตการรัน ACP ไปยังเซสชัน parent เมื่อ
runtime: "acp"; ละไว้สำหรับการสร้างเอเจนต์ย่อยแบบเนทีฟแทนที่โมเดลของเอเจนต์ย่อย ค่าที่ไม่ถูกต้องจะถูกข้าม และเอเจนต์ย่อยจะรันบนโมเดลเริ่มต้นพร้อมคำเตือนในผลลัพธ์ของเครื่องมือ
แทนที่ระดับ thinking สำหรับการรันเอเจนต์ย่อย
ค่าเริ่มต้นเป็น
agents.defaults.subagents.runTimeoutSeconds เมื่อมีการตั้งค่า มิฉะนั้นเป็น 0 เมื่อมีการตั้งค่า การรันเอเจนต์ย่อยจะถูกยกเลิกหลังจาก N วินาทีเมื่อเป็น
true จะร้องขอการผูก thread ของช่องทางสำหรับเซสชันเอเจนต์ย่อยนี้หากละ
mode และ thread: true ค่าเริ่มต้นจะกลายเป็น session mode: "session" ต้องใช้ thread: true"delete" จะเก็บถาวรทันทีหลังจากประกาศ (ยังคงเก็บทรานสคริปต์ไว้ผ่านการเปลี่ยนชื่อ)require จะปฏิเสธการสร้าง เว้นแต่รันไทม์ child เป้าหมายจะอยู่ใน sandboxfork จะแยกทรานสคริปต์ปัจจุบันของผู้ร้องขอไปยังเซสชัน child เฉพาะเอเจนต์ย่อยแบบเนทีฟ การสร้างที่ผูกกับ thread มีค่าเริ่มต้นเป็น fork; การสร้างที่ไม่ใช่ thread มีค่าเริ่มต้นเป็น isolatedชื่องานและการกำหนดเป้าหมาย
taskName เป็นตัวระบุที่โมเดลเห็นสำหรับการจัดการ orchestration ไม่ใช่คีย์เซสชัน
ใช้สำหรับชื่อ child ที่เสถียร เช่น review_subagents,
linux_validation หรือ docs_update เมื่อผู้ประสานงานอาจต้องควบคุม
หรือหยุด child นั้นในภายหลัง
การแก้เป้าหมายยอมรับการตรงกันแบบชัดเจนกับ taskName และ prefix
ที่ไม่กำกวม การจับคู่ถูกจำกัดอยู่ในหน้าต่างเป้าหมาย active/recent เดียวกับที่ใช้
โดยเป้าหมาย /subagents แบบหมายเลข ดังนั้น child ที่เสร็จสิ้นไปนานแล้วจะไม่ทำให้
ตัวระบุที่นำกลับมาใช้ใหม่กำกวม หาก children ที่ active หรือ recent สองตัวใช้
taskName เดียวกัน เป้าหมายจะกำกวม ให้ใช้ดัชนีรายการ คีย์เซสชัน หรือ
run id แทน
เป้าหมายที่สงวนไว้ last และ all ไม่ใช่ค่า taskName ที่ถูกต้อง
เพราะมีความหมายด้านการควบคุมอยู่แล้ว
เครื่องมือ: sessions_yield
สิ้นสุดเทิร์นโมเดลปัจจุบันและรออีเวนต์รันไทม์ โดยหลักคืออีเวนต์
การเสร็จสิ้นของเอเจนต์ย่อย ให้มาถึงเป็นข้อความถัดไป ใช้หลังจาก
สร้างงาน child ที่จำเป็นเมื่อผู้ร้องขอไม่สามารถให้คำตอบสุดท้าย
ได้จนกว่า completion เหล่านั้นจะมาถึง
sessions_yield เป็น primitive สำหรับการรอ อย่าแทนที่ด้วยลูป polling
ผ่าน subagents, sessions_list, sessions_history, shell
sleep หรือการ polling process เพียงเพื่อตรวจจับการเสร็จสิ้นของ child
ใช้ sessions_yield เฉพาะเมื่อรายการเครื่องมือที่มีผลของเซสชันมีเครื่องมือนี้
โปรไฟล์เครื่องมือแบบ minimal หรือ custom บางรายการอาจเปิดเผย sessions_spawn และ
subagents โดยไม่เปิดเผย sessions_yield; ในกรณีนั้น อย่าประดิษฐ์
ลูป polling เพียงเพื่อรอการเสร็จสิ้น
เมื่อมี children ที่ active อยู่ OpenClaw จะใส่บล็อกพรอมป์
Active Subagents ขนาดกะทัดรัดที่รันไทม์สร้างขึ้นลงในเทิร์นปกติ เพื่อให้ผู้ร้องขอเห็น
เซสชัน child ปัจจุบัน, run ids, สถานะ, ป้ายกำกับ, งาน และ
นามแฝง taskName โดยไม่ต้อง polling ฟิลด์งานและป้ายกำกับใน
บล็อกนั้นถูก quote เป็นข้อมูล ไม่ใช่คำสั่ง เพราะอาจมีต้นทาง
จากอาร์กิวเมนต์การสร้างที่ผู้ใช้/โมเดลให้มา
เครื่องมือ: subagents
แสดงรายการ ควบคุม หรือหยุดการรันเอเจนต์ย่อยที่ถูกสร้างและเป็นของเซสชัน
ผู้ร้องขอ ขอบเขตจำกัดอยู่ที่ผู้ร้องขอปัจจุบัน; child จะเห็น/ควบคุมได้เฉพาะ
children ที่ตัวเองควบคุมอยู่เท่านั้น
ใช้ subagents สำหรับสถานะตามคำขอ การดีบัก การควบคุม หรือการหยุด
ใช้ sessions_yield เพื่อรออีเวนต์การเสร็จสิ้น
เซสชันที่ผูกกับ thread
เมื่อเปิดใช้การผูก thread สำหรับช่องทาง เอเจนต์ย่อยสามารถคงการผูก กับ thread เพื่อให้ข้อความติดตามผลของผู้ใช้ใน thread นั้นยังคง route ไปยัง เซสชันเอเจนต์ย่อยเดียวกันช่องทางที่รองรับ thread
Discord เป็นช่องทางเดียวที่รองรับอยู่ในขณะนี้ รองรับ เซสชันเอเจนต์ย่อยที่ผูกกับ thread แบบถาวร (sessions_spawn พร้อม
thread: true), การควบคุม thread แบบ manual (/focus, /unfocus, /agents,
/session idle, /session max-age) และคีย์ adapter
channels.discord.threadBindings.enabled,
channels.discord.threadBindings.idleHours,
channels.discord.threadBindings.maxAgeHours และ
channels.discord.threadBindings.spawnSessions
ลำดับอย่างย่อ
ตรวจสอบ timeout
ใช้
/session idle เพื่อตรวจสอบ/อัปเดต auto-unfocus เมื่อไม่มีการใช้งาน และ
/session max-age เพื่อควบคุมเพดานแบบ hard capการควบคุมแบบ manual
| คำสั่ง | ผลลัพธ์ |
|---|---|
/focus <target> | ผูก thread ปัจจุบัน (หรือสร้างใหม่) กับเป้าหมายเอเจนต์ย่อย/เซสชัน |
/unfocus | ลบการผูกสำหรับ thread ปัจจุบันที่ถูกผูกไว้ |
/agents | แสดงรายการการรันที่ active และสถานะการผูก (thread:<id> หรือ unbound) |
/session idle | ตรวจสอบ/อัปเดต auto-unfocus เมื่อ idle (เฉพาะ thread ที่ผูกและโฟกัสอยู่) |
/session max-age | ตรวจสอบ/อัปเดต hard cap (เฉพาะ thread ที่ผูกและโฟกัสอยู่) |
สวิตช์การกำหนดค่า
- ค่าเริ่มต้นแบบ global:
session.threadBindings.enabled,session.threadBindings.idleHours,session.threadBindings.maxAgeHours - คีย์ override ของช่องทางและ auto-bind เมื่อสร้าง เป็นแบบเฉพาะ adapter ดู ช่องทางที่รองรับ thread ด้านบน
Allowlist
รายการ id ของเอเจนต์ที่สามารถกำหนดเป้าหมายผ่าน
agentId แบบชัดเจน (["*"] อนุญาตทุกตัว) ค่าเริ่มต้น: เฉพาะเอเจนต์ผู้ร้องขอ หากคุณตั้งค่ารายการและยังต้องการให้ผู้ร้องขอสร้างตัวเองด้วย agentId ให้ใส่ id ของผู้ร้องขอไว้ในรายการallowlist ของเอเจนต์เป้าหมายเริ่มต้นที่ใช้เมื่อเอเจนต์ผู้ร้องขอไม่ได้ตั้งค่า
subagents.allowAgents ของตัวเองบล็อกการเรียก
sessions_spawn ที่ละ agentId (บังคับให้เลือกโปรไฟล์อย่างชัดเจน) การ override รายเอเจนต์: agents.list[].subagents.requireAgentIdtimeout ต่อการเรียกสำหรับความพยายามส่งประกาศ
agent ของ Gateway ค่าเป็นจำนวนเต็มบวกในหน่วยมิลลิวินาที และถูก clamp ให้อยู่ในค่าสูงสุดของ timer ที่ปลอดภัยต่อแพลตฟอร์ม การลองใหม่แบบ transient อาจทำให้เวลารอประกาศทั้งหมดนานกว่า timeout ที่กำหนดไว้หนึ่งครั้งsessions_spawn จะปฏิเสธเป้าหมาย
ที่จะรันโดยไม่อยู่ใน sandbox
การค้นพบ
ใช้agents_list เพื่อดูว่า id ของเอเจนต์ใดได้รับอนุญาตสำหรับ
sessions_spawn อยู่ในขณะนี้ การตอบกลับรวมโมเดลที่มีผลของเอเจนต์แต่ละตัวที่แสดง
และ metadata รันไทม์ที่ฝังไว้ เพื่อให้ผู้เรียกแยกความแตกต่างระหว่าง PI, Codex
app-server และรันไทม์เนทีฟอื่น ๆ ที่กำหนดค่าไว้ได้
การเก็บถาวรอัตโนมัติ
- เซสชันเอเจนต์ย่อยจะถูกเก็บถาวรโดยอัตโนมัติหลังจาก
agents.defaults.subagents.archiveAfterMinutes(ค่าเริ่มต้น60) - การเก็บถาวรใช้
sessions.deleteและเปลี่ยนชื่อทรานสคริปต์เป็น*.deleted.<timestamp>(โฟลเดอร์เดียวกัน) cleanup: "delete"จะเก็บถาวรทันทีหลังจากประกาศ (ยังคงเก็บทรานสคริปต์ไว้ผ่านการเปลี่ยนชื่อ)- การเก็บถาวรอัตโนมัติเป็นแบบ best-effort; timer ที่ค้างอยู่จะหายไปหาก Gateway รีสตาร์ท
runTimeoutSecondsไม่ เก็บถาวรอัตโนมัติ; มันเพียงหยุดการรัน เซสชันยังคงอยู่จนกว่าจะถูกเก็บถาวรอัตโนมัติ- การเก็บถาวรอัตโนมัติใช้กับเซสชัน depth-1 และ depth-2 เท่า ๆ กัน
- การล้างข้อมูลเบราว์เซอร์แยกจากการล้างข้อมูลเก็บถาวร: แท็บ/กระบวนการเบราว์เซอร์ที่ติดตามจะถูกปิดแบบ best-effort เมื่อการรันเสร็จสิ้น แม้ว่าจะเก็บระเบียนทรานสคริปต์/เซสชันไว้ก็ตาม
เอเจนต์ย่อยแบบซ้อน
โดยค่าเริ่มต้น เอเจนต์ย่อยไม่สามารถสร้างเอเจนต์ย่อยของตัวเองได้ (maxSpawnDepth: 1) ตั้งค่า maxSpawnDepth: 2 เพื่อเปิดใช้การซ้อนหนึ่งระดับ
ซึ่งคือ รูปแบบ orchestrator: main → orchestrator sub-agent →
worker sub-sub-agents
ระดับความลึก
| ความลึก | รูปแบบคีย์เซสชัน | บทบาท | สร้างได้หรือไม่ |
|---|---|---|---|
| 0 | agent:<id>:main | เอเจนต์หลัก | เสมอ |
| 1 | agent:<id>:subagent:<uuid> | เอเจนต์ย่อย (orchestrator เมื่ออนุญาต depth 2) | เฉพาะเมื่อ maxSpawnDepth >= 2 |
| 2 | agent:<id>:subagent:<uuid>:subagent:<uuid> | เอเจนต์ย่อยของเอเจนต์ย่อย (leaf worker) | ไม่เคย |
สายประกาศ
ผลลัพธ์ไหลย้อนกลับขึ้นไปตามสาย:- worker depth-2 เสร็จสิ้น → ประกาศไปยัง parent ของมัน (orchestrator depth-1)
- orchestrator depth-1 ได้รับประกาศ สังเคราะห์ผลลัพธ์ เสร็จสิ้น → ประกาศไปยัง main
- เอเจนต์ main ได้รับประกาศและส่งต่อให้ผู้ใช้
คำแนะนำด้านการปฏิบัติงาน: เริ่มงานลูกหนึ่งครั้งแล้วรอเหตุการณ์การเสร็จสิ้น แทนที่จะสร้างลูป polling รอบ
sessions_list, sessions_history, /subagents list หรือคำสั่ง exec sleep
sessions_list และ /subagents list รักษาความสัมพันธ์ของเซสชันลูกให้มุ่งเน้นที่งานที่ยังทำงานอยู่ — ลูกที่ยังทำงานอยู่จะยังคงแนบอยู่ ลูกที่สิ้นสุดแล้วจะยังมองเห็นได้ในหน้าต่างเวลาล่าสุดช่วงสั้น ๆ และลิงก์ลูกแบบ store-only ที่ค้างจะถูกละเว้นหลังพ้นหน้าต่างความสดใหม่ วิธีนี้ป้องกันไม่ให้เมตาดาต้า spawnedBy / parentSessionKey เก่าปลุกลูกเงาขึ้นมาใหม่หลังรีสตาร์ท หากเหตุการณ์การเสร็จสิ้นของลูกมาถึงหลังจากคุณส่งคำตอบสุดท้ายไปแล้ว การติดตามผลที่ถูกต้องคือโทเค็นเงียบแบบตรงตัว NO_REPLY / no_replyนโยบายเครื่องมือตามความลึก
- บทบาทและขอบเขตการควบคุมจะถูกเขียนลงในเมตาดาต้าเซสชันตอน spawn ซึ่งช่วยป้องกันไม่ให้คีย์เซสชันแบบแบนหรือที่กู้คืนมาได้รับสิทธิ์ orchestrator กลับมาโดยไม่ตั้งใจ
- ความลึก 1 (orchestrator, เมื่อ
maxSpawnDepth >= 2): ได้รับsessions_spawn,subagents,sessions_list,sessions_historyเพื่อให้จัดการลูกของตนได้ เครื่องมือเซสชัน/ระบบอื่น ๆ ยังคงถูกปฏิเสธ - ความลึก 1 (leaf, เมื่อ
maxSpawnDepth == 1): ไม่มีเครื่องมือเซสชัน (พฤติกรรมเริ่มต้นปัจจุบัน) - ความลึก 2 (leaf worker): ไม่มีเครื่องมือเซสชัน —
sessions_spawnจะถูกปฏิเสธเสมอที่ความลึก 2 ไม่สามารถ spawn ลูกเพิ่มเติมได้
ขีดจำกัดการ spawn ต่อเอเจนต์
แต่ละเซสชันเอเจนต์ (ที่ความลึกใดก็ได้) สามารถมีลูกที่ทำงานอยู่ได้สูงสุดmaxChildrenPerAgent
(ค่าเริ่มต้น 5) ต่อครั้ง วิธีนี้ป้องกันการกระจายงานแบบ runaway
จาก orchestrator ตัวเดียว
การหยุดแบบ cascade
การหยุด orchestrator ความลึก 1 จะหยุดลูกความลึก 2 ทั้งหมดของมันโดยอัตโนมัติ:/stopในแชตหลักจะหยุดเอเจนต์ความลึก 1 ทั้งหมดและ cascade ไปยังลูกความลึก 2 ของพวกมัน/subagents kill <id>หยุดซับเอเจนต์ที่ระบุและ cascade ไปยังลูกของมัน/subagents kill allหยุดซับเอเจนต์ทั้งหมดของผู้ร้องขอและ cascade
การยืนยันตัวตน
การยืนยันตัวตนของซับเอเจนต์ถูก resolve ด้วย รหัสเอเจนต์ ไม่ใช่ด้วยประเภทเซสชัน:- คีย์เซสชันซับเอเจนต์คือ
agent:<agentId>:subagent:<uuid> - auth store ถูกโหลดจาก
agentDirของเอเจนต์นั้น - โปรไฟล์ auth ของเอเจนต์หลักจะถูกผสานเข้าเป็น fallback; โปรไฟล์เอเจนต์จะ override โปรไฟล์หลักเมื่อมีความขัดแย้ง
ประกาศ
ซับเอเจนต์รายงานกลับผ่านขั้นตอนประกาศ:- ขั้นตอนประกาศทำงานภายในเซสชันซับเอเจนต์ (ไม่ใช่เซสชันผู้ร้องขอ)
- หากซับเอเจนต์ตอบกลับว่า
ANNOUNCE_SKIPแบบตรงตัว จะไม่มีการโพสต์สิ่งใด - หากข้อความ assistant ล่าสุดเป็นโทเค็นเงียบแบบตรงตัว
NO_REPLY/no_replyเอาต์พุตประกาศจะถูกระงับ แม้เคยมีความคืบหน้าที่มองเห็นได้ก่อนหน้า
- เซสชันผู้ร้องขอระดับบนใช้การเรียก
agentแบบ follow-up พร้อมการส่งมอบภายนอก (deliver=true) - เซสชันซับเอเจนต์ผู้ร้องขอที่ซ้อนกันจะได้รับการฉีด follow-up ภายใน (
deliver=false) เพื่อให้ orchestrator สามารถสังเคราะห์ผลลัพธ์ลูกภายในเซสชันได้ - หากเซสชันซับเอเจนต์ผู้ร้องขอที่ซ้อนกันหายไป OpenClaw จะ fallback ไปยังผู้ร้องขอของเซสชันนั้นเมื่อพร้อมใช้งาน
บริบทประกาศ
บริบทประกาศถูกทำให้เป็นมาตรฐานเป็นบล็อกเหตุการณ์ภายในที่เสถียร:| ฟิลด์ | แหล่งที่มา |
|---|---|
| แหล่งที่มา | subagent หรือ cron |
| รหัสเซสชัน | คีย์/รหัสเซสชันลูก |
| ประเภท | ประเภทประกาศ + ป้ายกำกับงาน |
| สถานะ | ได้มาจากผลลัพธ์รันไทม์ (success, error, timeout หรือ unknown) — ไม่ได้ อนุมานจากข้อความโมเดล |
| เนื้อหาผลลัพธ์ | ข้อความ assistant ที่มองเห็นได้ล่าสุด มิฉะนั้นเป็นข้อความ tool/toolResult ล่าสุดที่ผ่านการ sanitize |
| การติดตามผล | คำแนะนำที่อธิบายว่าเมื่อใดควรตอบกลับและเมื่อใดควรเงียบ |
บรรทัดสถิติ
payload ประกาศมีบรรทัดสถิติที่ท้ายสุด (แม้เมื่อถูก wrap):- รันไทม์ (เช่น
runtime 5m12s) - การใช้โทเค็น (input/output/total)
- ค่าใช้จ่ายโดยประมาณเมื่อมีการตั้งค่าราคาโมเดล (
models.providers.*.models[].cost) sessionKey,sessionIdและเส้นทาง transcript เพื่อให้เอเจนต์หลักดึงประวัติผ่านsessions_historyหรือตรวจไฟล์บนดิสก์ได้
เหตุผลที่ควรเลือก sessions_history
sessions_history เป็นเส้นทาง orchestration ที่ปลอดภัยกว่า:
- การเรียกคืนของ assistant ถูกทำให้เป็นมาตรฐานก่อน: ลบ thinking tags; ลบ scaffolding
<relevant-memories>/<relevant_memories>; ลบบล็อก payload XML การเรียกเครื่องมือแบบข้อความล้วน (<tool_call>,<function_call>,<tool_calls>,<function_calls>) รวมถึง payload ที่ถูกตัดและปิดไม่สมบูรณ์; ลบ scaffolding การเรียก/ผลลัพธ์เครื่องมือที่ถูกลดระดับและ marker บริบทประวัติ; ลบโทเค็นควบคุมโมเดลที่รั่ว (<|assistant|>, ASCII<|...|>อื่น ๆ, แบบ full-width<|...|>); ลบ XML การเรียกเครื่องมือ MiniMax ที่ malformed - ข้อความที่คล้าย credential/token จะถูก redact
- บล็อกยาวสามารถถูกตัดให้สั้นลงได้
- ประวัติขนาดใหญ่มากสามารถทิ้งแถวเก่ากว่าหรือแทนที่แถวที่ใหญ่เกินด้วย
[sessions_history omitted: message too large] - การตรวจ transcript ดิบบนดิสก์เป็น fallback เมื่อคุณต้องการ transcript แบบ byte-for-byte เต็มรูปแบบ
นโยบายเครื่องมือ
ซับเอเจนต์ใช้โปรไฟล์และ pipeline นโยบายเครื่องมือเดียวกับพาเรนต์หรือ เอเจนต์เป้าหมายก่อน หลังจากนั้น OpenClaw จะใช้ชั้นข้อจำกัดของซับเอเจนต์ เมื่อไม่มีtools.profile ที่จำกัด ซับเอเจนต์จะได้รับ เครื่องมือทั้งหมด ยกเว้น
เครื่องมือเซสชัน และเครื่องมือระบบ:
sessions_listsessions_historysessions_sendsessions_spawn
sessions_history ยังคงเป็นมุมมองการเรียกคืนที่มีขอบเขตและผ่านการ sanitize ที่นี่ด้วย —
ไม่ใช่การ dump transcript ดิบ
เมื่อ maxSpawnDepth >= 2 ซับเอเจนต์ orchestrator ความลึก 1 จะได้รับ
sessions_spawn, subagents, sessions_list และ
sessions_history เพิ่มเติม เพื่อให้จัดการลูกของตนได้
Override ผ่าน config
tools.subagents.tools.allow เป็นตัวกรอง allow-only ขั้นสุดท้าย มันสามารถจำกัด
ชุดเครื่องมือที่ resolve แล้วให้แคบลง แต่ไม่สามารถ เพิ่มกลับ เครื่องมือที่ถูกลบ
โดย tools.profile ได้ ตัวอย่างเช่น tools.profile: "coding" มี
web_search/web_fetch แต่ไม่มีเครื่องมือ browser หากต้องการให้
ซับเอเจนต์โปรไฟล์ coding ใช้ browser automation ได้ ให้เพิ่ม browser ที่
ขั้นโปรไฟล์:
agents.list[].tools.alsoAllow: ["browser"] ต่อเอเจนต์ เมื่อมีเพียงเอเจนต์เดียว
ที่ควรได้รับ browser automation
Concurrency
ซับเอเจนต์ใช้ queue lane เฉพาะภายใน process:- ชื่อ lane:
subagent - Concurrency:
agents.defaults.subagents.maxConcurrent(ค่าเริ่มต้น8)
Liveness และการกู้คืน
OpenClaw ไม่ถือว่าการไม่มีendedAt เป็นหลักฐานถาวรว่าซับเอเจนต์
ยังมีชีวิตอยู่ รันที่ยังไม่จบซึ่งเก่ากว่า stale-run window จะหยุดถูกนับ
เป็น active/pending ใน /subagents list, สรุปสถานะ,
descendant completion gating และการตรวจ concurrency ต่อเซสชัน
หลังจาก Gateway รีสตาร์ท รันที่กู้คืนมาแบบค้างและยังไม่จบจะถูกตัดออก เว้นแต่
เซสชันลูกของมันถูกทำเครื่องหมาย abortedLastRun: true เซสชันลูกที่ถูก
ยกเลิกจากการรีสตาร์ทเหล่านั้นยังคงกู้คืนได้ผ่าน flow การกู้คืน orphan ของซับเอเจนต์
ซึ่งจะส่งข้อความ resume สังเคราะห์ก่อนล้าง marker ที่ถูกยกเลิก
การกู้คืนอัตโนมัติหลังรีสตาร์ทมีขอบเขตต่อเซสชันลูก หากลูกซับเอเจนต์เดียวกัน
ถูกยอมรับให้กู้คืน orphan ซ้ำ ๆ ภายใน rapid re-wedge window
OpenClaw จะคง tombstone การกู้คืนไว้บนเซสชันนั้นและหยุด auto-resume
ในการรีสตาร์ทครั้งต่อ ๆ ไป เรียกใช้
openclaw tasks maintenance --apply เพื่อ reconcile task record หรือ
openclaw doctor --fix เพื่อล้างแฟล็กการกู้คืนที่ถูกยกเลิกและค้างบน
เซสชันที่ถูก tombstone
หากการ spawn ซับเอเจนต์ล้มเหลวด้วย Gateway
PAIRING_REQUIRED /
scope-upgrade ให้ตรวจ RPC caller ก่อนแก้ไขสถานะ pairing
การประสานงาน sessions_spawn ภายในควรเชื่อมต่อเป็น
client.id: "gateway-client" พร้อม client.mode: "backend" ผ่าน
auth แบบ direct loopback shared-token/password; เส้นทางนั้นไม่ขึ้นกับ
scope baseline ของอุปกรณ์ที่จับคู่ของ CLI ผู้เรียกจากระยะไกล,
deviceIdentity แบบชัดเจน, เส้นทาง device-token แบบชัดเจน และไคลเอนต์ browser/node
ยังคงต้องได้รับการอนุมัติอุปกรณ์ตามปกติสำหรับ scope upgradesการหยุด
- การส่ง
/stopในแชตผู้ร้องขอจะ abort เซสชันผู้ร้องขอและหยุดรันซับเอเจนต์ที่ยังทำงานอยู่ซึ่ง spawn จากเซสชันนั้น พร้อม cascade ไปยังลูกที่ซ้อนอยู่ /subagents kill <id>หยุดซับเอเจนต์ที่ระบุและ cascade ไปยังลูกของมัน
ข้อจำกัด
- การประกาศของซับเอเจนต์เป็นแบบ best-effort หาก gateway รีสตาร์ท งาน “announce back” ที่ pending จะหายไป
- ซับเอเจนต์ยังคงใช้ทรัพยากร process ของ gateway เดียวกัน; ให้ถือว่า
maxConcurrentเป็นวาล์วนิรภัย sessions_spawnเป็นแบบ non-blocking เสมอ: ส่งคืน{ status: "accepted", runId, childSessionKey }ทันที- บริบทซับเอเจนต์ฉีดเฉพาะ
AGENTS.md,TOOLS.md,SOUL.md,IDENTITY.mdและUSER.md(ไม่มีMEMORY.md,HEARTBEAT.mdหรือBOOTSTRAP.md) - ความลึกการซ้อนสูงสุดคือ 5 (
maxSpawnDepthrange: 1–5) แนะนำให้ใช้ความลึก 2 สำหรับกรณีใช้งานส่วนใหญ่ maxChildrenPerAgentจำกัดจำนวนลูกที่ทำงานอยู่ต่อเซสชัน (ค่าเริ่มต้น5, range1–20)