Fundamentals

ลูปเอเจนต์

ลูปแบบเอเจนต์คือการรัน "จริง" แบบเต็มของเอเจนต์: การรับเข้า → การประกอบบริบท → การอนุมานของโมเดล → การเรียกใช้เครื่องมือ → การสตรีมคำตอบ → การคงข้อมูล เป็นเส้นทางที่เชื่อถือได้ซึ่งเปลี่ยนข้อความ ให้เป็นการกระทำและคำตอบสุดท้าย พร้อมรักษาสถานะเซสชันให้สอดคล้องกัน

ใน OpenClaw ลูปคือการรันแบบลำดับเดียวต่อเซสชัน ซึ่งปล่อยเหตุการณ์วงจรชีวิตและสตรีม ขณะที่โมเดลคิด เรียกเครื่องมือ และสตรีมผลลัพธ์ เอกสารนี้อธิบายวิธีเชื่อมลูปจริงนั้น ตั้งแต่ต้นจนจบ

จุดเข้าใช้งาน

  • Gateway RPC: agent และ agent.wait
  • CLI: คำสั่ง agent

วิธีทำงาน (ภาพรวมระดับสูง)

  1. RPC agent ตรวจสอบพารามิเตอร์ แก้ไขเซสชัน (sessionKey/sessionId) คงข้อมูลเมตาเซสชัน และส่งคืน { runId, acceptedAt } ทันที
  2. agentCommand รันเอเจนต์:
    • แก้ไขค่าเริ่มต้นของโมเดล + thinking/verbose/trace
    • โหลดสแนปช็อต Skills
    • เรียก runEmbeddedAgent (รันไทม์เอเจนต์ OpenClaw)
    • ปล่อย lifecycle end/error หากลูปแบบฝังไม่ได้ปล่อยเหตุการณ์นั้น
  3. runEmbeddedAgent:
    • จัดลำดับการรันผ่านคิวต่อเซสชัน + คิวส่วนกลาง
    • แก้ไขโมเดล + โปรไฟล์ auth และสร้างเซสชัน OpenClaw
    • สมัครรับเหตุการณ์รันไทม์และสตรีมเดลตาของผู้ช่วย/เครื่องมือ
    • บังคับใช้ timeout -> ยกเลิกการรันหากเกินกำหนด
    • สำหรับเทิร์น app-server ของ Codex จะยกเลิกเทิร์นที่รับแล้วซึ่งหยุดสร้างความคืบหน้า app-server ก่อนเกิดเหตุการณ์สิ้นสุด
    • ส่งคืนเพย์โหลด + เมตาดาตาการใช้งาน
  4. subscribeEmbeddedAgentSession เชื่อมเหตุการณ์รันไทม์เอเจนต์ไปยังสตรีม agent ของ OpenClaw:
    • เหตุการณ์เครื่องมือ => stream: "tool"
    • เดลตาของผู้ช่วย => stream: "assistant"
    • เหตุการณ์วงจรชีวิต => stream: "lifecycle" (phase: "start" | "end" | "error")
  5. agent.wait ใช้ waitForAgentRun:
    • รอ lifecycle end/error สำหรับ runId
    • ส่งคืน { status: ok|error|timeout, startedAt, endedAt, error? }

การเข้าคิว + ภาวะพร้อมกัน

  • การรันถูกจัดลำดับต่อคีย์เซสชัน (เลนเซสชัน) และอาจผ่านเลนส่วนกลางด้วย
  • สิ่งนี้ป้องกันการแข่งขันของเครื่องมือ/เซสชัน และรักษาประวัติเซสชันให้สอดคล้องกัน
  • ช่องทางรับส่งข้อความสามารถเลือกโหมดคิว (steer/followup/collect/interrupt) ที่ป้อนเข้าสู่ระบบเลนนี้ ดู คิวคำสั่ง
  • การเขียนทรานสคริปต์ยังได้รับการป้องกันด้วยล็อกการเขียนเซสชันบนไฟล์เซสชัน ล็อกนี้ รับรู้กระบวนการและอิงไฟล์ จึงจับตัวเขียนที่ข้ามคิวภายในกระบวนการหรือมาจาก กระบวนการอื่นได้ ตัวเขียนทรานสคริปต์เซสชันรอได้สูงสุด session.writeLock.acquireTimeoutMs ก่อนรายงานว่าเซสชันไม่ว่าง ค่าเริ่มต้นคือ 60000 มิลลิวินาที
  • ล็อกการเขียนเซสชันไม่เป็นแบบ reentrant โดยค่าเริ่มต้น หากตัวช่วยตั้งใจซ้อนการยึด ล็อกเดียวกันโดยยังรักษาตัวเขียนเชิงตรรกะหนึ่งตัวไว้ จะต้องเลือกใช้โดยชัดเจนด้วย allowReentrant: true

