---
read_when:
    - คุณต้องดีบักรหัสเซสชัน, JSONL ของทรานสคริปต์ หรือฟิลด์ใน `sessions.json`
    - คุณกำลังเปลี่ยนพฤติกรรม Compaction อัตโนมัติ หรือเพิ่มงานดูแลระบบ “ก่อน Compaction”
    - คุณต้องการใช้งานการล้างหน่วยความจำหรือ system turns แบบเงียบៗ
summary: 'เจาะลึก: ที่เก็บเซสชัน + ทรานสคริปต์, วงจรชีวิต, และกลไกภายในของ Compaction (อัตโนมัติ)'
title: เจาะลึกการจัดการเซสชัน
x-i18n:
    generated_at: "2026-04-26T11:41:20Z"
    model: gpt-5.4
    provider: openai
    source_hash: f41f1c403f978c22cc2a929629e1811414d1399fa7f9e28c481fcb594d30196f
    source_path: reference/session-management-compaction.md
    workflow: 15
---

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

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

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

- [การจัดการเซสชัน](/th/concepts/session)
- [Compaction](/th/concepts/compaction)
- [ภาพรวมหน่วยความจำ](/th/concepts/memory)
- [การค้นหาหน่วยความจำ](/th/concepts/memory-search)
- [การตัดแต่งเซสชัน](/th/concepts/session-pruning)
- [สุขอนามัยของทรานสคริปต์](/th/reference/transcript-hygiene)

---

## แหล่งข้อมูลหลัก: Gateway

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

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

---

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

OpenClaw คงข้อมูลเซสชันไว้สองชั้น:

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

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

---

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

ต่อ agent หนึ่งตัว บนโฮสต์ Gateway:

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

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

---

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

การคงอยู่ของเซสชันมีตัวควบคุมการบำรุงรักษาอัตโนมัติ (`session.maintenance`) สำหรับ `sessions.json` และอาร์ติแฟกต์ของทรานสคริปต์:

- `mode`: `warn` (ค่าเริ่มต้น) หรือ `enforce`
- `pruneAfter`: จุดตัดอายุของรายการที่เก่า (ค่าเริ่มต้น `30d`)
- `maxEntries`: จำกัดจำนวนรายการใน `sessions.json` (ค่าเริ่มต้น `500`)
- `rotateBytes`: หมุนเวียน `sessions.json` เมื่อขนาดใหญ่เกินไป (ค่าเริ่มต้น `10mb`)
- `resetArchiveRetention`: ระยะเวลาการเก็บอาร์ไคฟ์ทรานสคริปต์ `*.reset.<timestamp>` (ค่าเริ่มต้น: เท่ากับ `pruneAfter`; `false` ปิดการล้างข้อมูล)
- `maxDiskBytes`: งบประมาณไดเรกทอรีเซสชันสูงสุดแบบเลือกได้
- `highWaterBytes`: เป้าหมายหลังการล้างข้อมูลแบบเลือกได้ (ค่าเริ่มต้น `80%` ของ `maxDiskBytes`)

ลำดับการบังคับใช้สำหรับการล้างข้อมูลงบประมาณดิสก์ (`mode: "enforce"`):

1. ลบอาร์ติแฟกต์ทรานสคริปต์ที่เก็บถาวรหรือไม่มีเจ้าของที่เก่าที่สุดก่อน
2. หากยังเกินเป้าหมาย ให้ไล่รายการเซสชันที่เก่าที่สุดออกพร้อมไฟล์ทรานสคริปต์
3. ทำต่อไปจนกว่าปริมาณการใช้จะน้อยกว่าหรือเท่ากับ `highWaterBytes`

ใน `mode: "warn"` OpenClaw จะรายงานการไล่รายการออกที่อาจเกิดขึ้น แต่จะไม่เปลี่ยนแปลงที่เก็บ/ไฟล์

รันการบำรุงรักษาตามต้องการ:

```bash
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
```

---

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

การรัน Cron แบบแยกจะสร้างรายการเซสชัน/ทรานสคริปต์ด้วย และมีตัวควบคุมการเก็บรักษาเฉพาะ:

- `cron.sessionRetention` (ค่าเริ่มต้น `24h`) จะตัดแต่งเซสชันการรัน Cron แบบแยกเก่าออกจากที่เก็บเซสชัน (`false` ปิดการทำงาน)
- `cron.runLog.maxBytes` + `cron.runLog.keepLines` จะตัดแต่งไฟล์ `~/.openclaw/cron/runs/<jobId>.jsonl` (ค่าเริ่มต้น: `2_000_000` ไบต์ และ `2000` บรรทัด)

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

---

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

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

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

- แชตหลัก/แชตตรง (ต่อ agent): `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>` (เว้นแต่จะ override)

