---
read_when:
    - การปรับความถี่หรือการส่งข้อความของ Heartbeat
    - การตัดสินใจเลือกระหว่าง Heartbeat และ Cron สำหรับงานที่ตั้งเวลาไว้
sidebarTitle: Heartbeat
summary: ข้อความการสำรวจสถานะ Heartbeat และกฎการแจ้งเตือน
title: Heartbeat
x-i18n:
    generated_at: "2026-07-19T07:24:05Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 84129f3660ca730698dcda2e8ddf04dce909d3e3a4a9823e886eab53be52f61a
    source_path: gateway/heartbeat.md
    workflow: 16
---

<Note>
**Heartbeat เทียบกับ cron?** ดูคำแนะนำว่าควรใช้แต่ละแบบเมื่อใดได้ที่ [ระบบอัตโนมัติ](/th/automation)
</Note>

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

Heartbeat คือรอบการทำงานตามกำหนดเวลาในเซสชันหลัก โดย **ไม่** สร้างระเบียน [งานเบื้องหลัง](/th/automation/tasks) ระเบียนงานมีไว้สำหรับงานที่แยกออกไปทำต่างหาก (การเรียกใช้ ACP, เอเจนต์ย่อย, งาน cron แบบแยกส่วน)

การแก้ไขปัญหา: [งานตามกำหนดเวลา](/th/automation/cron-jobs#troubleshooting)

## เริ่มต้นอย่างรวดเร็ว (สำหรับผู้เริ่มต้น)

<Steps>
  <Step title="เลือกความถี่">
    เปิดใช้ Heartbeat ไว้ (ค่าเริ่มต้นคือ `30m` หรือ `1h` เมื่อกำหนดค่าการยืนยันตัวตนด้วย Anthropic OAuth/โทเค็น รวมถึงการใช้ Claude CLI ซ้ำ) หรือกำหนดความถี่เอง
  </Step>
  <Step title="เพิ่ม HEARTBEAT.md (ไม่บังคับ)">
    สร้างรายการตรวจสอบ `HEARTBEAT.md` ขนาดเล็กหรือบล็อก `tasks:` ในพื้นที่ทำงานของเอเจนต์
  </Step>
  <Step title="กำหนดปลายทางของข้อความ Heartbeat">
    `target: "none"` เป็นค่าเริ่มต้น ให้ตั้งค่า `target: "last"` เพื่อส่งไปยังผู้ติดต่อล่าสุด
  </Step>
  <Step title="ปรับแต่งเพิ่มเติม (ไม่บังคับ)">
    - เปิดใช้การส่งเหตุผลของ Heartbeat เพื่อความโปร่งใส
    - ใช้บริบทเริ่มต้นแบบเบา หากการเรียกใช้ Heartbeat ต้องการเพียง `HEARTBEAT.md`
    - เปิดใช้เซสชันแบบแยกส่วนเพื่อหลีกเลี่ยงการส่งประวัติการสนทนาทั้งหมดในทุก Heartbeat
    - จำกัด Heartbeat ให้อยู่ในช่วงเวลาที่ใช้งาน (เวลาท้องถิ่น)

  </Step>
</Steps>

ตัวอย่างการกำหนดค่า:

```json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "last", // ส่งไปยังผู้ติดต่อล่าสุดอย่างชัดเจน (ค่าเริ่มต้นคือ "none")
        directPolicy: "allow", // ค่าเริ่มต้น: อนุญาตเป้าหมายแบบตรง/DM; ตั้งเป็น "block" เพื่อระงับ
        lightContext: true, // ไม่บังคับ: แทรกเฉพาะ HEARTBEAT.md จากไฟล์เริ่มต้น
        isolatedSession: true, // ไม่บังคับ: ใช้เซสชันใหม่ในแต่ละครั้ง (ไม่มีประวัติการสนทนา)
        skipWhenBusy: true, // ไม่บังคับ: เลื่อนด้วยเมื่อเอเจนต์ย่อยหรือเลนซ้อนของเอเจนต์นี้ไม่ว่าง
        // activeHours: { start: "08:00", end: "24:00" },
        // includeReasoning: true, // ไม่บังคับ: ส่งข้อความ `Thinking` แยกต่างหากด้วย
      },
    },
  },
}
```

## ค่าเริ่มต้น

- ช่วงเวลา: `30m` การใช้ค่าเริ่มต้นของผู้ให้บริการ Anthropic จะเพิ่มเป็น `1h` เมื่อโหมดการยืนยันตัวตนที่แก้ไขแล้วเป็น OAuth/โทเค็น (รวมถึงการใช้ Claude CLI ซ้ำ) แต่เฉพาะเมื่อยังไม่ได้ตั้งค่า `heartbeat.every` ตั้งค่า `agents.defaults.heartbeat.every` หรือ `agents.list[].heartbeat.every` สำหรับแต่ละเอเจนต์ และใช้ `0m` เพื่อปิดใช้
- เนื้อหาพรอมต์ (กำหนดค่าได้ผ่าน `agents.defaults.heartbeat.prompt`): `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`
- หมดเวลา: รอบ Heartbeat ที่ไม่ได้ตั้งค่าจะใช้ `agents.defaults.timeoutSeconds` หากมีการตั้งค่าไว้ มิฉะนั้นจะใช้ความถี่ของ Heartbeat โดยจำกัดสูงสุดที่ 600 วินาที ตั้งค่า `agents.defaults.heartbeat.timeoutSeconds` หรือ `agents.list[].heartbeat.timeoutSeconds` สำหรับแต่ละเอเจนต์ หากงาน Heartbeat ต้องใช้เวลานานกว่านั้น
- พรอมต์ Heartbeat จะถูกส่งเป็นข้อความของผู้ใช้ **ตามต้นฉบับทุกประการ** พรอมต์ระบบจะมีส่วน "Heartbeats" เฉพาะเมื่อเปิดใช้ Heartbeat สำหรับเอเจนต์เริ่มต้น (และ `includeSystemPromptSection` ไม่ใช่ `false`) และการเรียกใช้จะถูกทำเครื่องหมายไว้ภายใน
- เมื่อปิดใช้ Heartbeat ด้วย `0m` การเรียกใช้ตามปกติจะละเว้น `HEARTBEAT.md` จากบริบทเริ่มต้นด้วย เพื่อไม่ให้โมเดลเห็นคำสั่งที่ใช้กับ Heartbeat เท่านั้น
- ช่วงเวลาที่ใช้งาน (`heartbeat.activeHours`) จะตรวจสอบตามเขตเวลาที่กำหนดค่าไว้ เมื่ออยู่นอกช่วงดังกล่าว Heartbeat จะถูกข้ามจนถึงรอบถัดไปที่อยู่ภายในช่วง
- Heartbeat จะเลื่อนโดยอัตโนมัติขณะที่งาน cron กำลังทำงานหรืออยู่ในคิว ตั้งค่า `heartbeat.skipWhenBusy: true` เพื่อเลื่อนเอเจนต์ด้วยเมื่อเอเจนต์ย่อยที่ผูกกับคีย์เซสชันของตนเองหรือเลนคำสั่งซ้อนกำลังทำงาน เอเจนต์อื่นในระดับเดียวกันจะไม่หยุดเพียงเพราะเอเจนต์อื่นมีงานของเอเจนต์ย่อยกำลังดำเนินการอีกต่อไป

## วัตถุประสงค์ของพรอมต์ Heartbeat

พรอมต์เริ่มต้นตั้งใจให้ครอบคลุมกว้าง:

- **งานเบื้องหลัง**: "พิจารณางานที่ยังค้างอยู่" กระตุ้นให้เอเจนต์ตรวจสอบสิ่งที่ต้องติดตาม (กล่องจดหมาย ปฏิทิน การแจ้งเตือน งานในคิว) และแจ้งสิ่งเร่งด่วน
- **การสอบถามผู้ใช้**: "สอบถามผู้ใช้ของคุณเป็นครั้งคราวในช่วงกลางวัน" กระตุ้นให้ส่งข้อความสั้น ๆ เช่น "มีอะไรให้ช่วยไหม" เป็นครั้งคราว แต่หลีกเลี่ยงการรบกวนในเวลากลางคืนโดยใช้เขตเวลาท้องถิ่นที่กำหนดค่าไว้ (ดู [เขตเวลา](/th/concepts/timezone))

Heartbeat สามารถตอบสนองต่องาน [เบื้องหลัง](/th/automation/tasks) ที่เสร็จสมบูรณ์แล้วได้ แต่การเรียกใช้ Heartbeat เองจะไม่สร้างระเบียนงาน

หากต้องการให้ Heartbeat ทำสิ่งที่เฉพาะเจาะจงมาก (เช่น "ตรวจสอบสถิติ Gmail PubSub" หรือ "ตรวจสอบสถานะ Gateway") ให้ตั้งค่า `agents.defaults.heartbeat.prompt` (หรือ `agents.list[].heartbeat.prompt`) เป็นเนื้อหาแบบกำหนดเอง (ส่งตามต้นฉบับทุกประการ)

## สัญญาการตอบกลับ

- หากไม่มีสิ่งใดต้องดำเนินการ ให้ตอบด้วย **`HEARTBEAT_OK`**
- การเรียกใช้ Heartbeat อาจเรียก `heartbeat_respond` พร้อม `notify: false` แทนเพื่อไม่ให้มีการอัปเดตที่มองเห็นได้ หรือเรียก `notify: true` พร้อม `notificationText` สำหรับการแจ้งเตือน เมื่อมีการตอบกลับจากเครื่องมือแบบมีโครงสร้าง การตอบกลับดังกล่าวจะมีลำดับความสำคัญเหนือข้อความสำรอง
- ผลลัพธ์ `heartbeat_respond` ที่มีความหมายพร้อม `notify: false` จะยังคงเงียบ แต่จะถูกจดจำเป็นบริบทภายในแบบมีขอบเขตสำหรับรอบการทำงานของผู้ใช้ครั้งถัดไปในเซสชันนั้น การตอบรับ `no_change` และการแจ้งเตือนที่มองเห็นได้จะไม่ถูกจัดเก็บด้วยวิธีนี้
- ระหว่างการเรียกใช้ Heartbeat OpenClaw จะถือว่า `HEARTBEAT_OK` เป็นการตอบรับเมื่อปรากฏที่ **จุดเริ่มต้นหรือจุดสิ้นสุด** ของคำตอบ โทเค็นจะถูกนำออกและคำตอบจะถูกละทิ้งหากเนื้อหาที่เหลือมีความยาว **≤ `ackMaxChars`** (ค่าเริ่มต้น: 300)
- หาก `HEARTBEAT_OK` ปรากฏที่ **กลาง** คำตอบ ระบบจะไม่ปฏิบัติต่อค่านั้นเป็นกรณีพิเศษ
- สำหรับการแจ้งเตือน **ห้าม** ใส่ `HEARTBEAT_OK` ให้ส่งคืนเฉพาะข้อความแจ้งเตือน

นอกการทำงานของ Heartbeat ค่า `HEARTBEAT_OK` ที่หลงเหลืออยู่ตรงจุดเริ่มต้น/จุดสิ้นสุดของข้อความจะถูกนำออกและบันทึกลงล็อก ส่วนข้อความที่มีเพียง `HEARTBEAT_OK` จะถูกละทิ้ง

## การกำหนดค่า

```json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // ค่าเริ่มต้น: 30m (0m ปิดใช้)
        model: "anthropic/claude-opus-4-6",
        includeReasoning: false, // ค่าเริ่มต้น: false (ส่งข้อความ Thinking แยกต่างหากเมื่อมี)
        lightContext: false, // ค่าเริ่มต้น: false; true จะเก็บเฉพาะ HEARTBEAT.md จากไฟล์เริ่มต้นในพื้นที่ทำงาน
        isolatedSession: false, // ค่าเริ่มต้น: false; true จะเรียกใช้ Heartbeat แต่ละครั้งในเซสชันใหม่ (ไม่มีประวัติการสนทนา)
        skipWhenBusy: false, // ค่าเริ่มต้น: false; true จะรอเลนของเอเจนต์ย่อย/เลนซ้อนของเอเจนต์นี้ด้วย
        target: "last", // ค่าเริ่มต้น: none | ตัวเลือก: last | none | <channel id> (แกนหลักหรือ Plugin เช่น "imessage")
        to: "+15551234567", // ไม่บังคับ: แทนที่ค่าตามช่องทาง
        accountId: "ops-bot", // ไม่บังคับ: รหัสช่องทางแบบหลายบัญชี
        prompt: "อ่าน HEARTBEAT.md หากมีอยู่ (บริบทพื้นที่ทำงาน) ปฏิบัติตามอย่างเคร่งครัด ห้ามอนุมานหรือกล่าวซ้ำถึงงานเก่าจากแชตก่อนหน้า หากไม่มีสิ่งใดต้องดำเนินการ ให้ตอบ HEARTBEAT_OK",
        includeSystemPromptSection: true, // ค่าเริ่มต้น: true; false จะละเว้นส่วนพรอมต์ระบบ ## Heartbeats สำหรับเอเจนต์เริ่มต้น
        ackMaxChars: 300, // จำนวนอักขระสูงสุดที่อนุญาตหลัง HEARTBEAT_OK
      },
    },
  },
}
```

### ขอบเขตและลำดับความสำคัญ

- `agents.defaults.heartbeat` กำหนดพฤติกรรม Heartbeat ส่วนกลาง
- `agents.list[].heartbeat` ผสานทับลงไป หากเอเจนต์ใดมีบล็อก `heartbeat` **เฉพาะเอเจนต์เหล่านั้น** เท่านั้นที่จะเรียกใช้ Heartbeat
- `channels.defaults.heartbeat` กำหนดค่าเริ่มต้นด้านการมองเห็นสำหรับทุกช่องทาง
- `channels.<channel>.heartbeat` แทนที่ค่าเริ่มต้นของช่องทาง
- `channels.<channel>.accounts.<id>.heartbeat` (ช่องทางแบบหลายบัญชี) แทนที่การตั้งค่ารายช่องทาง

### Heartbeat รายเอเจนต์

หากรายการ `agents.list[]` ใดมีบล็อก `heartbeat` **เฉพาะเอเจนต์เหล่านั้น** เท่านั้นที่จะเรียกใช้ Heartbeat บล็อกรายเอเจนต์จะผสานทับ `agents.defaults.heartbeat` (จึงสามารถตั้งค่าเริ่มต้นที่ใช้ร่วมกันเพียงครั้งเดียวและแทนที่ค่าสำหรับแต่ละเอเจนต์ได้)

ตัวอย่าง: มีเอเจนต์สองตัว แต่เฉพาะเอเจนต์ตัวที่สองเท่านั้นที่เรียกใช้ Heartbeat

```json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "last", // ส่งไปยังผู้ติดต่อล่าสุดอย่างชัดเจน (ค่าเริ่มต้นคือ "none")
      },
    },
    list: [
      { id: "main", default: true },
      {
        id: "ops",
        heartbeat: {
          every: "1h",
          target: "whatsapp",
          to: "+15551234567",
          timeoutSeconds: 45,
          prompt: "อ่าน HEARTBEAT.md หากมีอยู่ (บริบทพื้นที่ทำงาน) ปฏิบัติตามอย่างเคร่งครัด ห้ามอนุมานหรือกล่าวซ้ำถึงงานเก่าจากแชตก่อนหน้า หากไม่มีสิ่งใดต้องดำเนินการ ให้ตอบ HEARTBEAT_OK",
        },
      },
    ],
  },
}
```

### ตัวอย่างช่วงเวลาที่ใช้งาน

จำกัด Heartbeat ให้อยู่ในเวลาทำการตามเขตเวลาที่ระบุ:

```json5
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",
        target: "last", // ส่งไปยังผู้ติดต่อล่าสุดอย่างชัดเจน (ค่าเริ่มต้นคือ "none")
        activeHours: {
          start: "09:00",
          end: "22:00",
          timezone: "America/New_York", // ไม่บังคับ; ใช้ userTimezone หากตั้งค่าไว้ มิฉะนั้นใช้เขตเวลาของโฮสต์
        },
      },
    },
  },
}
```

เมื่ออยู่นอกช่วงนี้ (ก่อน 9 นาฬิกาหรือหลัง 22 นาฬิกาตามเวลาตะวันออก) Heartbeat จะถูกข้าม รอบตามกำหนดเวลาถัดไปที่อยู่ภายในช่วงจะทำงานตามปกติ

### การตั้งค่าแบบ 24/7

หากต้องการให้ Heartbeat ทำงานตลอดทั้งวัน ให้ใช้รูปแบบใดรูปแบบหนึ่งต่อไปนี้:

- ละเว้น `activeHours` ทั้งหมด (ไม่มีข้อจำกัดด้านช่วงเวลา ซึ่งเป็นพฤติกรรมเริ่มต้น)
- กำหนดช่วงเต็มวัน: `activeHours: { start: "00:00", end: "24:00" }`

<Warning>
อย่าตั้งเวลา `start` และ `end` เป็นเวลาเดียวกัน (เช่น `08:00` ถึง `08:00`) ระบบจะถือว่าเป็นช่วงที่มีความกว้างเป็นศูนย์ ดังนั้น Heartbeat จะถูกข้ามเสมอ
</Warning>

### ตัวอย่างหลายบัญชี

ใช้ `accountId` เพื่อระบุบัญชีเฉพาะในช่องทางแบบหลายบัญชี เช่น Telegram:

```json5
{
  agents: {
    list: [
      {
        id: "ops",
        heartbeat: {
          every: "1h",
          target: "telegram",
          to: "12345678:topic:42", // ไม่บังคับ: ส่งไปยังหัวข้อ/เธรดที่ระบุ
          accountId: "ops-bot",
        },
      },
    ],
  },
  channels: {
    telegram: {
      accounts: {
        "ops-bot": { botToken: "YOUR_TELEGRAM_BOT_TOKEN" },
      },
    },
  },
}
```

### หมายเหตุเกี่ยวกับฟิลด์

<ParamField path="every" type="string">
  ช่วงเวลาของ Heartbeat (สตริงระยะเวลา หน่วยเริ่มต้น = นาที)
</ParamField>
<ParamField path="model" type="string">
  การแทนที่โมเดลสำหรับการเรียกใช้ Heartbeat ซึ่งไม่บังคับ (`provider/model`)
</ParamField>
<ParamField path="includeReasoning" type="boolean" default="false">
  เมื่อเปิดใช้ จะส่งข้อความ `Thinking` แยกต่างหากด้วยเมื่อมี (รูปแบบเดียวกับ `/reasoning on`)
</ParamField>
<ParamField path="lightContext" type="boolean" default="false">
  เมื่อเป็น true การเรียกใช้ Heartbeat จะใช้บริบทเริ่มต้นแบบเบาและเก็บเฉพาะ `HEARTBEAT.md` จากไฟล์เริ่มต้นในพื้นที่ทำงาน
</ParamField>
<ParamField path="isolatedSession" type="boolean" default="false">
  เมื่อเป็น true Heartbeat แต่ละครั้งจะทำงานในเซสชันใหม่โดยไม่มีประวัติการสนทนาก่อนหน้า ใช้รูปแบบการแยกส่วนเดียวกับ cron `sessionTarget: "isolated"` ซึ่งลดค่าใช้จ่ายโทเค็นต่อ Heartbeat ลงอย่างมาก ใช้ร่วมกับ `lightContext: true` เพื่อประหยัดสูงสุด การกำหนดเส้นทางการส่งยังคงใช้บริบทของเซสชันหลัก
</ParamField>
<ParamField path="skipWhenBusy" type="boolean" default="false">
  เมื่อเป็น true การเรียกใช้ Heartbeat จะเลื่อนออกไปตามเลนที่ไม่ว่างเพิ่มเติมของเอเจนต์นั้น ได้แก่ เอเจนต์ย่อยที่ผูกกับคีย์เซสชันของตนเองหรืองานคำสั่งซ้อน เลน cron จะเลื่อน Heartbeat เสมอแม้ไม่มีแฟล็กนี้ เพื่อไม่ให้โฮสต์โมเดลภายในเรียกใช้พรอมต์ cron และ Heartbeat พร้อมกัน
</ParamField>
<ParamField path="session" type="string">
  คีย์เซสชันสำหรับการเรียกใช้ Heartbeat ซึ่งไม่บังคับ

- `main` (ค่าเริ่มต้น): เซสชันหลักของเอเจนต์
- คีย์เซสชันที่ระบุอย่างชัดเจน (คัดลอกจาก `openclaw sessions --json` หรือ [CLI สำหรับเซสชัน](/th/cli/sessions))
- รูปแบบคีย์เซสชัน: ดู [เซสชัน](/th/concepts/session) และ [กลุ่ม](/th/channels/groups)

</ParamField>
<ParamField path="target" type="string">
- `last`: ส่งไปยังช่องทางภายนอกที่ใช้ล่าสุด
- ช่องทางที่ระบุชัดเจน: ช่องทางหรือรหัส Plugin ใดๆ ที่กำหนดค่าไว้ เช่น `discord`, `matrix`, `telegram` หรือ `whatsapp`
- `none` (ค่าเริ่มต้น): เรียกใช้ Heartbeat แต่ **ไม่ส่ง** ออกไปภายนอก

</ParamField>
<ParamField path="directPolicy" type='"allow" | "block"' default="allow">
  ควบคุมลักษณะการส่งโดยตรง/ทาง DM `allow`: อนุญาตให้ส่ง Heartbeat โดยตรง/ทาง DM `block`: ระงับการส่งโดยตรง/ทาง DM (`reason=dm-blocked`)

</ParamField>
<ParamField path="to" type="string">
  ตัวเลือกระบุผู้รับแทนค่าเดิม (รหัสเฉพาะของช่องทาง เช่น E.164 สำหรับ WhatsApp หรือรหัสแชต Telegram) สำหรับหัวข้อ/เธรดของ Telegram ให้ใช้ `<chatId>:topic:<messageThreadId>`

</ParamField>
<ParamField path="accountId" type="string">
  รหัสบัญชีเสริมสำหรับช่องทางที่มีหลายบัญชี เมื่อ `target: "last"` รหัสบัญชีจะใช้กับช่องทางล่าสุดที่ได้รับการระบุ หากช่องทางนั้นรองรับบัญชี มิฉะนั้นระบบจะไม่สนใจค่านี้ หากรหัสบัญชีไม่ตรงกับบัญชีที่กำหนดค่าไว้สำหรับช่องทางที่ได้รับการระบุ ระบบจะข้ามการส่ง

</ParamField>
<ParamField path="prompt" type="string">
  ใช้แทนเนื้อหาพรอมต์เริ่มต้น (ไม่ผสานรวม)

</ParamField>
<ParamField path="includeSystemPromptSection" type="boolean" default="true">
  กำหนดว่าจะใส่ส่วนพรอมต์ระบบ `## Heartbeats` ของเอเจนต์เริ่มต้นหรือไม่ ตั้งค่า `false` เพื่อคงลักษณะการทำงานของรันไทม์ Heartbeat (รอบเวลา การส่ง และ HEARTBEAT.md) แต่ไม่นำคำสั่ง Heartbeat ไปรวมในพรอมต์ระบบของเอเจนต์

</ParamField>
<ParamField path="ackMaxChars" type="number" default="300">
  จำนวนอักขระสูงสุดที่อนุญาตหลัง `HEARTBEAT_OK` ก่อนส่ง

</ParamField>
<ParamField path="suppressToolErrorWarnings" type="boolean">
  เมื่อตั้งเป็น true ให้ระงับเพย์โหลดคำเตือนข้อผิดพลาดของเครื่องมือระหว่างการเรียกใช้ Heartbeat

</ParamField>
<ParamField path="timeoutSeconds" type="number" default="global timeout or min(every, 600)">
  จำนวนวินาทีสูงสุดที่อนุญาตให้รอบการทำงานของเอเจนต์ Heartbeat ดำเนินการก่อนถูกยกเลิก หากไม่ตั้งค่า ระบบจะใช้ `agents.defaults.timeoutSeconds` เมื่อมีการตั้งค่านั้น มิฉะนั้นจะใช้รอบเวลาของ Heartbeat โดยจำกัดสูงสุดที่ 600 วินาที

</ParamField>
<ParamField path="activeHours" type="object">
  จำกัดการเรียกใช้ Heartbeat ให้อยู่ภายในช่วงเวลา ออบเจ็กต์ประกอบด้วย `start` (HH:MM รวมเวลานี้ด้วย ใช้ `00:00` สำหรับเวลาเริ่มต้นของวัน), `end` (HH:MM ไม่รวมเวลานี้ อนุญาตให้ใช้ `24:00` สำหรับเวลาสิ้นสุดวัน) และ `timezone` ซึ่งเป็นตัวเลือกเสริม

- หากละไว้หรือเป็น `"user"`: ใช้ `agents.defaults.userTimezone` หากมีการตั้งค่าไว้ มิฉะนั้นจะใช้เขตเวลาของระบบโฮสต์เป็นค่าทดแทน
- `"local"`: ใช้เขตเวลาของระบบโฮสต์เสมอ
- ตัวระบุ IANA ใดๆ (เช่น `America/New_York`): ใช้โดยตรง หากไม่ถูกต้องจะใช้ลักษณะการทำงานของ `"user"` ข้างต้นเป็นค่าทดแทน
- `start` และ `end` ต้องไม่เท่ากันสำหรับช่วงเวลาที่ทำงาน ค่าที่เท่ากันจะถือว่ามีความกว้างเป็นศูนย์ (อยู่นอกช่วงเวลาเสมอ)
- เมื่ออยู่นอกช่วงเวลาที่ทำงาน ระบบจะข้าม Heartbeat จนกว่าจะถึงรอบถัดไปภายในช่วงเวลา

</ParamField>

## ลักษณะการส่ง

<AccordionGroup>
  <Accordion title="การกำหนดเส้นทางเซสชันและเป้าหมาย">
    - โดยค่าเริ่มต้น Heartbeat จะทำงานในเซสชันหลักของเอเจนต์ (`agent:<id>:<mainKey>`) หรือ `global` เมื่อ `session.scope = "global"` ตั้งค่า `session` เพื่อเปลี่ยนเป็นเซสชันของช่องทางที่ระบุ (Discord/WhatsApp/ฯลฯ)
    - `session` มีผลเฉพาะกับบริบทการทำงาน การส่งถูกควบคุมโดย `target` และ `to`
    - หากต้องการส่งไปยังช่องทาง/ผู้รับที่ระบุ ให้ตั้งค่า `target` + `to` เมื่อใช้ `target: "last"` ระบบจะส่งผ่านช่องทางภายนอกล่าสุดของเซสชันนั้น
    - โดยค่าเริ่มต้น การส่ง Heartbeat อนุญาตเป้าหมายโดยตรง/ทาง DM ตั้งค่า `directPolicy: "block"` เพื่อระงับการส่งไปยังเป้าหมายโดยตรง โดยยังคงเรียกใช้รอบ Heartbeat
    - หากคิวหลัก เลนของเซสชันเป้าหมาย เลน Cron หรืองาน Cron ที่กำลังทำงานอยู่ไม่ว่าง ระบบจะข้าม Heartbeat และลองใหม่ในภายหลัง
    - หาก `skipWhenBusy: true` เลนของเอเจนต์ย่อยที่อิงคีย์เซสชันและเลนซ้อนของเอเจนต์นี้จะเลื่อนการเรียกใช้ Heartbeat เช่นกัน เลนที่ไม่ว่างของเอเจนต์อื่นจะไม่ทำให้เอเจนต์นี้เลื่อนการทำงาน
    - หาก `target` ไม่สามารถระบุปลายทางภายนอกได้ ระบบยังคงทำงาน แต่จะไม่ส่งข้อความออก

  </Accordion>
  <Accordion title="การมองเห็นและลักษณะการข้าม">
    - หาก `showOk`, `showAlerts` และ `useIndicator` ถูกปิดใช้งานทั้งหมด ระบบจะข้ามการทำงานตั้งแต่ต้นในฐานะ `reason=alerts-disabled`
    - หากปิดใช้งานเฉพาะการส่งการแจ้งเตือน OpenClaw ยังสามารถเรียกใช้ Heartbeat อัปเดตการประทับเวลาของงานที่ถึงกำหนด คืนค่าการประทับเวลาเมื่อเซสชันไม่ได้ใช้งาน และระงับเพย์โหลดการแจ้งเตือนที่ส่งออก
    - หากเป้าหมาย Heartbeat ที่ได้รับการระบุรองรับตัวบ่งชี้การพิมพ์ OpenClaw จะแสดงว่ากำลังพิมพ์ขณะที่ Heartbeat ทำงาน โดยใช้เป้าหมายเดียวกับที่ Heartbeat จะส่งเอาต์พุตแชตไป และถูกปิดใช้งานด้วย `typingMode: "never"`

  </Accordion>
  <Accordion title="วงจรชีวิตและการตรวจสอบเซสชัน">
    - การตอบกลับที่มีเฉพาะ Heartbeat **ไม่** ทำให้เซสชันยังคงทำงานอยู่ เมทาดาทาของ Heartbeat อาจอัปเดตแถวเซสชัน แต่การหมดอายุเมื่อไม่ได้ใช้งานจะใช้ `lastInteractionAt` จากข้อความจริงล่าสุดของผู้ใช้/ช่องทาง และการหมดอายุรายวันจะใช้ `sessionStartedAt`
    - ประวัติใน Control UI และ WebChat จะซ่อนพรอมต์ Heartbeat และการตอบรับที่มีเฉพาะ OK ทรานสคริปต์เซสชันเบื้องหลังยังคงมีรอบเหล่านั้นเพื่อการตรวจสอบ/เล่นซ้ำได้
    - [งานเบื้องหลัง](/th/automation/tasks) ที่แยกออกมาสามารถเพิ่มอีเวนต์ระบบลงในคิวและปลุก Heartbeat เมื่อเซสชันหลักควรรับรู้บางสิ่งอย่างรวดเร็ว การปลุกดังกล่าวไม่ได้ทำให้การเรียกใช้ Heartbeat กลายเป็นงานเบื้องหลัง

  </Accordion>
</AccordionGroup>

## การควบคุมการมองเห็น

โดยค่าเริ่มต้น ระบบจะระงับการตอบรับ `HEARTBEAT_OK` ขณะที่ส่งเนื้อหาการแจ้งเตือน คุณสามารถปรับค่านี้สำหรับแต่ละช่องทางหรือแต่ละบัญชีได้:

```yaml
channels:
  defaults:
    heartbeat:
      showOk: false # ซ่อน HEARTBEAT_OK (ค่าเริ่มต้น)
      showAlerts: true # แสดงข้อความแจ้งเตือน (ค่าเริ่มต้น)
      useIndicator: true # ส่งอีเวนต์ตัวบ่งชี้ (ค่าเริ่มต้น)
  telegram:
    heartbeat:
      showOk: true # แสดงการตอบรับ OK บน Telegram
  whatsapp:
    accounts:
      work:
        heartbeat:
          showAlerts: false # ระงับการส่งการแจ้งเตือนสำหรับบัญชีนี้
```

ลำดับความสำคัญ: ต่อบัญชี → ต่อช่องทาง → ค่าเริ่มต้นของช่องทาง → ค่าเริ่มต้นในตัว

### แต่ละแฟล็กทำอะไร

- `showOk`: ส่งการตอบรับ `HEARTBEAT_OK` เมื่อโมเดลส่งคืนคำตอบที่มีเฉพาะ OK
- `showAlerts`: ส่งเนื้อหาการแจ้งเตือนเมื่อโมเดลส่งคืนคำตอบที่ไม่ใช่ OK
- `useIndicator`: ส่งอีเวนต์ตัวบ่งชี้สำหรับพื้นผิวสถานะของ UI

หากทั้ง **สามค่า** เป็น false OpenClaw จะข้ามการเรียกใช้ Heartbeat ทั้งหมด (ไม่มีการเรียกโมเดล)

### ตัวอย่างต่อช่องทางเทียบกับต่อบัญชี

```yaml
channels:
  defaults:
    heartbeat:
      showOk: false
      showAlerts: true
      useIndicator: true
  slack:
    heartbeat:
      showOk: true # บัญชี Slack ทั้งหมด
    accounts:
      ops:
        heartbeat:
          showAlerts: false # ระงับการแจ้งเตือนสำหรับบัญชี ops เท่านั้น
  telegram:
    heartbeat:
      showOk: true
```

### รูปแบบทั่วไป

| เป้าหมาย                                     | การกำหนดค่า                                                                                   |
| ---------------------------------------- | ---------------------------------------------------------------------------------------- |
| ลักษณะการทำงานเริ่มต้น (ปิดเสียง OK เปิดการแจ้งเตือน) | _(ไม่ต้องกำหนดค่า)_                                                                     |
| ปิดเสียงทั้งหมด (ไม่มีข้อความ ไม่มีตัวบ่งชี้) | `channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false }` |
| เฉพาะตัวบ่งชี้ (ไม่มีข้อความ)             | `channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true }`  |
| แสดง OK ในช่องทางเดียวเท่านั้น                  | `channels.telegram.heartbeat: { showOk: true }`                                          |

## HEARTBEAT.md (ไม่บังคับ)

หากมีไฟล์ `HEARTBEAT.md` อยู่ในเวิร์กสเปซ พรอมต์เริ่มต้นจะสั่งให้เอเจนต์อ่านไฟล์นี้ ให้มองว่าไฟล์นี้เป็น "รายการตรวจสอบ Heartbeat" ซึ่งควรมีขนาดเล็ก คงที่ และปลอดภัยสำหรับการพิจารณาทุก 30 นาที

ในการทำงานตามปกติ ระบบจะแทรก `HEARTBEAT.md` เฉพาะเมื่อเปิดใช้งานแนวทาง Heartbeat สำหรับเอเจนต์เริ่มต้น การปิดใช้งานรอบเวลาของ Heartbeat ด้วย `0m` หรือตั้งค่า `includeSystemPromptSection: false` จะไม่นำไฟล์นี้ไปรวมในบริบทบูตสแตรปตามปกติ

บนแฮร์เนส Codex แบบเนทีฟ เนื้อหา `HEARTBEAT.md` จะไม่ถูกแทรกเข้าไปในรอบการทำงานเหมือนไฟล์บูตสแตรปอื่น หากมีไฟล์นี้และมีเนื้อหาที่ไม่ใช่ช่องว่าง หมายเหตุโหมดการทำงานร่วมกันของ Heartbeat จะชี้ Codex ไปยังไฟล์และสั่งให้อ่านไฟล์ก่อนดำเนินการต่อ

หากมี `HEARTBEAT.md` แต่ไม่มีเนื้อหาที่มีผล (มีเพียงบรรทัดว่าง ความคิดเห็น Markdown/HTML หัวข้อ Markdown เช่น `# Heading` เครื่องหมายรั้ว หรือโครงรายการตรวจสอบที่ว่างเปล่า) OpenClaw จะข้ามการเรียกใช้ Heartbeat เพื่อประหยัดการเรียก API การข้ามดังกล่าวจะรายงานเป็น `reason=empty-heartbeat-file` หากไม่มีไฟล์ Heartbeat จะยังคงทำงานและโมเดลจะตัดสินใจว่าควรทำอะไร

ควรทำให้ไฟล์มีขนาดเล็กมาก (รายการตรวจสอบหรือข้อความเตือนสั้นๆ) เพื่อหลีกเลี่ยงไม่ให้พรอมต์มีขนาดใหญ่เกินไป

ตัวอย่าง `HEARTBEAT.md`:

```md
# รายการตรวจสอบ Heartbeat

- ตรวจสอบอย่างรวดเร็ว: มีเรื่องเร่งด่วนในกล่องข้อความหรือไม่
- หากเป็นช่วงกลางวัน ให้ตรวจสอบสถานะสั้นๆ หากไม่มีเรื่องอื่นค้างอยู่
- หากงานถูกขัดขวาง ให้จดว่า _ขาดอะไรอยู่_ และถาม Peter ในครั้งถัดไป
```

### บล็อก `tasks:`

`HEARTBEAT.md` ยังรองรับบล็อก `tasks:` แบบมีโครงสร้างขนาดเล็กสำหรับการตรวจสอบตามช่วงเวลาภายใน Heartbeat เอง

ตัวอย่าง:

```md
tasks:

- name: inbox-triage
  interval: 30m
  prompt: "ตรวจหาอีเมลเร่งด่วนที่ยังไม่ได้อ่าน และทำเครื่องหมายรายการที่มีข้อจำกัดด้านเวลา"
- name: calendar-scan
  interval: 2h
  prompt: "ตรวจสอบการประชุมที่กำลังจะมาถึงซึ่งต้องเตรียมตัวหรือติดตามผล"

# คำสั่งเพิ่มเติม

- ทำให้การแจ้งเตือนสั้นกระชับ
- หากไม่มีสิ่งใดต้องดำเนินการหลังตรวจสอบงานที่ถึงกำหนดทั้งหมดแล้ว ให้ตอบ HEARTBEAT_OK
```

<AccordionGroup>
  <Accordion title="ลักษณะการทำงาน">
    - OpenClaw จะแยกวิเคราะห์บล็อก `tasks:` และตรวจสอบแต่ละงานตาม `interval` ของงานนั้น
    - เฉพาะงานที่ **ถึงกำหนด** เท่านั้นที่จะรวมอยู่ในพรอมต์ Heartbeat สำหรับรอบนั้น
    - หากไม่มีงานที่ถึงกำหนด ระบบจะข้าม Heartbeat ทั้งหมด (`reason=no-tasks-due`) เพื่อหลีกเลี่ยงการเรียกโมเดลโดยสูญเปล่า
    - เนื้อหาที่ไม่ใช่งานใน `HEARTBEAT.md` จะถูกเก็บไว้และต่อท้ายเป็นบริบทเพิ่มเติมหลังรายการงานที่ถึงกำหนด
    - การประทับเวลาการทำงานล่าสุดของงานจะจัดเก็บไว้ในสถานะเซสชัน (`heartbeatTaskState`) ดังนั้นช่วงเวลาจึงยังคงอยู่หลังการรีสตาร์ตตามปกติ
    - การประทับเวลาของงานจะเลื่อนไปข้างหน้าหลังจากการเรียกใช้ Heartbeat ดำเนินเส้นทางการตอบกลับตามปกติเสร็จสมบูรณ์เท่านั้น การเรียกใช้ `empty-heartbeat-file` / `no-tasks-due` ที่ถูกข้ามจะไม่ทำเครื่องหมายว่างานเสร็จสมบูรณ์

  </Accordion>
</AccordionGroup>

โหมดงานมีประโยชน์เมื่อต้องการให้ไฟล์ Heartbeat ไฟล์เดียวเก็บการตรวจสอบตามรอบเวลาหลายรายการ โดยไม่ต้องเสียค่าใช้จ่ายให้ทั้งหมดในทุกรอบ

### เอเจนต์สามารถอัปเดต HEARTBEAT.md ได้หรือไม่

ได้ หากคุณสั่งให้ดำเนินการ

`HEARTBEAT.md` เป็นเพียงไฟล์ปกติในเวิร์กสเปซของเอเจนต์ ดังนั้นคุณจึงสามารถบอกเอเจนต์ (ในการแชตปกติ) ได้ดังตัวอย่างต่อไปนี้:

- "อัปเดต `HEARTBEAT.md` เพื่อเพิ่มการตรวจสอบปฏิทินรายวัน"
- "เขียน `HEARTBEAT.md` ใหม่ให้สั้นลงและเน้นการติดตามผลในกล่องข้อความ"

หากต้องการให้สิ่งนี้เกิดขึ้นโดยอัตโนมัติ คุณยังสามารถเพิ่มบรรทัดที่ระบุอย่างชัดเจนในพรอมต์ Heartbeat เช่น: "หากรายการตรวจสอบล้าสมัย ให้อัปเดต HEARTBEAT.md ด้วยรายการที่ดีกว่า"

<Warning>
อย่าใส่ข้อมูลลับ (คีย์ API หมายเลขโทรศัพท์ โทเค็นส่วนตัว) ลงใน `HEARTBEAT.md` เนื่องจากข้อมูลดังกล่าวจะกลายเป็นส่วนหนึ่งของบริบทพรอมต์
</Warning>

## การปลุกด้วยตนเอง (ตามคำขอ)

ใช้ `openclaw system event` เพื่อเพิ่มอีเวนต์ระบบลงในคิว และเลือกเรียก Heartbeat ทันทีได้:

```bash
openclaw system event --text "Check for urgent follow-ups" --mode now
```

| แฟล็ก                         | คำอธิบาย                                                                                      |
| ---------------------------- | ------------------------------------------------------------------------------------------------ |
| `--text <text>`              | ข้อความเหตุการณ์ของระบบ (จำเป็น)                                                                    |
| `--mode <mode>`              | `now` เรียกใช้ Heartbeat ทันที ส่วน `next-heartbeat` (ค่าเริ่มต้น) จะรอรอบที่กำหนดไว้ครั้งถัดไป |
| `--session-key <sessionKey>` | กำหนดเป้าหมายเหตุการณ์ไปยังเซสชันที่ระบุ ค่าเริ่มต้นคือเซสชันหลักของเอเจนต์                   |
| `--json`                     | แสดงผลเป็น JSON                                                                                     |

หากไม่ได้ระบุ `--session-key` และมีเอเจนต์หลายตัวที่กำหนดค่า `heartbeat` ไว้ `--mode now` จะเรียกใช้ Heartbeat ของเอเจนต์เหล่านั้นแต่ละตัวทันที

การควบคุม Heartbeat ที่เกี่ยวข้องในกลุ่ม CLI เดียวกัน:

```bash
openclaw system heartbeat last     # แสดงเหตุการณ์ Heartbeat ล่าสุด
openclaw system heartbeat enable   # เปิดใช้งาน Heartbeat
openclaw system heartbeat disable  # ปิดใช้งาน Heartbeat
```

## การส่งมอบข้อมูลการให้เหตุผล (ไม่บังคับ)

โดยค่าเริ่มต้น Heartbeat จะส่งเฉพาะเพย์โหลด "คำตอบ" สุดท้ายเท่านั้น

หากต้องการความโปร่งใส ให้เปิดใช้งาน:

- `agents.defaults.heartbeat.includeReasoning: true`

เมื่อเปิดใช้งาน Heartbeat จะส่งข้อความแยกต่างหากซึ่งนำหน้าด้วย `Thinking` ด้วย (มีรูปแบบเดียวกับ `/reasoning on`) ซึ่งอาจมีประโยชน์เมื่อเอเจนต์กำลังจัดการหลายเซสชัน/หลาย Codex และต้องการทราบเหตุผลที่เอเจนต์ตัดสินใจแจ้งเตือน แต่ก็อาจเปิดเผยรายละเอียดภายในมากเกินกว่าที่ต้องการได้เช่นกัน ควรปิดไว้ในการแชตกลุ่ม

## การคำนึงถึงค่าใช้จ่าย

Heartbeat จะเรียกใช้รอบการทำงานเต็มรูปแบบของเอเจนต์ ช่วงเวลาที่สั้นลงจะใช้โทเค็นมากขึ้น หากต้องการลดค่าใช้จ่าย:

- ใช้ `isolatedSession: true` เพื่อหลีกเลี่ยงการส่งประวัติการสนทนาทั้งหมด (ลดจากประมาณ 100K โทเค็นเหลือประมาณ 2-5K ต่อการเรียกใช้)
- ใช้ `lightContext: true` เพื่อจำกัดไฟล์บูตสแตรปให้เหลือเพียง `HEARTBEAT.md`
- ตั้งค่า `model` ที่มีต้นทุนต่ำกว่า (เช่น `ollama/llama3.2:1b`)
- กำหนดให้ `HEARTBEAT.md` มีขนาดเล็ก
- ใช้ `target: "none"` หากต้องการเพียงการอัปเดตสถานะภายใน

## บริบทล้นหลังจาก Heartbeat

Heartbeat จะคงโมเดลรันไทม์ที่มีอยู่ของเซสชันที่ใช้ร่วมกันไว้หลังจากการเรียกใช้เสร็จสิ้น ดังนั้น Heartbeat ที่เปลี่ยนเซสชันไปใช้โมเดลภายในเครื่องที่เล็กกว่า (ตัวอย่างเช่น โมเดล Ollama ที่มีหน้าต่างบริบทขนาด 32k) อาจทำให้โมเดลนั้นยังคงถูกใช้ในรอบถัดไปของเซสชันหลัก หากรอบถัดไปดังกล่าวรายงานว่าบริบทล้น และโมเดลรันไทม์ล่าสุดของเซสชันตรงกับ `heartbeat.model` ที่กำหนดค่าไว้ ข้อความกู้คืนของ OpenClaw จะระบุว่าการคงค้างของโมเดลจาก Heartbeat น่าจะเป็นสาเหตุและแนะนำวิธีแก้ไข

เพื่อหลีกเลี่ยงปัญหานี้ ให้ใช้ `isolatedSession: true` เพื่อเรียกใช้ Heartbeat ในเซสชันใหม่ (อาจใช้ร่วมกับ `lightContext: true` เพื่อให้พรอมต์มีขนาดเล็กที่สุด) หรือเลือกโมเดล Heartbeat ที่มีหน้าต่างบริบทใหญ่เพียงพอสำหรับเซสชันที่ใช้ร่วมกัน

## เนื้อหาที่เกี่ยวข้อง

- [ระบบอัตโนมัติ](/th/automation) - กลไกการทำงานอัตโนมัติทั้งหมดโดยสรุป
- [งานเบื้องหลัง](/th/automation/tasks) - วิธีติดตามงานที่ทำงานแยกออกมา
- [เขตเวลา](/th/concepts/timezone) - ผลของเขตเวลาต่อการกำหนดเวลา Heartbeat
- [การแก้ไขปัญหา](/th/automation/cron-jobs#troubleshooting) - การดีบักปัญหาระบบอัตโนมัติ
