Minbook
EN
크론 + Telegram + Claude로 만든 자기 개선 시스템 — $0 아키텍처 해부

크론 + Telegram + Claude로 만든 자기 개선 시스템 — $0 아키텍처 해부

MJ · · 8 분 소요

1편에서 소개한 Self-Tuning Loop 패턴을 실제로 운영하는 시스템의 전체 아키텍처. 데이터 수집(35개 소스), AI 큐레이션, Telegram 입력 파이프라인, 주간 자동 리뷰, Syncthing 기반 무배포 프롬프트 진화까지.

이전 편에서 Self-Tuning Loop의 개념을 소개했습니다. AI 초안과 사용자 최종본의 diff를 캡처하고, 패턴을 분석하여 프롬프트를 자동 진화시키는 4단계 순환.

이번 편에서는 이 루프를 실제로 6주째 운영하고 있는 시스템을 해부합니다. 이론이 아닌 프로덕션 환경의 이야기입니다.


시스템 개요: 하나의 대시보드, 다섯 개의 자동화

이 시스템은 개인의 반복 업무를 하나로 모아서 AI가 처리하고, 그 결과를 피드백 루프로 개선하는 구조입니다.

graph TD
    subgraph 수집 ["Layer 1: 자동 수집 (04:00 KST)"]
        RSS["RSS 19개"]
        HN["Hacker News 8쿼리"]
        WEB["GitHub Trending + HF Papers"]
        RED["Reddit 2개"]
        TAV["Tavily 검색 7개"]
        STATS["GA4 + GitHub + Naver"]
    end

    subgraph 저장 ["Layer 2: Supabase"]
        RAW["daily_news_raw"]
        DN["daily_news (큐레이션 20개)"]
        DS["daily_stats"]
        LD["linkedin_drafts"]
        TQ["task_queue"]
    end

    subgraph AI ["Layer 3: AI 처리"]
        CURATE["뉴스 큐레이션 (06:30)"]
        LINKEDIN["LinkedIn 드래프트 (10:00)"]
        DISPATCH["태스크 디스패처 (매시)"]
    end

    subgraph 피드백 ["Layer 4: Self-Tuning Loop"]
        FB["👍/👎 + 북마크 + 편집 diff"]
        REVIEW["주간 자동 리뷰 (토 03:00)"]
        EVOLVE["프롬프트 자동 패치"]
    end

    RSS & HN & WEB & RED & TAV --> RAW
    STATS --> DS
    RAW --> CURATE --> DN
    DN --> FB --> REVIEW --> EVOLVE
    EVOLVE -->|"다음 주 큐레이션 개선"| CURATE

다섯 가지 자동화가 돌아가고 있습니다.

자동화주기하는 일
뉴스 수집매일 04:0035개 소스에서 뉴스 수집 → dedup → 저장
AI 큐레이션매일 06:30150개 → 20개 선별 + 요약
LinkedIn 드래프트매일 10:00전일 뉴스 + 피드백 기반 포스트 2건 생성
태스크 디스패처매시 정각Telegram 입력 처리 (블로그/리서치/아이디어)
주간 리뷰토요일 03:00큐레이션 품질 분석 + 프롬프트 자동 패치

추가 비용: $0. 전체 스택이 무료 티어로 작동합니다.


이 시스템이 돌아가는 하드웨어

다른 프로젝트를 위해 구매했던 Mini PC가 있었습니다. Intel N100, 16GB RAM, Windows 11. 원래는 Slack 기반 AI 에이전트 프레임워크(OpenClaw, 이후 BoltShark로 전환)를 24/7 운영하려고 산 것이었는데, 프로젝트가 아카이브되면서 하드웨어만 남았습니다.

이 유휴 장비를 재활용했습니다.

컴포넌트역할실행 환경
pm2 + node-cron뉴스/Stats 수집 크론WSL Ubuntu
Claude DesktopAI 큐레이션, LinkedIn 드래프트, 태스크 디스패처Windows
SyncthingMac ↔ Mini PC 파일 동기화Windows + Mac