กฎแบบ canonical มีเอกสารอยู่ที่ [/concepts/session](/th/concepts/session)

---

## รหัสเซสชัน (`sessionId`)

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

กฎคร่าว ๆ:

- **รีเซ็ต** (`/new`, `/reset`) จะสร้าง `sessionId` ใหม่สำหรับ `sessionKey` นั้น
- **รีเซ็ตรายวัน** (ค่าเริ่มต้น 4:00 น. ตามเวลาท้องถิ่นบนโฮสต์ gateway) จะสร้าง `sessionId` ใหม่ในข้อความถัดไปหลังข้ามเส้นแบ่งการรีเซ็ต
- **หมดอายุเมื่อไม่มีการใช้งาน** (`session.reset.idleMinutes` หรือเดิม `session.idleMinutes`) จะสร้าง `sessionId` ใหม่เมื่อมีข้อความเข้ามาหลังพ้นช่วงไม่มีการใช้งาน เมื่อกำหนดทั้งรายวัน + ไม่มีการใช้งานไว้พร้อมกัน ตัวที่หมดอายุก่อนจะชนะ
- **เหตุการณ์ของระบบ** (Heartbeat, การปลุก Cron, การแจ้งเตือน exec, งานดูแลระบบของ gateway) อาจเปลี่ยนแถวเซสชันได้ แต่จะไม่ขยายความใหม่ของการรีเซ็ตรายวัน/ไม่มีการใช้งาน การโรลโอเวอร์จากการรีเซ็ตจะทิ้งประกาศเหตุการณ์ระบบที่อยู่ในคิวสำหรับเซสชันก่อนหน้า ก่อนสร้างพรอมป์ต์ใหม่
- **ตัวป้องกันการแตกแขนงจากพาเรนต์ของเธรด** (`session.parentForkMaxTokens`, ค่าเริ่มต้น `100000`) จะข้ามการ fork ทรานสคริปต์จากเซสชันพาเรนต์เมื่อเซสชันพาเรนต์มีขนาดใหญ่เกินไปแล้ว; เธรดใหม่จะเริ่มแบบสด ตั้งค่าเป็น `0` เพื่อปิด

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

---

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

ชนิดค่าของที่เก็บคือ `SessionEntry` ใน `src/config/sessions.ts`

ฟิลด์สำคัญ (ไม่ครบทั้งหมด):

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

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

---

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

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

ไฟล์เป็น JSONL:

- บรรทัดแรก: ส่วนหัวเซสชัน (`type: "session"` มี `id`, `cwd`, `timestamp`, `parentSession` แบบเลือกได้)
- จากนั้น: รายการเซสชันพร้อม `id` + `parentId` (ต้นไม้)

ประเภทรายการที่สำคัญ:

- `message`: ข้อความ user/assistant/toolResult
- `custom_message`: ข้อความที่ส่วนขยาย inject เข้ามาซึ่ง _เข้าสู่_ บริบทโมเดล (สามารถซ่อนจาก UI ได้)
- `custom`: สถานะของส่วนขยายที่ _ไม่เข้าสู่_ บริบทโมเดล
- `compaction`: สรุป Compaction ที่คงไว้พร้อม `firstKeptEntryId` และ `tokensBefore`
- `branch_summary`: สรุปที่คงไว้เมื่อมีการนำทางกิ่งของต้นไม้

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

---

## context window เทียบกับโทเค็นที่ติดตาม

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

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

หากคุณกำลังปรับแต่งขีดจำกัด:

- context window มาจากแค็ตตาล็อกโมเดล (และสามารถ override ผ่าน config ได้)
- `contextTokens` ในที่เก็บเป็นค่าประมาณ/การรายงานขณะรัน; อย่าถือว่าเป็นการรับประกันแบบเข้มงวด

ดูเพิ่มเติมที่ [/token-use](/th/reference/token-use)

---

## Compaction: มันคืออะไร

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

หลังจาก Compaction เทิร์นในอนาคตจะเห็น:

- สรุป Compaction
- ข้อความหลัง `firstKeptEntryId`

Compaction เป็นแบบ**คงอยู่ถาวร** (ไม่เหมือนการตัดแต่งเซสชัน) ดู [/concepts/session-pruning](/th/concepts/session-pruning)

## ขอบเขตชังก์ของ Compaction และการจับคู่เครื่องมือ

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

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

---

## เมื่อใดที่เกิด Compaction อัตโนมัติ (Pi runtime)

ใน Pi agent แบบฝัง Compaction อัตโนมัติจะทำงานในสองกรณี:

1. **การกู้คืนเมื่อโอเวอร์โฟลว์**: โมเดลส่งคืนข้อผิดพลาด context overflow
   (`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` และรูปแบบอื่นที่คล้ายกันจากผู้ให้บริการ) → compact → ลองใหม่
