Claude Code로 나만의 개인 에이전트 만들기

OpenClaw GitHub 스타가 10만 개를 넘긴 사이, Mac Mini M4는 커뮤니티 게시판에서 품귀라는 말이 농담이 아니게 됐다. 항상 켜져 있고 10~15W밖에 안 먹는 기계가 개인 AI 비서의 표준 어플라이언스로 굳어가는 흐름이다.

하지만 솔직히 말하면, 이미 Claude Code를 메인 작업 환경으로 쓰고 있는 사람한테 OpenClaw가 정답일까. 새 스택을 또 하나 떠안기보다는 이미 익숙한 곳에 비서를 한 명 더 앉히는 게 자연스러울 수 있다. 이 글은 Claude Code 위에 Discord 채널 하나를 붙이고, 오케스트레이터 에이전트 한 개로 일정·태스크·메모리를 모두 굴려본 경험을 정리한 글이다.

핵심 요약

  • 개인 에이전트의 진짜 적은 “수동성”이다. 사용자가 먼저 말 걸기를 기다리는 비서는 결국 방치된다
  • Claude Code의 sub-agent + skill + hook 3종 구조면 OpenClaw 같은 별도 플랫폼 없이도 멀티 채널 비서를 만들 수 있다
  • 처음부터 거창하게 짓지 말고, 임원 비서 업무 두 가지(일정·태스크)부터 출발해 메모리와 회고 루틴을 얹는 식으로 키운다

왜 굳이 직접 만드는가

OpenClaw가 폭발적으로 성장한 이유는 명확하다. WhatsApp, Telegram, Slack, Discord, iMessage 같은 25개 이상의 채널을 한 큐에 꿰고, Mac Mini에 올려놓으면 24시간 잠들지 않는 비서가 된다. Peter Steinberger가 PSPDFKit 매각 이후 사이드 프로젝트로 시작한 게 어느새 표준이 됐다(Lenny’s Newsletter 인터뷰 참고).

[인물] I built a team of 9 AI agents that run my work and life. Here's how you can too.
출처: OpenClaw: The complete guide to building, training, and living with your personal AI agent

문제는 이걸 그대로 도입하면 자기 워크플로우를 OpenClaw에 맞춰야 한다는 점이다. 이미 Claude Code 안에 도메인별 프로젝트를 여러 개 굴리고 있다면 — AI 센싱, 마케팅, 영상 제작 같은 — 결국 두 시스템을 잇는 어댑터를 또 만들게 된다.

반대 방향이 더 자연스럽다. Claude Code 자체를 비서의 본체로 삼고, 채널은 인풋/아웃풋만 담당시키는 것. Claude Code는 이미 sub-agent로 컨텍스트를 격리하고, skill로 재사용 가능한 플레이북을 만들고, hook으로 결정론적 자동화를 박을 수 있는 풀스택을 갖췄다. 새 플랫폼을 배울 게 아니라, 이미 매일 쓰는 도구를 더 깊이 쓰는 길이다.

진짜 문제는 수동성이다

주변을 보면 OpenClaw나 비슷한 비서를 깔아놓고 처음 며칠은 신기해하다가, 어느 순간 “잘 있니?” 정도만 던지는 사람이 적지 않다. 도구가 부족해서가 아니라 사람이 먼저 말 걸기를 기다리도록 설계된 비서는 결국 방치된다.

이 분야를 오래 들여다보면 흔한 패턴이다. 사람은 생각보다 수동적이다. 그래서 비서가 먼저 Proactive하게 움직여야 한다. 예전 어시스턴트들이 푸시 노티로 추천을 쏟아붓던 시절은 솔직히 짜증났지만, 메신저 UI를 통해 “어제 못 끝낸 follow-up 3건 있는데 오늘 쳐낼래?” 같은 메시지가 먼저 오는 건 부담이 덜하다. 이건 톤의 문제다.

그래서 처음 설계할 때부터 이걸 핵심 원칙으로 잡았다.