การเตรียมเซสชัน + เวิร์กสเปซ

  • เวิร์กสเปซถูกแก้ไขและสร้างขึ้น การรันแบบ sandbox อาจเปลี่ยนเส้นทางไปยังรากเวิร์กสเปซ sandbox
  • Skills ถูกโหลด (หรือนำกลับมาใช้จากสแนปช็อต) และฉีดเข้า env และ prompt
  • ไฟล์ bootstrap/context ถูกแก้ไขและฉีดเข้าในรายงาน system prompt
  • มีการยึดล็อกการเขียนเซสชัน จากนั้นเปิดและเตรียม SessionManager ก่อนเริ่มสตรีม เส้นทาง การเขียนทรานสคริปต์ใหม่ การทำ Compaction หรือการตัดทอนในภายหลัง ต้องใช้ล็อกเดียวกันก่อนเปิดหรือ เปลี่ยนแปลงไฟล์ทรานสคริปต์

การประกอบ prompt + system prompt

  • system prompt ถูกสร้างจาก prompt พื้นฐานของ OpenClaw, prompt ของ Skills, บริบท bootstrap และการแทนที่รายรัน
  • บังคับใช้ขีดจำกัดเฉพาะโมเดลและโทเค็นสำรองสำหรับ Compaction
  • ดู System prompt เพื่อดูว่าโมเดลเห็นอะไร

จุด hook (ตำแหน่งที่คุณดักแทรกได้)

OpenClaw มีระบบ hook สองแบบ:

  • hook ภายใน (hook ของ Gateway): สคริปต์ขับเคลื่อนด้วยเหตุการณ์สำหรับคำสั่งและเหตุการณ์วงจรชีวิต
  • hook ของ Plugin: จุดขยายภายในวงจรชีวิตเอเจนต์/เครื่องมือและ pipeline ของ gateway

hook ภายใน (hook ของ Gateway)

  • agent:bootstrap: รันขณะสร้างไฟล์ bootstrap ก่อนสรุป system prompt ใช้สิ่งนี้เพื่อเพิ่ม/ลบไฟล์บริบท bootstrap
  • hook คำสั่ง: /new, /reset, /stop และเหตุการณ์คำสั่งอื่นๆ (ดูเอกสาร Hooks)

ดู Hooks สำหรับการตั้งค่าและตัวอย่าง

hook ของ Plugin (วงจรชีวิตเอเจนต์ + gateway)

สิ่งเหล่านี้รันภายในลูปเอเจนต์หรือ pipeline ของ gateway:

  • before_model_resolve: รันก่อนเซสชัน (ไม่มี messages) เพื่อแทนที่ provider/model อย่างกำหนดได้แน่นอนก่อนการแก้ไขโมเดล
  • before_prompt_build: รันหลังโหลดเซสชัน (พร้อม messages) เพื่อฉีด prependContext, systemPrompt, prependSystemContext หรือ appendSystemContext ก่อนส่ง prompt ใช้ prependContext สำหรับข้อความไดนามิกต่อเทิร์น และใช้ฟิลด์ system-context สำหรับคำแนะนำคงที่ที่ควรอยู่ในพื้นที่ system prompt
  • before_agent_start: hook ความเข้ากันได้แบบเดิมที่อาจรันในเฟสใดเฟสหนึ่ง ควรใช้ hook แบบชัดเจนด้านบน
  • before_agent_reply: รันหลังการกระทำแบบ inline และก่อนการเรียก LLM ช่วยให้ Plugin รับเทิร์นนี้และส่งคืนคำตอบสังเคราะห์หรือปิดเสียงเทิร์นทั้งหมด
  • agent_end: ตรวจสอบรายการข้อความสุดท้ายและเมตาดาตาการรันหลังเสร็จสิ้น
  • before_compaction / after_compaction: สังเกตหรือใส่หมายเหตุรอบการทำ Compaction
  • before_tool_call / after_tool_call: ดักพารามิเตอร์/ผลลัพธ์ของเครื่องมือ
  • before_install: ตรวจสอบวัสดุการติดตั้ง skill หรือ Plugin ที่จัดเตรียมแล้ว หลังนโยบายติดตั้งของผู้ปฏิบัติการรัน เมื่อ hook ของ Plugin ถูกโหลดในกระบวนการ OpenClaw ปัจจุบัน
  • tool_result_persist: แปลงผลลัพธ์เครื่องมือแบบซิงโครนัสก่อนเขียนลงในทรานสคริปต์เซสชันที่ OpenClaw เป็นเจ้าของ
  • message_received / message_sending / message_sent: hook ข้อความขาเข้า + ขาออก
  • session_start / session_end: ขอบเขตวงจรชีวิตเซสชัน
  • gateway_start / gateway_stop: เหตุการณ์วงจรชีวิต gateway

