본문으로 건너뛰기

크론 내부

cron 하위 시스템은 간단한 일회성 지연부터 기술 주입 및 크로스 플랫폼 제공을 통해 반복되는 cron 표현 작업에 이르기까지 예약된 작업 실행을 제공합니다.

주요 파일

파일목적
cron/jobs.py작업 모델, 저장, jobs.json에 대한 원자적 읽기/쓰기
cron/scheduler.py스케줄러 루프 — 예정된 작업 감지, 실행, 반복 추적
tools/cronjob_tools.py모델 페이싱 cronjob 도구 등록 및 핸들러
gateway/run.py게이트웨이 통합 — 장기 실행 루프의 크론 틱
hermes_cli/cron.pyCLI hermes cron 하위 명령

스케줄링 모델

네 가지 일정 형식이 지원됩니다.

형식행동
상대적 지연30m, 2h, 1d일회성, 지정된 지속 시간 이후 발사
간격every 2h, every 30m반복적이고 일정한 간격으로 발생합니다.
크론 표현0 9 * * *표준 5개 필드 크론 구문(분, 시, 일, 월, 요일)
ISO 타임스탬프2025-01-15T09:00:00원샷, 정확한 시간에 발사

모델 방향 표면은 작업 스타일 작업이 포함된 단일 cronjob 도구입니다. run, remove.

작업 저장

작업은 원자적 쓰기 의미(임시 파일에 쓴 다음 이름 바꾸기)를 사용하여 ~/.hermes/cron/jobs.json에 저장됩니다. 각 작업 레코드에는 다음이 포함됩니다.

{
"id": "a1b2c3d4e5f6",
"name": "Daily briefing",
"prompt": "Summarize today's AI news and funding rounds",
"schedule": {
"kind": "cron",
"expr": "0 9 * * *",
"display": "0 9 * * *"
},
"skills": ["ai-funding-daily-report"],
"deliver": "telegram:-1001234567890",
"repeat": {
"times": null,
"completed": 42
},
"state": "scheduled",
"enabled": true,
"next_run_at": "2025-01-16T09:00:",
"last_run_at": "2025-01-15T09:00:",
"last_status": "ok",
"created_at": "2025-01-01T00:00:",
"model": null,
"provider": null,
"script": null
}

작업 수명주기 상태

상태의미
scheduled활성 상태이며 다음 예정된 시간에 실행됩니다.
paused일시 중지됨 - 재개될 때까지 실행되지 않습니다.
completed반복 횟수가 소진되거나 일발이 발사되었습니다.
running현재 실행 중(임시 상태)

이전 버전과의 호환성

이전 작업에는 skills 배열 대신 단일 skill 필드가 있을 수 있습니다. 스케줄러는 로드 시 이를 정규화합니다. 단일 skillskills: [skill]으로 승격됩니다.

스케줄러 런타임

틱주기

스케줄러는 정기적인 틱(기본값: 60초마다)으로 실행됩니다.

tick()
1. Acquire scheduler lock (prevents overlapping ticks)
2. Load all jobs from jobs.json
3. Filter to due jobs (next_run <= now AND state == "scheduled")
4. For each due job:
a. Set state to "running"
b. Create fresh AIAgent session (no conversation history)
c. Load attached skills in order (injected as user messages)
d. Run the job prompt through the agent
e. Deliver the response to the configured target
f. Update run_count, compute next_run
g. If repeat count exhausted → state = "completed"
h. Otherwise → state = "scheduled"
5. Write updated jobs back to jobs.json
6. Release scheduler lock

게이트웨이 통합

게이트웨이 모드에서 스케줄러는 메시지 처리와 함께 60초마다 scheduler.tick()을 호출하는 전용 백그라운드 스레드(_start_cron_ticker in gateway/run.py)에서 실행됩니다.

CLI 모드에서 크론 작업은 hermes cron 명령이 실행되거나 활성 CLI 세션 중에만 실행됩니다.

새로운 세션 격리

각 크론 작업은 완전히 새로운 에이전트 세션에서 실행됩니다.

  • 이전 실행의 대화 기록이 없습니다.
  • 이전 cron 실행에 대한 메모리 없음(메모리/파일에 유지되지 않는 한)
  • 프롬프트는 독립적이어야 합니다. 크론 작업은 명확한 질문을 할 수 없습니다.
  • cronjob 도구 세트가 비활성화되었습니다(재귀 가드).

기술 지원 일자리

크론 작업은 skills 필드를 통해 하나 이상의 스킬을 연결할 수 있습니다. 실행 시:

  1. 스킬은 지정된 순서대로 로드됩니다.
  2. 각 스킬의 SKILL.md 콘텐츠가 컨텍스트로 삽입됩니다.
  3. 작업 프롬프트가 작업 지침으로 추가됩니다.
  4. 에이전트는 결합된 스킬 컨텍스트 + 프롬프트를 처리합니다.

이를 통해 cron 프롬프트에 전체 지침을 붙여넣지 않고도 재사용 가능하고 테스트된 워크플로가 가능해집니다. 예를 들어:

Create a daily funding report → attach "ai-funding-daily-report" skill

스크립트 지원 작업

