Skip to content

백엔드 개발자의 AI 비서 만들기 (1편) — 1월 28일, 맥미니와 Anthropic 공지

📚 시리즈: 백엔드 개발자의 AI 비서 만들기

1 / 3
  1. 11편 - 왜 만들었나지금 읽는 중
  2. 22편 - 메시지 처리 과정
  3. 33편 - RAG 기억 시스템
백엔드 개발자의 AI 비서 만들기 (1편) — 1월 28일, 맥미니와 Anthropic 공지




TL;DR

  • 발단 1: 1월 28일, 당근마켓에서 맥미니 중고 충동구매 → “기왕 돈 썼으니 제대로 해보자”
  • 발단 2: 바로 그 주, Anthropic이 Claude Max를 서드파티 SaaS에 연결하면 계정 밴 예고
  • 두 가지가 겹쳤다: 서버가 생겼고, 직접 만들 수밖에 없는 이유도 생겼다
  • 48시간 후: Discord 메시지를 보내면 집 맥미니가 Claude를 돌려 답해주는 프로토타입 완성
  • 지금: 크론 93개, RAG 12만 청크, 대시보드까지 — 그 충동구매 하나가 만들어낸 결과

1월 28일, 당근마켓

사실 Jarvis의 시작은 Anthropic 공지가 아니었습니다.

1월 28일, 당근마켓을 켰다가 눈에 띄는 매물을 발견했습니다. 맥미니 M2 16GB, 거의 새것인데 가격이 말도 안 되게 쌌습니다. 고민을 20초쯤 했나요. 채팅을 보내서 약속을 잡았습니다.

직거래로 받아온 맥미니를 책상에 놓으면서 생각했습니다.

“기왕 샀으니까 제대로 써보자.”

항상 켜둘 수 있는 서버가 생겼다는 게 핵심이었습니다. 그때까지는 개인 프로젝트를 클라우드 VM에 올렸는데, 비용도 신경 쓰이고 껐다 켰다 하는 게 번거로웠습니다. 맥미니는 전기세만 내면 24시간 돌릴 수 있습니다. M2 칩이라 발열도 적고, 소음도 없고, 책상 한 켠에 조용히 있으면 됩니다. 월 전기세가 얼마나 추가됐는지는 확인했지만 여기에 쓰지는 않겠습니다. 아내가 읽을 수도 있으니까요.

막연하게 “이걸로 뭔가 자동화를 해봐야겠다”는 생각이 들었습니다. AI 관련 뭔가를. 구체적으로 뭘 만들지는 몰랐지만.


같은 주, Anthropic 공지

맥미니를 받고 며칠 뒤, 이런 공지를 읽었습니다.

“Claude.ai Pro/Max 플랜 구독자가 해당 계정을 제3자 애플리케이션 또는 서비스에 연결하여 API처럼 활용하는 행위는 이용약관 위반에 해당합니다. 해당 행위가 감지될 경우 사전 통보 없이 계정이 영구 정지될 수 있습니다.”

읽고 나서 5초 정도 멍했습니다.

공지는 명확했습니다. Claude Max 구독을 서드파티 앱에 연결해서 쓰는 행위 자체가 대상이었습니다. Claude Max(월 $100)에 자동화 스크립트 3개가 동시에 연결돼 있었으니, 딱 해당하는 케이스였습니다.

선택지가 갑자기 명확해졌습니다.

  1. 그냥 쓰다가 어느 날 계정이 날아가는 경험 하기
  2. Claude를 아예 안 쓰기
  3. 직접 만들기

2번은 불가능했습니다. 2025년 중반부터 AI 없이 개발한다는 건 계산기 없이 회계하겠다는 말이랑 비슷해졌습니다. 그리고 마침 방금 맥미니를 샀습니다. 24시간 돌릴 수 있는 서버가 있습니다.

두 가지가 딱 맞아 떨어졌습니다. 맥미니 = 인프라, 밴 공지 = 동기. 직접 만들기로 했습니다.


claude -p 한 줄이 전부를 바꿨다

직접 만들기로 결정하면 먼저 무엇이 가능한지를 파악해야 했습니다.

Claude API를 쓰는 방법이 있었는데, 비용이 문제였습니다.