핵심 요구사항왜 중요한가
[1] 음성 입력 가능운전 중·산책 중 떠오르는 brain dump를 놓치지 않기 위해
[2] 주기적 선제 제안비서가 먼저 말 걸지 않으면 결국 안 쓰게 된다
[3] 기존 Claude Code 프로젝트 활용도메인 작업을 처음부터 다시 짓지 않기 위해

임원 비서가 하는 일에서 출발하기

뭐부터 만들어야 할지 막막할 때, 회사에서 임원 비서들이 가장 많이 하는 업무가 뭔지 떠올려봤다. 답은 단순하다. 일정 관리와 태스크 관리. 거기서 시작했다.

  • 일정: Google Calendar를 연동했다. Work/Personal 캘린더를 자동 분류하고, “내일 오후에 1시간 회의 잡아줘” 같은 자연어 요청을 처리한다
  • 태스크: Things 3를 SQLite 직접 읽기로 연결했다. 쓰기는 URL scheme. brain dump가 들어오면 자동 분류해서 적절한 Project로 푸시한다

그리고 회사 비서가 절대 못 하는 한 가지를 추가했다. 개인 메모리 저장. 일기를 작성하고, 하루를 정리하는 루틴이다. 기억은 비서의 가장 큰 자산이다. 어제 무슨 결정을 했고, 지난주에 어떤 고민이 있었는지 떠오르는 비서와 매번 백지에서 시작하는 비서는 완전히 다른 도구다.

이게 다였다. 처음에는. 그리고 한 달 정도 굴려보면서 부족한 부분을 하나씩 메워나갔다.

Google Calendar 활용을 통한 일정 관리 연동

오케스트레이터 한 개로 모든 걸 라우팅하기

가장 중요한 설계 결정은 에이전트가 도메인 작업을 직접 하지 않게 하는 것이었다. 블로그도, 영상도, 논문 리서치도 이미 별도 Claude Code 프로젝트가 있었다. 오케스트레이터(Orchestrator)는 그저 입력을 받아 적절한 곳으로 위임하고, 결과를 받아서 사용자 채널로 회신하기만 하면 된다.

이걸 Delegate-First 원칙이라고 부른다. 도메인별로 잘 만들어진 외부 프로젝트들 — AI 센싱 팀, 영상 제작 팀, 위키 프로젝트 등 — 을 그대로 두고, 비서는 라우팅 허브 역할만 한다.

입력(Telegram / Discord / iMessage / Terminal)
  → router (분류)
  → sub-agent · skill · 외부 프로젝트 위임
  → 결과 회신 + 메모리 갱신 + 작업 큐 관리

라우팅 로직은 한 군데에서만 관리한다. .claude/routing/registry.yaml 파일 하나. 다른 곳을 수정하면 안 된다. 이 원칙을 깨는 순간 어디가 진실인지 알 수 없게 된다. 

라우팅 우선순위는 9단계로 정해놨다.

우선순위규칙예시
1명시 슬래시·프로젝트명 직접 언급/sensing/clip/remember
2Fast-path: 단일 trigger 단독 매칭 → router 우회“일정 등록” → calendar-agent
3공용 슬래시 tone 분기육아 → 가족 프로젝트 / 기술 → AI 센싱
4결과물 형식이 키영상 → youtube-contents, PPT → ai-sensing
5서사 프레임워크 매칭Minto / SCQA / Story Circle → storytelling
6리서치 분기새 주제 → 센싱 / 기존 위키 → llm-wiki
7체이닝 시퀀스“센싱 → 마케팅 → PPT”
8모호 시 한 줄 확인트리거 둘 이상 매칭
9매칭 없음 → 본 세션에서 처리잡담/메타

핵심은 2번 Fast-path다. 모호하지 않은 명령은 router를 거치지 않고 바로 위임한다. router 모델은 가장 무거운 Opus를 쓰고 sub-agent들은 Sonnet을 쓰는데, 매번 router를 거치면 비용이 몇 배로 뛴다.

Sub-agent로 컨텍스트를 격리하기

