Community translations by veiseule.ai — Help improve them on Crowdin
Skip to main content

การจัดการเซสชันและการคอมแพคชัน(เจาะลึก)

เอกสารนี้อธิบายวิธีที่ OpenClaw จัดการเซสชันแบบครบวงจร:

  • การกำหนดเส้นทางเซสชัน (ข้อความขาเข้าถูกแมปไปยัง sessionKey อย่างไร)
  • ที่เก็บเซสชัน (sessions.json) และสิ่งที่ติดตาม
  • การคงอยู่ของทรานสคริปต์ (*.jsonl) และโครงสร้าง
  • สุขอนามัยของทรานสคริปต์ (การปรับแก้เฉพาะผู้ให้บริการก่อนรัน)
  • ขีดจำกัดบริบท (หน้าต่างบริบทเทียบกับโทเคนที่ติดตาม)
  • การคอมแพคชัน (แบบแมนนวล+อัตโนมัติ) และตำแหน่งสำหรับเชื่อมงานก่อนการคอมแพคชัน
  • งานดูแลแบบเงียบ (เช่น การเขียนหน่วยความจำที่ไม่ควรแสดงผลต่อผู้ใช้)

หากต้องการภาพรวมระดับสูงก่อน ให้เริ่มที่:


แหล่งอ้างอิงหลัก: Gateway

OpenClaw ถูกออกแบบโดยมี กระบวนการ Gateway เพียงหนึ่งเดียว ที่เป็นเจ้าของสถานะเซสชัน

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

ชั้นการคงอยู่สองชั้น

OpenClaw คงอยู่เซสชันในสองชั้น:

  1. ที่เก็บเซสชัน (sessions.json) - แผนที่คีย์/ค่า: sessionKey -> SessionEntry - ขนาดเล็ก เปลี่ยนแปลงได้ ปลอดภัยต่อการแก้ไข(หรือลบรายการ) - ติดตามเมทาดาทาเซสชัน(session id ปัจจุบัน กิจกรรมล่าสุด สวิตช์ ตัวนับโทเคน ฯลฯ)

  2. ทรานสคริปต์ (<sessionId>.jsonl) - ทรานสคริปต์แบบต่อท้ายอย่างเดียวพร้อมโครงสร้างแบบต้นไม้(รายการมี id + parentId) - เก็บการสนทนาจริง+การเรียกเครื่องมือ+สรุปการคอมแพคชัน - ใช้สร้างบริบทของโมเดลใหม่สำหรับรอบถัดไป


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

ต่อเอเจนต์ บนโฮสต์Gateway:

  • ที่เก็บ: ~/.openclaw/agents/<agentId>/sessions/sessions.json
  • บันทึกการสนทนา: ~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl
  • เซสชันหัวข้อของTelegram: .../<sessionId>-topic-<threadId>.jsonl

OpenClaw แก้ไขเส้นทางเหล่านี้ผ่าน src/config/sessions.ts.


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

sessionKey ระบุว่า คุณอยู่ในถังการสนทนาใด (การกำหนดเส้นทาง+การแยก)

รูปแบบที่พบบ่อย:

  • แชตหลัก/โดยตรง(ต่อเอเจนต์): 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> (เว้นแต่ถูกแทนที่)

กฎมาตรฐานถูกบันทึกไว้ที่ /concepts/session.


session id (sessionId)

แต่ละ sessionKey ชี้ไปยัง sessionId ปัจจุบัน(ไฟล์ทรานสคริปต์ที่ใช้สานต่อการสนทนา)

กฎโดยสรุป:

  • รีเซ็ต (/new, /reset) จะสร้าง sessionId ใหม่สำหรับ sessionKey นั้น
  • รีเซ็ตรายวัน (ค่าเริ่มต้น 04:00 น. ตามเวลาท้องถิ่นบนโฮสต์Gateway) จะสร้าง sessionId ใหม่ในข้อความถัดไปหลังเส้นแบ่งการรีเซ็ต
  • หมดอายุจากความไม่ใช้งาน (session.reset.idleMinutes หรือแบบเดิม session.idleMinutes) จะสร้าง sessionId ใหม่เมื่อมีข้อความเข้ามาหลังพ้นช่วงไม่ใช้งาน เมื่อกำหนดทั้งรายวัน+ไม่ใช้งาน กรณีที่หมดอายุก่อนจะถูกใช้ ประเภทเอนทรีที่น่าสนใจ:

รายละเอียดการทำงาน: การตัดสินใจเกิดขึ้นใน initSessionState() ใน src/auto-reply/reply/session.ts.


สคีมาที่เก็บเซสชัน (sessions.json)

