리포트 & 업무 자동화

클로드 코드 루프로 매일 아침 자동으로 도는 작업 만들기

클로드 코드의 루프 네 가지 유형을 정리하고, 그중 시간 기반 루프를 macOS launchd로 구현해 매일 아침 사람 없이 스스로 갱신되는 팀 대시보드를 만든 실제 사례를, 왜 /loop이 아니라 launchd인지와 실패를 스스로 고치는 워치독까지 함께 정리했습니다.

데이터솔루션팀 대시보드는 매일 아침 담당자가 출근하기 전에 이미 그날 것으로 갱신돼 있습니다. 아무도 버튼을 누르지 않았는데도요. 밤사이 Jira와 Slack에서 데이터가 모이고, 팀 주간 요약과 휴가 현황, 개인별 AI 활용 진단이 새로 그려지고, 화면이 빌드돼 배포까지 끝나 있습니다. 이걸 돌리는 건 클로드 코드의 루프입니다.

클로드 코드에서 루프는 같은 작업을 반복해서 시킬 때, 매번 프롬프트를 새로 쓰는 대신 언제 시작하고 언제 멈출지를 정해 두고 맡기는 방식입니다. 위 대시보드가 바로 그렇게 돕니다.

어떤 루프를 쓸지 고민하는 매도비

어떤 일에 어떤 루프를 맞출지부터가 시작입니다.

클로드 코드에서 루프란 무엇인가

클로드 코드 팀은 루프를 에이전트가 정지 조건을 만족할 때까지 작업 사이클을 반복하는 것으로 정의합니다. 에이전트는 지시를 받아 스스로 도구를 쓰고 중간 결과를 확인하며 일하는 AI입니다. 답 한 줄을 내놓고 끝나지 않고, 파일을 열어 읽고 명령을 실행하고 그 결과를 보고서 다음 수를 정합니다.

매번 프롬프트를 새로 쓰는 대신 언제 시작하고 언제 멈출지를 설계해 맡긴다는 게 루프의 요점입니다. 무엇이 한 바퀴를 시작시키는지, 언제 멈추는지를 어떻게 두느냐에 따라 크게 네 가지 패턴으로 나눠 볼 수 있습니다. 명령과 일대일로 딱 떨어지는 분류라기보다, 자동화를 설계할 때 무엇이 다음 실행을 밀고 무엇을 보고 멈추는지로 가르는 실무 구분입니다.

클로드 코드 루프의 네 가지 유형

턴 기반(Turn-based)이 기본입니다. 프롬프트를 한 번 보내면 한 바퀴가 시작되고, Claude가 다 됐다고 보거나 맥락이 더 필요할 때 멈춥니다. 좋아요 버튼 하나 만들기처럼 한 번 하고 마는 짧은 작업이 여기 해당합니다. 검증 절차를 스킬 문서로 적어 두면 결과를 넘기기 전에 Claude가 스스로 확인합니다.

목표 기반(/goal)은 완료 여부를 확인할 수 있을 때 씁니다. /goal 홈페이지 Lighthouse 점수 90 이상, 5번 시도 후 중단처럼 목표와 멈출 조건을 함께 주면, 거기 닿거나 시도 한도가 찰 때까지 반복합니다. 점수만이 아니라 테스트 통과, 처리할 큐 비움처럼 Claude가 결과로 확인할 수 있는 조건이면 됩니다. 애매한 “잘 만들어줘”보다 검증할 수 있는 조건일수록 잘 맞습니다.

시간 기반(/loop, /schedule)은 정해진 간격이 한 바퀴를 시작시킵니다. /loop 5m PR 확인하고 리뷰 코멘트 반영, CI 실패 수정이 그런 예입니다. 고정 간격으로 걸면 취소하거나 만료될 때까지 돌고, 처리할 일이 없어지면(PR이 머지되거나 큐가 비면) 멈추게 조건을 걸 수도 있습니다. /loop은 지금 열린 로컬 세션에서 돌고, /schedule은 같은 반복을 Anthropic이 관리하는 클라우드 루틴으로 올려 돌립니다.

