한줄 요약
수동 실행 → launchd 자동 스케줄 → 잠자기 상태에서 실행 실패 → pmset + caffeinate 조합까지, 완전 무인 자동화를 만들면서 배운 것들
이런 분들께 도움돼요
자동화를 만들어놨는데 "왜 안 돌아가지?" 경험이 있는 분
macOS에서 launchd/pmset으로 스케줄 작업을 해보고 싶은 분
Claude Code로 시스템 레벨 디버깅까지 해본 사례가 궁금한 분
소개: 시도하고자 했던 것과 그 이유
문제 상황 (Before)
[이전 글](이전 사례 글 링크)에서 YouTube 방송 요약 시스템을 6단계에 걸쳐 개선했습니다. LLM 선택, 라이브 요약, Docker 환경, 코너 탐지, 프로그램별 템플릿까지 완성한 상태였습니다.
하지만 매일 아침 수동으로 실행하는 게 여전히 귀찮았습니다:
아침에 일어나서 맥북 열고 → 터미널 열고 →
/뉴스공장실행자막 생성 대기: 라이브 종료 후 자막이 생길 때까지 5분마다 확인
API 실패 대응: 크레딧 부족이나 Rate limit 걸리면 다른 모델로 수동 전환
아침에 일어나면 요약이 자동으로 완성되어 있는 환경을 만들고 싶었습니다.
시작하게 된 계기
자막 모니터링, LLM 폴백 체인, 파이프 캡처 등 실사용하면서 발견된 엣지 케이스들이 하나씩 쌓였습니다. "이왕 여기까지 왔으면 완전 무인으로 만들자"는 마음으로 다시 Claude Code와 작업을 시작했습니다.
진행 방법: 어떤 도구를 사용했고, 어떻게 활용했나요?
사용한 도구
도구명: Claude Code (VS Code 확장)
모델: Claude Opus 4.5
기타 도구: macOS launchd, pmset, caffeinate, yt-dlp, ffmpeg, Whisper API, Gemini API
AI와 협업한 과정
1. 자막 자동 모니터링 + 뉴스공장 템플릿
상황: 라이브 종료 후 자막이 생성되기까지 시간이 걸리는데, 그동안 5분마다 수동으로 확인하고 있었습니다.
이렇게 요청했어요:
/뉴스공장명령어에서 자막이 없으면 5분 간격으로 자동 재시도하도록 해줘. 그리고 뉴스공장 전용 템플릿이 자동 적용되게 해줘.
결과: --watch --poll-interval 30 옵션으로 자막 생성 자동 대기 기능 완성. 더 이상 수동으로 확인할 필요가 없어졌습니다.
2. LLM 폴백 체인
상황: Gemini API 크레딧이 소진되면 요약이 실패하고, 수동으로 --model claude로 바꿔서 다시 실행해야 했습니다.
이렇게 요청했어요:
API 호출 실패 시 gemini → claude → gpt 순으로 자동 전환되는 폴백 체인을 만들어줘
결과: _call_llm_with_fallback() 함수가 자동으로 다음 모델로 전환. 어떤 모델이 실제로 사용됐는지 튜플로 반환해서 로그에 기록됩니다.
3. 라이브 캡처 시점 제어 + 파이프 방식
상황: --live-from-start 옵션으로 방송 처음부터 캡처하려 했는데, DASH 프로토콜에서 --download-sections가 동작하지 않았습니다.
이렇게 요청했어요:
yt-dlp의 --live-from-start에서 --download-sections가 안 먹히는 문제를 해결해줘
결과: yt-dlp -f 140 --live-from-start -o - | ffmpeg -i pipe:0 -t {seconds} 파이프 방식으로 우회. yt-dlp가 DASH로 전체 스트림을 파이프에 내보내고, ffmpeg가 원하는 구간만 잘라내는 방식입니다.
막혔던 순간: 이 부분에서 삽질을 많이 했습니다. --download-sections이 왜 안 되는지 한참을 Claude Code와 시행착오를 반복했고, 결국 HLS vs DASH 프로토콜 차이를 이해한 후에야 파이프 방식이라는 대안이 나왔습니다.
4. 자동 스케줄 (launchd + pmset)
상황: 매일 아침 수동 실행 대신, Mac이 자동으로 깨어나서 요약을 시작하게 하고 싶었습니다.
이렇게 요청했어요:
월~금 오전 7시 5분에 자동으로 라이브 요약이 시작되도록 launchd 스케줄을 만들어줘. Mac이 잠자기 상태여도 자동으로 깨어나게 해줘.
결과:
com.gpters.newsfactory.plist(launchd 스케줄)sudo pmset repeat wakeorpoweron MTWRF 07:00:00(Mac 자동 기상)schedule_newsfactory.sh(실행 스크립트 + caffeinate + 알림)
5. 잠자기 wake 실패 진단 및 해결 (오늘 세션)
상황: 자동 스케줄을 설정해놨는데, 오늘 아침에 요약이 생성되지 않았습니다. 로그 파일조차 없었습니 다.
이렇게 요청했어요:
오늘 2/3 뉴스공장 1차 요약 진행하고 있나? 스케줄 작업 확인해줘
Claude Code가 찾아낸 원인: pmset 로그를 분석해서, Mac이 07:00에 정상적으로 깨어났지만 2초 만에 다시 잠들었다는 것을 밝혀냈습니다:
한국어 텍스트가 포함된 검은 화면의 스크린샷
07:00:00 Display is turned on
07:00:02 UserIsActive TimedOut (2초!)
07:00:02 Display is turned off → 다시 잠자기
07:05에 launchd가 뉴스공장 스크립트를 실행해야 했지만, Mac이 이미 잠들어 있어서 실행 자체가 안 된 것이었습니다.
해결:
caffeinate -u -t 600을 07:00에 실행하는 별도 launchd job을 만들어서, Mac이 깨어난 후 10분간 잠자기를 방지하자
com.gpters.morning-caffeinate.plist를 새로 만들고, 테스트까지 완료:
pmset repeat으로 Mac 기상 → caffeinate가 즉시 실행되어 잠자기 방지 → 5분 후 newsfactory 정상 실행
추가로 iCloud Desktop 경로 문제도 발견: plist의 WorkingDirectory가 iCloud 경로로 리다이렉트되면서 getcwd: Operation not permitted 에러가 발생하고 있었습니다. WorkingDirectory를 제거하고 스크립트 내에서 상대경로를 사용하도록 수정했습니다.
막혔던 순간과 해결
문제: launchd, pmset, caffeinate, iCloud Desktop, HLS vs DASH... 모르는 CLI 명령어와 시스템 동작이 계속 나왔습니다. Claude Code에게 "이거 해결해줘"라고 맡기면 시행착오가 반복되면서 시간만 소모되는 경우가 많았습니다.
해결: 잘 모르는 개념이 나오면, 어느 정도 직접 이해하고 학습한 뒤에 작업을 이어가는 게 결국 더 효율적이었습니다. 예를 들어 --download-sections가 왜 안 되는지 yt-dlp 이슈를 직접 찾아보고 HLS/DASH 차이를 이해한 후에야, Claude Code에게 올바른 방향(파이프 방식)을 제시할 수 있었습니다.
결과와 배운 점
Before vs After
항목
Before (1/24)
After (2/3)
실행 방식
매일 아침 수동 실행
Mac 자동 기상 → 완전 무인 실행
자막 대기
5분마다 수동 확인
자동 모니터링 + 재시도
API 실패
수동으로 모델 전환
gemini → claude → gpt 자동 폴백
라이브 캡처
라이브 엣지만 가능
방송 처음부터 파이프 캡처 가능
잠자기 대응
없음 (실패 몰랐음)
caffeinate로 10분 유지 보장
결과물
아침에 일어나면 docs/summaries/ 폴더에 오늘자 뉴스공장 요약이 자동으로 생성되어 있습니다. 실패 시 macOS 알림으로 알려줍니다.
자동 실행 흐름:
07:00 Mac 자동 기상 (pmset repeat)
07:00 caffeinate 실행 → 10분간 잠자기 방지
07:05 schedule_newsfactory.sh 실 행
→ 라이브 감지 대기
→ 오디오 캡처 (40분, 3분 청크)
→ Whisper STT
→ AI 요약 (폴백 체인)
→ Markdown 저장 + macOS 알림
배운 점과 나만의 꿀팁
효과적이었던 것
자동화는 "만들면 끝"이 아니라 운영이 시작: 만들어놓고 실제로 돌려보면 예상못한 문제(잠자기, iCloud 경로, 프로토콜 차이)가 계속 나옵니다
모르는 건 배우면서 하기: CLI 명령어에 대한 이해 부족으로 삽질을 많이 했습니다. 잘 모르는 게 나오면 어느 정도 이해하고 학습하면서 다루는 것이 결국 더 효율적입니다
테스트는 실제 환경에서: "잠자기 → wake → 스크립트 실행"처럼 실제 시나리오를 재현해서 테스트해야 합니다. 깨어있는 상태에서만 테스트하면 놓치는 게 많습니다
이렇게 하면 안 돼요 (주의사항)
AI에게 모든 걸 맡기고 기다리기: 특히 시스템 레벨(OS, 네트워크) 문제는 내가 어느 정도 이해해야 올바른 방향을 잡을 수 있습니다
"돌아가니까 됐다" 마인드: 한 번 성공했다고 끝이 아닙니다. 잠자기 상태, 네트워크 끊김, API 장애 등 다양한 상황에서 테스트해봐야 합니다
과정 중 시행착오
launchd + pmset + caffeinate를 조합하는 과정에서 시행착오가 정말 많았습니다:
iCloud Desktop 경로 문제: launchd에서
WorkingDirectory를 지정하면 iCloud가 가로채서getcwd실패 → WorkingDirectory 제거로 해결pmset schedule vs repeat 차이: 일회성
schedule은 잠자기 wake에서 신뢰성이 낮았고, 반복repeat만 안정적으로 동작2초 만에 다시 잠드는 문제: pmset repeat으로 깨워도 사용자 활동 없으면 즉시 재잠자기 → caffeinate
-u로 user activity 시뮬레이션
각각의 문제를 발견할 때마다 "이것까지 신경 써야 하나?" 싶었지만, 결국 하나씩 해결하니 안정적인 자동화가 완성됐습니다.
앞으로의 계획
다음 단계
요약 결과를 Notion이나 Slack으로 자동 전송해서, Mac을 열지 않아도 폰에서 바로 확인할 수 있게 하고 싶습니다
운영 안정성 모니터링 강화 (연속 실패 시 알림 등)
다른 업무에 적용한다면?
macOS에서 정기적으로 돌려야 하는 스크립트가 있다면, launchd + pmset + caffeinate 조합을 활용할 수 있습니다. 잠자기 상태 대응이 핵심입니다.
재사용 가능한 프롬프트
프롬프트 1: 스케줄 실행 실패 진단
[스케줄 도구]로 예약한 작업이 실행되지 않았어.
로그 파일이 생성되지 않은 걸로 봐서 스크립트 자체가 실행 안 된 것 같아.
확인해야 할 것:
1. 스케줄 등록 상태
2. 시스템 로그에서 해당 시간대 이벤트
3. 잠자기/wake 이력
원인을 찾아줘.
프롬프트 2: LLM 폴백 체인 구현
[스크립트명]에서 API 호출 실패 시 자동으로 다른 모델로 전환되는 폴백 체인을 만들어줘.
순서: [모델1] → [모델2] → [모델3]
반환값: (응답 텍스트, 실제 사용된 모델명) 튜플
적용 대상: [함수1], [함수2] 등 LLM 호출하는 모든 함수
프롬프트 3: macOS 잠자기 대응 자동화
launchd 스케줄 작업이 잠자기 상태에서 실행되어야 해.
현재 설정:
- pmset repeat wakeorpoweron으로 [시간]에 Mac 기상
- launchd StartCalendarInterval로 [시간+5분]에 스크립트 실행
문제: Mac이 깨어났다가 바로 다시 잠들어서 스크립트 미실행
해결: caffeinate -u -t 600으로 잠자기 방지하는 별도 launchd job 필요
도움 받은 글 (옵션)
참고한 자료
macOS pmset 공식 문서: https://ss64.com/mac/pmset.html
Apple Community - pmset wake 관련: https://discussions.apple.com/thread/254622716
yt-dlp 공식 문서: https://github.com/yt-dlp/yt-dlp
작성일: 2026-02-03 작성자: suhyuk (gpters 20기)