Claude Code의 sub-agent는 각자 자기만의 컨텍스트 윈도우를 가진 전문 인스턴스다. 검색 결과, 로그 덤프, 멀티스텝 추론 같은 verbose 출력이 본 세션을 더럽히지 않는다(Claude Code 공식 문서).

[아키텍처] Create and use specialized AI subagents in Claude Code for task-specific workflows and improved context management.
출처: Create custom subagents – Claude Code Docs

이 격리가 왜 중요할까. 일정 등록 한 번에 캘린더 API 응답 50KB가 본 세션에 박히면, 그 다음 대화부터 모든 토큰이 의미 없이 비싸진다. sub-agent를 쓰면 결과만 한 줄로 받아온다.

비서에 들어간 sub-agent는 13개다. 각자 단일 책임을 갖는다.

Sub-agent책임호출 시점
router분류·라우팅 결정모호한 자연어 입력
project-dispatcher외부 프로젝트 subprocess 실행도메인 작업 위임
memory-curatorwiki/palace 저장·회상기억 쓰기
calendar-agentGoogle Calendar CRUD일정 요청
daily-brief-agent아침 브리핑 (07:30)launchd 트리거
daily-reflection-agent저녁 회고 (22:00)수동/자동
brain-dump-agent4분류 (할일/아이디어/결정/사람)/braindump
things-agentThings3 To-Do CRUD태스크 요청
diary-agent일상 기록 저장자연 발화 감지

Hook으로 결정론적 자동화 박기

LLM이 못 하는 일이 있다. 매번 똑같이 하기. 모델은 “이 음성 첨부 오면 자동으로 STT 돌려줘”라고 시켜도 까먹는다. 그래서 Hook이 필요하다.

Hook은 이벤트 발생 시 실행되는 결정론적 스크립트다. 모델의 해석에 의존하지 않고 시스템 레벨에서 강제된다.

비서에 박은 hook 몇 개를 보면 감이 온다.

  • auto-memory.sh: 사용자 발화에서 사실/선호/결정을 자동 추출
  • new-topic-guard.sh: 새 주제 감지 시 /clear 안내 (토큰 절약)
  • discord-prompt-enforcer.sh: Discord 음성 첨부 자동 transcription
  • discord-stop-enforcer.sh: 종료 전 reply 호출 검사

특히 마지막 두 개가 음성 입력 요구사항을 푸는 핵심이다. Discord에 음성 메시지를 보내면 hook이 첨부 파일을 다운로드하고, whisper.cpp 로컬 모델(ggml-small.bin, 약 466MB)로 변환한 뒤 텍스트로 라우팅에 흘려넣는다. 외부 API 비용은 0원. Apple Silicon Metal 가속으로 충분히 빠르다.

메모리는 wiki + palace 하이브리드로

비서에게 기억을 주는 방식은 여러 가지다. 가장 단순한 건 매번 대화 로그를 다 읽게 하는 것. 하지만 이건 토큰을 게걸스럽게 먹는다. 반대로 모든 걸 RAG로 처리하면 문맥이 끊긴다.

쓴 방법은 하이브리드 위키 + 메모리 팰리스다.

계층역할특징
MEMORY.md항상 로드되는 인덱스한 줄당 ~150자, 새 페이지 추가 시 한 줄
memory/wiki/영구 지식개념·인물·아이디어·follow-up
memory/palace/work/작업 기억컨텍스트 단위
memory/daily/저녁 회고 산출물YYYY-MM-DD.md
memory/diary/일상 발화 누적시점별 자동 저장
memory/weekly/주간 회고YYYY-Www.md

핵심은 MEMORY.md다. 매 턴 always-on으로 로드되는 인덱스. 여기에는 정말 필요한 것만 한 줄씩 적는다. “이 사람은 광명시 철산동 거주, KBO는 키움 팬, 라우팅은 registry.yaml에서만 관리” 같은 식이다. 상세는 별도 wiki 페이지로 빠지고, 인덱스는 가볍게 유지한다.

