음성봇을 스텁부터 만든 이유 — 테스트로 설계를 먼저 굳히다

시리즈 · 음성봇 직접 만들기 — 실시간 음성봇의 뼈대를 바닥부터 만든 8편 기록입니다. 1. 끼어들기(barge-in) — 재생 중인 TTS를 실시간으로 끊는 법 2. "말이 끝났다"는 판단 — VAD 엔드포인터 3. 엔진을 코드 수정 없이 바꾸는 인터페이스 설계 4. 로컬 LLM 대화 두뇌와 도구 호출 루프 5. 매 턴 지연시간을 재는 이유 6. 브라우저 마이크에서 서버까지 — 오디오 프로토콜 7. 로컬 Whisper STT 연결하기 8. 스텁부터 만든 이유 — 테스트 우선 설계 (완결) — 지금 보는 글 돌아보며 시작하는 마지막 편 이 시리즈를 시작할 때부터 정해 둔 규칙이 하나 있었습니다. 진짜 음성 인식 모델과 진짜 합성 모델이 준비되기 전까지는, 그 둘을 흉내만 내는 가짜 엔진으로 전체 구조를 먼저 돌려본다는 규칙입니다. 여덟 편을 거치며 끼어들기 처리, 상태 흐름, 프로토콜, 엔진 인터페이스를 하나씩 다뤘는데, 그 모든 것이 사실 이 가짜 엔진 위에서 검증됐습니다. 지금 코드를 다시 열어 보면 그때는 별생각 없이 세운 규칙이 결과적으로 시리즈 전체의 진행 속도를 결정했다는 게 눈에 들어옵니다. 이번 편에서는 왜 굳이 가짜부터 만들었는지, 그리고 그 선택이 시리즈 전체에 어떤 영향을 남겼는지 정리하면서 이 시리즈를 마무리하려 합니다. 실제 모델을 기다리지 않기로 한 이유 음성봇의 핵심 로직은 사실 음성 인식이나 음성 합성 자체가 아닙니다. 사용자가 말을 시작했는지 끝냈는지 판단하는 상태머신, 합성 중에 끼어들기가 들어왔을 때 스트림을 멈추는 동시성 처리, 이벤트가 순서대로 오가는 흐름 제어 같은 것들이 훨씬 까다롭습니다. 반면 실제 인식·합성 모델은 무겁고 설치가 까다롭고 실행 속도도 느립니다. 이 두 가지를 한꺼번에 붙잡고 있으면 어려운 동시성 버그를 실제 모델의 로딩 시간과 뒤섞어 디버깅하게 됩니다. 모델이 느려서 반응이 늦은 건지, 상태머신이 잘못 짜여서 늦은 건지 구분이 안 되는 상황을 미...

맥북 배터리 사이클·건강 확인하는 법 (명령 한 줄 + 메뉴바 위젯)


시리즈 · 직접 만든 macOS 도구 — 메뉴바에 사는 작은 앱들을 하나씩 만들어 온 기록입니다.

  1. Claude Code 사용량 메뉴바 모니터
  2. AI 에이전트 상태 모니터 (파이썬 rumps)
  3. 맥북 배터리 건강·메뉴바 유틸 3선 — 지금 보는 글
  4. 말하면 노션에 꽂히는 온디바이스 받아쓰기 앱
  5. 맥 절전·자리비움 방지 (마우스 지글러)

맥북 배터리 사이클, 왜 매번 설정을 헤집어야 하나

맥북 배터리가 얼마나 닳았는지 보려면 매번 같은 길을 갑니다. 설정 → 배터리 → 배터리 상태 → 거기서야 충전 사이클과 최대 충전 용량이 보입니다. 자주 보고 싶은 정보인데 너무 깊이 있습니다.

사실 명령 한 줄이면 바로 보입니다. 이 글에서는 먼저 그 방법을 정리하고, 한 발 더 나아가 메뉴바에 상시 띄우는 위젯까지 만들어 봅니다. 만들고 나니 비슷한 잡일이 더 보여서, 물 마시기 리마인더와 스크린샷 자동 정리까지 같은 방식으로 세 개를 만들었습니다. 전부 셸 한 줄이나 작은 스크립트면 되는 것들입니다.