프로액티브(Proactive)는 사람이 실시간으로 붙어 있지 않고 이벤트나 스케줄에 맡깁니다. 버그 리포트 처리, 이슈 트리아지, 의존성 업그레이드처럼 손이 익은 반복 업무에 씁니다. 앞의 세 방식에 다이나믹 워크플로우와 오토 모드를 얹어 구성합니다.

턴 기반Turn-based · 기본트리거프롬프트 한 번종료Claude가 완료로 판단짧은 일회성 작업목표 기반/goal트리거프롬프트 + 목표·시도수종료목표 달성 또는 시도 한도완료를 확인할 수 있을 때시간 기반/loop · /schedule · OS 스케줄러 — 이 글의 사례트리거정해진 시간 간격종료취소하거나 일이 끝날 때반복 작업 · 외부 시스템 감시프로액티브Proactive · 사람 실시간 개입 없음트리거이벤트 또는 스케줄구성앞의 셋 + 워크플로우·오토잘 정의된 반복 업무

이 대시보드는 세 번째, 시간 기반 루프입니다. 다만 /loop이나 /schedule을 쓰지 않았습니다.

매일 아침 파이프라인은 무슨 일을 하나

대시보드가 갱신되기까지 아침에 다섯 단계가 순서대로 돕니다.

  • 평일 08:00, 코드가 Jira와 Slack에서 원본 데이터를 긁어 오고, headless claude가 에픽별 타임라인과 팀 주간 요약으로 정리합니다.
  • 평일 08:30, Claude가 Slack 연차 스레드를 읽어 휴가 데이터를 갱신합니다. Slack에는 Slack MCP로 붙습니다.
  • 평일 08:45, 정량 지표를 근거로 개인별 AI 활용 진단 코멘트를 갱신합니다.
  • 매일 09:00, 파이썬이 정량 데이터를 모으고 웹을 빌드해 배포합니다. 앞 단계들이 만든 것이 이때 화면에 올라갑니다.
  • 매일 09:40, 워치독이 오늘 산출물이 다 신선한지 보고, 이상하면 진단 에이전트를 깨웁니다.

headless claude는 사람이 보는 화면 없이 뒤에서 도는 클로드 코드입니다. 평소에는 창을 띄우고 대화하지만, 아침에는 아무도 모니터 앞에 없으니 명령으로만 실행합니다. Slack이나 Jira 같은 외부 도구에 붙는 통로가 MCP고, 08:30이 연차 스레드를 직접 읽는 것도 이 연결 덕입니다.

08:00히스토리Jira·Slack 수집08:30연차Slack MCP08:45AI 진단정량 지표 기반09:00빌드·배포웹 빌드·배포09:40워치독신선도 점검이상 감지 시 진단 에이전트 가동

왜 클로드 코드 스케줄러가 아니라 launchd인가

클로드 코드가 시간 기반 루프를 여러 방식으로 지원하는데도 굳이 launchd를 쓴 데는 이유가 있습니다. launchd는 macOS가 정해진 시각에 프로그램을 자동으로 실행해 주는 OS 스케줄러입니다.

/loop부터 걸립니다. /loop은 지금 살아 있는 세션 안의 반복이라, 터미널을 닫으면 루프도 끝납니다. 밤새 터미널이 켜져 있으리란 보장이 없으니 매일 아침 무인 실행에는 못 맡깁니다.

/schedule은 클라우드 루틴으로 올라갑니다. 그런데 이 파이프라인은 클라우드에 없는 것들을 필요로 합니다. 접근하려는 외부 시스템이 사내망만 허용해서 사내망 IP로 나가야 하고, 자격 증명은 이 컴퓨터에 있고, 빌드와 배포 환경도 여기 있습니다. 클라우드로는 이 중 어느 것도 성립하지 않습니다.

클로드 코드에는 로컬 컴퓨터에서 도는 예약 실행도 있습니다. 로컬 파일과 도구를 쓸 수 있으니 후보이긴 했습니다. 다만 이 사례는 여러 셸 스크립트와 파이썬 빌드, 배포, 로그 확인을 하나의 OS 작업 묶음으로 관리해야 했습니다. 그래서 클로드 코드 안의 스케줄러에 전부 담기보다, macOS의 launchd를 바깥 트리거로 두고 필요한 순간에만 headless claude를 부르는 쪽이 단순했습니다.