데일리 루틴으로 Proactive 만들기

선제 제안 요구사항을 어떻게 풀었는지가 가장 흥미로운 부분이다. 시간 기반 트리거를 잔뜩 박아놨다.

시각트리거산출
07:30/start (launchd)오늘 캘린더 + follow-up + 이월 + 날씨 + 미세먼지 + 어제 KBO → Discord push
수시/braindump4분류, “할일”은 Things3 Inbox로 push
22:00/wrap-up저녁 회고 저장 + Discord 알림
일 20:00/weekly-review7일 데이터 집계 → 주간 회고

/start만 OS 레벨 launchd로 돌린다. 이유는 Claude Code 내장 cron의 durable=true 옵션이 무시되는 이슈가 있어서, 가장 중요한 아침 브리핑은 안전하게 launchd로 빼놨다. 다른 cron들은 daily-brief-agent의 cron-renewer skill이 매일 아침 만료가 24시간 미만인 항목을 자동 재등록한다.

이 루틴이 박힌 뒤로 비서를 쓰는 빈도가 확연히 달라졌다. 아침 7시 30분에 디스코드에 “오늘 미팅 3개, 어제 처리 못한 follow-up 2건, 미세먼지 나쁨”이 떠 있으면 자연스럽게 답장하게 된다. 비서는 먼저 말 걸어야 산다.

매일 아침 전달 되는 AI 센싱 브리핑

빈 MCP로 서브 클로드 격리하기

마지막으로 안 알려진 함정 하나. 외부 프로젝트로 위임할 때 그냥 claude -p "/sensing ..."을 쓰면 부모 세션의 플러그인과 MCP 설정이 따라간다. Telegram 플러그인이 stale-poller로 충돌해서 자식 프로세스가 409 Conflict로 죽는 사고를 한 번 겪고 나서 박은 패턴이다.

claude -p "/sensing weekly" \
  --strict-mcp-config \
  --mcp-config .claude/empty-mcp.json \
  --settings '{"enabledPlugins":{"telegram@claude-plugins-official":false}}'

빈 MCP 설정으로 자식 세션을 격리하면 부모의 플러그인 경합이 자식까지 번지지 않는다. 위임할 때마다 깨끗한 환경에서 시작하는 게 안전하다.

아직 갈 길은 멀다

솔직히 이 비서를 쓴 지 얼마 안 됐다. 부족한 부분이 많다. 데일리 루틴은 잘 도는데, 정작 /sync 같은 낮 시간 동기화 커맨드는 아직 미구현이다. Discord 재부팅 이슈도 풀어야 한다. launchd 자동시작이 없어서 재부팅하면 push 채널이 죽는다.

그래도 한 달 굴려본 인상은 분명하다. OpenClaw처럼 잘 만든 플랫폼을 가져다 쓰는 것보다, 이미 매일 쓰는 도구 위에 얇게 쌓는 게 결국 오래 간다. 비서는 도구의 풍성함이 아니라 자기 워크플로우와의 맞물림으로 살아남는다.

다음 단계로는 Mac Mini를 한 대 들여서 비서가 거기 살게 할 생각이다. 노트북에 묶여 있으면 24시간 비서가 못 된다. 항상 켜져 있어야 진짜 비서다. 이건 OpenClaw가 옳게 짚은 부분이다.

당장 시도해볼 수 있는 한 가지는 /braindump 같은 커맨드 하나만이라도 만들어 보는 것이다. 자연어로 떠오르는 것들을 던지면 4분류해서 적절한 곳에 보내주는 sub-agent. 이거 하나만 잘 굴려도 머릿속이 한결 가벼워진다. 비서를 처음부터 13개 sub-agent로 시작하지 말자. 하나씩 쌓는 게 맞다.

비슷하게 Claude Code로 개인 비서를 굴려본 경험이 있다면 댓글로 알려주면 좋겠다. 어디까지 위임하고, 어디부터는 직접 처리하는지 — 그 경계가 사람마다 어떻게 다른지 궁금하다.


참고 자료