Skip to main content
Heartbeat와 Cron 중 무엇을 사용해야 하나요? 각각 언제 사용해야 하는지에 대한 지침은 자동화를 참조하세요.
Heartbeat는 기본 세션에서 주기적으로 에이전트 턴을 실행하여, 모델이 사용자에게 불필요한 메시지를 반복해서 보내지 않으면서도 주의가 필요한 사항을 알릴 수 있게 합니다. Heartbeat는 예약된 기본 세션 턴이며 백그라운드 작업 레코드를 생성하지 않습니다. 작업 레코드는 분리된 작업(ACP 실행, 하위 에이전트, 격리된 Cron 작업)을 위한 것입니다. 문제 해결: 예약된 작업

빠른 시작(초보자)

1

실행 주기 선택

Heartbeat를 활성화된 상태로 유지하거나(기본값은 30m, Claude CLI 재사용을 포함하여 Anthropic OAuth/토큰 인증이 구성된 경우 1h) 원하는 실행 주기를 설정합니다.
2

HEARTBEAT.md 추가(선택 사항)

에이전트 작업 공간에 간단한 HEARTBEAT.md 체크리스트나 tasks: 블록을 만듭니다.
3

Heartbeat 메시지를 보낼 위치 결정

기본값은 target: "none"입니다. 마지막 연락 대상으로 라우팅하려면 target: "last"를 설정합니다.
4

선택적 조정

  • 투명성을 위해 Heartbeat 추론 전달을 활성화합니다.
  • Heartbeat 실행에 HEARTBEAT.md만 필요한 경우 경량 부트스트랩 컨텍스트를 사용합니다.
  • Heartbeat마다 전체 대화 기록을 전송하지 않도록 격리된 세션을 활성화합니다.
  • Heartbeat 실행 시간을 활동 시간(현지 시간)으로 제한합니다.
구성 예시:

기본값

  • 간격: 30m. Anthropic 제공자 기본값을 적용하면 확인된 인증 모드가 OAuth/토큰(Claude CLI 재사용 포함)일 때 1h로 늘어나지만, heartbeat.every가 설정되지 않은 경우에만 적용됩니다. agents.defaults.heartbeat.every 또는 에이전트별 agents.list[].heartbeat.every를 설정하세요. 비활성화하려면 0m을 사용합니다.
  • 프롬프트 본문(agents.defaults.heartbeat.prompt로 구성 가능): HEARTBEAT.md가 있으면 읽으세요(작업 공간 컨텍스트). 내용을 엄격히 따르세요. 이전 채팅의 오래된 작업을 추론하거나 반복하지 마세요. 주의가 필요한 사항이 없으면 HEARTBEAT_OK로 응답하세요.
  • 시간 제한: Heartbeat 턴에 별도 설정이 없으면 agents.defaults.timeoutSeconds가 설정된 경우 해당 값을 사용합니다. 그렇지 않으면 최대 600초로 제한된 Heartbeat 실행 주기를 사용합니다. 더 긴 Heartbeat 작업에는 agents.defaults.heartbeat.timeoutSeconds 또는 에이전트별 agents.list[].heartbeat.timeoutSeconds를 설정합니다.
  • Heartbeat 프롬프트는 사용자 메시지로 그대로 전송됩니다. 시스템 프롬프트에는 기본 에이전트에서 Heartbeat가 활성화되어 있고 includeSystemPromptSectionfalse가 아닌 경우에만 “Heartbeats” 섹션이 포함되며, 실행에는 내부적으로 플래그가 지정됩니다.
  • 0m으로 Heartbeat를 비활성화하면 일반 실행에서도 부트스트랩 컨텍스트에서 HEARTBEAT.md를 제외하므로 모델이 Heartbeat 전용 지침을 보지 않습니다.
  • 활동 시간(heartbeat.activeHours)은 구성된 시간대에서 확인됩니다. 시간 범위를 벗어나면 해당 범위 안의 다음 틱까지 Heartbeat를 건너뜁니다.
  • Cron 작업이 실행 중이거나 대기열에 있으면 Heartbeat가 자동으로 연기됩니다. 에이전트 자체의 세션 키 기반 하위 에이전트 또는 중첩 명령 레인이 사용 중일 때도 연기하려면 heartbeat.skipWhenBusy: true를 설정합니다. 다른 에이전트에서 하위 에이전트 작업이 진행 중이라는 이유만으로 형제 에이전트가 더 이상 일시 중지되지 않습니다.