2. **การดูแลรักษาตามเกณฑ์**: หลังจากเทิร์นสำเร็จ เมื่อ:

`contextTokens > contextWindow - reserveTokens`

โดยที่:

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

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

---

## การตั้งค่า Compaction (`reserveTokens`, `keepRecentTokens`)

การตั้งค่า Compaction ของ Pi อยู่ในการตั้งค่า Pi:

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

OpenClaw ยังบังคับใช้ค่าพื้นความปลอดภัยสำหรับการรันแบบฝัง:

- หาก `compaction.reserveTokens < reserveTokensFloor` OpenClaw จะเพิ่มให้
- ค่าพื้นเริ่มต้นคือ `20000` โทเค็น
- ตั้งค่า `agents.defaults.compaction.reserveTokensFloor: 0` เพื่อปิดค่าพื้น
- หากค่าสูงกว่าอยู่แล้ว OpenClaw จะไม่เปลี่ยน
- `/compact` แบบแมนนวลจะเคารพ `agents.defaults.compaction.keepRecentTokens` ที่ระบุชัดเจน
  และเก็บจุดตัดส่วนท้ายล่าสุดของ Pi ไว้ หากไม่มีงบประมาณการเก็บที่ระบุชัดเจน
  Compaction แบบแมนนวลจะยังคงเป็นจุดตรวจแบบฮาร์ด และบริบทที่สร้างใหม่จะเริ่มจาก
  สรุปใหม่

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

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

---

## ผู้ให้บริการ Compaction แบบเสียบปลั๊กได้

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

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

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

---

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

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

- `/status` (ในเซสชันแชตใดก็ได้)
- `openclaw status` (CLI)
- `openclaw sessions` / `sessions --json`
- โหมด verbose: `🧹 Auto-compaction complete` + จำนวน Compaction

---

## งานดูแลระบบแบบเงียบ (`NO_REPLY`)

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

ข้อตกลง:

- ผู้ช่วยเริ่มเอาต์พุตด้วยโทเค็นเงียบแบบตรงตัว `NO_REPLY` /
  `no_reply` เพื่อระบุว่า “อย่าส่งการตอบกลับให้ผู้ใช้”
- OpenClaw จะลบ/ระงับสิ่งนี้ในเลเยอร์การส่งมอบ
- การระงับด้วยโทเค็นเงียบแบบตรงตัวไม่สนตัวพิมพ์เล็กใหญ่ ดังนั้น `NO_REPLY` และ
  `no_reply` จะนับเหมือนกันเมื่อเพย์โหลดทั้งหมดมีเพียงโทเค็นเงียบนั้น
- ใช้สำหรับเทิร์นแบบเบื้องหลังจริง/ไม่ต้องส่งมอบเท่านั้น ไม่ใช่ทางลัดสำหรับ
  คำขอปกติจากผู้ใช้ที่ต้องมีการดำเนินการ

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

---

## “การล้างหน่วยความจำ” ก่อน Compaction (ใช้งานแล้ว)

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

OpenClaw ใช้แนวทาง **ล้างก่อนถึงเกณฑ์**:

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

Config (`agents.defaults.compaction.memoryFlush`):

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

หมายเหตุ:

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

Pi ยังเปิดเผย hook `session_before_compact` ใน Plugin API ด้วย แต่ตรรกะการล้างของ OpenClaw
ปัจจุบันอยู่ฝั่ง Gateway

---

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

- session key ไม่ถูกต้องใช่ไหม เริ่มที่ [/concepts/session](/th/concepts/session) และยืนยัน `sessionKey` ใน `/status`
- ที่เก็บกับทรานสคริปต์ไม่ตรงกันใช่ไหม ยืนยันโฮสต์ Gateway และเส้นทางที่เก็บจาก `openclaw status`
- Compaction ถี่เกินไปใช่ไหม ตรวจสอบ:
  - context window ของโมเดล (เล็กเกินไป)
  - การตั้งค่า Compaction (`reserveTokens` ที่สูงเกินไปสำหรับหน้าต่างของโมเดลอาจทำให้ Compact เร็วขึ้น)
  - tool-result ที่พองเกิน: เปิดใช้/ปรับแต่งการตัดแต่งเซสชัน
- เทิร์นแบบเงียบรั่วใช่ไหม ยืนยันว่าการตอบกลับเริ่มด้วย `NO_REPLY` (โทเค็นแบบตรงตัวที่ไม่สนตัวพิมพ์เล็กใหญ่) และคุณใช้บิลด์ที่มีการแก้ไขการระงับการสตรีมแล้ว

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

- [การจัดการเซสชัน](/th/concepts/session)
- [การตัดแต่งเซสชัน](/th/concepts/session-pruning)
- [Context engine](/th/concepts/context-engine)