작업은 script 필드를 통해 Python 스크립트를 연결할 수도 있습니다. 스크립트는 각 에이전트 차례 전에 실행되며 해당 stdout은 프롬프트에 컨텍스트로 삽입됩니다. 이를 통해 데이터 수집 및 변경 감지 패턴이 가능해집니다.

# ~/.hermes/scripts/check_competitors.py
import requests, json
# Fetch competitor release notes, diff against last run
# Print summary to stdout — agent analyzes and reports

스크립트 시간 초과의 기본값은 120초입니다. _get_script_timeout()은 3계층 체인을 통해 제한을 해결합니다.

  1. 모듈 수준 재정의_SCRIPT_TIMEOUT(테스트/원숭이 패치용) 기본값과 다른 경우에만 사용됩니다.
  2. 환경 변수HERMES_CRON_SCRIPT_TIMEOUT
  3. 구성config.yamlcron.script_timeout_seconds(load_config()을 통해 읽기)
  4. 기본값 — 120초

제공자 복구

run_job()은 사용자가 구성한 대체 제공자와 자격 증명 풀을 AIAgent 인스턴스에 전달합니다.

  • 대체 제공자config.yaml에서 fallback_providers(목록) 또는 fallback_model(레거시 dict)을 읽어 게이트웨이의 _load_fallback_model() 패턴과 일치합니다. fallback_model=에서 AIAgent.__init__로 전달되어 두 형식을 대체 체인으로 정규화합니다.
  • 자격 증명 풀 — 확인된 런타임 제공자 이름을 사용하여 agent.credential_pool에서 load_pool(provider)을 통해 로드됩니다. 풀에 자격 증명(pool.has_credentials())이 있는 경우에만 전달됩니다. 429/비율 제한 오류에 대해 동일한 제공자 키 순환을 활성화합니다.

이는 게이트웨이의 동작을 반영합니다. 이것이 없으면 cron 에이전트는 복구를 시도하지 않고 속도 제한으로 인해 실패하게 됩니다.

전달 모델

Cron 작업 결과는 지원되는 모든 플랫폼에 전달될 수 있습니다.

대상구문
오리진 채팅origin작업이 생성된 채팅으로 전달
로컬 파일local~/.hermes/cron/output/에 저장
텔레그램telegram 또는 telegram:&lt;chat_id&gt;telegram:-1001234567890
불화discord 또는 discord:#channeldiscord:#engineering
슬랙slackSlack 홈 채널로 전달
왓츠앱whatsappWhatsApp 홈으로 배달
신호signal시그널에 전달
매트릭스matrixMatrix 홈룸으로 배달
가장 중요한mattermostMattermost 집으로 배송
이메일email이메일로 전달
SMSsmsSMS로 전달
홈어시스턴트homeassistantHA 대화로 전달
딩톡dingtalk딩톡으로 전달하기
페이슈feishu페이슈에게 전달
위컴wecomWeCom으로 전달
웨이신weixinWeixin(WeChat)으로 배송
블루버블스bluebubblesBlueBubbles를 통해 iMessage로 전달
QQ봇qqbot공식 API v2를 통해 QQ(Tencent)에 전달

텔레그램 주제의 경우 telegram:&lt;chat_id&gt;:&lt;thread_id&gt;(예: telegram:-1001234567890:17585) 형식을 사용하세요.

응답 래핑

기본적으로(cron.wrap_response: true) cron 전달은 다음으로 래핑됩니다.

  • 크론 작업 이름과 작업을 식별하는 헤더
  • 에이전트이 대화 중에 전달된 메시지를 볼 수 없음을 알리는 바닥글

cron 응답의 [SILENT] 접두사는 전달을 완전히 억제합니다. 이는 파일에 쓰거나 부작용을 수행하기만 하면 되는 작업에 유용합니다.

세션 격리

Cron 전달은 게이트웨이 세션 대화 기록에 미러링되지 않습니다. 크론 작업 자체 세션에만 존재합니다. 이렇게 하면 대상 채팅 대화에서 메시지 교체 위반이 방지됩니다.

재귀 가드

Cron 실행 세션에는 cronjob 도구 세트가 비활성화되어 있습니다. 이는 다음을 방지합니다.

  • 새 크론 작업 생성을 통해 예약된 작업
  • 토큰 사용량이 폭발적으로 증가할 수 있는 재귀적 스케줄링
  • 작업 내에서 작업 일정이 실수로 변경됨

잠금

스케줄러는 크로스 프로세스 파일 기반 잠금(Unix의 경우 fcntl.flock, Windows의 경우 msvcrt.locking)을 사용하여 중복되는 틱이 동일한 예정 작업 배치를 두 번 실행하는 것을 방지합니다. 심지어 게이트웨이의 프로세스 내 티커와 독립 실행형 hermes cron/수동 tick() 사이에서도 마찬가지입니다. 전화. 잠금을 획득할 수 없는 경우 tick()은 즉시 0을 반환합니다.

CLI 인터페이스

hermes cron CLI는 직접적인 작업 관리를 제공합니다.

hermes cron list                    # Show all jobs
hermes cron create # Interactive job creation (alias: add)
hermes cron edit <job_id> # Edit job configuration
hermes cron pause <job_id> # Pause a running job
hermes cron resume <job_id> # Resume a paused job
hermes cron run <job_id> # Trigger immediate execution
hermes cron remove <job_id> # Delete a job