ชนิดค่าของ store คือ SessionEntry ใน src/config/sessions.ts.

ฟิลด์สำคัญ(ไม่ครบถ้วน):

  • sessionId: id ทรานสคริปต์ปัจจุบัน(ชื่อไฟล์ได้จากค่านี้เว้นแต่ตั้ง sessionFile)
  • updatedAt: เวลาประทับกิจกรรมล่าสุด
  • sessionFile: การแทนที่เส้นทางทรานสคริปต์แบบชัดเจน(ไม่บังคับ)
  • chatType: direct | group | room (ช่วย UI และนโยบายการส่ง)
  • provider, subject, room, space, displayName: เมทาดาทาสำหรับการติดป้ายกลุ่ม/ช่องทาง
  • สวิตช์:
  • thinkingLevel, verboseLevel, reasoningLevel, elevatedLevel
  • sendPolicy (แทนที่ระดับต่อเซสชัน)
  • การเลือกโมเดล:
  • providerOverride, modelOverride, authProfileOverride
  • ตัวนับโทเคน(ดีที่สุดเท่าที่ทำได้/ขึ้นกับผู้ให้บริการ):
  • inputTokens, outputTokens, totalTokens, contextTokens
  • compactionCount: ความถี่ที่การคอมแพคชันอัตโนมัติสำเร็จสำหรับคีย์เซสชันนี้
  • memoryFlushAt: เวลาประทับของการฟลัชหน่วยความจำก่อนคอมแพคชันครั้งล่าสุด
  • memoryFlushCompactionCount: จำนวนครั้งการคอมแพคชันเมื่อการฟลัชครั้งล่าสุดรัน

ที่เก็บสามารถแก้ไขได้อย่างปลอดภัย แต่ Gateway เป็นผู้มีอำนาจ: อาจเขียนทับหรือเติมข้อมูลรายการใหม่เมื่อเซสชันรัน


โครงสร้างทรานสคริปต์ (*.jsonl)

ทรานสคริปต์ถูกจัดการโดย @mariozechner/pi-coding-agent ของ SessionManager.

ไฟล์เป็น JSONL:

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

Compaction เป็นแบบ ถาวร (ไม่เหมือนกับ session pruning)

  • message: ข้อความผู้ใช้/ผู้ช่วย/ผลลัพธ์เครื่องมือ
  • custom_message: ข้อความที่ส่วนขยายแทรกและ เข้าสู่ บริบทโมเดล(ซ่อนจาก UI ได้)
  • custom: สถานะส่วนขยายที่ ไม่เข้าสู่ บริบทโมเดล
  • compaction: สรุปการคอมแพคชันที่ถูกคงอยู่พร้อม firstKeptEntryId และ tokensBefore
  • branch_summary: สรุปที่ถูกคงอยู่เมื่อสลับสาขาของต้นไม้

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


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

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

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

หากคุณกำลังปรับจูนขีดจำกัด:

  • หน้าต่างบริบทมาจากแคตตาล็อกโมเดล(และสามารถแทนที่ผ่านคอนฟิก)
  • contextTokens ใน store เป็นค่าประมาณ/รายงานระหว่างรัน อย่าถือเป็นการรับประกันแบบเข้มงวด

ดูเพิ่มเติมที่ /token-use.


การคอมแพคชัน: คืออะไร

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

หลังการคอมแพคชัน รอบถัดไปจะเห็น:

  • สรุปการคอมแพคชัน
  • ข้อความหลัง firstKeptEntryId

ธรรมเนียมปฏิบัติ: การคอมแพคชันเป็นแบบ คงอยู่ถาวร (ต่างจากการตัดแต่งเซสชัน) ดู /concepts/session-pruning.


เมื่อใดที่การคอมแพคชันอัตโนมัติเกิดขึ้น (รันไทม์Pi)

ในเอเจนต์Piแบบฝัง การคอมแพคชันอัตโนมัติจะทริกเกอร์ในสองกรณี:

  1. กู้คืนจากโอเวอร์โฟลว์: โมเดลส่งข้อผิดพลาดบริบทล้น → คอมแพค → ลองใหม่
  2. บำรุงรักษาตามเกณฑ์: หลังรอบที่สำเร็จ เมื่อ:

contextTokens > contextWindow - reserveTokens

โดยที่:

  • contextWindow คือหน้าต่างบริบทของโมเดล
  • reserveTokens คือพื้นที่เผื่อสำหรับพรอมป์ต์+เอาต์พุตโมเดลถัดไป

นี่คือความหมายเชิงรันไทม์ของPi(OpenClaw รับอีเวนต์ แต่Piเป็นผู้ตัดสินใจว่าจะคอมแพคเมื่อใด)