WSL Ubuntu에서 Node.js 크론이 돌고, Windows의 Claude Desktop이 스케줄 태스크로 AI 작업을 처리합니다. 두 환경은 /mnt/c/ 경로로 연결됩니다.


Layer 1: 데이터 수집 — 35개 소스, 자동 dedup

매일 04:00 KST에 node-cron이 35개 소스에서 뉴스를 수집합니다.

카테고리소스수집 방식
공식 블로그 (Tier 1)OpenAI, Google AI, DeepMind, HuggingFace, NVIDIA, MetaRSS
전문가 (Tier 2)Simon Willison, Ahead of AI, One Useful Thing, Latent SpaceRSS
미디어 (Tier 3)TechCrunch AI, VentureBeat AI, MIT Tech ReviewRSS
한국 (Tier 4)AI Times, MIT Tech Review KR, GeekNews, PyTorch KoreaRSS
커뮤니티Hacker News (8개 키워드), Reddit (r/ML, r/LocalLLaMA)API + RSS
검색Anthropic, BCG, Bain, Deloitte, Gartner, Stanford HAITavily
트렌드GitHub Trending Python, HuggingFace Papers스크래핑

수집 후 3단계 dedup이 적용됩니다.

1. URL 정규화 — 쿼리 파라미터, trailing slash 제거 후 비교 2. 제목 유사도 — 동일 뉴스가 다른 URL로 배포된 경우 필터링 3. 토픽 워드 매칭 — 3개 이상 키워드가 겹치면 중복 후보로 표시

결과: 매일 50~200개 항목이 daily_news_raw 테이블에 저장됩니다. 실패한 소스 목록도 함께 기록됩니다.

04:05 — Stats 수집

뉴스와 별도로 운영 지표도 수집합니다.

소스데이터
Google Analytics 43개 프로퍼티의 세션, 유저, 페이지뷰, 유입 소스
GitHub API5개 레포의 스타, 트래픽, stale 감지
Naver Blog4일간 방문자 + 일평균

Safety-net: 크론을 신뢰하지 않는다

WSL2 환경에서 node-cron이 조용히 실행을 건너뛰는 사건이 발생했습니다. pm2는 “online” 상태였지만, 04:05 스케줄의 로그 자체가 없었습니다. WSL2 VM이 idle 상태에서 일시 정지되면서, cron의 매 분 폴링 루프가 해당 시각을 건너뛴 것으로 추정됩니다.

이후 3중 방어를 구축했습니다.

1. 전역 crash handleruncaughtException, unhandledRejection 캐치 2. Startup catch-up — 프로세스 재시작 시 오늘 데이터 누락이면 즉시 보충 3. 06:00 safety-net cron — 결과 행(row) 존재 여부로 재검증. 없으면 재실행

핵심 교훈: pm2 “online”은 CPU가 돌고 있다는 보장이 아닙니다. 크론을 신뢰하지 말고, 결과를 검증해야 합니다.


Layer 2: AI 큐레이션 — 150개 → 20개

매일 06:30 KST, Claude Desktop의 스케줄 태스크가 curate-daily-news.md 프롬프트를 읽고 실행합니다.

큐레이션 기준

AI가 150개 원본에서 20개를 선별할 때 적용하는 기준:

기준설명
신선도14일 이내 (60일이었다가 리뷰 후 축소)
중복 제거직전 2일 daily_news와 URL 비교
Tier 가중치공식 블로그 > 전문가 > 미디어 > 커뮤니티
카테고리 분산Model, Method, Tool, Product, Industry 골고루
컨설팅펌 우선BCG, Bain, Deloitte 등 14일 이내 → 자동 포함

결과는 3-tier로 분류됩니다.

Must-Read (빨강) — 놓치면 안 되는 핵심 뉴스 Notable (앰버) — 알아두면 좋은 것 FYI (기본) — 참고용

대시보드에서 보이는 것

웹 대시보드(Lovable + Supabase)에서 당일 큐레이션 결과를 확인합니다. 각 뉴스 카드에는:

  • 카테고리 컬러 뱃지 (Model=보라, Tool=초록, Product=주황 등)
  • 저장 토글 (북마크)
  • 👍/👎 피드백 + 코멘트
  • 실패 소스 경고 배너

