Cron 작업 (Gateway 스케줄러)
Cron vs Heartbeat? 각각을 언제 사용해야 하는지에 대한 가이드는 Cron vs Heartbeat를 참고하십시오.Cron 은 Gateway 에 내장된 스케줄러입니다. 작업을 영속화하고, 적절한 시점에 에이전트를 깨우며, 선택적으로 출력을 채팅으로 전달할 수 있습니다. “매일 아침 이 작업을 실행” 또는 “20 분 후에 에이전트를 찌르기” 와 같은 요구라면, cron 이 메커니즘입니다. 문제 해결: /automation/troubleshooting
TL;DR
- Cron 은 Gateway 내부에서 실행됩니다 (모델 내부가 아님).
- 작업은
~/.openclaw/cron/아래에 영속화되므로 재시작 시에도 스케줄이 유실되지 않습니다. - 두 가지 실행 방식:
- 메인 세션: 시스템 이벤트를 큐에 넣고, 다음 하트비트에서 실행합니다.
- 격리됨:
cron:<jobId>에서 전용 에이전트 턴을 실행하며, 전달 방식(기본적으로 announce 또는 없음)을 선택합니다.
- 깨우기는 일급 기능입니다: 작업은 “지금 깨우기” 또는 “다음 하트비트”를 요청할 수 있습니다.
빠른 시작 (실행 중심)
일회성 알림을 생성하고, 존재를 확인한 뒤 즉시 실행합니다:도구 호출 동등물 (Gateway cron 도구)
정식 JSON 형태와 예시는 도구 호출을 위한 JSON 스키마를 참고하십시오.cron 작업 저장 위치
Cron 작업은 기본적으로 Gateway 호스트의~/.openclaw/cron/jobs.json 에 저장됩니다.
Gateway 는 파일을 메모리로 로드하고 변경 시 다시 기록하므로, 수동 편집은
Gateway 가 중지된 상태에서만 안전합니다. 변경에는 openclaw cron add/edit 또는 cron
도구 호출 API 사용을 권장합니다.
초보자 친화적 개요
cron 작업은 다음으로 생각할 수 있습니다: 언제 실행할지 + 무엇을 할지.-
스케줄 선택
- 일회성 알림 →
schedule.kind = "at"(CLI:--at) - 반복 작업 →
schedule.kind = "every"또는schedule.kind = "cron" - ISO 타임스탬프에 타임존이 없으면 UTC 로 처리됩니다.
- 일회성 알림 →
-
실행 위치 선택
sessionTarget: "main"→ 메인 컨텍스트로 다음 하트비트 동안 실행sessionTarget: "isolated"→cron:<jobId>에서 전용 에이전트 턴 실행
-
페이로드 선택
- 메인 세션 →
payload.kind = "systemEvent" - 격리 세션 →
payload.kind = "agentTurn"
- 메인 세션 →
schedule.kind = "at")은 기본적으로 성공 후 삭제됩니다. 유지하려면 deleteAfterRun: false 를 설정하십시오(성공 후 비활성화됩니다).
개념
작업
cron 작업은 다음을 포함하는 저장 레코드입니다:- 스케줄(언제 실행할지),
- 페이로드(무엇을 할지),
- 선택적 전달 모드(announce 또는 none).
- 선택적 에이전트 바인딩(
agentId): 특정 에이전트로 작업을 실행합니다. 누락되었거나 알 수 없는 경우 Gateway 는 기본 에이전트로 폴백합니다.
jobId 로 식별됩니다(CLI/Gateway API 에서 사용).
에이전트 도구 호출에서는 jobId 가 정식이며, 레거시 id 도 호환을 위해 허용됩니다.
일회성 작업은 기본적으로 성공 후 자동 삭제되며, 유지하려면 deleteAfterRun: false 를 설정하십시오.
스케줄
Cron 은 세 가지 스케줄 유형을 지원합니다:at:schedule.at(ISO 8601) 를 통한 일회성 타임스탬프every: 고정 간격(ms)cron: 선택적 IANA 타임존을 포함한 5 필드 cron 표현식
croner 를 사용합니다. 타임존이 생략되면 Gateway 호스트의
로컬 타임존이 사용됩니다.
메인 vs 격리 실행
메인 세션 작업 (시스템 이벤트)
메인 작업은 시스템 이벤트를 큐에 넣고 선택적으로 하트비트 러너를 깨웁니다. 반드시payload.kind = "systemEvent" 를 사용해야 합니다.
wakeMode: "now"(기본): 이벤트가 즉시 하트비트 실행을 트리거합니다.wakeMode: "next-heartbeat": 이벤트가 다음 예정된 하트비트를 기다립니다.
격리 작업 (전용 cron 세션)
격리 작업은 세션cron:<jobId> 에서 전용 에이전트 턴을 실행합니다.
주요 동작:
- 추적성을 위해 프롬프트 앞에
[cron:<jobId> <job name>]가 접두됩니다. - 각 실행은 새로운 세션 id 로 시작합니다(이전 대화 이월 없음).
- 기본 동작:
delivery가 생략되면, 격리 작업은 요약을 announce 합니다(delivery.mode = "announce"). delivery.mode(격리 전용)으로 동작을 선택합니다:announce: 대상 채널로 요약을 전달하고, 메인 세션에 간단한 요약을 게시합니다.none: 내부 전용(전달 없음, 메인 세션 요약 없음).
wakeMode는 메인 세션 요약 게시 시점을 제어합니다:now: 즉시 하트비트.next-heartbeat: 다음 예정된 하트비트를 대기.
페이로드 형태 (실행 내용)
두 가지 페이로드 유형이 지원됩니다:systemEvent: 메인 세션 전용, 하트비트 프롬프트를 통해 라우팅agentTurn: 격리 세션 전용, 전용 에이전트 턴 실행
agentTurn 필드:
message: 필수 텍스트 프롬프트model/thinking: 선택적 오버라이드(아래 참고)timeoutSeconds: 선택적 타임아웃 오버라이드
delivery.mode:none|announcedelivery.channel:last또는 특정 채널delivery.to: 채널별 대상(전화/채팅/채널 id)delivery.bestEffort: announce 전달 실패 시 작업 실패를 회피
delivery.channel/delivery.to 를 사용하십시오. delivery.mode = "none" 인 경우, 메인 세션에 요약이 게시되지 않습니다.
격리 작업에서 delivery 가 생략되면, OpenClaw 는 기본값으로 announce 를 사용합니다.
Announce 전달 흐름
delivery.mode = "announce" 인 경우, cron 은 아웃바운드 채널 어댑터를 통해 직접 전달합니다.
메시지를 작성하거나 전달하기 위해 메인 에이전트가 구동되지 않습니다.
동작 세부사항:
- 콘텐츠: 전달은 격리 실행의 아웃바운드 페이로드(텍스트/미디어)를 사용하며, 일반적인 청킹과 채널 포맷팅을 따릅니다.
- 하트비트 전용 응답(
HEARTBEAT_OK로 실제 콘텐츠가 없는 경우)은 전달되지 않습니다. - 격리 실행이 이미 메시지 도구를 통해 동일 대상에 메시지를 보냈다면, 중복을 피하기 위해 전달이 건너뜁니다.
- 전달 대상이 누락되었거나 유효하지 않으면
delivery.bestEffort = true가 아닌 한 작업은 실패합니다. - 메인 세션에 짧은 요약은
delivery.mode = "announce"인 경우에만 게시됩니다. - 메인 세션 요약은
wakeMode를 따릅니다:now는 즉시 하트비트를 트리거하고,next-heartbeat은 다음 예정된 하트비트를 대기합니다.
모델 및 사고(thinking) 오버라이드
격리 작업(agentTurn)은 모델과 사고 수준을 오버라이드할 수 있습니다:
model: 프로바이더/모델 문자열(예:anthropic/claude-sonnet-4-20250514) 또는 별칭(예:opus)thinking: 사고 수준(off,minimal,low,medium,high,xhigh; GPT-5.2 + Codex 모델 전용)
model 를 설정할 수 있지만, 이는 공유 메인 세션 모델을 변경합니다. 예기치 않은 컨텍스트 변화를 피하기 위해 모델 오버라이드는 격리 작업에만 권장합니다.
해결 우선순위:
- 작업 페이로드 오버라이드(최상)
- 훅별 기본값(예:
hooks.gmail.model) - 에이전트 설정 기본값
전달(채널 + 대상)
격리 작업은 최상위delivery 설정을 통해 채널로 출력을 전달할 수 있습니다:
delivery.mode:announce(요약 전달) 또는nonedelivery.channel:whatsapp/telegram/discord/slack/mattermost(플러그인) /signal/imessage/lastdelivery.to: 채널별 수신 대상
sessionTarget: "isolated").
delivery.channel 또는 delivery.to 이 생략되면, cron 은 메인 세션의
“마지막 라우트”(에이전트가 마지막으로 응답한 위치)로 폴백할 수 있습니다.
대상 형식 알림:
- Slack/Discord/Mattermost(플러그인) 대상은 모호성을 피하기 위해 명시적 접두사(예:
channel:<id>,user:<id>)를 사용해야 합니다. - Telegram 토픽은
:topic:형식을 사용하십시오(아래 참고).
Telegram 전달 대상(토픽 / 포럼 스레드)
Telegram 은message_thread_id 를 통해 포럼 토픽을 지원합니다. cron 전달의 경우,
to 필드에 토픽/스레드를 인코딩할 수 있습니다:
-1001234567890(채팅 id 만)-1001234567890:topic:123(권장: 명시적 토픽 마커)-1001234567890:123(약식: 숫자 접미사)
telegram:... / telegram:group:... 와 같은 접두 대상도 허용됩니다:
telegram:group:-1001234567890:topic:123
도구 호출을 위한 JSON 스키마
Gatewaycron.* 도구를 직접 호출할 때(에이전트 도구 호출 또는 RPC) 이 형태를 사용하십시오.
CLI 플래그는 20m 와 같은 사람 친화적 기간을 허용하지만, 도구 호출은
schedule.at 에 ISO 8601 문자열을, schedule.everyMs 에 밀리초를 사용해야 합니다.
cron.add 파라미터
일회성, 메인 세션 작업(시스템 이벤트):schedule.kind:at(at),every(everyMs), 또는cron(expr, 선택적tz)schedule.at는 ISO 8601 을 허용합니다(타임존 선택적; 생략 시 UTC 로 처리).everyMs는 밀리초입니다.sessionTarget는"main"또는"isolated"여야 하며,payload.kind과 일치해야 합니다.- 선택적 필드:
agentId,description,enabled,deleteAfterRun(at의 경우 기본값 true),delivery wakeMode는 생략 시"now"가 기본값입니다.
cron.update 파라미터
jobId가 정식이며,id은 호환을 위해 허용됩니다.- 패치에서 에이전트 바인딩을 제거하려면
agentId: null를 사용하십시오.
cron.run 및 cron.remove 파라미터
저장소 & 이력
- 작업 저장소:
~/.openclaw/cron/jobs.json(Gateway 관리 JSON) - 실행 이력:
~/.openclaw/cron/runs/<jobId>.jsonl(JSONL, 자동 정리) - 저장소 경로 오버라이드: 설정에서
cron.store
구성
cron.enabled: false(설정)OPENCLAW_SKIP_CRON=1(환경 변수)
CLI 빠른 시작
일회성 알림(UTC ISO, 성공 후 자동 삭제):--due 사용):
Gateway API 표면
cron.list,cron.status,cron.add,cron.update,cron.removecron.run(force 또는 due),cron.runs작업 없이 즉시 시스템 이벤트를 실행하려면openclaw system event를 사용하십시오.
문제 해결
“아무 것도 실행되지 않음”
- cron 이 활성화되어 있는지 확인:
cron.enabled및OPENCLAW_SKIP_CRON. - Gateway 가 연속적으로 실행 중인지 확인(Gateway 프로세스 내부에서 cron 이 실행됩니다).
cron스케줄의 경우: 타임존(--tz)과 호스트 타임존을 확인하십시오.
반복 작업이 실패 후 계속 지연됨
- OpenClaw 는 연속 오류 후 반복 작업에 지수적 재시도 백오프를 적용합니다: 재시도 간격은 30 초, 1 분, 5 분, 15 분, 이후 60 분입니다.
- 다음 성공 실행 후 백오프는 자동으로 리셋됩니다.
- 일회성(
at) 작업은 종료 실행(ok,error, 또는skipped) 후 비활성화되며 재시도하지 않습니다.
Telegram 이 잘못된 위치로 전달됨
- 포럼 토픽의 경우, 명시적이고 모호하지 않도록
-100…:topic:<id>를 사용하십시오. - 로그나 저장된 “마지막 라우트” 대상에
telegram:...접두사가 보이더라도 정상입니다. cron 전달은 이를 허용하며 토픽 id 를 올바르게 파싱합니다.