구분Claude API (종량제)Claude Max (정액)
요금사용량 비례, 월 $30~50+월 $100 고정
CLI 자동화별도 구현 필요claude -p 기본 제공
예측 가능성낮음 (자동화 붙이면 폭등)높음

Claude Max에는 claude -p — 터미널에서 헤드리스로 Claude를 호출하는 기능이 포함돼 있었습니다.

echo "오늘 PR 리뷰해줘" | claude -p "당신은 시니어 백엔드 개발자입니다."

이 한 줄이 가능하다는 걸 알고 나서 한동안 그냥 이것저것 실험했습니다. “이게 되네, 이것도 되네”를 반복했습니다. 쉘 스크립트에서 Claude를 호출할 수 있다면, launchd 크론에서 호출할 수 있다면, Discord 봇에서 호출할 수 있다면 — 자동화의 범위가 완전히 달라집니다.


설계 결정: Discord와 기억

만들기로 했으면 두 가지를 결정해야 했습니다.

어디서 쓸 것인가. 후보는 셋이었습니다.

방식장점단점
웹 앱 (Next.js)UI 편함개발 시간 오래 걸림
CLI 스크립트간단함모바일 불가, 알림 없음
Discord 봇모바일/PC 동시, 알림 기본Discord 서버 필요

Discord를 선택한 이유는 단순했습니다. 이미 하루에 10번 이상 열고 있었습니다. 새 앱을 만들어봤자 결국 안 쓰게 될 게 뻔했습니다. 쓸 도구는 이미 켜져 있는 앱 안에 있어야 합니다.

기억 문제. Claude는 기본적으로 매 대화가 초기화됩니다. 이걸 해결하지 않으면 그냥 Claude.ai 웹 쓰는 것과 다를 게 없었습니다. 두 가지를 조합하기로 했습니다.

  • 시스템 프롬프트 주입: 내 기술 스택, 현재 프로젝트, 성격을 매 대화에 자동으로 삽입
  • RAG 장기기억: 이전 대화를 벡터 DB에 저장하고, 관련 내용이 있으면 꺼내줌

기억 문제는 나중에 생각보다 훨씬 복잡하다는 걸 알게 됩니다. 그 얘기는 3편에서 합니다.


v0.1: 48시간, 그리고 첫 번째 삽질

맥미니를 받은 주말, 만들기 시작했습니다.

첫 버전은 단순하게 잡았습니다. Discord 메시지가 오면 → claude -p에 넘기고 → 응답을 Discord로. 그게 전부.

그런데 첫 테스트에서 바로 막혔습니다.

Discord에 메시지를 보냈습니다. 응답이 없습니다. 60초 후, 프로세스가 종료됐다는 로그가 찍혔습니다. 다시 실행. 메시지를 보냈습니다. 응답이 없습니다. 60초 후 종료. 이게 세 번 반복됐습니다.

동작은 하는데 응답이 없다는 게 가장 황당했습니다. 에러도 아니고, 그냥 조용히 타임아웃입니다.

원인은 TTY였습니다. claude -p는 처음 실행 시 인증 확인 프롬프트가 뜹니다. 터미널에서 직접 실행하면 사용자가 입력할 수 있지만, launchd 데몬은 TTY가 없어서 그 프롬프트에서 하염없이 기다리다 60초 후 자동 종료됩니다.

launchd plist에 HOME 경로와 PATH를 명시적으로 지정하고, 사전에 인증을 완료해두는 방식으로 해결했습니다. 지금 생각해보면 당연한 건데, “설치까지 다 했는데 왜 안 돼”를 반나절 동안 반복하다 찾았습니다. 데몬 환경은 터미널이 아니라는 걸 이 삽질로 배웠습니다.

나머지 반나절에 기본 동작을 완성했습니다.

v0.1의 전체 흐름은 이게 전부입니다.

graph LR
    U(["👤 Owner\n모바일 · PC"])
    D["Discord\n서버"]
    B["Node.js 봇\n맥미니 상주"]
    C["Claude Max\nclaude -p CLI"]

    U -->|"메시지 입력"| D
    D -->|"이벤트 수신"| B
    B -->|"헤드리스 호출"| C
    C -->|"텍스트 응답"| B
    B -->|"메시지 전송"| D
    D -->|"응답 표시"| U