이 피드백이 Layer 4의 Self-Tuning Loop으로 흘러갑니다.


Layer 3: Telegram 입력 파이프라인 — 폰에서 시스템으로

이 시스템에서 가장 독특한 부분입니다. Telegram Bot이 모바일 입력 레이어 역할을 합니다.

graph LR
    PHONE["📱 Telegram"] -->|"사진 + 캡션"| WEBHOOK["Supabase Edge Function"]
    WEBHOOK -->|"Vision + Tavily 전처리"| TQ["task_queue 테이블"]
    TQ -->|"매시 정각"| DISPATCH["Claude Desktop 디스패처"]
    DISPATCH -->|"타입별 라우팅"| RESULT["블로그/LinkedIn/리서치/아이디어"]

작동 방식

1. Telegram에서 사진과 캡션을 보냅니다. 키워드(/blog, /linkedin, /research, /idea)로 타입을 지정하거나, 한국어 키워드(블로그, 글감)도 인식합니다. 사진만 보내면 기본값 blog로 분류됩니다.

2. Supabase Edge Function(receive-telegram)이 웹훅으로 수신합니다.

  • 앨범(사진 여러 장)은 media_group_id로 묶어서 1건으로 처리
  • OpenAI Vision으로 사진 설명 생성
  • Tavily + Naver 검색으로 관련 정보 전처리
  • 결과를 task_queue 테이블에 pending으로 저장

3. Mini PC의 Claude Desktop이 매시 정각에 process-queue.md 프롬프트를 읽고, pending 태스크를 처리합니다.

  • blog → 네이버 블로그 초안 (3,500~5,000자, 9섹션 구조, 사진 배치)
  • linkedin → LinkedIn 포스트 드래프트
  • research → secondbrain에 리서치 노트 저장
  • idea / todo → secondbrain에 저장

4. 완료 시 Telegram으로 알림이 옵니다.

핵심 가치: 이동 중에 사진 한 장 보내면 됩니다. 나머지는 시스템이 처리합니다.


Layer 4: Self-Tuning Loop — 실제 작동

여기가 1편에서 다룬 개념이 실제로 구현된 부분입니다.

뉴스 큐레이션의 자기 개선

graph TD
    GEN["Generate: 큐레이션 프롬프트로 20개 선별"]
    CAP["Capture: 👍/👎 + 북마크 + 코멘트"]
    ANA["Analyze: 주간 리뷰 (토 03:00)"]
    EVO["Evolve: 큐레이션 프롬프트 자동 패치"]

    GEN --> CAP
    CAP --> ANA
    ANA --> EVO
    EVO -->|"다음 주 큐레이션 개선"| GEN

Generate: 매일 06:30, curate-daily-news.md 프롬프트가 뉴스 20개를 선별합니다.

Capture: 대시보드에서 사용자가 피드백을 남깁니다.

  • 👍 “이 뉴스는 좋았다” / 👎 “이건 필요 없었다”
  • 북마크 “나중에 다시 볼 것”
  • 코멘트 “이런 유형 더 보고 싶다”
  • 뉴스 URL 직접 제출 “이 기사가 빠졌다”

Analyze: 매주 토요일 03:00, weekly-review.md 프롬프트가 자동 실행됩니다.

  • 7일간의 피드백 데이터 조회
  • 선별 패턴 분석 (어떤 카테고리를 선호하는지, 어떤 소스가 반복 저평가되는지)
  • 사용자 제출 뉴스 분석 (큐레이션에서 빠진 것은 무엇이고 왜 빠졌는지)

Evolve: 분석 결과를 바탕으로 큐레이션 프롬프트를 자동 패치합니다.

  • Safe 변경 (빈도 높은 스타일/우선순위 조정) → git commit + push로 자동 반영
  • Risky 변경 (소스 추가/제거, 구조적 변경) → Telegram으로 제안만 전송

실제로 운영 초기(60일 신선도 필터)에서 주간 리뷰를 거쳐 14일 필터로 축소된 것이 자동 패치의 결과입니다.