이 글에서는 세 가지를 차례로 정리합니다. 핵심은 첫 번째, 배터리입니다.

명령 한 줄로 뽑아낸 배터리 건강·사이클 (터미널 실행 결과)
명령 한 줄로 뽑아낸 배터리 건강·사이클 (터미널 실행 결과)

1. 맥북 배터리 사이클·건강 확인 (메인)

방법 1 — 명령 한 줄 (가장 빠르고 확실)

맥북 배터리 정보는 system_profiler로 전부 뽑힙니다. 터미널에 이 한 줄이면 됩니다.


system_profiler SPPowerDataType | grep -E "Maximum Capacity|Cycle Count|Condition"

출력은 이렇게 나옵니다.


Maximum Capacity: 99%
Cycle Count: 131
Condition: Normal
  • Maximum Capacity(최대 충전 용량) = 흔히 말하는 "배터리 건강". 새 거 100%, 쓸수록 줄어듭니다. 80% 아래면 교체를 고려할 때입니다.
  • Cycle Count(충전 사이클) = 0%→100% 한 바퀴를 1회로 칩니다. 요즘 맥북은 보통 1,000회가 설계 수명입니다.
  • Condition = Normal이면 정상, Service Recommended면 점검 권장.

이 명령은 어느 맥에서나 동작합니다. 이것만 알아도 배터리 사이클 보려고 설정을 헤집을 일은 없습니다.

방법 2 — 설정 화면에서

GUI가 편하면 설정 → 배터리 → 배터리 상태(또는 옆의 정보 아이콘)에서 같은 값을 볼 수 있습니다. 충전 사이클과 최대 충전 용량이 그대로 표시됩니다. 다만 매번 여기까지 들어가야 해서, 명령이나 아래 메뉴바 위젯이 더 편합니다.

(보너스) 메뉴바에 상시 띄우기 — SwiftBar

매번 명령을 치기 귀찮다면 메뉴바에 상시 띄울 수 있습니다. SwiftBar는 셸 스크립트의 출력을 그대로 메뉴바에 그려주는 도구입니다. 파일명을 battery.5m.sh로 두면 5분마다 자동 실행됩니다.


#!/bin/bash
# 배터리 정보를 한 번에 읽어 파싱 (system_profiler는 느려서 1회만 호출)
PWR="$(system_profiler SPPowerDataType 2>/dev/null)"
HEALTH=$(echo "$PWR" | awk -F': ' '/Maximum Capacity/{gsub(/%/,"",$2); print $2; exit}')
CYCLES=$(echo "$PWR" | awk -F': ' '/Cycle Count/{print $2; exit}')
COND=$(echo "$PWR"   | awk -F': ' '/Condition/{print $2; exit}')

# 건강% 색 분기 (임계값으로 색을 바꿉니다)
HCOLOR="#34c759"                                       # 초록(양호)
[ "$HEALTH" -lt 90 ] && HCOLOR="#ff9f0a"              # 주황(주의)
[ "$HEALTH" -lt 80 ] && HCOLOR="#ff3b30"              # 빨강(교체 고려)

echo "🔋 ${HEALTH}%"                                   # 메뉴바 한 줄
echo "---"                                            # 아래는 드롭다운
echo "배터리 건강: ${HEALTH}% | color=${HCOLOR}"
echo "충전 사이클: ${CYCLES}회"
echo "상태: ${COND}"

SwiftBar의 규칙은 단순합니다. 첫 줄이 메뉴바 텍스트, --- 아래가 클릭하면 펼쳐지는 드롭다운, | color= 같은 파라미터로 색을 줍니다. 건강이 90% 아래면 주황, 80% 아래면 빨강으로 바뀌게 해서 한눈에 위험을 알 수 있습니다.

SwiftBar 배터리 플러그인 실행 화면 — 건강 99%, 사이클 132회, 충전 중 84%
SwiftBar 배터리 플러그인 실행 화면 — 건강·사이클·충전 상태가 드롭다운으로 표시됩니다