กฎการตัดสินใจของ hook สำหรับตัวกันขาออก/เครื่องมือ:

  • before_tool_call: { block: true } เป็นสถานะสิ้นสุดและหยุด handler ที่มีลำดับความสำคัญต่ำกว่า
  • before_tool_call: { block: false } เป็น no-op และไม่ล้างการบล็อกก่อนหน้า
  • before_install: { block: true } เป็นสถานะสิ้นสุดและหยุด handler ที่มีลำดับความสำคัญต่ำกว่า
  • before_install: { block: false } เป็น no-op และไม่ล้างการบล็อกก่อนหน้า
  • ใช้ security.installPolicy ไม่ใช่ before_install สำหรับการตัดสินใจอนุญาต/บล็อกการติดตั้งที่ผู้ปฏิบัติการเป็นเจ้าของ ซึ่งต้องครอบคลุมเส้นทางการติดตั้งและอัปเดตผ่าน CLI
  • message_sending: { cancel: true } เป็นสถานะสิ้นสุดและหยุด handler ที่มีลำดับความสำคัญต่ำกว่า
  • message_sending: { cancel: false } เป็น no-op และไม่ล้างการยกเลิกก่อนหน้า

ดู hook ของ Plugin สำหรับ API ของ hook และรายละเอียดการลงทะเบียน

harness อาจปรับ hook เหล่านี้แตกต่างกัน harness app-server ของ Codex รักษา hook ของ Plugin OpenClaw เป็นสัญญาความเข้ากันได้สำหรับพื้นผิว mirror ที่จัดทำเอกสารไว้ ขณะที่ hook native ของ Codex ยังคงเป็นกลไก Codex ระดับต่ำกว่าแยกต่างหาก

การสตรีม + คำตอบบางส่วน

  • เดลตาของผู้ช่วยถูกสตรีมจากรันไทม์เอเจนต์และปล่อยเป็นเหตุการณ์ assistant
  • การสตรีมบล็อกสามารถปล่อยคำตอบบางส่วนได้ทั้งที่ text_end หรือ message_end
  • การสตรีม reasoning สามารถปล่อยเป็นสตรีมแยกหรือเป็นคำตอบแบบบล็อกได้
  • ดู การสตรีม สำหรับพฤติกรรมการแบ่งชิ้นและคำตอบแบบบล็อก

การเรียกใช้เครื่องมือ + เครื่องมือรับส่งข้อความ

  • เหตุการณ์เริ่ม/อัปเดต/จบของเครื่องมือถูกปล่อยบนสตรีม tool
  • ผลลัพธ์เครื่องมือถูกทำให้ปลอดภัยด้านขนาดและเพย์โหลดรูปภาพก่อนบันทึก/ปล่อยเหตุการณ์
  • การส่งผ่านเครื่องมือรับส่งข้อความถูกติดตามเพื่อระงับการยืนยันของผู้ช่วยที่ซ้ำกัน

การจัดรูปคำตอบ + การระงับ

  • เพย์โหลดสุดท้ายถูกประกอบจาก:
    • ข้อความผู้ช่วย (และ reasoning ที่เป็นทางเลือก)
    • สรุปเครื่องมือแบบ inline (เมื่อ verbose + อนุญาต)
    • ข้อความข้อผิดพลาดของผู้ช่วยเมื่อโมเดลเกิดข้อผิดพลาด
  • โทเค็นเงียบที่ตรงตัว NO_REPLY / no_reply ถูกกรองออกจากเพย์โหลด ขาออก
  • รายการซ้ำจากเครื่องมือรับส่งข้อความถูกลบออกจากรายการเพย์โหลดสุดท้าย
  • หากไม่มีเพย์โหลดที่เรนเดอร์ได้เหลืออยู่และเครื่องมือเกิดข้อผิดพลาด จะปล่อยคำตอบข้อผิดพลาดเครื่องมือสำรอง (เว้นแต่เครื่องมือรับส่งข้อความได้ส่งคำตอบที่ผู้ใช้เห็นได้ไปแล้ว)