LinkedIn 드래프트의 자기 개선

LinkedIn 쪽도 같은 루프가 돌고 있습니다.

Generate: 매일 10:00, daily-linkedin-draft.md가 2건의 드래프트를 생성합니다. 전일 뉴스에서 👍을 받거나 북마크된 항목을 우선 소재로 선정합니다.

Capture: 대시보드의 LinkedIn Studio에서 드래프트를 편집합니다. 톤, 해시태그, 구조를 수정하고 발행합니다. 원본 드래프트와 최종 발행본이 모두 linkedin_drafts 테이블에 저장됩니다.

Analyze + Evolve: 매주 토요일 03:15, weekly-linkedin.md가 발행된 포스트들의 편집 패턴을 분석하고, 톤 가이드를 자동 업데이트합니다.


프롬프트 진화의 배포: Syncthing

여기서 핵심적인 인프라 디테일이 있습니다. 프롬프트 파일의 업데이트에 별도 배포가 필요 없습니다.

Mac과 Mini PC 사이에 Syncthing이 4개 폴더를 실시간 양방향 동기화합니다.

폴더내용배포
memory/Claude Code의 메모리 파일자동 싱크
claude-commands/커스텀 슬래시 명령Mac → Mini PC (단방향)
secondbrain/리서치 노트, 아이디어양방향
minbook-content/블로그 콘텐츠양방향

Claude Desktop의 스케줄 태스크는 매 실행 시 프롬프트 파일을 디스크에서 직접 읽습니다. 따라서:

1. Mac에서 daily-linkedin-draft.md의 톤 가이드를 수정합니다 2. Syncthing이 Mini PC로 자동 동기화합니다 (수 초 이내) 3. 다음 10:00 KST 실행 시 수정된 프롬프트가 바로 반영됩니다

pm2 재시작도 없고, git push도 없고, 배포 과정이 0입니다. 주간 리뷰가 프롬프트를 자동 패치하면, 그 파일이 Syncthing으로 싱크되고, 다음 실행부터 즉시 적용됩니다.

이것이 Self-Tuning Loop의 Evolve 단계가 실제로 마찰 없이 작동하는 이유입니다.

graph LR
    REVIEW["주간 리뷰<br/>(토 03:00)"] -->|"프롬프트 패치"| FILE["prompts/*.md<br/>(Mini PC)"]
    FILE -->|"Syncthing 싱크"| MAC["Mac에서도<br/>수정 가능"]
    MAC -->|"Syncthing 싱크"| FILE
    FILE -->|"다음 실행 시<br/>자동 반영"| CLAUDE["Claude Desktop<br/>스케줄 태스크"]

코드 변경은 git으로

프롬프트가 아닌 소스 코드(collect-news.ts, collect-stats.ts 등)를 수정할 때는 기존 방식을 따릅니다.

Mac에서 코드 수정 → git push → Mini PC에서 git pull → pm2 restart

하지만 Self-Tuning Loop에서 진화하는 것은 프롬프트 파일이지 소스 코드가 아닙니다. 프롬프트 진화에는 배포 과정이 없다는 것이 이 아키텍처의 핵심 장점입니다.


$0 비용 구조

컴포넌트서비스비용
DB + Auth + Edge Function + StorageSupabase (무료 티어)$0
뉴스 검색 (월 1,000건)Tavily (무료 티어)$0
AI 큐레이션 + 디스패처 + 리뷰Claude Desktop (Max 구독 포함)$0 추가
웹 대시보드Lovable (무료 티어)$0
파일 동기화Syncthing (오픈소스)$0
24/7 서버Mini PC (기존 보유)전기세만
합계$0 추가 비용

Mini PC는 다른 프로젝트(Slack AI 에이전트)를 위해 이미 구매한 것이고, Claude Max 구독도 개발용으로 이미 사용 중이었습니다. 이 시스템을 위해 추가로 지출한 비용은 없습니다.


크론 스케줄 전체