다만 메뉴바 표시는 환경을 좀 탑니다. 메뉴바 공간이 부족하거나 SwiftBar의 플러그인 폴더 권한이 잡히지 않으면 아이콘이 안 보일 수 있습니다(아래 "메뉴바에 안 뜰 때" 참고). 메뉴바에 안 떠도 걱정할 것 없습니다. 방법 1의 명령으로 언제든 같은 정보를 바로 볼 수 있으니까요. 메뉴바 위젯은 어디까지나 편의를 위한 보너스입니다.


2. 물 마시기 리마인더

하루 종일 일하다 보면 물 마시는 걸 잊습니다. 의식하지 않으면 한나절 내내 한 모금도 안 마시는 사람이 의외로 많습니다. 저도 그랬습니다. 그래서 정해진 간격마다 "물 마실 시간"을 알려줘 수분 섭취를 챙기게 하는 리마인더를 만들었습니다. 이 유틸의 본래 목적이 바로 이겁니다.

물만 반복하면 질리니, 스트레칭·눈 휴식·자세 같은 멘트도 번갈아 띄웁니다. 그리고 배려를 하나 넣었습니다. 밤이나 주말처럼 쉴 때는 조용하도록, 알림이 울리는 시간대(기본 업무시간)를 정해 둔 겁니다. 이건 어디까지나 부가 옵션이고, 핵심은 "물 좀 마시자"입니다.


WORK_START=9          # 업무 시작 시
WORK_END=18           # 이 시각 전까지만 알림
DEFAULT_INTERVAL=1800 # 알림 주기(초) = 30분

MENTIONS=(
  "물 한 잔 마시기"
  "일어나서 어깨 한 번 돌리기"
  "먼 곳 20초 바라보기 (눈 휴식)"
  "허리 펴고 자세 고쳐 앉기"
)

알림은 terminal-notifier(없으면 osascript 폴백)로 띄우고, 메뉴바에는 오늘 챙긴 누적 횟수를 표시합니다. 클릭하면 리셋·10분 스누즈·일시정지를 고를 수 있습니다. 이것도 SwiftBar 플러그인이라 파일명을 hydrate.1m.sh로 두면 1분마다 화면이 갱신됩니다.

메뉴바 누적 카운트와 업무시간 알림
메뉴바 누적 카운트와 업무시간 알림

3. 스크린샷 자동 정리 (백그라운드)

스크린샷을 찍으면 바탕화면이 금세 어질러집니다. 이건 메뉴바에 띄울 것도 없이 백그라운드에서 조용히 정리되면 됩니다. 그래서 이건 SwiftBar가 아니라 작은 Swift 앱으로 만들었습니다(메뉴바·Dock 아이콘 없음).

동작은 단순합니다.

  • ~/Desktop를 몇 초마다 확인
  • 스크린샷(스크린샷 *.png) → ~/Desktop/YYYY/MM/로 이동
  • 화면 녹화(*.mov) → ~/Desktop/recordings/YYYY/MM/로 이동
  • 날짜는 파일명에서 추출, 없으면 생성일 사용

안전장치가 중요합니다. 엄격한 파일명 패턴만, 최상위 파일만, 2초 이상 안정된 파일만 옮깁니다. 안 그러면 엉뚱한 파일까지 건드립니다.

빌드는 단일 파일을 swiftc로 컴파일하면 끝입니다.


swiftc ScreenshotTidy.swift -o ScreenshotTidy
⚠️ 처음 실행하면 macOS가 "데스크탑 폴더 접근 허용"을 묻습니다(TCC 권한). 허용해야 동작합니다.
어질러진 바탕화면이 날짜 폴더로 자동 정리된 결과
어질러진 바탕화면이 날짜 폴더로 자동 정리된 결과

셋의 공통 빌드법 — SwiftBar vs Swift 앱

세 유틸은 두 방식으로 나뉩니다.

