Technical reference

เจาะลึกการจัดการเซสชัน

กระบวนการ Gateway เพียงกระบวนการเดียว เป็นเจ้าของสถานะเซสชันตั้งแต่ต้นจนจบ UI ต่างๆ (แอป macOS, Control UI บนเว็บ, TUI) จะสอบถามรายการเซสชันและจำนวนโทเค็นจาก Gateway ในโหมดระยะไกล ไฟล์เซสชันจะอยู่บนโฮสต์ระยะไกล ดังนั้นการตรวจสอบไฟล์ใน Mac เครื่องของคุณจะไม่สะท้อนสิ่งที่ Gateway กำลังใช้งาน

เริ่มจากเอกสารภาพรวม: การจัดการเซสชัน, Compaction, ภาพรวมหน่วยความจำ, การค้นหาหน่วยความจำ, การตัดแต่งเซสชัน, การดูแลความสะอาดของบันทึกบทสนทนา, และข้อมูลอ้างอิงการกำหนดค่าฉบับเต็มที่ การกำหนดค่าเอเจนต์

ชั้นการจัดเก็บถาวรสองชั้น

  1. แถวเซสชัน (SQLite ต่อเอเจนต์) - แมปคีย์/ค่า sessionKey -> SessionEntry สถานะรันไทม์ที่เปลี่ยนแปลงได้ซึ่ง Gateway เป็นเจ้าของ ติดตามเมทาดาทา ได้แก่ ID เซสชันปัจจุบัน กิจกรรมล่าสุด ตัวเลือกเปิด/ปิด ตัวนับโทเค็น
  2. เหตุการณ์บันทึกบทสนทนา (SQLite ต่อเอเจนต์) - เพิ่มต่อท้ายเท่านั้นและมีโครงสร้างแบบต้นไม้ (รายการมี id + parentId) จัดเก็บบทสนทนา การเรียกใช้เครื่องมือ และสรุป Compaction รวมถึงสร้างบริบทโมเดลขึ้นใหม่สำหรับรอบถัดไป จุดตรวจสอบ Compaction เป็นเมทาดาทาที่ครอบทับบันทึกบทสนทนาตัวสืบทอดซึ่งผ่านการ Compaction แล้ว การ Compaction ครั้งใหม่จะไม่เขียนสำเนา .checkpoint.*.jsonl ชุดที่สอง

การติดตั้งรุ่นเก่าอาจยังมีไฟล์ sessions.json อยู่ภายใต้ไดเรกทอรี sessions/ ของเอเจนต์ ให้ถือว่าไฟล์เหล่านั้นเป็นอินพุตสำหรับการย้ายแถวเซสชันแบบเดิมหรือเป็น เป้าหมายการบำรุงรักษาแบบออฟไลน์อย่างชัดเจน การเริ่มต้น Gateway และ openclaw doctor --fix จะนำเข้าแถวเดิมที่ใช้งานอยู่และประวัติบันทึกบทสนทนาไปยังที่เก็บ SQLite ต่อเอเจนต์ โดยอัตโนมัติ เรียกใช้ openclaw doctor --session-sqlite inspect --session-sqlite-all-agents แล้วทำตามลำดับการย้ายข้อมูลของ Doctor เมื่อต้องการหลักฐานการตรวจสอบ หรือการยืนยันอย่างชัดเจน หากการย้ายข้อมูลล้มเหลวหลังจากเก็บอาร์ติแฟกต์บันทึกบทสนทนา แบบเดิมเข้าคลังแล้ว ให้ใช้โหมดกู้คืนของ Doctor จากลำดับดังกล่าว การกู้คืนจะใช้ไฟล์รายการการย้ายข้อมูล คืนค่าเฉพาะอาร์ติแฟกต์สนับสนุนที่เก็บถาวร และได้รับผลกระทบ จัดเตรียมรายงานปัญหา GitHub ที่ผ่านการล้างข้อมูลเมื่อมีการร้องขอ และไม่ทำให้รันไทม์ที่ใช้งานอยู่กลับมาอ่านไฟล์ JSONL อีกครั้ง

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

ตำแหน่งบนดิสก์

สำหรับแต่ละเอเจนต์ บนโฮสต์ Gateway (แก้ไขตำแหน่งผ่าน src/config/sessions.ts):

  • ที่เก็บแถวเซสชันรันไทม์: ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite
  • แถวบันทึกบทสนทนารันไทม์: ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite
  • อาร์ติแฟกต์บันทึกบทสนทนาแบบเดิม/ที่เก็บถาวร: ~/.openclaw/agents/<agentId>/sessions/
  • อินพุตการย้ายแถวแบบเดิม: ~/.openclaw/agents/<agentId>/sessions/sessions.json

การบำรุงรักษาที่เก็บและการควบคุมดิสก์

session.maintenance ควบคุมการบำรุงรักษาอัตโนมัติสำหรับแถวเซสชัน SQLite แถวบันทึกบทสนทนา SQLite อาร์ติแฟกต์ที่เก็บถาวร และไฟล์ประกอบวิถีการทำงาน:

