2026. 6. 21. 12:33ㆍ맥미니 OpenClaw 비서 봇 만들기
북산 비서실 v1 — CP15 정리 (2026-06-21)
아침 브리핑 파이프라인 6단계 전체 구현·실측·무인 자동화 완성
민감정보(봇 계정명·토큰·채널ID·IP·경로)는 마스킹 처리
1차 — 블로그용 (팩트 중심)
CP15. 아침 브리핑 파이프라인 — 6단계 무인 자동화 완성
맥미니 개인 비서 봇 "북산 비서실"의 2순위 작업인 아침 브리핑 자동화를 6단계 전체 구현·실측해서 무인으로 돌렸다. 매일 06:00(한국시간) 사람 손 없이 미국 증시 브리핑이 슬랙에 자동으로 올라온다.
전체 흐름
06:00 KST (cron 자동)
→ 시세 수집 → 뉴스 수집 → 송태섭 작성 → 이한나 검증 → 이한나 명의 슬랙 발송1단계 시세 수집. Finnhub 주력, 실패 시 Alpha Vantage 폴백, 둘 다 안 되면 "확인 불가"(값 안 지어냄). 지수 프록시 SPY·QQQ·DIA + 워치리스트 AMD·ROKT·GLW·DELL·ORCL. 미국 휴장·주말을 건너뛰고 직전 거래일 자동 판정. 첫 실행 8종목 전부 성공.
2단계 뉴스 수집. Alpha Vantage News & Sentiment에서 거시·시장 두 주제 각 10건, 총 20건을 관련도순 수집. 각 기사에 원래 관련도 순위를 보존해 시간순·관련도 둘 다 참고 가능. 개별 종목 잡뉴스는 수집에서 안 거르고 다음 단계 판단에 맡기는 설계.
3·4·5단계 작성·검증(파이프라인의 두뇌). 스크립트가 정보 담당(송태섭)과 비서실장(이한나)을 Claude API로 차례 호출한다. 봇을 깨우지 않고 API로 직접 부르는 방식이라 토큰 효율이 높다. 정보 담당이 시세+뉴스를 읽고 5칸 브리핑(시장 방향·핵심 이슈·주목 종목·리스크·한줄 결론)을 쓰면, 비서실장이 4기준(수치 출처·5칸 형식·당일자·무모순)으로 검증만 하고 통과시킨다(다시 쓰지 않아 토큰 절약). 미달이면 1회만 반려, 그래도 안 되면 미달 표시를 붙여 확정(무한 루프 방지). 평시 LLM 2콜. 인격은 실제 SOUL 파일에서 읽어와 지어내지 않는다. 첫 실행에서 개별 종목 잡뉴스 17건을 정확히 걸러내고 큰 흐름 3개(AI 전환·반도체 랠리·AI 전력 인프라)로 묶었다.
6단계 발송. 슬랙 API 직접 호출, 비서실장 토큰으로 발송해 비서실장 명의로 게시. 발송 전 봇 신원을 확인하는 장치. 마크다운을 슬랙 형식으로 변환(표는 코드블록, 모바일에서 깨지면 한 줄로 바꾸는 스위치 내장). 발송 실패 시 재시도 후 실패 알림. PC·폰 둘 다 정상 확인.
7단계 자동화 — 그리고 가장 큰 교훈. 4단계를 하나로 묶는 마스터 스크립트를 만들고 매일 06:00 자동 실행을 걸려는데, 처음 고른 launchd(macOS 표준 스케줄러)가 발사를 안 했다. 두 번 시도(11:50·12:10) 다 실패. 파고 보니 원인은 — 이 맥미니가 봇 전용 헤드리스라 화면 로그인 세션이 없어서, 사용자 단위 launchd 타이머가 작동하지 않았다. 봇이 멀쩡히 도는 건 상시 데몬이라 그런 거고, 시각 예약 발사는 다른 메커니즘이었다.
해결은 cron으로 전환. cron은 시스템 데몬이 돌려서 화면 로그인 여부와 무관하게 실행된다. 가까운 시각(12:20)으로 임시 테스트해 자동 발사를 두 눈으로 확인한 뒤, 매일 06:00으로 확정했다.
비용. 1회 실측 약 $0.074(LLM 2콜). 하루 1회면 월 약 $2.2.
오늘의 핵심 교훈 — 06:00에 바로 안 걸고 가까운 시각으로 먼저 테스트한 게 launchd 함정을 걸러냈다. 안 그랬으면 다음 날 아침 빈 슬랙을 보고 한참 헤맀을 것. 그리고 헤드리스 봇 맥에선 GUI 기반 launchd 캘린더가 아니라 cron을 써야 한다.
2차 — 깃허브용 (전체 내용 + 결정 태그)
CP15. 아침 브리핑 파이프라인 — 6단계 전체 구현·실측·무인 자동화
직전 CP14(1순위 SOUL 배치 + 시간버그 해결 + Claude Code 설치) 이후 ~ 2순위 완성까지의 델타.
작업폴더~/buksan-briefing. 진행방식 B(단계별 구현·실측). 봇 계정·호스트명·토큰·채널ID·IP는 마스킹.
설계 기조 [확정]
- 이한나 단일 창구 불변: 이사장 ↔ 이한나만. 송태섭은 직보 안 함, 뒤에서 작성. 발송은 이한나 명의.
- 최대 토큰 효율: 봇을 깨우지 않고 스크립트가 Claude API 직접 호출. 수집·발송은 스크립트(공짜), LLM은 작성·검증만 2콜.
- 호출 구조: 스크립트가 송태섭→이한나를 API로 차례 호출(오케스트레이터=스크립트). CP4 "봇 위임"에서 변경 [승인].
1단계 — 시세 market_fetch.py [확정]
- Finnhub
/quote주력 → AVGLOBAL_QUOTE폴백 →unavailable(값 안 지어냄). - 8티커: 지수 SPY·QQQ·DIA + 워치 AMD·ROKT·GLW·DELL·ORCL. watchlist config 분리.
- KST 고정(timezone +9),
classify_trade_day()로 휴장·주말 건너뛴 직전 거래일 판정. 장중 의심 시warning:intraday_possible별도 필드(status enum 안 깸). - 키
.env분리, 로그 키 비노출. 종료코드 키없음=3·전실패=4. - 첫 실행 8/8 OK 전부 Finnhub(폴백 0), exit0. ROKT 유효(close 117.58), Juneteenth(6/19)+주말 건너뛰고 trade_day=6/18.
2단계 — 뉴스 news_fetch.py [확정]
- AV News & Sentiment(시세 백업 AV키 재사용). topic 2개(economy_macro+financial_markets) 각 10건=20건,
sort=RELEVANCE, 지난 24h. - relevance_rank 보존(AV 관련도 topic별 1~10). 저장은 published_kst 최신순·rank 독립. note 메타로 "순서≠중요도, 선별은 내용 기준" 명시.
- 개별 종목 노이즈는 수집에서 안 거름 → 송태섭 몫(설계 원칙) [확정].
- 첫 실행 2/2 topic OK. AV 무료 티어가 topic 필터 받아줌(관문 통과). 중복 제거 동작.
3·4·5단계 — briefing_llm.py (파이프라인 두뇌) [확정]
- 스크립트가 송태섭·이한나를 Claude API 차례 호출. 평시 LLM 2콜, 반려 시 최대 4콜.
- SOUL 실제 파일에서 읽음(
read_soul_core): scout/main의 SOUL.md+IDENTITY.md+USER.md만(없으면 exit5 위조 방지). AGENTS/TOOLS/HEARTBEAT 제외. - 모델 claude-sonnet-4-6, thinking=disabled + effort=low(adaptive 토큰 낭비 회피) [승인].
- 캐싱 끔 [승인]: 평시 cache_read=0이라 캐싱이 손해(+$0.004) → 기조 "최대 효율"에 맞춰 끔.
- 이한나 검증 = structured output(JSON schema passed/failed_criteria/reason)으로 게이트 견고화. 재작성 금지(토큰 절약, output 23토큰).
- 반려 = A안 [확정]: 1회 반려 후 재미달이면 "검증 미달 항목" 붙여 확정(무한 루프 금지).
- 거시 경계 = A [승인]: 거시 부족 시 섹터 테마로 유연하게 채우되
[섹터 신호]명시, 개별 종목은 섹터 근거로만(단독 시황 금지). - 첫 실행: 평시 2콜·이한나 1차 통과·exit0. 노이즈 17건 걸러냄(Dynamix·코카콜라·마카오 등 → AI 전환·반도체 랠리·AI 전력 인프라 3핵심). 수치 JSON 일치. ≈$0.076/회. 본문 우수(5칸·이사장 호칭·이모지 없음·한줄결론=상황 요약·투자 권유 없음·출처 표기).
6단계 — 발송 send_briefing.py [확정]
- 슬랙
chat.postMessage직접. 이한나(Buksan Secretary) xoxb 토큰(송태섭 아님).auth.test로 봇 신원 사전 확인. - md→슬랙 mrkdwn 변환(헤더→
*굵게*,**→*, 표→코드블록,---→빈 줄). TABLE_STYLE 상수로 codeblock↔lines 전환 가능(폰 깨짐 대비). - 4000자 초과 시 스레드 분할. 실패 시 1회 재시도→실패 알림.
--notify-failure <단계>모드(마스터 호출용). - 첫 발송 성공: daily-briefing에 이한나 명의 5칸 브리핑 게시(PC·폰 OK).
7단계 — 마스터 + 크론 [확정]
run_briefing.sh: 절대경로PROJECT=/Users/*****/buksan-briefing·PY=/usr/bin/python3, KST 날짜,run_step()로 4단계 순차(market→news→briefing_llm "$DATE"→send_briefing "$DATE"). 앞 단계 실패 시 슬랙 알림+exit1 중단. 로그 output/logs.set -u. 손 테스트 ALL OK.- ★크론 방식 = cron 확정(launchd 아님) [확정 — 핵심 교훈]:
- launchd
gui/501은 헤드리스 로그인 윈도우(/dev/console소유자 root)라StartCalendarInterval미발사. GUI 세션이 active해야 발사되는데 봇 맥은 헤드리스. gateway는 KeepAlive 상시 데몬이라 캘린더 발사 능력을 검증 못 해줬음(착각 유발). - 레거시
load·모던bootstrap둘 다 11:50·12:10 미발사 실측 확인 → cron 전환(시스템 cron 데몬, GUI 무관, sleep 0 확인됨). - cron 12:20 임시 테스트 → 실측 발사 확인 →
crontab "0 6 * * *"+SHELL=/bin/bash+PATH명시 프로덕션 확정. - ★교훈: 헤드리스 봇 맥에선 GUI LaunchAgent 캘린더 안 됨 → cron 써야 함. (Claude Code MEMORY.md에
macmini-headless-scheduling저장)
- launchd
- plist
RunAtLoad=false(등록 시 즉시 실행 방지), StandardOut/ErrorPath를 로그 파일로(봇 plist의 /dev/null과 달리 크론 실패 원인 보존).
키·설치 [확정]
- 사용자가 nano로
.env직접 입력:SLACK_BOT_TOKEN(이한나)·SLACK_CHANNEL_ID·ANTHROPIC_API_KEY.grep -c your_=0확인. - ANTHROPIC_API_KEY = 봇 키와 공유($50 한도) [승인]: 봇·브리핑 둘 다 무인이라 같은 키. 코딩(Claude Code)만 구독으로 분리.
pip3 install anthropic(user 설치).
비용 실측
- 1회 ≈ $0.074(input ~16.5K·output ~1.7K, 2콜). 월 1회/일 ≈ ~$2.2.
- ⚠️ 콘솔 Usage는 지연·집계 단위 때문에 1회를 정확히 못 떼어 보임(로그가 실측 진실). 봇 대화가 같은 키라 합산됨 → [TODO] 브리핑 전용 키 분리 검토 시 콘솔 추적 명확해짐.
완성 상태
매일 06:00 KST 무인 자동: 시세 → 뉴스 → 송태섭 작성 → 이한나 검증 → 이한나 명의 슬랙 발송.
남은 TODO
- output 누적 정리 정책(매일 JSON·로그 쌓임)
- 봇 키 $50 한도 재점검(브리핑 LLM도 같은 키, 월 ~$2) / 브리핑 전용 키 분리 검토
- 멘션 겹침 미세조정, 송태섭 응답 안정성 모니터
- 채소연 엔진, v2 6인 SOUL 파일화
- 보안(VNC 암호·Tailscale 2FA·토큰 SecretRefs), 슬랙 owner·allowlist 유저ID, 리포명
'맥미니 OpenClaw 비서 봇 만들기' 카테고리의 다른 글
| # CP17 — 아침 브리핑 주간 모드(일요일/월요일) 추가 (0) | 2026.06.22 |
|---|---|
| ## CP16. 무인 자동화, 진짜로 돌다 — 그리고 다음 일감 (0) | 2026.06.22 |
| CP14 — v1 인격 배치 완료 + 멀티봇 + 속도·안정성·시간 결정 (0) | 2026.06.21 |
| 맥미니 OpenClaw 비서 봇 만들기 (13) — 모니터 없이, 노트북 한 대로 다 하기 (0) | 2026.06.20 |
| 맥미니 OpenClaw 비서 봇 만들기 (12) — 설치 실전과 슬랙 연결의 다섯 함정 (0) | 2026.06.20 |