유틸 방식 메뉴바 이유
배터리·물 리마인더 SwiftBar(셸) 메뉴바(보너스) 정보를 상시 보여주면 편함
스크린샷 정리 Swift 앱 없음 백그라운드로 조용히 돌면 됨

SwiftBar 셸 플러그인이 입문엔 가장 쉽습니다. 규칙은 세 개뿐입니다.

  1. 파일명이 주기 — battery.5m.sh의 5m은 5분, hydrate.1m.sh의 1m은 1분 갱신
  2. 출력 = 화면 — 첫 줄은 메뉴바, --- 아래는 드롭다운
  3. | 뒤 파라미터 — color=, 클릭 액션, refresh=true

상시 정보가 아니라 백그라운드 자동화면 SwiftBar 대신 Swift 앱(.accessory + LSUIElement)으로 아이콘 없이 돌리는 게 깔끔합니다.


메뉴바에 안 뜰 때 (제가 실제로 겪은 함정)

SwiftBar 플러그인을 폴더에 넣고 새로고침했는데 메뉴바에 아무것도 안 떴습니다. 설정도 맞고 스크립트도 잘 도는데 말이죠.

원인은 메뉴바 공간 부족이었습니다. 노치가 있는 맥북에서 메뉴바 아이콘이 많으면, 새로 생긴 아이콘이 노치 뒤로 숨거나 잘립니다. 특히 메뉴가 긴 앱(IDE 등)이 활성일 때 더 심합니다.

확인·해결 순서는 이렇습니다.

  1. 스크립트가 실제로 도는지 먼저 확인: 터미널에서 직접 실행해 출력이 나오면 스크립트는 정상
  2. 바탕화면을 클릭해 Finder를 활성화 → 왼쪽 앱 메뉴가 짧아져 공간이 생김
  3. 그래도 안 보이면 메뉴바 관리 앱(Ice, 무료)으로 넘치는 아이콘 정리
  4. SwiftBar 플러그인 폴더가 ~/.swiftbar-plugins로 맞는지 확인

"안 뜬다 = 고장"이 아니라 "표시 공간이 없다"인 경우가 많습니다. 스크립트가 도는지부터 확인하면 됩니다.


마무리

세 유틸 모두 셸 한 줄이나 작은 스크립트면 충분합니다. 설정 깊이 들어가 보던 배터리 정보를 명령 한 줄로 꺼내고(원하면 메뉴바에도), 잊던 물을 챙기고, 어질러지던 바탕화면을 자동으로 정리합니다. "이런 게 있으면 좋겠는데" 싶은 잡일은 대부분 30분이면 직접 만들 수 있습니다.


자주 묻는 질문

Q. 배터리 사이클은 몇 회까지 괜찮나요?

A. 요즘 맥북은 설계 수명이 약 1,000회입니다. 그 전이라도 최대 충전 용량(건강)이 80% 아래로 떨어지면 교체를 고려할 때입니다.

Q. SwiftBar 없이도 배터리 정보를 볼 수 있나요?

A. 네. system_profiler SPPowerDataType 한 줄이면 터미널에서 바로 보입니다. 메뉴바 상시 표시가 필요할 때만 SwiftBar를 씁니다.

Q. 코딩을 잘 몰라도 만들 수 있나요?

A. SwiftBar 플러그인은 셸 스크립트 한 파일이라 입문용으로 적당합니다. 명령 출력을 그대로 메뉴바에 띄우는 구조라 진입장벽이 낮습니다.


이 글의 모든 유틸은 운영자가 직접 만들어 본인 맥에서 사용 중인 도구입니다. 수치(배터리 사이클·건강 등)는 운영자 기기 기준이며 기기마다 다릅니다. (2026년 6월 기준)

댓글

이 블로그의 인기 게시물

디스코드 구글캘린더 연동 봇 만들기: 카톡 캡처 OCR 자동 등록 시스템 구축

클로드 코드 비용 줄이는 법 — ollama 로컬 LLM 연동 (M3 맥북)

유튜브 노션 자동 저장 봇 만들기 — Claude CLI MCP + Discord 233일 운영기