Heartbeat 프롬프트의 용도

기본 프롬프트는 의도적으로 광범위하게 구성되어 있습니다.
  • 백그라운드 작업: “미완료 작업 고려”는 에이전트가 후속 항목(받은편지함, 캘린더, 미리 알림, 대기 중인 작업)을 검토하고 긴급한 사항을 알리도록 유도합니다.
  • 사용자 안부 확인: “낮 시간에 가끔 사용자 안부 확인”은 때때로 간단한 “필요한 것이 있나요?” 메시지를 보내도록 유도하지만, 구성된 현지 시간대를 사용하여 야간에 불필요한 메시지를 보내지 않습니다(시간대 참조).
Heartbeat는 완료된 백그라운드 작업에 반응할 수 있지만 Heartbeat 실행 자체는 작업 레코드를 생성하지 않습니다. Heartbeat가 매우 구체적인 작업(예: “Gmail PubSub 통계 확인” 또는 “Gateway 상태 확인”)을 수행하도록 하려면 agents.defaults.heartbeat.prompt(또는 agents.list[].heartbeat.prompt)를 사용자 지정 본문으로 설정하세요. 본문은 그대로 전송됩니다.

응답 규약

  • 주의가 필요한 사항이 없으면 **HEARTBEAT_OK**로 응답합니다.
  • 대신 Heartbeat 실행에서 heartbeat_respond를 호출할 수 있습니다. 표시되는 업데이트가 없도록 하려면 notify: false를 사용하고, 알림을 보내려면 notify: truenotificationText를 함께 사용합니다. 구조화된 도구 응답이 있으면 텍스트 대체 응답보다 우선합니다.
  • Heartbeat 실행 중에는 응답의 시작 또는 끝HEARTBEAT_OK가 표시되면 OpenClaw가 이를 확인 응답으로 처리합니다. 해당 토큰을 제거한 뒤 남은 내용이 ackMaxChars(기본값: 300)이면 응답을 폐기합니다.
  • HEARTBEAT_OK가 응답의 중간에 표시되면 특별하게 처리하지 않습니다.
  • 알림의 경우 HEARTBEAT_OK를 포함하지 말고 알림 텍스트만 반환합니다.
Heartbeat 외부에서는 메시지 시작이나 끝에 잘못 포함된 HEARTBEAT_OK가 제거되고 로그에 기록됩니다. 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를 실행합니다.

활성 시간 예시

특정 시간대의 업무 시간으로 Heartbeat를 제한합니다.
이 시간 범위 밖(미국 동부 시간 오전 9시 이전 또는 오후 10시 이후)에는 Heartbeat를 건너뜁니다. 시간 범위 안에서 다음으로 예약된 틱은 정상적으로 실행됩니다.

연중무휴 설정

Heartbeat를 하루 종일 실행하려면 다음 패턴 중 하나를 사용하세요.
  • activeHours를 완전히 생략합니다(시간 범위 제한 없음. 기본 동작입니다).
  • 하루 전체 범위를 설정합니다: activeHours: { start: "00:00", end: "24:00" }.
startend를 같은 시간으로 설정하지 마세요(예: 08:00부터 08:00까지). 이는 폭이 0인 시간 범위로 처리되므로 Heartbeat를 항상 건너뜁니다.

다중 계정 예시

Telegram과 같은 다중 계정 채널에서 특정 계정을 대상으로 지정하려면 accountId를 사용하세요.

필드 참고 사항