결국 트리거를 어디 둘지는 작업이 무엇을 필요로 하느냐를 따라갑니다. 로컬에 있는 것을 써야 하면 OS 스케줄러, 클라우드에서 지켜보기만 하면 되는 일이면 /schedule입니다. 수집과 판단을 나눌 수 있다면 섞어 쓰는 길도 있습니다. 사내망 안에서 필요한 데이터를 먼저 산출물로 만들고 민감한 값을 걸러낸 다음, 그 정리를 클라우드 루틴에 맡기는 식입니다. 이 사례는 원본 접근부터 정리, 빌드, 배포가 한 로컬 환경에 묶여 있어 launchd로 한데 뒀습니다.

로컬 자원이 필요한가?사내망 IP · 로컬 자격 증명 · 빌드/배포 환경OS 스케줄러 (launchd)로컬에서 무인 실행 · 이 글의 사례아니오세션이 닫혀도 계속 돌아야 하는가?밤새·주말에도 무인으로/schedule클라우드에서 실행아니오/loop열린 로컬 세션에서 반복

launchd로 스케줄을 걸면 손으로는 되던 게 자동 실행에서만 실패하는 일이 흔합니다. launchd는 사람이 여는 터미널과 달리 로그인 셸의 프로필을 읽지 않아서, .zshrc 같은 데서 잡히던 PATH나 API 토큰이 비어 있습니다. 그래서 스크립트 안에서 PATH를 직접 지정하고, 토큰이 든 설정 파일을 명시적으로 불러옵니다.

성공과 실패를 무엇으로 판정하나

무인 실행이 성공했는지 어떻게 알까요. 흔히 종료 코드를 봅니다. 스크립트가 0으로 끝났으면 성공으로 치는 방식인데, 이 파이프라인은 종료 코드를 믿지 않습니다.

headless claude가 API 에러로 죽었는데도 종료 코드가 0으로 찍힌 적이 있어서입니다. 그 숫자만 봤다면 그날을 성공으로 기록했겠지만, 대시보드에는 어제 것이 그대로 걸려 있었습니다. 아침마다 사람이 화면을 눈으로 대조하지 않으니 이런 조용한 실패는 한참 뒤에야 들통납니다.

종료 코드로 보면exit 0스크립트는 정상 종료성공으로 기록산출물 신선도로 보면대시보드 = 어제 날짜오늘 것으로 갱신 안 됨실패로 판정

그렇다고 종료 코드를 버리지는 않습니다. 다만 그걸 최종 성공으로 삼지 않습니다. 종료 코드와 로그는 프로세스가 어떻게 끝났는지 말해 주고, 산출물 신선도는 사람이 볼 화면이 실제로 갱신됐는지 말해 줍니다. 그래서 판정의 마지막 기준을 산출물로 뒀습니다. 오늘 결과물이 오늘 날짜, 오늘 시각으로 새로 쓰였는지를 파일의 생성·수정 시각으로 봅니다. 어제 것이 그대로면 종료 코드가 0이어도 실패입니다. 프로그램이 잘 끝났느냐가 아니라 결과물이 새것이냐를 봅니다.

실패하면 스스로 고치는 워치독

무인 루프에서 진짜 비용이 나는 건 실패한 날 아침입니다. 그래서 진단만 전담하는 에이전트를 따로 두고, 그걸 자동으로 깨우는 워치독을 루프 끝에 붙였습니다. 워치독은 자동 실행이 조용히 실패하는 걸 잡아내는 마지막 점검자입니다. 09:40 워치독은 세 단계로 움직입니다.

먼저 오늘 산출물이 다 신선한지만 확인합니다. 여기서 LLM은 안 씁니다. 정상이면 그대로 끝나니, 아무 문제 없는 날은 비용이 0입니다.

이상하다 싶어도 곧장 손대지 않고 20분을 기다렸다 다시 봅니다. Mac이 슬립에서 늦게 깨어 잡이 밀리는 날이 있는데, 그런 날을 실패로 오해하지 않으려는 여유입니다.

그래도 이상이면 그때 진단 에이전트가 headless로 기동합니다. 스케줄러 상태, 로그, 산출물 순으로 원인을 좁히고, 증거가 있는 모듈만 다시 돌립니다. 그날 배포가 빠졌으면 배포까지 복구하고, 결과는 담당자에게 DM으로 보냅니다.