복잡한 게 없습니다. Discord에서 받고, 맥미니가 CLI를 실행하고, 결과를 돌려줍니다. 미들웨어도, 큐도, API 서버도 없습니다. 그냥 이게 다입니다.


“아, 이게 되네” 순간

일요일 오후였습니다. 맥미니는 방에서 켜져 있고, 저는 근처 카페에서 커피를 마시고 있었습니다. 휴대폰으로 Discord를 열었습니다.


#jarvis-work

오늘 개발 계획 잡아줘. Spring Batch 로직 리팩토링 남았고, 블로그 초안도 써야 하는데 우선순위 정해줘


Jarvis (4초 후)

우선순위 정리해드리겠습니다.

1순위 — Spring Batch 리팩토링 (2~3시간 예상) Chunk 방식 전환 전, 현재 Tasklet 로직의 트랜잭션 경계부터 파악하세요. 리팩토링 중간에 구조를 바꾸면 롤백 포인트를 잃습니다.

2순위 — 블로그 초안 (1시간) 리팩토링 후 실제 성능 수치가 나와야 글의 핵심 데이터가 생깁니다. 수치 없이 쓰면 나중에 다시 써야 합니다.


방에 있는 맥미니가 제 질문을 받아서, 거기 설치된 Claude CLI를 실행하고, 응답을 Discord로 보내줬습니다. 카페에서, 모바일로.

이 순간이 확신이 됐습니다. “이게 진짜 될 수 있겠다.”


맥미니가 24시간 켜져 있다는 것

동작을 확인하고 나서 launchd 서비스로 등록했습니다. macOS launchd는 systemd와 비슷합니다. 부팅 시 자동 시작, 크래시 시 재시작.

맥미니가 항상 켜져 있다는 게 생각보다 훨씬 중요한 조건이었습니다. 노트북이었다면 잠자기 모드에 들어가거나 덮개를 닫으면 크론이 죽습니다. 맥미니는 화면이 꺼져도 CPU는 계속 돌아갑니다.

지금 launchd에 등록된 Jarvis 관련 서비스 수입니다.

$ launchctl list | grep jarvis

PID    Status  Label
12847  0       com.jarvis.bot
13021  0       com.jarvis.cron.morning-brief
13022  0       com.jarvis.cron.infra-daily
13023  0       com.jarvis.cron.blog-sync
13024  0       com.jarvis.cron.git-monitor
-      0       com.jarvis.cron.weekly-retrospect
...
(총 93개)

v0.1 시점엔 com.jarvis.bot 하나였습니다. 지금은 93개입니다.

93개가 구체적으로 어떤 일을 하는지 카테고리별로 묶으면 이렇습니다.

graph TD
    ROOT["⏰ launchd 크론\n93개"]

    ROOT --> DEV["🛠 개발 지원 — 약 28개"]
    ROOT --> BLOG["✍️ 블로그·커리어 — 약 22개"]
    ROOT --> OPS["📡 인프라 모니터링 — 약 27개"]
    ROOT --> LIFE["🗓 일상·기록 — 약 16개"]

    DEV --> D1["PR / 이슈 모니터링"]
    DEV --> D2["배포 상태 체크"]
    DEV --> D3["코드 리뷰 알림"]

    BLOG --> B1["포스팅 아이디어 수집"]
    BLOG --> B2["면접 일일 기록"]
    BLOG --> B3["기술 트렌드 요약"]

    OPS --> O1["디스크·메모리 감시"]
    OPS --> O2["Cloud Run 헬스체크"]
    OPS --> O3["에러 로그 집계"]

    LIFE --> L1["아침 브리핑"]
    LIFE --> L2["주간 회고"]
    LIFE --> L3["운동 기록"]

처음부터 93개를 설계한 게 아닙니다. “이것도 자동화할 수 있겠는데?”가 반복되면서 쌓인 결과입니다. 하나씩 보면 각자 “이게 없으면 불편한” 역할이 있고, 합치면 93개입니다. 이 숫자 자체가 문제의 시작이기도 했는데, 그 얘기는 아래 한계 섹션에서 합니다.


지금의 Jarvis: v0.1에서 얼마나 달라졌나

항목v0.1 (Day 3)현재
Discord 채널1개 (범용)11개 (업무/자동화/모니터링/블로그 등 목적별)
크론 스케줄러0개93개 (launchd 기반)
장기기억없음LanceDB 기반 RAG, 12만 청크
안전장치없음watchdog + 자동복구 + 4단계 장애예방
웹 대시보드없음Jarvis Board (board.ramsbaby.com)
월 비용$100 (Max 구독만)$100 + GCP Cloud Run ~$3