시간 (KST)작업실행 환경비고
04:00뉴스 수집 (35개 소스)pm2 node-cron
04:05Stats 수집 (GA4 + GitHub + Naver)pm2 node-cron
06:00Safety-net 재검증pm2 node-cron누락 시 재실행
06:30AI 뉴스 큐레이션Claude Desktop
09:30Minbook 메타데이터 동기화pm2 node-cronGitHub API
10:00LinkedIn 자동 드래프트 2건Claude Desktop
매시 :00Telegram 태스크 디스패처Claude Desktop
토 03:00주간 뉴스 품질 리뷰Claude DesktopSelf-Tuning
토 03:15주간 LinkedIn 패턴 분석Claude DesktopSelf-Tuning

모든 pm2 cron에 { timezone: 'Asia/Seoul' } 명시. WSL2 환경에서 호스트 시간대 드리프트를 방지합니다.


6주 운영 데이터

뉴스 큐레이션

지표초기 (Week 1)현재 (Week 6)변화
일일 수집량80~120개130~200개소스 최적화 후 증가
실패 소스 비율15~20%5% 이내RSS URL 수정 + 폴백
신선도 필터60일14일주간 리뷰 자동 조정
cross-day 중복미검사직전 2일 검사주간 리뷰 제안 → 구현

인시던트

날짜사건원인대응
4/4GeekNews RSS 403URL 변경/rss/news로 수정
4/4Naver visitors 0날짜 형식 불일치전체 visitor 수집 후 최신값
4/8daily_stats 누락WSL2 cron silent miss3중 방어 구축 (Phase 4.2)
4/12블로그 태스크 17.5시간파일 생성 시 퍼미션 팝업 블로킹임시 파일 금지 규칙 + heredoc 패턴

자동 프롬프트 패치 이력

주간 리뷰가 실제로 패치한 것들:

  • 신선도 필터: 60일 → 14일 (오래된 기사 반복 선별 문제)
  • cross-day URL dedup 추가 (직전 2일 daily_news lookback)
  • 컨설팅펌 뉴스 우선순위 조건에 14일 이내 제한 추가
  • LinkedIn 드래프트 톤: 6타입 템플릿 체계화

아키텍처 요약

graph TB
    subgraph Mac ["💻 Mac (개발)"]
        CODE["코드 수정"]
        PROMPT_EDIT["프롬프트 수정"]
        DASH["대시보드 (브라우저)"]
    end

    subgraph Sync ["🔄 Syncthing"]
        S["실시간 양방향 동기화"]
    end

    subgraph MiniPC ["🖥 Mini PC (운영)"]
        PM2["pm2 크론<br/>수집 + safety-net"]
        CD["Claude Desktop<br/>큐레이션 + 디스패치 + 리뷰"]
        PROMPTS["prompts/*.md"]
    end

    subgraph Cloud ["☁️ Cloud"]
        SB["Supabase<br/>DB + Auth + Edge Function"]
        TG["Telegram Bot<br/>입력 + 알림"]
        LV["Lovable<br/>웹 대시보드"]
    end

    CODE -->|"git push/pull"| PM2
    PROMPT_EDIT --> S --> PROMPTS
    PM2 -->|"수집 데이터"| SB
    CD -->|"읽기/쓰기"| SB
    CD -->|"프롬프트 로드"| PROMPTS
    TG -->|"webhook"| SB
    SB --> LV
    LV --> DASH

5개 레이어, $0 추가 비용, 24/7 자동 운영.

Mini PC가 없어도 구현 가능합니다. Mac이 24/7 켜져 있거나, 클라우드 VM을 쓰면 됩니다. 핵심은 크론 + AI 디스패처 + 피드백 DB + 파일 싱크라는 조합이지, 특정 하드웨어가 아닙니다.


다음 편 예고

이 시스템은 특정 개인의 워크플로우에 맞춰져 있습니다. 다음 편에서는 Self-Tuning Loop의 핵심 패턴을 누구든 적용할 수 있는 모듈로 추출하고, GitHub에 레퍼런스 구현을 공개합니다.

  • 4단계 루프를 범용 모듈로 분리
  • Supabase 스키마 + 분석/진화 프롬프트 전문 공개
  • 이메일, 블로그 적용 예시
  • Quick Start 가이드

참고 자료

공유

관련 글