① 신선도 확인결정적 헬스체크이상② 20분 대기재확인·오탐 방지이상③ 진단 에이전트상태·로그·산출물재실행·복구DM 보고정상 → LLM 호출 없이 종료 (비용 0)종료

진단 에이전트에는 두 가지 철칙이 있습니다. 로그에 증거가 없으면 재시작하지 않습니다. 그리고 로그인 만료처럼 사람이 손대야만 풀리는 원인 앞에서는, 억지로 고치려 들지 않고 필요한 조치를 보고하는 선에서 멈춥니다. 뭐든 자동으로 고치려다 상황을 더 어그러뜨리는 게 더 큰 사고이기 때문입니다.

한 번 겪은 고장은 에이전트 정의에 적어 둡니다. 슬립으로 잡이 밀린 날, CLI 세션이 만료된 날, 봇이 채널에서 강퇴된 날. 이렇게 적어 두면 같은 데서 두 번 헤매지 않습니다. 겪은 실패가 규칙으로 쌓여 다음 실행이 덜 헤매는 이 흐름을 자기개선 루프라고 부릅니다. 실패를 규칙으로 되먹이는 하네스 이야기에서 이미지 생성으로도 한 번 다뤘습니다.

만들면서 확인한 것들

클로드 코드는 한 번 로그인해 두면 로컬에 저장된 인증을 계속 씁니다. 그래서 사람이 자리를 비운 무인 상태에서도 백그라운드에서 정상으로 돕니다. 여기에 미리 붙여 둔 Slack MCP 연결이 더해져, 단순한 스크립트로 끝나는 일뿐 아니라 LLM의 판단과 외부 도구 연결이 필요한 일까지 OS 레벨에서 자동으로 돌아갑니다. 08:30 연차 갱신이 Slack을 읽어 정리하는 게 그렇습니다. 인증은 클로드 코드 쪽, MCP는 도구 연결 쪽으로 역할이 나뉘어 있어서, 둘 다 미리 확인해 둬야 무인 실행이 멈추지 않습니다.

launchd에는 단계 사이의 의존성 체인이 없습니다. 앞 단계가 끝났다고 다음 단계가 저절로 이어지지 않습니다. 그래서 08:00에서 09:40까지 시각을 벌려, 앞 단계가 끝날 시간을 주고 다음 단계를 예약해 순서를 맞췄습니다. 다만 시각 간격만으로 순서가 완벽히 보장되지는 않습니다. Mac이 슬립에서 늦게 깨면 밀린 단계들이 몰려 돌 수 있어서, 마지막의 산출물 신선도 점검이 순서가 어긋난 날을 걸러 주는 안전판입니다.

직접 만들어 본다면

작은 자동화부터 같은 뼈대로 만들 수 있습니다.

  1. 무엇을 매일 만들지, 그 산출물부터 정합니다. “이게 새것이면 성공”이라고 말할 수 있는 결과물이 있어야 성공을 판정할 수 있습니다.
  2. 만드는 과정을 스크립트 하나로 손으로 먼저 돌려 봅니다. PATH와 토큰을 스크립트 안에서 직접 챙겨, 자동 실행으로 넘어가도 환경이 비지 않게 합니다.
  3. 트리거를 정합니다. 로컬에 있는 게 필요 없으면 /schedule로 클라우드에, 로컬 자격 증명이나 사내망 접근, 빌드·배포가 필요하면 launchd 같은 OS 스케줄러로 겁니다.
  4. 성공은 종료 코드가 아니라 산출물 신선도로 봅니다. 실행 뒤 결과물이 오늘 날짜로 새로 쓰였는지 확인하고, 아니면 실패로 다뤄 다시 돌리거나 알림을 남깁니다.
  5. 실패하면 그 교훈을 규칙으로 적어, 다음 실행이 먼저 읽게 합니다. 사람이 손대야만 풀리는 원인은 자동 수리 대신 보고로 멈추게 해 둡니다.