คีย์ ค่าเริ่มต้น หมายเหตุ
mode "enforce" หรือ "warn" (รายงานเท่านั้น ไม่มีการแก้ไข)
pruneAfter "30d" เกณฑ์อายุของรายการที่ล้าสมัย
maxEntries 500 ขีดจำกัดจำนวนรายการเซสชัน
resetArchiveRetention เก็บไว้ (ไม่มีเกณฑ์อายุ) เกณฑ์อายุสำหรับคลังบันทึกบทสนทนา *.reset.*/*.deleted.*; การระบุระยะเวลาจะเปิดใช้การลบ
maxDiskBytes 10gb งบประมาณดิสก์สำหรับเซสชันต่อเอเจนต์; false ปิดใช้งาน
highWaterBytes 80% ของ maxDiskBytes เป้าหมายหลังการล้างข้อมูลตามงบประมาณ

การรีเซ็ตจะเลื่อนแมปปิง sessionKey -> sessionId ที่ใช้งานอยู่ไปข้างหน้า แต่เก็บเซสชัน บันทึกบทสนทนา วิถีการทำงาน และแถวการค้นหา SQLite ก่อนหน้าไว้ ประวัตินั้นยังคงค้นหาได้ภายใต้คีย์เซสชันเดิม รายการทั่วไปของรายการและเซสชันจะแสดงเฉพาะแมปปิงใหม่ที่ใช้งานอยู่ ประวัติการรีเซ็ตที่เก็บไว้จะถูกจำกัดด้วยงบประมาณดิสก์ ไม่ใช่ resetArchiveRetention ซึ่งกำหนดอายุเฉพาะอาร์ติแฟกต์ที่เก็บถาวรเท่านั้น การลบอย่างชัดเจนแตกต่างออกไป โดยจะเขียนและตรวจสอบคลังบันทึกบทสนทนาแบบบีบอัด (*.jsonl.deleted.<timestamp>.zst เมื่อมี zstd) ก่อนลบแถวของเซสชันที่ถูกลบ

การบังคับใช้ maxDiskBytes ใช้จำนวนไบต์จริง ได้แก่ ไฟล์หลัก SQLite ต่อเอเจนต์ ไฟล์ -wal ของไฟล์ดังกล่าว และไฟล์ที่นับรวมในไดเรกทอรีเซสชันของเอเจนต์ ระบบจะไม่ประเมินขนาด JSON ของแถวหรือหักขนาดเชิงตรรกะของแถวออกจากยอดรวมนั้น

เซสชันตรวจสอบการรันโมเดลของ Gateway (คีย์ที่ตรงกับ agent:*:explicit:model-run-<uuid>) มีระยะเวลาการเก็บรักษา 24h แบบคงที่แยกต่างหาก การตัดแต่งนี้จะทำงานเมื่อมีแรงกดดันเท่านั้น กล่าวคือจะทำงานเฉพาะเมื่อถึงจุดที่ต้องบำรุงรักษา/จำกัดรายการเซสชัน และเฉพาะก่อนขั้นตอนล้างข้อมูล/จำกัดรายการล้าสมัยทั่วระบบ เซสชันแบบชัดเจนอื่นๆ จะไม่ใช้ระยะเวลาการเก็บรักษานี้

เมื่อการใช้งานจริงรวมเกิน maxDiskBytes ขั้นตอน mode: "enforce" จะเรียกคืนพื้นที่ฐานข้อมูลที่สร้างจุดตรวจสอบได้ก่อน จากนั้นจึงลบคลังการรีเซ็ต/การลบที่เก็บไว้ซึ่งเก่าที่สุด หากการใช้งานยังสูงกว่า highWaterBytes ระบบจะไล่ตรวจเซสชัน SQLite ในอดีตตาม sessions.updated_at โดยเริ่มจากรายการเก่าที่สุด “ในอดีต” หมายถึง ID เซสชันไม่ได้ถูกอ้างอิงโดยรายการเซสชันที่ใช้งานอยู่ เป้าหมายเส้นทาง หรือการรันที่รับแล้ว/กำลังดำเนินการ สำหรับแต่ละรายการเป้าหมาย การล้างข้อมูลจะเขียน เรียก fsync และอ่านคลังแบบบีบอัดกลับมาตรวจสอบ ก่อนที่ธุรกรรมการเขียนจะลบแถวเซสชันและการฉายภาพบันทึกบทสนทนา วิถีการทำงาน สถานะใช้งาน ดัชนี และ FTS ของเซสชันนั้น ซึ่งรวมถึงเซสชันที่มีเหตุการณ์วิถีการทำงานแต่ไม่มีเหตุการณ์บันทึกบทสนทนา การล้างข้อมูลจะตรวจสอบการอ้างอิงเส้นทาง รายการ และการรับงานอีกครั้งขณะลบ วัดการใช้งานจริงใหม่หลังจากลบคลังหรือเซสชันเป้าหมายแต่ละรายการ และหยุดที่ highWaterBytes

การเขียนที่ยืนยันแล้วและการลบจะลงใน WAL ก่อน การล้างข้อมูลจะสร้างจุดตรวจสอบเพื่อให้ WAL ย่อขนาดได้ทันที จากนั้นใช้ incremental vacuum เพื่อคืนหน้าส่วนท้ายที่ว่างและมีสิทธิ์เรียกคืนจากไฟล์หลัก หน้าที่ยังเรียกคืนไม่ได้จะคงอยู่ในไฟล์หลักและจึงยังถูกนับในการวัดจริงครั้งถัดไป mode: "warn" รายงานปริมาณจริงที่เกินอยู่ในปัจจุบันโดยไม่สร้างจุดตรวจสอบ ไม่เขียนคลัง และไม่ลบแถว

เรียกใช้การบำรุงรักษาเมื่อต้องการ:

bash
openclaw sessions cleanup --dry-runopenclaw sessions cleanup --enforce

การบำรุงรักษาจะเก็บตัวชี้บทสนทนาภายนอกที่คงทน เช่น เซสชันกลุ่มและเซสชันแชตที่จำกัดขอบเขตตามเธรด แต่รายการรันไทม์สังเคราะห์ (cron, hooks, heartbeat, ACP, เอเจนต์ย่อย) ยังสามารถถูกลบได้เมื่อเกินอายุ จำนวน หรืองบประมาณดิสก์ที่กำหนด การรัน cron แบบแยกใช้การควบคุม cron.sessionRetention แยกต่างหาก โดยไม่ขึ้นกับระยะเวลาการเก็บรักษาของเซสชันตรวจสอบการรันโมเดล

การเขียนปกติของ Gateway จะไหลผ่านตัวเข้าถึงเซสชัน ซึ่งจัดลำดับการแก้ไข SQLite ต่อเอเจนต์ผ่านเส้นทางตัวเขียนรันไทม์ โค้ดรันไทม์ควรใช้ตัวช่วยของตัวเข้าถึงใน src/config/sessions/session-accessor.ts เป็นหลัก ส่วนตัวช่วย sessions.json แบบเดิมเป็นเครื่องมือสำหรับการย้ายข้อมูลและการบำรุงรักษาแบบออฟไลน์ เมื่อเข้าถึง Gateway ได้ openclaw sessions cleanup และ openclaw agents delete ที่ไม่ใช่การทดลองทำงานจะมอบหมายการแก้ไขที่เก็บให้ Gateway เพื่อให้การล้างข้อมูลเข้าร่วมคิวตัวเขียนเดียวกัน ส่วน --store <path> เป็นเส้นทางซ่อมแซมแบบออฟไลน์ที่ชัดเจนสำหรับที่เก็บแบบเดิมที่เลือกและจะทำงานในเครื่องเสมอ (เช่นเดียวกับ --dry-run) การล้างข้อมูล maxEntries จะแบ่งเป็นชุดสำหรับที่เก็บขนาดระดับโปรดักชัน ดังนั้นที่เก็บอาจเกินขีดจำกัดที่กำหนดชั่วครู่ก่อนที่การล้างข้อมูลเมื่อถึงค่าสูงสุดครั้งถัดไปจะเขียนใหม่ให้ลดลง การอ่านจะไม่ตัดแต่งหรือจำกัดรายการระหว่างการเริ่มต้น Gateway การดำเนินการดังกล่าวทำได้เฉพาะการเขียนหรือ openclaw sessions cleanup --enforce เท่านั้น โดยอย่างหลังจะบังคับใช้ขีดจำกัดทันที และตัดแต่งอาร์ติแฟกต์บันทึกบทสนทนา จุดตรวจสอบ และวิถีการทำงานแบบเดิมที่เก่าและไม่มีการอ้างอิง แม้ไม่ได้กำหนดงบประมาณดิสก์ไว้

OpenClaw จะไม่สร้างข้อมูลสำรองหมุนเวียน sessions.json.bak.* โดยอัตโนมัติระหว่างการเขียนของ Gateway อีกต่อไป สคีมาปัจจุบันปฏิเสธคีย์ session.maintenance.rotateBytes แบบเดิม และ openclaw doctor --fix จะลบคีย์ดังกล่าวออกจากการกำหนดค่ารุ่นเก่า

การแก้ไขบันทึกบทสนทนาใช้คิวการเขียนเซสชันสำหรับเป้าหมายบันทึกบทสนทนา SQLite:

การล็อกการเขียนเซสชันใช้ค่าเริ่มต้นแบบคงที่สำหรับโปรดักชัน ตัวแปรสภาพแวดล้อม OPENCLAW_SESSION_WRITE_LOCK_* ที่เกี่ยวข้องยังคงพร้อมใช้งานสำหรับ การวินิจฉัยระดับกระบวนการและการแทนที่ในกรณีฉุกเฉิน

การดาวน์เกรดหลังเปลี่ยนมาใช้ SQLite

คืนค่าอาร์ติแฟกต์บันทึกบทสนทนาแบบเดิมที่เก็บถาวรก่อนเรียกใช้ OpenClaw รุ่นเก่าที่ใช้ไฟล์เป็นที่เก็บ:

bash
openclaw doctor --session-sqlite restore --session-sqlite-all-agents

การย้ายข้อมูลจะคงไฟล์ sessions.json แบบเดิมไว้เพื่อการสนับสนุนและ การย้อนกลับ แต่ไฟล์ JSONL บันทึกบทสนทนาที่ใช้งานอยู่ซึ่งนำเข้า SQLite แล้วจะถูก เปลี่ยนชื่อไปไว้ใน session-sqlite-import-archive/ รันไทม์รุ่นเก่าที่ใช้ไฟล์เป็นที่เก็บจะติดตาม พาธ sessionFile ใน sessions.json จึงต้องคืนค่าอาร์ติแฟกต์เหล่านั้น ก่อนเริ่มต้น การคืนค่าใช้ไฟล์รายการการย้ายข้อมูล ย้ายเฉพาะอาร์ติแฟกต์ที่เก็บถาวร ซึ่งมีการบันทึกไว้และพาธเดิมหายไป และคงฐานข้อมูล SQLite ไว้ สำหรับการกู้คืนไปข้างหน้า

เซสชันที่สร้างหลังเปลี่ยนมาใช้ SQLite จะอยู่ใน SQLite เท่านั้นและจะไม่ปรากฏต่อ รันไทม์รุ่นเก่าที่ใช้ไฟล์เป็นที่เก็บ หากอัปเกรดอีกครั้งหลังดาวน์เกรด ให้เรียกใช้ลำดับ การตรวจสอบและการยืนยันของ Doctor อีกครั้ง เพื่อให้ OpenClaw สามารถตรวจสอบ อาร์ติแฟกต์แบบเดิมที่คืนค่าแล้วก่อนนำเข้า

เซสชัน Cron และบันทึกการรัน

การรัน cron แบบแยกจะสร้างรายการเซสชัน/บันทึกบทสนทนาของตนเองพร้อมระยะเวลาการเก็บรักษาเฉพาะ:

  • cron.sessionRetention (ค่าเริ่มต้น "24h") จะตัดแต่งเซสชันการรัน cron แบบแยกที่เก่าออกจากที่เก็บ; false ปิดใช้งาน
  • ประวัติการรันจะเก็บแถวสถานะสิ้นสุดล่าสุด 2000 แถวต่องาน cron แถวที่สูญหายยังคงมีช่วงเวลาล้างข้อมูล 24 ชั่วโมง

เมื่อ cron บังคับสร้างเซสชันการรันแบบแยกใหม่ ระบบจะล้างข้อมูลรายการเซสชัน cron:<jobId> ก่อนหน้าก่อนเขียนแถวใหม่ โดยจะนำค่ากำหนดที่ปลอดภัยติดไปด้วย (การตั้งค่าการคิด/เร็ว/ละเอียด/การให้เหตุผล ป้ายกำกับ ชื่อที่แสดง) และการแทนที่โมเดล/การยืนยันตัวตนที่ผู้ใช้เลือกอย่างชัดเจน แต่จะตัดบริบทบทสนทนาแวดล้อมออก (การกำหนดเส้นทางช่องทาง/กลุ่ม นโยบายการส่ง/คิว การยกระดับ สิ่งที่มา การผูกกับรันไทม์ ACP) เพื่อให้การรันแบบแยกครั้งใหม่ไม่สามารถสืบทอดสิทธิ์การส่งหรือรันไทม์ที่ล้าสมัยจากการรันครั้งเก่า

คีย์เซสชัน (sessionKey)

sessionKey ระบุว่าคุณอยู่ในบักเก็ตบทสนทนาใด (การกำหนดเส้นทาง + การแยก) กฎมาตรฐาน: /concepts/session

รูปแบบ ตัวอย่าง
แชตหลัก/โดยตรง (ต่อเอเจนต์) agent:<agentId>:<mainKey> (ค่าเริ่มต้น main)
กลุ่ม agent:<agentId>:<channel>:group:<id>
ห้อง/ช่องทาง (Discord/Slack) agent:<agentId>:<channel>:channel:<id> หรือ ...:room:<id>
Cron cron:<job.id>
Webhook hook:<uuid> (เว้นแต่ถูกแทนที่)

ID เซสชัน (sessionId)

sessionKey แต่ละรายการชี้ไปยัง sessionId ปัจจุบัน (ข้อมูลประจำตัวบันทึกบทสนทนา SQLite ที่ใช้ดำเนินบทสนทนาต่อ) ตรรกะการตัดสินใจอยู่ใน initSessionState() ภายใน src/auto-reply/reply/session.ts

  • รีเซ็ต (/new, /reset) สร้าง sessionId ใหม่สำหรับ sessionKey นั้น
  • ไม่มีการรีเซ็ตอัตโนมัติ เป็นค่าเริ่มต้น โดย sessionId ปัจจุบันจะดำเนินต่อไป ขณะที่ Compaction ควบคุมบริบทของโมเดลที่ใช้งานอยู่ให้อยู่ภายในขอบเขต
  • รีเซ็ตรายวัน (session.reset.mode: "daily") สร้าง sessionId ใหม่เมื่อมีข้อความถัดไปหลังพ้นขอบเขตชั่วโมงท้องถิ่นที่กำหนดค่าไว้ (session.reset.atHour, ค่าเริ่มต้น 4)
  • การหมดอายุเมื่อไม่มีการใช้งาน (session.reset.mode: "idle" ร่วมกับ session.reset.idleMinutes หรือ session.idleMinutes แบบเดิม) สร้าง sessionId ใหม่เมื่อมีข้อความเข้ามาหลังพ้นช่วงเวลาที่ไม่มีการใช้งาน หากกำหนดค่าทั้งรายวันและเมื่อไม่มีการใช้งาน เงื่อนไขใดหมดอายุก่อนจะมีผล
  • การกลับมาทำงานต่อเมื่อ Control UI เชื่อมต่อใหม่ จะคงเซสชันที่มองเห็นอยู่ในขณะนั้นไว้สำหรับการส่งหนึ่งครั้งหลังเชื่อมต่อใหม่ เมื่อ Gateway ได้รับ sessionId ที่ตรงกันจากไคลเอนต์ UI ของผู้ปฏิบัติงาน นี่เป็นสัญญาณแบบใช้ครั้งเดียว การส่งข้อมูลเก่าตามปกติยังคงสร้าง sessionId ใหม่
  • เหตุการณ์ระบบ (Heartbeat, การปลุกโดย Cron, การแจ้งเตือน exec, งานบันทึกสถานะของ Gateway) อาจเปลี่ยนแปลงแถวเซสชัน แต่จะไม่ยืดอายุความใหม่ของการรีเซ็ตรายวัน/เมื่อไม่มีการใช้งาน เมื่อเปลี่ยนผ่านการรีเซ็ต ระบบจะทิ้งประกาศเหตุการณ์ระบบที่อยู่ในคิวของเซสชันก่อนหน้า ก่อนสร้างพรอมต์ใหม่
  • นโยบายการ fork จากพาเรนต์ ใช้สาขาที่ใช้งานอยู่ของ OpenClaw เมื่อสร้างเธรดหรือ fork ของเอเจนต์ย่อย หากสาขานั้นมีขนาดใหญ่เกินไป (เกินขีดจำกัดภายในคงที่ ซึ่งปัจจุบันคือ 100K โทเค็น) OpenClaw จะเริ่มลูกด้วยบริบทแยกต่างหาก แทนที่จะล้มเหลวหรือสืบทอดประวัติที่ใช้งานไม่ได้ การกำหนดขนาดเป็นไปโดยอัตโนมัติและไม่สามารถกำหนดค่าได้ โดย session.parentForkMaxTokens แบบเดิมจะถูกลบออกโดย openclaw doctor --fix
  • การ fork โดยผู้ปฏิบัติงาน: sessions.create { parentSessionKey, fork: true } สร้างเซสชันใหม่ที่ทรานสคริปต์แตกแขนงจากสถานะปัจจุบันของพาเรนต์ (ใช้กลไก fork เดียวกับการสร้างเอเจนต์ย่อย รวมถึงขีดจำกัดขนาดข้างต้น) ระบบจะปฏิเสธการ fork ขณะที่พาเรนต์มีการรันที่ใช้งานอยู่ สืบทอดการเลือกโมเดลของพาเรนต์ เว้นแต่จะส่งค่าเข้ามาอย่างชัดเจน และทำเครื่องหมาย forkedFromParent ของลูกพร้อมตัวนับโทเค็นใหม่

สคีมาของที่เก็บเซสชัน

ที่เก็บรันไทม์เก็บค่า SessionEntry ไว้ใน SQLite แยกตามเอเจนต์ ชนิดของค่าคือ SessionEntry ใน src/config/sessions.ts ฟิลด์สำคัญ (ไม่ใช่รายการทั้งหมด):

  • sessionId: ID ทรานสคริปต์ปัจจุบันที่ใช้ระบุแถวทรานสคริปต์ใน SQLite
  • sessionStartedAt: เวลาประทับเริ่มต้นของ sessionId ปัจจุบัน ซึ่งใช้ตรวจสอบความใหม่ของการรีเซ็ตรายวัน แถวแบบเดิมอาจอนุมานค่านี้จากส่วนหัวเซสชัน JSONL
  • lastInteractionAt: เวลาประทับของการโต้ตอบจริงล่าสุดจากผู้ใช้/ช่องทาง ซึ่งใช้ตรวจสอบความใหม่ของการรีเซ็ตเมื่อไม่มีการใช้งาน เพื่อไม่ให้เหตุการณ์ Heartbeat, Cron และ exec คงเซสชันไว้ แถวแบบเดิมที่ไม่มีฟิลด์นี้จะใช้เวลาเริ่มต้นเซสชันที่กู้คืนมาแทน
  • updatedAt: เวลาประทับของการเปลี่ยนแปลงแถวในที่เก็บครั้งล่าสุด ใช้สำหรับการแสดงรายการ/ตัดทิ้ง/บันทึกสถานะ ไม่ใช่แหล่งอ้างอิงความใหม่ของการรีเซ็ตรายวัน/เมื่อไม่มีการใช้งาน
  • archivedAt: เวลาประทับการเก็บถาวรที่ไม่บังคับ เซสชันที่เก็บถาวรจะยังอยู่ในที่เก็บพร้อมทรานสคริปต์ครบถ้วน และไม่รวมอยู่ในการแสดงรายการที่ใช้งานอยู่ตามปกติ
  • pinnedAt: เวลาประทับการปักหมุดที่ไม่บังคับ เซสชันที่ใช้งานอยู่และถูกปักหมุดจะเรียงอยู่ก่อนเซสชันที่ไม่ถูกปักหมุด การเก็บเซสชันถาวรจะล้างการปักหมุด
  • การทำงานร่วมกันกับเธรด Codex: ทั้งสองฟิลด์ใช้รูปแบบการจัดการเธรดของ Codex โดยค่าบูลีน archived/pinned บนสายสื่อสารจะถูกอนุมานจากเวลาประทับและประทับค่าโดยเซิร์ฟเวอร์เสมอ ซึ่งตรงกับความหมายของ threads.archived_at ใน Codex และการซีเรียลไลซ์แบบ camelCase เวลาประทับของ OpenClaw ใช้มิลลิวินาทีตั้งแต่ epoch ส่วน Codex ใช้วินาทีตั้งแต่ epoch ดังนั้นบริดจ์จึงแปลงค่าที่รอยต่อ Plugin codex ขณะนี้ Codex ยังไม่มี API สำหรับการปักหมุด (มีเพียง thread/archive/thread/unarchive) สถานะที่ปักหมุดจึงยังคงอยู่ฝั่ง OpenClaw จนกว่าจะมี API ดังกล่าว ซึ่งเมื่อมีแล้ว รูปแบบที่สอดคล้องกันจะช่วยให้เซสชันที่เชื่อมโยงสามารถส่งสถานะการปักหมุดไปกลับได้โดยอัตโนมัติ
  • การควบคุมดูแลของ Codex จะแสดงเฉพาะเธรดเนทีฟที่ไม่ได้เก็บถาวรเท่านั้น เธรด idle หรือ notLoaded ภายใน Gateway ซึ่งไม่ทราบสถานะกิจกรรม จะเก็บถาวรผ่าน thread/archive แบบเนทีฟได้ก็ต่อเมื่อผู้ปฏิบัติงานยืนยันอย่างชัดเจนว่าไม่มีกระบวนการ Codex อื่นเป็นเจ้าของ Plugin จะอ่านสถานะภายในกระบวนการใหม่ก่อน จากนั้นเธรดจะหายไปจากแค็ตตาล็อก การอ่านดังกล่าวไม่สามารถพิสูจน์ได้ว่ากระบวนการ App Server อื่นไม่ได้ใช้งานเธรดอยู่ OpenClaw ปฏิเสธการเก็บแถวที่ใช้งานอยู่และแถวข้อผิดพลาดเป็นถาวร และยังไม่รองรับการเก็บถาวรผ่าน Node ที่จับคู่จนกว่าบริดจ์ของ Node จะควบคุมวงจรชีวิตเธรดแบบสตรีมทั้งหมดได้ การยกเลิกการเก็บถาวรในไคลเอนต์ Codex แบบเนทีฟทำให้เธรดมีสิทธิ์ปรากฏขึ้นอีกครั้ง
  • lastReadAt / markedUnreadAt: เวลาประทับสถานะการอ่านที่ประทับโดยเซิร์ฟเวอร์ผ่าน sessions.patch { unread } โดย unread: false บันทึกการอ่าน (ตั้งค่า lastReadAt และล้าง markedUnreadAt) ส่วน unread: true ทำเครื่องหมายเซสชันว่าไม่ได้อ่านจนกว่าจะมีการอ่านครั้งถัดไป แถวเซสชันแสดงค่าบูลีน unread ที่อนุมานได้ ได้แก่ ถูกทำเครื่องหมายว่าไม่ได้อ่านอย่างชัดเจน หรือถูกอ่านก่อนกิจกรรมล่าสุด เซสชันที่ไม่เคยถูกทำเครื่องหมายว่าอ่านแล้วจะยังคงเป็น unread: false เพื่อไม่ให้การติดตั้งเดิมแสดงสถานะใหม่ขึ้นมาเมื่ออัปเกรด
  • lastActivityAt: เวลาประทับของการรันเอเจนต์ที่เสร็จสมบูรณ์ล่าสุดซึ่งนับเป็นกิจกรรมที่ควรทำให้เกิดสถานะยังไม่ได้อ่าน (การรันจากผู้ใช้ ช่องทาง และ Cron) เทิร์นของ Heartbeat และเหตุการณ์ภายใน รวมถึงแพตช์เมทาดาทา จะไม่อัปเดตค่านี้ และ updatedAt ไม่ใช่สัญญาณกิจกรรม
  • sessionFile: ตัวทำเครื่องหมายแบบเดิมที่คงไว้เพื่อความเข้ากันได้ของการย้ายข้อมูล/การเก็บถาวร รันไทม์ที่ใช้งานอยู่ใช้ข้อมูลระบุตัวตนของ SQLite
  • chatType: direct | group | room
  • provider, subject, room, space, displayName: เมทาดาทาป้ายกำกับกลุ่ม/ช่องทาง
  • ตัวสลับ: thinkingLevel, verboseLevel, reasoningLevel, elevatedLevel, sendPolicy (การแทนที่ค่าระดับเซสชัน)
  • การเลือกโมเดล: providerOverride, modelOverride, authProfileOverride
  • ตัวนับโทเค็น (ตามความพยายาม/ขึ้นอยู่กับผู้ให้บริการ): inputTokens, outputTokens, totalTokens, contextTokens
  • compactionCount: จำนวนครั้งที่การ Compaction อัตโนมัติเสร็จสมบูรณ์สำหรับคีย์เซสชันนี้
  • memoryFlushAt / memoryFlushCompactionCount: เวลาประทับและจำนวนครั้งของ Compaction ในการฟลัชหน่วยความจำก่อน Compaction ครั้งล่าสุด

Gateway เป็นแหล่งอ้างอิงหลัก โดยอาจเขียนรายการใหม่หรือเติมข้อมูลรายการกลับคืนขณะที่เซสชัน ทำงานอยู่ สำหรับการติดตั้งแบบเดิมที่ใช้ไฟล์เป็นที่เก็บ ให้ย้ายข้อมูลด้วย openclaw doctor --session-sqlite import --session-sqlite-all-agents แทนการ แก้ไข sessions.json แล้วคาดหวังให้รันไทม์อ่านไฟล์นั้นต่อไป

โครงสร้างเหตุการณ์ของทรานสคริปต์

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

  • รายการแรก: ส่วนหัวเซสชัน - type: "session", id, cwd, timestamp, และ parentSession ซึ่งไม่บังคับ
  • จากนั้น: รายการที่มี id + parentId (โครงสร้างต้นไม้)

ชนิดรายการที่สำคัญ:

  • message: ข้อความจากผู้ใช้/ผู้ช่วย/toolResult
  • custom_message: ข้อความที่ส่วนขยายแทรกเข้ามาซึ่ง เข้าสู่ บริบทของโมเดล (แสดงผลใน TUI เมื่อเป็น display: true และซ่อนทั้งหมดเมื่อเป็น display: false)
  • custom: สถานะส่วนขยายที่ ไม่เข้าสู่ บริบทของโมเดล (สำหรับคงสถานะส่วนขยายไว้ระหว่างการโหลดใหม่)
  • compaction: สรุป Compaction ที่บันทึกถาวรพร้อม firstKeptEntryId และ tokensBefore
  • branch_summary: สรุปที่บันทึกถาวรเมื่อไปยังสาขาหนึ่งของต้นไม้

OpenClaw ตั้งใจไม่ "แก้ไขปรับแต่ง" ทรานสคริปต์ โดย Gateway ใช้ SessionManager เพื่ออ่าน/เขียนทรานสคริปต์

หน้าต่างบริบทเทียบกับโทเค็นที่ติดตาม

สองแนวคิดที่แตกต่างกัน:

  1. หน้าต่างบริบทของโมเดล: ขีดจำกัดตายตัวต่อโมเดล (โทเค็นที่โมเดลมองเห็นได้) มาจากแค็ตตาล็อกโมเดลและสามารถแทนที่ผ่านการกำหนดค่าได้
  2. ตัวนับในที่เก็บเซสชัน: สถิติสะสมที่เขียนลงในแถวเซสชัน (ใช้สำหรับ /status และแดชบอร์ด) contextTokens เป็นค่าประมาณ/ค่ารายงานของรันไทม์ อย่าถือว่าเป็นการรับประกันอย่างเคร่งครัด

ข้อมูลเพิ่มเติมเกี่ยวกับขีดจำกัด: /reference/token-use

Compaction คืออะไร

Compaction สรุปบทสนทนาเก่าเป็นรายการ compaction ที่บันทึกถาวรในทรานสคริปต์ และคงข้อความล่าสุดไว้ครบถ้วน หลัง Compaction เทิร์นในอนาคตจะเห็นสรุป Compaction พร้อมข้อความหลัง firstKeptEntryId Compaction เป็นแบบ ถาวร ต่างจากการตัดเซสชัน โปรดดู /concepts/session-pruning

Compaction แบบฝังใน OpenClaw จะสืบทอดระดับการคิดของเซสชันตามค่าเริ่มต้น ตั้งค่า agents.defaults.compaction.thinkingLevel เพื่อใช้ระดับแยกต่างหากสำหรับการเรียกสรุป โดยรันไทม์จะจำกัดค่าให้เหมาะกับโมเดล Compaction หรือโมเดลสำรองแต่ละรายการ เซิร์ฟเวอร์แอป Codex แบบเนทีฟเป็นผู้ควบคุมคำขอ compact และไม่สามารถรับการแทนที่ระดับการคิดเฉพาะ Compaction ได้ ดังนั้น OpenClaw จะแสดงคำเตือนและปล่อยให้ Codex จัดการการตั้งค่านั้น

การแทรกส่วน AGENTS.md กลับเข้าไปหลัง Compaction ต้องเลือกเปิดใช้ผ่าน agents.defaults.compaction.postCompactionSections เมื่อไม่ได้ตั้งค่าหรือเป็น [] OpenClaw จะไม่ต่อท้ายข้อความตัดตอนจาก AGENTS.md เพิ่มจากสรุป Compaction

ขอบเขตส่วนย่อยและการจับคู่เครื่องมือ

เมื่อแบ่งทรานสคริปต์ยาวออกเป็นส่วนย่อยสำหรับ Compaction OpenClaw จะรักษาการจับคู่การเรียกเครื่องมือของผู้ช่วยกับรายการ toolResult ที่ตรงกัน:

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

การเกิด Compaction อัตโนมัติ

มีทริกเกอร์สองรายการในเอเจนต์ OpenClaw แบบฝัง:

  1. การกู้คืนจากการเกินขีดจำกัด: โมเดลส่งคืนข้อผิดพลาดบริบทเกินขีดจำกัด (request_too_large, context length exceeded, input exceeds the maximum number of tokens, input token count exceeds the maximum number of input tokens, input is too long for the model, ollama error: context length exceeded และรูปแบบอื่นที่ขึ้นอยู่กับผู้ให้บริการ) ให้ทำ Compaction แล้วลองใหม่ เมื่อผู้ให้บริการรายงานจำนวนโทเค็นที่พยายามใช้ OpenClaw จะส่งต่อจำนวนที่ตรวจพบดังกล่าวไปยัง Compaction สำหรับการกู้คืนจากการเกินขีดจำกัด หากผู้ให้บริการยืนยันว่าเกินขีดจำกัดแต่ไม่เปิดเผยจำนวนที่แยกวิเคราะห์ได้ OpenClaw จะส่งจำนวนสังเคราะห์ที่เกินงบประมาณเพียงเล็กน้อยไปยังกลไก Compaction และการวินิจฉัย หากการกู้คืนจากการเกินขีดจำกัดยังคงล้มเหลว OpenClaw จะแสดงคำแนะนำอย่างชัดเจนและคงการแมปเซสชันปัจจุบันไว้ แทนการเปลี่ยนไปใช้ ID เซสชันใหม่โดยไม่แจ้ง ให้ลองส่งข้อความอีกครั้ง เรียกใช้ /compact หรือเรียกใช้ /new
  2. การบำรุงรักษาตามเกณฑ์: หลังเทิร์นสำเร็จ เมื่อบริบทปัจจุบันเกินขนาดหน้าต่างของโมเดลลบด้วยพื้นที่สำรองในตัวของ OpenClaw สำหรับพรอมต์และเอาต์พุตถัดไปของโมเดล

มีกลไกป้องกันเพิ่มเติมอีกสองรายการที่ทำงานนอกเหนือจากทริกเกอร์สองรายการนี้:

  • Compaction ภายในเครื่องก่อนเริ่ม: ตั้งค่า agents.defaults.compaction.maxActiveTranscriptBytes (เป็นไบต์หรือสตริง เช่น "20mb") เพื่อเรียกใช้ Compaction ภายในเครื่องก่อนเปิดการทำงานรอบถัดไป เมื่อทรานสคริปต์ที่ใช้งานอยู่มีขนาดถึงค่าดังกล่าว นี่เป็นกลไกควบคุมขนาดเพื่อลดต้นทุนการเปิดซ้ำภายในเครื่อง ไม่ใช่การเก็บถาวรแบบดิบ โดย Compaction เชิงความหมายตามปกติยังคงทำงาน และต้องใช้ truncateAfterCompaction เพื่อให้ข้อมูลสรุปที่ผ่าน Compaction กลายเป็นทรานสคริปต์ตัวสืบทอดใหม่
  • การตรวจสอบล่วงหน้าระหว่างเทิร์น: ตั้งค่า agents.defaults.compaction.midTurnPrecheck.enabled: true (ค่าเริ่มต้น false) เพื่อเพิ่มกลไกป้องกันลูปเครื่องมือ หลังผนวกผลลัพธ์ของเครื่องมือและก่อนเรียกโมเดลครั้งถัดไป OpenClaw จะประเมินแรงกดดันต่อพรอมต์โดยใช้ตรรกะงบประมาณก่อนเริ่มแบบเดียวกับที่ใช้เมื่อเริ่มเทิร์น หากบริบทไม่พอดีอีกต่อไป กลไกป้องกันจะไม่ทำ Compaction ภายในขั้นตอนนั้น แต่จะส่งสัญญาณการตรวจสอบล่วงหน้าระหว่างเทิร์นแบบมีโครงสร้าง หยุดการส่งพรอมต์ปัจจุบัน และให้ลูปการทำงานชั้นนอกใช้เส้นทางการกู้คืนที่มีอยู่ (ตัดผลลัพธ์เครื่องมือที่มีขนาดใหญ่เกินไปเมื่อเพียงพอ หรือเรียกใช้โหมด Compaction ที่กำหนดค่าไว้แล้วลองใหม่) ใช้ได้กับโหมด Compaction ทั้ง default และ safeguard รวมถึง Compaction เพื่อป้องกันที่อาศัยผู้ให้บริการ โดยทำงานเป็นอิสระจาก maxActiveTranscriptBytes: กลไกป้องกันขนาดไบต์ทำงานก่อนเปิดเทิร์น ส่วนการตรวจสอบล่วงหน้าระหว่างเทิร์นทำงานภายหลัง หลังผนวกผลลัพธ์เครื่องมือใหม่แล้ว

การตั้งค่า Compaction

json5
{  agents: {    defaults: {      compaction: {        enabled: true,        keepRecentTokens: 20000,      },    },  },}

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

การเรียก /compact ด้วยตนเองจะใช้ค่า agents.defaults.compaction.keepRecentTokens ที่ระบุไว้อย่างชัดเจน และคงจุดตัดส่วนท้ายล่าสุดของรันไทม์ไว้ หากไม่ได้ระบุงบประมาณการเก็บรักษาอย่างชัดเจน Compaction ด้วยตนเองจะเป็นจุดตรวจสอบแบบตายตัว และบริบทที่สร้างใหม่จะเริ่มจากข้อมูลสรุปใหม่

เมื่อเปิดใช้งาน truncateAfterCompaction OpenClaw จะหมุนเวียนทรานสคริปต์ที่ใช้งานอยู่ไปยังตัวสืบทอดที่ผ่าน Compaction หลังทำ Compaction การดำเนินการจุดตรวจสอบสำหรับการแตกแขนง/กู้คืนจะใช้ตัวสืบทอดที่ผ่าน Compaction ดังกล่าว ส่วนไฟล์จุดตรวจสอบเดิมก่อนทำ Compaction จะยังคงอ่านได้ขณะที่มีการอ้างอิงอยู่

ผู้ให้บริการ Compaction ที่เปลี่ยนได้

Plugin ลงทะเบียนผู้ให้บริการ Compaction ผ่าน registerCompactionProvider() บน API ของ Plugin เมื่อกำหนด agents.defaults.compaction.provider เป็นรหัสผู้ให้บริการที่ลงทะเบียนไว้ ส่วนขยายเพื่อป้องกันจะมอบหมายการสรุปให้ผู้ให้บริการนั้นแทนไปป์ไลน์ summarizeInStages ในตัว

  • provider: รหัสของ Plugin ผู้ให้บริการ Compaction ที่ลงทะเบียนไว้ ไม่ต้องตั้งค่าเพื่อใช้การสรุปด้วย LLM เริ่มต้น การตั้งค่า provider จะบังคับใช้ mode: "safeguard"
  • ผู้ให้บริการจะได้รับคำสั่ง Compaction และนโยบายการรักษาตัวระบุเช่นเดียวกับเส้นทางในตัว และกลไกป้องกันจะยังคงรักษาบริบทส่วนท้ายของเทิร์นล่าสุดและเทิร์นที่ถูกแบ่งไว้หลังได้รับผลลัพธ์จากผู้ให้บริการ
  • การสรุปเพื่อป้องกันในตัวจะกลั่นข้อมูลสรุปก่อนหน้าใหม่ร่วมกับข้อความใหม่ แทนการเก็บข้อมูลสรุปก่อนหน้าทั้งหมดไว้แบบคำต่อคำ
  • โหมดป้องกันจะเปิดใช้การตรวจสอบคุณภาพข้อมูลสรุปโดยค่าเริ่มต้น ตั้งค่า qualityGuard.enabled: false เพื่อข้ามพฤติกรรมการลองใหม่เมื่อผลลัพธ์มีรูปแบบไม่ถูกต้อง
  • หากผู้ให้บริการล้มเหลวหรือส่งคืนผลลัพธ์ว่าง OpenClaw จะย้อนกลับไปใช้การสรุปด้วย LLM ในตัวโดยอัตโนมัติ สัญญาณยกเลิก/หมดเวลาที่ผู้เรียกสั่งอย่างชัดเจนจะถูกส่งต่อ ไม่ถูกกลืนทิ้ง เพื่อให้การยกเลิกได้รับการเคารพเสมอ

แหล่งที่มา: src/plugins/compaction-provider.ts, src/agents/agent-hooks/compaction-safeguard.ts

ส่วนที่ผู้ใช้มองเห็น

  • /status ในเซสชันแชตใดก็ได้
  • openclaw status (CLI)
  • openclaw sessions / openclaw sessions --json
  • บันทึกของ Gateway (pnpm gateway:watch หรือ openclaw logs --follow): embedded run auto-compaction start + complete
  • โหมดรายละเอียด: 🧹 Auto-compaction complete พร้อมจำนวนครั้งของ Compaction

งานดูแลแบบเงียบ (NO_REPLY)

OpenClaw รองรับเทิร์นแบบ "เงียบ" สำหรับงานเบื้องหลังที่ไม่ควรให้ผู้ใช้เห็นผลลัพธ์ระหว่างดำเนินการ

  • ผู้ช่วยจะเริ่มผลลัพธ์ด้วยโทเค็นเงียบที่ตรงกันทุกประการ NO_REPLY / no_reply เพื่อหมายความว่า "ไม่ต้องส่งการตอบกลับให้ผู้ใช้" OpenClaw จะตัด/ระงับข้อความนี้ในชั้นการส่งมอบ
  • การระงับโทเค็นเงียบที่ตรงกันทุกประการไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่: ทั้ง NO_REPLY และ no_reply จะถือว่าเข้าเงื่อนไขเมื่อเพย์โหลดทั้งหมดมีเพียงโทเค็นเงียบ
  • ตั้งแต่ 2026.1.10 เป็นต้นมา OpenClaw ยังระงับการสตรีมฉบับร่าง/สถานะกำลังพิมพ์เมื่อส่วนข้อมูลบางส่วนเริ่มด้วย NO_REPLY เพื่อไม่ให้การดำเนินการแบบเงียบเปิดเผยผลลัพธ์บางส่วนระหว่างเทิร์น
  • กลไกนี้มีไว้สำหรับเทิร์นเบื้องหลัง/ไม่มีการส่งมอบอย่างแท้จริงเท่านั้น ไม่ใช่ทางลัดสำหรับคำขอทั่วไปของผู้ใช้ที่ต้องดำเนินการ

การเขียนหน่วยความจำลงดิสก์ก่อน Compaction

ก่อนเกิด Compaction อัตโนมัติ OpenClaw สามารถเรียกใช้เทิร์นแบบเอเจนต์ที่เงียบเพื่อเขียนสถานะถาวรลงดิสก์ (เช่น memory/YYYY-MM-DD.md ในพื้นที่ทำงานของเอเจนต์) เพื่อไม่ให้ Compaction ลบบริบทสำคัญ โดยจะตรวจสอบการใช้บริบทของเซสชัน และเมื่อเกินเกณฑ์อ่อนที่ต่ำกว่าเกณฑ์ Compaction จะส่งคำสั่ง "เขียนหน่วยความจำตอนนี้" แบบเงียบโดยใช้โทเค็นเงียบที่ตรงกันทุกประการ NO_REPLY / no_reply เพื่อไม่ให้ผู้ใช้เห็นสิ่งใด

การกำหนดค่า (agents.defaults.compaction.memoryFlush) โปรดดูข้อมูลอ้างอิงฉบับเต็มที่ /gateway/config-agents:

คีย์ ค่าเริ่มต้น หมายเหตุ
enabled true
model ไม่ได้ตั้งค่า การแทนที่ผู้ให้บริการ/โมเดลที่ตรงกันทุกประการสำหรับเทิร์นการเขียนลงดิสก์เท่านั้น เช่น ollama/qwen3:8b
softThresholdTokens 4000 ระยะห่างต่ำกว่าเกณฑ์ Compaction ที่เรียกใช้การเขียนลงดิสก์
forceFlushTranscriptBytes ไม่ได้ตั้งค่า (ปิดใช้งาน) บังคับเขียนลงดิสก์เมื่อไฟล์ทรานสคริปต์มีขนาดถึงจำนวนไบต์นี้ (หรือสตริง เช่น "2mb") แม้ว่าตัวนับโทเค็นจะไม่เป็นปัจจุบัน โดย 0 จะปิดใช้งาน
prompt ในตัว ข้อความผู้ใช้สำหรับเทิร์นการเขียนลงดิสก์
systemPrompt ในตัว พรอมต์ระบบเพิ่มเติมที่ผนวกสำหรับเทิร์นการเขียนลงดิสก์

หมายเหตุ:

  • พรอมต์/พรอมต์ระบบเริ่มต้นมีคำแนะนำ NO_REPLY เพื่อระงับการส่งมอบ
  • เมื่อตั้งค่า model เทิร์นการเขียนลงดิสก์จะใช้โมเดลดังกล่าวโดยไม่สืบทอดสายการย้อนกลับของเซสชันที่ใช้งานอยู่ เพื่อให้งานดูแลเฉพาะภายในเครื่องไม่ย้อนกลับไปใช้โมเดลสนทนาแบบชำระเงินโดยไม่แจ้งเมื่อเกิดความล้มเหลว
  • การเขียนลงดิสก์จะทำงานหนึ่งครั้งต่อรอบ Compaction (ติดตามในแถวเซสชัน)
  • การเขียนลงดิสก์จะทำงานเฉพาะเซสชัน OpenClaw แบบฝังตัว ส่วนแบ็กเอนด์ CLI และเทิร์น Heartbeat จะข้ามขั้นตอนนี้
  • ระบบจะข้ามการเขียนลงดิสก์เมื่อพื้นที่ทำงานของเซสชันเป็นแบบอ่านอย่างเดียว (workspaceAccess: "ro" หรือ "none")
  • ดูรูปแบบไฟล์ในพื้นที่ทำงานและรูปแบบการเขียนได้ที่ หน่วยความจำ

OpenClaw เปิดเผยฮุก session_before_compact ใน API ของส่วนขยาย แต่ตรรกะการเขียนลงดิสก์ข้างต้นอยู่ฝั่ง Gateway (src/auto-reply/reply/memory-flush.ts, src/auto-reply/reply/agent-runner-memory.ts) ไม่ได้อยู่ในฮุกดังกล่าว

รายการตรวจสอบการแก้ไขปัญหา

  • คีย์เซสชันไม่ถูกต้องหรือไม่? เริ่มจาก /concepts/session และยืนยัน sessionKey ใน /status
  • ข้อมูลในที่เก็บไม่ตรงกับทรานสคริปต์หรือไม่? ยืนยันโฮสต์ Gateway และพาธของที่เก็บจาก openclaw status
  • Compaction เกิดถี่เกินไปหรือไม่? ตรวจสอบหน้าต่างบริบทของโมเดล (หากเล็กเกินไปจะบังคับให้ทำ Compaction บ่อยครั้ง) และผลลัพธ์เครื่องมือที่มีขนาดใหญ่เกินไป (ปรับแต่งการตัดแต่งเซสชัน)
  • ทุกพรอมต์ดูเหมือนจะล้นในโมเดลภายในเครื่องขนาดเล็กหรือไม่? ยืนยันว่าผู้ให้บริการรายงานหน้าต่างบริบทของโมเดลที่ถูกต้อง OpenClaw จะจำกัดพื้นที่สำรองที่มีผลได้ก็ต่อเมื่อทราบขนาดหน้าต่างดังกล่าว
  • เทิร์นแบบเงียบมีข้อมูลรั่วไหลหรือไม่? ยืนยันว่าคำตอบเริ่มต้นด้วยโทเค็นเงียบที่ตรงกันทุกประการ NO_REPLY (ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่) และกำลังใช้บิลด์ที่มีการแก้ไขการระงับการสตรีม (2026.1.10+)

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

Was this useful?
On this page

On this page