폰에 말하면 집 맥이 일한다 — 자작 음성비서 구성
받아쓰기·텔레그램 봇·집 맥의 게이트웨이·구독 CLI를 엮어 음성으로 맥을 부리는 자작 비서를 만든 과정과, 인격 오염·chat_id 함정, 안전 설계를 정리합니다.
손이 아니라 입으로 맥을 부리고 싶었다
설거지를 하다가, 산책을 하다가 문득 “집 맥 디스크 아직 여유 있나?”가 궁금할 때가 있습니다. 그때마다 집에 돌아가 터미널을 열거나 원격 데스크톱을 켜는 건 과했습니다. 결국 저는 폰에 대고 말만 하면 집 맥이 대신 일하고, 그 결과를 무선 이어폰이 읽어주는 구조를 직접 만들어 봤습니다.
전체 흐름은 이렇습니다. 폰에서 말한 것을 받아쓰기로 텍스트로 바꾸고 → 텔레그램 봇으로 그 텍스트를 보내고 → 집(혹은 사무실) 맥에서 돌아가는 게이트웨이(Node)가 메시지를 수신하고 → 구독 중인 AI CLI를 로컬 프로세스로 실행하고 → 결과를 다시 텔레그램으로 회신하고 → 폰 알림을 이어폰이 읽어주는 것입니다.
실제로 “디스크 용량 확인해줘”라고 말하면, 집 맥이 df를 실행하고 “431GB 남음” 같은 답을 텔레그램으로 돌려줍니다. 핵심은 별도 API 키를 새로 발급하지 않고, 이미 쓰고 있는 구독 CLI를 그대로 호출한다는 점입니다.
게이트웨이는 그냥 얇은 다리다
게이트웨이라고 거창하게 불렀지만, 하는 일은 단순합니다. 텔레그램에서 메시지를 받아서, 그 내용을 로컬 프로세스로 넘기고, 나온 결과를 다시 텔레그램으로 보내는 것뿐입니다.
텔레그램 메시지 수신
→ claude -p 로 로컬 실행
→ 화이트리스트 조회 명령만 수행
→ 결과 문자열을 텔레그램으로 회신
여기서 AI를 부르는 부분은 새로 뭔가를 붙이는 게 아니라, 구독 중인 CLI를 claude -p로 한 번 호출하는 게 전부입니다. 새 인프라도, 새 요금제도 아니고, 평소 쓰던 도구를 프로세스로 부르는 얇은 다리 하나를 놓은 셈입니다.
나를 이틀 잡아먹은 두 함정
머릿속 그림은 반나절이면 될 것 같았는데, 실제로는 사소한 두 곳에서 막혔습니다.
첫째, 인격이 바뀌는 문제입니다. claude -p를 그냥 부르면 실행한 폴더의 CLAUDE.md를 읽어 인격이 바뀝니다. 저는 음성비서로 부르는데, 프로젝트 폴더에서 실행하니 코딩 도우미처럼 답하더군요. 해법은 세 가지였습니다. 아무것도 없는 중립 폴더에서 실행하고, --system-prompt-file로 음성비서 페르소나를 고정하고, --allowedTools ""로 도구를 차단하는 것입니다. 이렇게 하니 비로소 “비서”의 말투로 고정됐습니다.
cd /path/to/empty-neutral-dir
claude -p "$MESSAGE" \
--system-prompt-file /path/to/assistant.txt \
--allowedTools ""
둘째, 텔레그램이 조용히 안 보내지는 문제입니다. 회신이 안 와서 한참을 헤맸는데, 에러도 안 났습니다. 원인은 chat_id 자리에 봇 이름(@...)을 넣은 것이었습니다. 여기에는 숫자 chat_id를 써야 합니다. 봇 이름을 넣으면 실패가 조용히 삼켜져서, 로그만 보면 정상처럼 보입니다.
# 잘못된 예 (조용히 실패)
chat_id = "@my_bot_name"
# 올바른 예
chat_id = "<숫자-CHAT-ID>"
토큰과 chat_id 실제 값은 여기 적지 않고 자리표시자로 둡니다. 이 두 값이 코드에 노출되면 그대로 남의 손에 넘어갈 수 있으니까요.
삭제는 음성에게 맡기지 않는다
가장 오래 고민한 건 기능이 아니라 안전이었습니다. 음성 인식은 한 번씩 엉뚱하게 알아듣습니다. 그 한 번의 오인식이 서버를 망칠 수 있다는 게 제일 무서웠습니다.
그래서 음성 경로에서는 조회 명령만 화이트리스트로 허용했습니다. 디스크 여유, 프로세스 상태, 백업 상태 확인 정도입니다. 삭제나 설정 변경은 음성 경로에서 아예 차단했습니다. “정리해줘” 같은 말을 잘못 알아들어 파일을 지우는 사고가, 조회 몇 개 막히는 불편보다 훨씬 크다고 봤기 때문입니다.
정리하자면, 이 구조의 판단 기준은 세 가지였습니다. 새 키를 만들지 말고 이미 쓰는 CLI를 재사용할 것, 인격과 도구는 실행 환경에서 강제로 고정할 것, 그리고 파괴적인 명령은 음성에게 절대 넘기지 말 것. 편리함은 이 세 선을 지키는 안에서만 의미가 있었습니다.
이런 자작 시스템의 삽질과 판단 기준을 종종 정리해 보냅니다. 비슷한 걸 만들어 보고 싶다면 뉴스레터를 구독해 두세요.
자주 묻는 질문
음성비서를 만드는데 별도 AI API 키가 꼭 필요한가요?
아니요. 이미 구독해서 쓰는 CLI가 있다면 그걸 로컬 프로세스로 호출하면 됩니다. 저는 claude -p를 게이트웨이에서 실행하는 방식으로 붙였고, 별도 API 키 발급 없이 구독 CLI를 그대로 재사용했습니다.
claude -p로 음성비서를 만들면 왜 코딩 도우미처럼 답하나요?
claude -p는 실행한 폴더의 CLAUDE.md를 읽어 인격을 바꾸기 때문입니다. 아무것도 없는 중립 폴더에서 실행하고, --system-prompt-file로 페르소나를 고정하면 음성비서 말투로 고정됩니다.
텔레그램으로 회신이 조용히 안 갈 때 먼저 볼 곳은 어디인가요?
chat_id 자리에 봇 이름(@...)을 넣었는지 확인하세요. 여기에는 반드시 숫자 chat_id가 들어가야 하고, 봇 이름을 넣으면 에러 없이 전송만 되지 않습니다.