string
Heartbeat 간격(기간 문자열. 기본 단위 = 분).
string
Heartbeat 실행에 사용할 선택적 모델 재정의(provider/model).
boolean
기본값:"false"
활성화하면 별도의 Thinking 메시지가 있는 경우 함께 전송합니다(/reasoning on과 동일한 형식).
boolean
기본값:"false"
true이면 Heartbeat 실행에서 경량 부트스트랩 컨텍스트를 사용하고 워크스페이스 부트스트랩 파일 중 HEARTBEAT.md만 유지합니다.
boolean
기본값:"false"
true이면 각 Heartbeat가 이전 대화 기록이 없는 새 세션에서 실행됩니다. Cron의 sessionTarget: "isolated"와 동일한 격리 패턴을 사용합니다. Heartbeat당 토큰 비용이 크게 줄어듭니다. 최대한 절감하려면 lightContext: true와 함께 사용하세요. 전송 라우팅에는 계속 기본 세션 컨텍스트가 사용됩니다.
boolean
기본값:"false"
true이면 해당 에이전트의 추가 사용 중 레인, 즉 자체 세션 키 기반 하위 에이전트 또는 중첩 명령 작업이 실행 중일 때 Heartbeat 실행을 연기합니다. 이 플래그가 없어도 Cron 레인은 항상 Heartbeat를 연기하므로 로컬 모델 호스트에서 Cron과 Heartbeat 프롬프트가 동시에 실행되지 않습니다.
string
Heartbeat 실행에 사용할 선택적 세션 키입니다.
  • main(기본값): 에이전트 기본 세션.
  • 명시적 세션 키(openclaw sessions --json 또는 세션 CLI에서 복사).
  • 세션 키 형식: 세션그룹을 참조하세요.
string
  • last: 마지막으로 사용한 외부 채널로 전송합니다.
  • 명시적 채널: 구성된 모든 채널 또는 Plugin ID(예: discord, matrix, telegram, whatsapp).
  • none(기본값): Heartbeat를 실행하지만 외부로 전송하지 않습니다.
"allow" | "block"
기본값:"allow"
직접 메시지/DM 전송 동작을 제어합니다. allow: 직접 메시지/DM으로 Heartbeat 전송을 허용합니다. block: 직접 메시지/DM 전송을 차단합니다(reason=dm-blocked).
string
선택적 수신자 재정의(채널별 ID, 예: WhatsApp의 E.164 또는 Telegram 채팅 ID). Telegram 주제/스레드에는 <chatId>:topic:<messageThreadId>를 사용합니다.
string
다중 계정 채널을 위한 선택적 계정 ID. target: "last"인 경우 계정을 지원하면 확인된 마지막 채널에 계정 ID가 적용되고, 그렇지 않으면 무시됩니다. 계정 ID가 확인된 채널에 구성된 계정과 일치하지 않으면 전송을 건너뜁니다.
string
기본 프롬프트 본문을 재정의합니다(병합하지 않음).
boolean
기본값:"true"
기본 에이전트의 ## Heartbeats 시스템 프롬프트 섹션을 삽입할지 여부입니다. 에이전트 시스템 프롬프트에서 Heartbeat 지침은 생략하면서 Heartbeat 런타임 동작(주기, 전송, HEARTBEAT.md)을 유지하려면 false로 설정합니다.
number
기본값:"300"
전송 전 HEARTBEAT_OK 뒤에 허용되는 최대 문자 수입니다.
boolean
true이면 Heartbeat 실행 중 도구 오류 경고 페이로드를 억제합니다.
number
기본값:"global timeout or min(every, 600)"
Heartbeat 에이전트 턴이 중단되기 전에 허용되는 최대 시간(초)입니다. 설정하지 않으면 agents.defaults.timeoutSeconds가 설정된 경우 해당 값을 사용하고, 그렇지 않으면 최대 600초로 제한된 Heartbeat 주기를 사용합니다.
object
Heartbeat 실행을 특정 시간대로 제한합니다. start(HH:MM, 포함; 하루 시작에는 00:00 사용), end(HH:MM, 미포함; 하루 끝에는 24:00 허용), 선택적 timezone을 포함하는 객체입니다.
  • 생략하거나 "user": 설정된 경우 agents.defaults.userTimezone을 사용하고, 그렇지 않으면 호스트 시스템 시간대로 대체합니다.
  • "local": 항상 호스트 시스템 시간대를 사용합니다.
  • 모든 IANA 식별자(예: America/New_York): 직접 사용하며, 유효하지 않으면 위의 "user" 동작으로 대체합니다.
  • 활성 시간대에서는 startend가 같아서는 안 됩니다. 같은 값은 너비가 0인 시간대(항상 시간대 밖)로 처리됩니다.
  • 활성 시간대 밖에서는 시간대 안의 다음 틱까지 Heartbeat를 건너뜁니다.