การตั้งค่าการคอมแพคชัน (reserveTokens, keepRecentTokens)

การตั้งค่าการคอมแพคชันของPiอยู่ใน Pi settings:

{
  compaction: {
    enabled: true,
    reserveTokens: 16384,
    keepRecentTokens: 20000,
  },
}

OpenClaw ยังบังคับใช้ค่า safety floor สำหรับการรันแบบฝัง:

  • หาก compaction.reserveTokens < reserveTokensFloor, OpenClaw จะปรับเพิ่ม
  • ค่าเริ่มต้นของ floor คือ 20000 โทเคน
  • ตั้ง agents.defaults.compaction.reserveTokensFloor: 0 เพื่อปิด floor
  • หากค่าสูงกว่าอยู่แล้ว OpenClaw จะไม่เปลี่ยน

เหตุผล: เหลือพื้นที่เผื่อพอสำหรับ “งานดูแล” หลายรอบ(เช่น การเขียนหน่วยความจำ) ก่อนที่การคอมแพคชันจะหลีกเลี่ยงไม่ได้

การติดตั้ง: ensurePiCompactionReserveTokens() ใน src/agents/pi-settings.ts (ถูกเรียกจาก src/agents/pi-embedded-runner.ts).


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

คุณสามารถสังเกตการคอมแพคชันและสถานะเซสชันได้ผ่าน:

  • /status (ในทุกเซสชันแชต)
  • openclaw status (CLI)
  • openclaw sessions / sessions --json
  • โหมด verbose: 🧹 Auto-compaction complete + จำนวนครั้งการคอมแพคชัน

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

OpenClaw รองรับรอบแบบ “เงียบ” สำหรับงานเบื้องหลังที่ผู้ใช้ไม่ควรเห็นเอาต์พุตระหว่างทาง

นี่คือ Clawd ผู้ให้กำเนิดกุ้งล็อบสเตอร์ของคุณ

  • ผู้ช่วยเริ่มเอาต์พุตด้วย NO_REPLY เพื่อระบุว่า “อย่าส่งคำตอบให้ผู้ใช้”
  • OpenClaw จะตัด/ระงับสิ่งนี้ในชั้นการส่งมอบ

ตั้งแต่ 2026.1.10 เป็นต้นมา OpenClaw ยังระงับ การสตรีมแบบร่าง/ตัวบ่งชี้การพิมพ์ เมื่อชังก์บางส่วนเริ่มด้วย NO_REPLY เพื่อไม่ให้การทำงานเงียบรั่วเอาต์พุตระหว่างรอบ


“การฟลัชหน่วยความจำ” ก่อนการคอมแพคชัน (ติดตั้งแล้ว)

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

OpenClaw ใช้วิธี pre-threshold flush:

  1. เฝ้าดูการใช้บริบทของเซสชัน
  2. เมื่อข้าม “soft threshold”(ต่ำกว่าเกณฑ์คอมแพคชันของPi) ให้รันคำสั่งเงียบ “เขียนหน่วยความจำเดี๋ยวนี้” ไปยังเอเจนต์
  3. ใช้ NO_REPLY เพื่อให้ผู้ใช้ไม่เห็นอะไร

คอนฟิก (agents.defaults.compaction.memoryFlush):

  • enabled (ค่าเริ่มต้น: true)
  • softThresholdTokens (ค่าเริ่มต้น: 4000)
  • prompt (ข้อความผู้ใช้สำหรับรอบฟลัช)
  • systemPrompt (system prompt เพิ่มเติมที่ต่อท้ายสำหรับรอบฟลัช)

หมายเหตุ:

  • พรอมป์ต์เริ่มต้น/system prompt มีคำใบ้ NO_REPLY เพื่อระงับการส่งมอบ
  • การฟลัชจะรันหนึ่งครั้งต่อรอบการคอมแพคชัน(ติดตามใน sessions.json)
  • การฟลัชจะรันเฉพาะเซสชันPiแบบฝัง(แบ็กเอนด์CLIจะข้าม)
  • จะข้ามการฟลัชเมื่อเวิร์กสเปซเซสชันเป็นแบบอ่านอย่างเดียว(workspaceAccess: "ro" หรือ "none")
  • ดู Memory สำหรับเลย์เอาต์ไฟล์เวิร์กสเปซและรูปแบบการเขียน

Pi ยังเปิดเผยฮุก session_before_compact ใน API ของส่วนขยาย แต่ตรรกะการฟลัชของ OpenClaw อยู่ฝั่ง Gateway ในปัจจุบัน


เช็กลิสต์การแก้ไขปัญหา

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