두 가지 크론 예시를 들면,

아침 브리핑 (매일 오전 8시): 전날 밤 사이에 생긴 GitHub PR 상태, 미완료 태스크, 날씨를 취합해서 Discord DM으로 보내줍니다. 출근 전에 오늘 뭐부터 해야 할지 이미 정리돼 있습니다.

인프라 일일 리포트 (매일 오후 6시): Cloud Run 서비스 상태, launchd 데몬 이상 여부, 에러 로그 요약을 Discord #ops-daily 채널에 포스팅합니다. 이 리포트 덕분에 서비스가 조용히 죽어있던 걸 다음날 아침이 아니라 당일 오후에 잡은 적이 여러 번 있습니다.


솔직한 한계

한계 1: Claude Max 사용 한도

무제한이 아닙니다. 크론이 몰리거나 긴 컨텍스트 대화를 반복하면 5시간 쿼터에 걸립니다.

실제로 어느 날 오전, 크론 4개가 동시에 실행되는 시간대에 긴 기술 질문을 던졌다가 쿼터 초과로 Jarvis가 무반응이었습니다. 봇이 죽은 줄 알고 SSH를 열었는데, 로그에는 “5시간 한도 초과”였습니다. 그 이후로 크론 실행 시간대와 주요 대화 시간을 최대한 분리했습니다. 완벽하진 않지만 충돌 빈도는 크게 줄었습니다.

한계 2: 맥미니가 꺼지면 Jarvis도 꺼진다

여행 중이거나 장시간 자리를 비울 때 가장 불안합니다. 실제로는 2박 3일 여행에서도 맥미니가 꺼지지 않아서 크론은 계속 돌았지만, 이게 언제까지 보장된다는 보장은 없습니다. 정전이나 네트워크 단절이 생기면 크론 93개가 전부 멈춥니다. 클라우드로 이전하는 것도 고민 중인데, claude -p가 클라우드 환경에서 실행되는 구조로 전부 바꿔야 해서 쉽게 결정이 안 됩니다.

한계 3: 유지보수 복잡도

크론이 93개를 넘어가면서 관리가 생각보다 힘듭니다. 하나가 실패했을 때 어디서 실패했는지 찾는 과정이 문제입니다. launchctl status로는 실패 여부만 알 수 있고, 원인은 각 로그 파일을 직접 열어봐야 합니다. 로그 파일이 여러 디렉터리에 흩어져 있어서, 로그 확인만으로 10분이 넘는 경우가 있었습니다. 이 문제를 해결하려고 Jarvis Board(웹 대시보드)를 만들었는데, 그 얘기는 4편에서 다루겠습니다.


마치며

솔직히 맥미니를 안 샀다면 Jarvis는 없었을 겁니다. “기왕 돈 썼으니 제대로 해보자”는 심리가 없었다면, Anthropic 공지를 읽고도 그냥 조용히 서비스 연결을 끊고 말았을 것입니다.

충동구매가 사이드 프로젝트를 만든다는 걸 이때 알았습니다.

다음 편에서는 Jarvis의 전체 구조를 다룹니다.

v0.1 때 채널이 하나였는데, 어느 날 “이번 주 블로그 주제 추천해줘”라고 물었더니 오전에 올라온 인프라 알림을 근거로 “서버 디스크 관리 자동화를 쓰면 어떨까요”라고 답했습니다. 블로그 글을 쓰려던 건데 DevOps 아이디어를 받은 겁니다.

그날부터 채널을 쪼개기 시작했습니다. 지금은 11개입니다. Discord 봇 → Nexus MCP → Claude CLI 전체 흐름, 아키텍처 다이어그램도 같이 정리합니다.

참고 :

https://www.anthropic.com
https://github.com/ramsbaby/openclaw




읽어주셔서 감사합니다.🖐


Ramsbaby
Written byRamsbaby
이 블로그는 직접 개발/운영하는 블로그이므로 당신을 불쾌하게 만드는 불필요한 광고가 없습니다.

#My Github#소개 페이지#Blog OpenSource Github#Blog OpenSource Demo Site