전송 동작

  • Heartbeat는 기본적으로 에이전트의 기본 세션(agent:<id>:<mainKey>)에서 실행되며, session.scope = "global"이면 global에서 실행됩니다. 특정 채널 세션(Discord/WhatsApp 등)으로 재정의하려면 session을 설정합니다.
  • session은 실행 컨텍스트에만 영향을 주며, 전송은 targetto로 제어됩니다.
  • 특정 채널/수신자에게 전송하려면 target + to를 설정합니다. target: "last"이면 해당 세션에서 마지막으로 사용한 외부 채널로 전송합니다.
  • Heartbeat 전송은 기본적으로 직접/DM 대상을 허용합니다. Heartbeat 턴은 계속 실행하면서 직접 대상 전송을 억제하려면 directPolicy: "block"을 설정합니다.
  • 기본 큐, 대상 세션 레인, Cron 레인 또는 활성 Cron 작업이 사용 중이면 Heartbeat를 건너뛰고 나중에 다시 시도합니다.
  • skipWhenBusy: true이면 이 에이전트의 세션 키 기반 하위 에이전트 및 중첩 레인도 Heartbeat 실행을 연기합니다. 다른 에이전트의 사용 중인 레인은 이 에이전트의 실행을 연기하지 않습니다.
  • target에서 외부 목적지를 확인할 수 없어도 실행은 계속되지만 외부 메시지는 전송되지 않습니다.
  • showOk, showAlerts, useIndicator가 모두 비활성화되어 있으면 실행 시작 전에 reason=alerts-disabled로 건너뜁니다.
  • 알림 전송만 비활성화된 경우에도 OpenClaw는 Heartbeat를 실행하고, 기한이 된 작업의 타임스탬프를 업데이트하고, 세션 유휴 타임스탬프를 복원하고, 외부 알림 페이로드를 억제할 수 있습니다.
  • 확인된 Heartbeat 대상이 입력 중 표시를 지원하면 Heartbeat 실행이 활성 상태인 동안 OpenClaw가 입력 중 상태를 표시합니다. 이는 Heartbeat가 채팅 출력을 전송할 때와 동일한 대상을 사용하며, typingMode: "never"로 비활성화할 수 있습니다.
  • Heartbeat 전용 응답은 세션을 활성 상태로 유지하지 않습니다. Heartbeat 메타데이터가 세션 행을 업데이트할 수 있지만, 유휴 만료는 마지막 실제 사용자/채널 메시지의 lastInteractionAt을 사용하고 일일 만료는 sessionStartedAt을 사용합니다.
  • Control UI 및 WebChat 기록에서는 Heartbeat 프롬프트와 OK 전용 확인 응답을 숨깁니다. 기본 세션 트랜스크립트에는 감사/재실행을 위해 해당 턴이 계속 포함될 수 있습니다.
  • 분리된 백그라운드 작업은 시스템 이벤트를 큐에 넣고, 기본 세션이 어떤 사항을 빠르게 인지해야 할 때 Heartbeat를 깨울 수 있습니다. 이 깨우기 동작이 Heartbeat 실행을 백그라운드 작업으로 만들지는 않습니다.

표시 제어