클로드 코드를 아직 안 써봤어도 시작할 수 있습니다. launchd도 워치독도 없이, 지금 쓰는 AI 대화창 하나면 됩니다. 반복해서 시키는 일의 지시문을 매번 새로 쓰지 말고 파일에 저장해 두고, 그 옆에 교훈 파일을 하나 만들어 실수할 때마다 한 줄씩 적습니다. 다음에 일을 시킬 때 지시문과 교훈 파일을 함께 붙여 넣으면, AI가 지난 실수를 피한 자리에서 시작합니다. 이게 손에 익어 사람이 안 봐도 되겠다 싶어지면, 그때 스케줄러와 워치독을 얹어 무인으로 올려도 늦지 않습니다. 🐹

무인으로 스스로 도는 자동화에 올라탄 매도비

자주 묻는 질문

클로드 코드에서 루프란 무엇인가요?

클로드 코드 팀은 루프를 에이전트가 정지 조건을 만족할 때까지 작업 사이클을 반복하는 것으로 정의합니다. 매번 새로 프롬프트를 쓰는 대신, 언제 시작하고 언제 멈출지를 미리 설계해 작업을 맡기는 방식입니다. 트리거가 무엇이고 언제 멈추느냐에 따라 턴 기반, 목표 기반, 시간 기반, 프로액티브의 네 가지 유형으로 나뉩니다.

/loop과 /schedule은 무엇이 다른가요?

둘 다 시간 기반 루프를 만드는 명령이지만 도는 위치가 다릅니다. /loop은 지금 열려 있는 로컬 세션 안에서 지정한 간격마다 작업을 반복합니다. 터미널을 닫으면 루프도 함께 끝납니다. /schedule은 같은 반복을 클라우드에서 돌려, 로컬 컴퓨터가 꺼져 있어도 실행됩니다. 그래서 로컬 자원이 필요 없는 감시성 작업은 /schedule이, 로컬 자원이 꼭 필요한 작업은 OS 스케줄러가 맞습니다.

/goal은 언제 쓰나요?

목표 기반 루프인 /goal은 완료를 명확히 정의할 수 있는 작업에 씁니다. 예를 들어 "홈페이지 Lighthouse 점수를 90 이상으로, 5번 시도 후 중단"처럼 목표와 최대 시도 횟수를 함께 정하면, Claude가 조기에 멈추지 않고 목표에 도달하거나 시도 한도에 닿을 때까지 반복합니다. 테스트 통과 수나 점수처럼 정량으로 대조할 수 있는 기준일수록 효과가 좋습니다.

매일 아침 자동으로 도는 작업은 어떻게 만드나요?

시간 기반 루프로 만듭니다. 로컬 자원이 필요 없는 작업은 /schedule로 클라우드에 올리면 됩니다. 로컬 컴퓨터의 자격 증명이나 사내망 접근, 빌드·배포 환경이 필요하다면 macOS launchd 같은 OS 스케줄러로 시각을 예약하고, 화면 없이 도는 headless claude가 실제 작업을 수행하게 합니다. 성공 판정은 종료 코드가 아니라 산출물이 오늘 새로 갱신됐는지로 하는 편이 안전합니다.

launchd로 스케줄을 걸면 왜 토큰이나 경로가 비어 있나요?

launchd로 도는 스크립트는 사람이 여는 터미널과 환경이 다릅니다. launchd는 로그인 셸의 프로필(.zshrc 같은 파일)을 읽지 않아서, 평소 터미널에서 잡히던 PATH나 API 토큰이 자동 실행에서는 비어 있습니다. 그래서 스크립트 안에서 PATH를 직접 지정하고, 토큰이 담긴 설정 파일을 명시적으로 불러와야 합니다. 손으로 실행하면 되는데 스케줄러에서만 실패한다면 대개 이 환경 차이가 원인입니다.

사람이 지켜보지 않는 무인 실행이 성공했는지 어떻게 확인하나요?

종료 코드만 믿으면 안 됩니다. headless claude가 API 에러로 죽어도 종료 코드가 0으로 찍히는 경우가 있기 때문입니다. 그래서 실행이 끝난 뒤 오늘의 산출물이 실제로 새로 만들어졌는지를 함께 봅니다. 결과 파일의 생성 시각과 수정 시각이 오늘로 갱신됐으면 성공, 어제 것이 그대로 남아 있으면 종료 코드가 0이어도 실패로 봅니다. 무인 파이프라인일수록 이 산출물 신선도 기준이 중요합니다.