Compaction + การลองใหม่

  • Auto-compaction ปล่อยเหตุการณ์สตรีม compaction และสามารถกระตุ้นการลองใหม่
  • เมื่อลองใหม่ บัฟเฟอร์ในหน่วยความจำและสรุปเครื่องมือจะถูกรีเซ็ตเพื่อหลีกเลี่ยงผลลัพธ์ซ้ำ
  • ดู Compaction สำหรับ pipeline ของ Compaction

สตรีมเหตุการณ์ (ปัจจุบัน)

  • lifecycle: ปล่อยโดย subscribeEmbeddedAgentSession (และเป็น fallback โดย agentCommand)
  • assistant: เดลตาที่สตรีมจากรันไทม์เอเจนต์
  • tool: เหตุการณ์เครื่องมือที่สตรีมจากรันไทม์เอเจนต์

การจัดการช่องแชต

  • เดลตาของผู้ช่วยถูกบัฟเฟอร์เป็นข้อความ delta ของแชต
  • ปล่อย final ของแชตเมื่อเกิด lifecycle end/error

Timeout

  • ค่าเริ่มต้นของ agent.wait: 30 วินาที (เฉพาะการรอ) พารามิเตอร์ timeoutMs จะแทนที่
  • รันไทม์เอเจนต์: ค่าเริ่มต้นของ agents.defaults.timeoutSeconds คือ 172800 วินาที (48 ชั่วโมง); บังคับใช้ในตัวจับเวลา abort ของ runEmbeddedAgent
  • รันไทม์ Cron: timeoutSeconds ของ agent-turn ที่แยกโดดเดี่ยวเป็นของ cron ตัว scheduler เริ่มตัวจับเวลานั้นเมื่อการดำเนินการเริ่มขึ้น ยกเลิกการรันพื้นฐานเมื่อถึงกำหนดเวลาที่กำหนดค่าไว้ จากนั้นรันการล้างข้อมูลแบบมีขอบเขตก่อนบันทึก timeout เพื่อไม่ให้เซสชันลูกค้างเก่าทำให้เลนติดค้าง
  • การวินิจฉัยความมีชีวิตของเซสชัน: เมื่อเปิดใช้ diagnostics, diagnostics.stuckSessionWarnMs จะจัดประเภทเซสชัน processing ที่ใช้เวลานานและไม่มี reply, tool, status, block หรือความคืบหน้า ACP ที่สังเกตได้ การรันแบบฝัง การเรียกโมเดล และการเรียกเครื่องมือที่ active จะรายงานเป็น session.long_running; การเรียกโมเดลแบบเงียบที่มีเจ้าของยังคงเป็น session.long_running จนถึง diagnostics.stuckSessionAbortMs เพื่อไม่ให้ provider ที่ช้าหรือไม่สตรีมถูกรายงานว่าค้างเร็วเกินไป งานที่ active แต่ไม่มีความคืบหน้าล่าสุดจะรายงานเป็น session.stalled; การเรียกโมเดลที่มีเจ้าของจะเปลี่ยนเป็น session.stalled เมื่อถึงหรือหลังเกณฑ์ abort และกิจกรรมโมเดล/เครื่องมือเก่าที่ไม่มีเจ้าของจะไม่ถูกซ่อนไว้ในฐานะ long-running session.stuck สงวนไว้สำหรับการทำบัญชีเซสชันเก่าที่กู้คืนได้ รวมถึงเซสชันที่อยู่ในคิวและ idle พร้อมกิจกรรมโมเดล/เครื่องมือเก่าที่ไม่มีเจ้าของ การทำบัญชีเซสชันเก่าจะปล่อยเลนเซสชันที่ได้รับผลกระทบทันทีหลังผ่าน recovery gate; การรันแบบฝังที่ stalled จะถูก abort-drain หลัง diagnostics.stuckSessionAbortMs เท่านั้น (ค่าเริ่มต้น: อย่างน้อย 5 นาทีและ 3 เท่าของเกณฑ์เตือน) เพื่อให้งานที่เข้าคิวกลับมาทำงานต่อได้โดยไม่ตัดการรันที่เพียงแค่ช้าออก การกู้คืนปล่อยผลลัพธ์ requested/completed แบบมีโครงสร้าง และสถานะ diagnostic จะถูกทำเครื่องหมาย idle เฉพาะเมื่อ generation การประมวลผลเดียวกันยังเป็นปัจจุบันอยู่ diagnostic session.stuck ที่เกิดซ้ำจะ back off ขณะที่เซสชันยังไม่เปลี่ยนแปลง
  • Timeout ขณะโมเดล idle: OpenClaw ยกเลิกคำขอโมเดลเมื่อไม่มีชิ้นส่วนคำตอบมาถึงก่อนครบหน้าต่าง idle models.providers.<id>.timeoutSeconds ขยายตัวเฝ้าระวัง idle นี้สำหรับ provider ในเครื่อง/โฮสต์เองที่ช้า แต่ยังถูกจำกัดโดย agents.defaults.timeoutSeconds หรือ timeout เฉพาะการรันที่ต่ำกว่า เพราะสิ่งเหล่านั้นควบคุมการรันเอเจนต์ทั้งหมด มิฉะนั้น OpenClaw ใช้ agents.defaults.timeoutSeconds เมื่อกำหนดค่าไว้ โดยจำกัดไว้ที่ 120 วินาทีตามค่าเริ่มต้น การรันโมเดลบนคลาวด์ที่ถูก Cron กระตุ้นโดยไม่มี timeout ของโมเดลหรือเอเจนต์แบบชัดเจนจะใช้ตัวเฝ้าระวัง idle ค่าเริ่มต้นเดียวกัน; เมื่อมี timeout การรัน cron แบบชัดเจน การค้างของสตรีมโมเดลบนคลาวด์จะถูกจำกัดที่ 60 วินาที เพื่อให้ model fallback ที่กำหนดค่าไว้รันได้ก่อนกำหนดเวลาภายนอกของ cron การรันโมเดลในเครื่องหรือโฮสต์เองที่ถูก Cron กระตุ้นจะปิดใช้ตัวเฝ้าระวังโดยนัย เว้นแต่กำหนดค่า timeout แบบชัดเจนไว้ และ timeout การรัน cron แบบชัดเจนยังคงเป็นหน้าต่าง idle สำหรับ provider ในเครื่อง/โฮสต์เอง ดังนั้น provider ในเครื่องที่ช้าควรตั้ง models.providers.<id>.timeoutSeconds
  • Timeout คำขอ HTTP ของ provider: models.providers.<id>.timeoutSeconds ใช้กับการ fetch HTTP ของโมเดลของ provider นั้น รวมถึง connect, headers, body, timeout คำขอ SDK, การจัดการ abort ของ guarded-fetch ทั้งหมด และตัวเฝ้าระวัง idle ของสตรีมโมเดล ใช้สิ่งนี้สำหรับ provider ในเครื่อง/โฮสต์เองที่ช้า เช่น Ollama ก่อนเพิ่ม timeout ของรันไทม์เอเจนต์ทั้งหมด และคง timeout ของเอเจนต์/รันไทม์ให้สูงอย่างน้อยเท่ากันเมื่อคำขอโมเดลต้องรันนานขึ้น

ตำแหน่งที่สิ่งต่างๆ อาจจบก่อนกำหนด

  • หมดเวลาของเอเจนต์ (ยกเลิก)
  • AbortSignal (ยกเลิก)
  • Gateway ตัดการเชื่อมต่อหรือ RPC หมดเวลา
  • หมดเวลา agent.wait (รอเท่านั้น ไม่หยุดเอเจนต์)

ที่เกี่ยวข้อง

  • เครื่องมือ — เครื่องมือเอเจนต์ที่มีให้ใช้
  • Hooks — สคริปต์ที่ขับเคลื่อนด้วยเหตุการณ์ ซึ่งถูกทริกเกอร์โดยเหตุการณ์ในวงจรชีวิตของเอเจนต์
  • Compaction — วิธีสรุปการสนทนาที่ยาว
  • การอนุมัติ Exec — จุดควบคุมการอนุมัติสำหรับคำสั่งเชลล์
  • การคิด — การกำหนดค่าระดับการคิด/การให้เหตุผล
Was this useful?
On this page

On this page