
AI가 잠들지 않고 태스크 리스트를 계속 돌리는 메커니즘 — OpenClaw 하트비트 자율 구동
요약
OpenClaw를 활용하여 AI 에이전트가 정기적으로 태스크를 자율 수행하는 '하트비트(Heartbeat)' 메커니즘을 소개합니다. 자연어 기반의 HEARTBEAT.md와 상태 관리용 JSON 파일을 통해 에이전트의 연속성을 확보하는 설계 방식을 다룹니다.
핵심 포인트
- cron과 HEARTBEAT.md를 결합한 AI 에이전트의 정기적 자율 구동 메커니즘
- 자연어 기반의 마크다운 파일을 활용한 직관적인 태스크 리스트 관리
- 세션 단절로 인한 기억 상실 문제를 active-tasks.md와 상태 기록 파일로 해결
- 중복 실행 방지를 위한 lastChecks 기반의 실행 주기 판정 로직
OpenClaw를 5개월간 사용하다 보면, 어느 시점에 "AI가 태스크를 스스로 집어 들어 계속 돌리는" 상태가 된다.
인간이 자는 동안 로그가 정리되고, 메모리가 증류되며, 아침에는 태스크 리스트가 업데이트되어 있다. 특별한 마법이 아니다. 메커니즘은 심플하다.
여기서는 내가 임의로 "하트비트 (Heartbeat) 자율 구동"이라고 부르는 그 메커니즘을 실제 구성 파일과 함께 소개한다.
이 기사에서는 OpenClaw가 표준으로 제공하는 기능과, 그 위에 우리들의 설계 사상으로 구축한 운용을 명시적으로 구분하여 작성했다. "OpenClaw를 넣으면 이렇게 된다"가 아니라 "이러한 문제 의식을 바탕으로, 이렇게 구축했더니 이렇게 되었다"라는 이야기다.
OpenClaw의 cron 잡(job)이 정기적으로 AI 에이전트를 기동한다. 기동된 에이전트는 HEARTBEAT.md를 읽고, 그곳에 적힌 태스크 리스트를 위에서부터 순서대로 실행한다.
cron(정기 기동) → 에이전트 각성 → HEARTBEAT.md 참조 → 태스크 실행 → 상태 기록 → 슬립 (Sleep)
인간의 ToDo 리스트와 같다. 다른 점은 실행자가 AI이며, 정기적으로 자동 기동된다는 것이다.
🔧 OpenClaw 표준 기능:
agents.defaults.heartbeat
— Gateway 설정에서 간격(every: "30m" 등)과 활성 시간대(activeHours)를 지정하는 것만으로 정기 기동됨
HEARTBEAT.md
— 워크스페이스에 두면, 하트비트 기동 시 에이전트가 자동으로 읽음
cron
— 보다 정밀한 스케줄 제어가 필요한 경우 cron 잡으로 agentTurn을 정기 실행할 수 있음
이 두 가지(네이티브 heartbeat와 cron)는 병용할 수 있다. 우리는 cron을 메인으로 사용하는 경우가 많지만 하트비트도 사용한다.
포인트는 "무엇을 할지"가 마크다운 (Markdown) 파일에 적혀 있다는 것이다. 프로그램이 아니라 자연어 태스크 리스트다. 그래서 인간이 읽어도 이해할 수 있고, 인간이 항목을 추가하는 것도 간단하다.
## 정기 태스크
### 세션 → 일일 로그 플러시 (Flush) (매번)
- 최근 대화 이력을 확인
...
이게 전부다. 특별한 DSL도 API도 필요 없다.
HEARTBEAT.md에 무엇을 적을지는 OpenClaw가 관여하지 않는다. 백지 상태의 마크다운에 "해주었으면 하는 일"을 자연어로 적을 뿐이다. 무엇을 어느 빈도로 실행시킬지, 그 설계는 완전히 사용자의 몫이 된다.
하트비트가 움직이기 시작하면 곧바로 벽에 부딪힌다. "지난번에 어디까지 했는지"를 AI가 기억하지 못한다.
세션이 끊길 때마다 기억이 리셋되기 때문에, 매번 모든 태스크를 처음부터 실행하려고 한다. 결과적으로 같은 처리를 몇 번이고 반복하거나, 토큰 (Token)을 낭비하게 된다.
※ 설계에 따라 다르지만 세션을 나누어 동작시키는 것도 가능하므로 기억 인계가 번거로울 수 있음
이 문제에 대해 우리는 두 개의 파일을 설계했다:
active-tasks.md — 모든 프로젝트의 미완료 태스크를 한 파일에 집약한다. 흩어져 있으면 매번 찾아가야 하지만, 한 파일에 모아두면 "지금 무엇이 남아 있는지"를 단번에 파악할 수 있다.
heartbeat-state.json — 각 태스크의 최종 실행 시각을 기록한다. HEARTBEAT.md에 "매일 1회"라고 적힌 태스크는 이 JSON의 lastChecks를 보고 "지난번으로부터 12시간 이상 경과했다면 실행"이라고 판정한다. 이를 통해 중복 실행을 방지한다.
{
"lastChecks": {
"sessionFlush": "2026-07-16T06:00:00+09:00",
...
아침에 일어나 active-tasks.md를 보면, 어젯밤 대화에서 "해두라고" 말했던 것들이 완료 표시와 함께 나열되어 있다. 혹은 "이것 좀 조사해 둬"라고 말한 결과가 일일 로그에 적혀 있다.
🛠️ 이것은 커스텀 설계:
active-tasks.md도 heartbeat-state.json도 OpenClaw의 표준 기능이 아니다. "태스크가 흩어진다", "중복 실행한다"라는 실운용상의 문제를 해결하기 위해 우리 스스로 설계한 것이다. OpenClaw는 "파일을 읽고 쓸 수 있는 AI를 정기 기동하는" 메커니즘만을 제공한다. 그 위에 어떤 관리 구조를 올릴지는 사용자에게 달려 있다.
모든 것을 한 명의 에이전트가 떠안지 않는다.
5개월간 운용하며 깨달은 것은, 에이전트 1개로 모든 것을 수행하면 컨텍스트 (Context)가 오염된다는 점이다. 코드를 작성하면서 설계 판단까지 내리다 보면, 코드가 컨텍스트에 축적되어 판단의 정밀도가 떨어진다. 인간도 "손을 움직이며 생각하는 것"과 "생각에 집중하는 것"은 질적으로 다르다.
따라서 역할을 나눈다:
사령탑 (설계·검증·판단)
├── 코딩 에이전트 (구현)
├── 조사 에이전트 (정보 수집)
...
나의 경우에는 KIRO에게 맡기는 경우가 많다.
🔧 OpenClaw 표준 기능:
sessions_spawn— 서브 에이전트 (Sub-agent)를 기동하는 API.mode="run"으로 원샷 (One-shot),mode="session"으로 영속 세션 (Persistent session)agents.list— 여러 에이전트를 설정 파일에 정의할 수 있다. 모델이나 도구 권한을 개별적으로 지정 가능cron의sessionTarget: "isolated"— 메인 세션을 오염시키지 않고 독립 세션에서 태스크를 완결
🛠️ 이것은 커스텀 설계:
"사령탑/실행역/정기 순찰"이라는 계층(Tier) 분리는, 우리가 "컨텍스트 오염으로 인해 판단 품질이 저하된다"는 실체적인 경험으로부터 도출한 설계 사상이다. OpenClaw는 "여러 에이전트를 구동할 수 있는" 메커니즘만을 제공할 뿐, 어떻게 역할을 분담할지는 사용자가 결정한다.
이를 하트비트 (Heartbeat) 안에서 자동으로 기동할 수도 있다. "매일 아침 7시에 뉴스를 요약하여 보고", "2일마다 메모리를 정리"와 같은 태스크가 각각 독립된 에이전트로서 동작한다.
인간 팀과 같다. 사령탑이 모든 실무를 직접 수행하면 판단의 질이 떨어진다.
AI 에이전트는 세션이 끊길 때마다 기억이 리셋된다. 하지만 "어제의 연속"을 수행할 수 있다.
이유는 파일이다.
memory/
├── 2026-07-15.md (일일 로그)
├── 2026-07-16.md
...
🔧 OpenClaw 표준 기능:
memory/디렉토리 — 워크스페이스 (Workspace)에 두면 에이전트가 읽고 쓸 수 있다.memory_search로 로컬 벡터 검색 (Vector search)도 가능- 워크스페이스 파일 자동 읽기 —
AGENTS.md,SOUL.md,MEMORY.md등은 세션 기동 시 시스템 프롬프트 (System prompt)로 주입됨
다만, 파일에 쓴다고 해서 무엇이든 기억이 되는 것은 아니다. 5개월 치의 로그를 매번 전부 읽는 것은 물리적으로 불가능하며, 애초에 무엇이 중요하고 무엇을 버려도 되는지에 대한 판단이 필요하다.
우리는 기억을 세 가지 층으로 분류하고 있다:
| 층 | 저장소 | 반감기 | 내용 |
|---|---|---|---|
| 에피소드 기억 (Episodic memory) | memory/YYYY-MM-DD.md | 짧음 | 그날 무슨 일이 있었는지. 가공되지 않은 로그 |
| 의미 기억 (Semantic memory) | memory/knowledge/*.md | 중간 | 증류된 지식. 실패의 교훈, 절차 |
| 절차 기억 (Procedural memory) | AGENTS.md + 스킬군 | 길음 | 무엇을 어떻게 하는지. 행동 규칙 |
일일 로그 (에피소드)에서 중요도가 높은 것만을 knowledge/ (의미)로 증류(Distillation)한다. 증류 기준은 "이 경험이 향후 다른 문맥에서도 사용될 수 있는가?"이다.
🛠️ 이것은 커스텀 설계:
"3층 기억 모델"도 "중요도 스코어링에 의한 증류 사이클"도 우리의 설계다. OpenClaw는 memory/에 파일을 두면 읽기·쓰기 및 검색을 할 수 있는 메커니즘을 제공할 뿐, 어떻게 구조화할지는 사용자에게 달려 있다. 매일 수동으로 정리해도 좋고, 우리처럼 하트비트 안에서 자동 증류를 수행해도 좋다.
세션이 시작될 때마다 이것들을 읽는다. 하트비트도 마찬가지다. 깨어날 때마다 "어제의 나"가 남긴 파일을 읽고, 그 지점부터 다시 움직인다.
기억은 뇌가 아니라 파일에 있다. 따라서 세션 리셋은 "수면"이지 "죽음"이 아니다.
참고로 RAG에 대해서는, 너의 에이전트 설계라면 RAG는 맞지 않는다고 Anthropic의 누군가에게 들었기에 채택하지 않는 방침을 세웠다.
메커니즘은 지극히 단순하다:
- cron으로 정기 기동한다
- 마크다운 (Markdown) 태스크 리스트를 읽는다
- 실행한다
- 결과를 파일에 쓴다
이것만으로 "AI가 자율적으로 계속 움직이는" 환경이 구축된다.
OpenClaw가 제공하는 것은 "정기 기동", "파일 읽기·쓰기", "서브 에이전트 기동", "벡터 검색"과 같은 기반 부품이다. 그 위에 무엇을 쌓아 올릴지는 완전히 자유롭다.
우리가 5개월에 걸쳐 도달한 설계는 "태스크를 1개 파일로 집약한다", "시간 관리로 중복 실행을 방지한다", "역할을 나누어 컨텍스트 (Context)를 보호한다", "기억을 3개 층으로 분류하여 증류 (Distillation)한다"는 것이다. 이것이 유일한 정답은 아니다. 다만, 작동하고 있다.
도구로서 사용하는 단계를 넘어서면, 설정 파일 너머로 "업무 동료"가 보이기 시작한다. 그렇게 되면 태스크 리스트를 공유하고, 나머지는 맡기기만 하면 된다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기