기본적으로 알림 콘텐츠는 전송하지만 HEARTBEAT_OK 확인 응답은 억제합니다. 채널별 또는 계정별로 이를 조정할 수 있습니다.
우선순위: 계정별 → 채널별 → 채널 기본값 → 내장 기본값.

각 플래그의 역할

  • showOk: 모델이 OK 전용 응답을 반환하면 HEARTBEAT_OK 확인 응답을 전송합니다.
  • showAlerts: 모델이 OK가 아닌 응답을 반환하면 알림 콘텐츠를 전송합니다.
  • useIndicator: UI 상태 화면에 표시기 이벤트를 방출합니다.
세 가지가 모두 false이면 OpenClaw는 Heartbeat 실행을 완전히 건너뜁니다(모델 호출 없음).

채널별 및 계정별 예시

일반적인 패턴

HEARTBEAT.md(선택 사항)

작업 공간에 HEARTBEAT.md 파일이 있으면 기본 프롬프트가 에이전트에게 이 파일을 읽도록 지시합니다. 이를 30분마다 검토할 수 있는 작고 안정적이며 안전한 “Heartbeat 체크리스트”라고 생각하면 됩니다. 일반 실행에서는 기본 에이전트에 Heartbeat 지침이 활성화된 경우에만 HEARTBEAT.md가 삽입됩니다. 0m으로 Heartbeat 주기를 비활성화하거나 includeSystemPromptSection: false를 설정하면 일반 부트스트랩 컨텍스트에서 이 파일이 생략됩니다. 네이티브 Codex 하네스에서는 다른 부트스트랩 파일과 달리 HEARTBEAT.md 콘텐츠가 턴에 삽입되지 않습니다. 파일이 존재하고 공백이 아닌 콘텐츠가 있으면 Heartbeat 협업 모드 메모가 Codex에 해당 파일을 가리키고 진행하기 전에 파일을 읽도록 지시합니다. HEARTBEAT.md가 존재하지만 사실상 비어 있는 경우(빈 줄, Markdown/HTML 주석, # 제목 같은 Markdown 제목, 펜스 마커 또는 빈 체크리스트 항목만 포함) OpenClaw는 API 호출을 줄이기 위해 Heartbeat 실행을 건너뜁니다. 이 건너뛰기는 reason=empty-heartbeat-file로 보고됩니다. 파일이 없어도 Heartbeat는 계속 실행되며 모델이 수행할 작업을 결정합니다. 프롬프트가 불필요하게 커지는 것을 방지하려면 파일을 작게 유지하십시오(짧은 체크리스트 또는 알림). HEARTBEAT.md 예시:

tasks: 블록

HEARTBEAT.md는 Heartbeat 자체에서 주기 기반 확인을 수행하는 작은 구조화된 tasks: 블록도 지원합니다. 예시:
  • OpenClaw는 tasks: 블록을 파싱하고 각 작업을 자체 interval과 비교하여 확인합니다.
  • 해당 틱에 기한이 도래한 작업만 Heartbeat 프롬프트에 포함됩니다.
  • 기한이 도래한 작업이 없으면 불필요한 모델 호출을 피하기 위해 Heartbeat를 완전히 건너뜁니다(reason=no-tasks-due).
  • HEARTBEAT.md의 작업 외 콘텐츠는 유지되며 기한이 도래한 작업 목록 뒤에 추가 컨텍스트로 덧붙여집니다.
  • 작업의 마지막 실행 타임스탬프는 세션 상태(heartbeatTaskState)에 저장되므로 일반적인 재시작 후에도 주기가 유지됩니다.
  • 작업 타임스탬프는 Heartbeat 실행이 정상 응답 경로를 완료한 후에만 갱신됩니다. 건너뛴 empty-heartbeat-file / no-tasks-due 실행은 작업을 완료된 것으로 표시하지 않습니다.
모든 틱에서 각 작업의 비용을 지불하지 않고 하나의 Heartbeat 파일에 여러 정기 확인 작업을 담으려는 경우 작업 모드가 유용합니다.

에이전트가 HEARTBEAT.md를 업데이트할 수 있나요?

예. 에이전트에게 요청하면 됩니다. HEARTBEAT.md는 에이전트 작업 공간에 있는 일반 파일이므로 일반 채팅에서 에이전트에게 다음과 같이 지시할 수 있습니다.
  • “매일 캘린더를 확인하도록 HEARTBEAT.md를 업데이트해 주세요.”
  • HEARTBEAT.md를 더 짧게 만들고 받은 편지함 후속 조치에 집중하도록 다시 작성해 주세요.”
이 작업이 선제적으로 수행되도록 하려면 Heartbeat 프롬프트에 다음과 같은 명시적 문장을 포함할 수도 있습니다. “체크리스트가 오래되면 HEARTBEAT.md를 더 나은 내용으로 업데이트하세요.”
HEARTBEAT.md에 비밀 정보(API 키, 전화번호, 비공개 토큰)를 넣지 마십시오. 프롬프트 컨텍스트의 일부가 됩니다.

수동 깨우기(요청 시)

시스템 이벤트를 큐에 넣고 선택적으로 즉시 Heartbeat를 트리거하려면 openclaw system event를 사용합니다.
--session-key가 지정되지 않았고 여러 에이전트에 heartbeat가 구성되어 있으면 --mode now는 해당 에이전트들의 Heartbeat를 각각 즉시 실행합니다. 동일한 CLI 그룹의 관련 Heartbeat 제어 명령:

추론 전송(선택 사항)

기본적으로 Heartbeat는 최종 “답변” 페이로드만 전달합니다. 투명성을 높이려면 다음을 활성화하세요.
  • agents.defaults.heartbeat.includeReasoning: true
활성화하면 Heartbeat는 Thinking 접두사가 붙은 별도의 메시지도 전달합니다(/reasoning on과 동일한 형식). 에이전트가 여러 세션/Codex를 관리할 때 왜 사용자에게 알림을 보내기로 결정했는지 확인하는 데 유용할 수 있지만, 원치 않는 내부 세부 정보가 더 많이 노출될 수도 있습니다. 그룹 채팅에서는 비활성화 상태를 유지하는 것이 좋습니다.

비용 고려 사항

Heartbeat는 전체 에이전트 턴을 실행합니다. 간격이 짧을수록 더 많은 토큰을 소비합니다. 비용을 줄이려면 다음을 따르세요.
  • 전체 대화 기록 전송을 피하려면 isolatedSession: true를 사용하세요(실행당 약 10만 토큰에서 약 2천~5천 토큰으로 감소).
  • 부트스트랩 파일을 HEARTBEAT.md로만 제한하려면 lightContext: true를 사용하세요.
  • 더 저렴한 model을 설정하세요(예: ollama/llama3.2:1b).
  • HEARTBEAT.md를 작게 유지하세요.
  • 내부 상태 업데이트만 필요하다면 target: "none"을 사용하세요.

Heartbeat 이후 컨텍스트 오버플로

Heartbeat 실행이 완료된 후에도 공유 세션의 기존 런타임 모델이 유지되므로, Heartbeat가 세션을 더 작은 로컬 모델(예: 컨텍스트 창이 32k인 Ollama 모델)로 전환했다면 다음 기본 세션 턴에서도 해당 모델이 그대로 사용될 수 있습니다. 이후 그 턴에서 컨텍스트 오버플로가 보고되고 세션의 마지막 런타임 모델이 구성된 heartbeat.model과 일치하면, OpenClaw의 복구 메시지는 Heartbeat 모델 잔류를 유력한 원인으로 지목하고 해결 방법을 제안합니다. 이를 방지하려면 isolatedSession: true를 사용하여 새 세션에서 Heartbeat를 실행하거나(가장 작은 프롬프트를 사용하려면 lightContext: true와 함께 사용 가능), 공유 세션에 충분히 큰 컨텍스트 창을 가진 Heartbeat 모델을 선택하세요.

관련 문서