01왜 이걸 하나
랩에서 실험을 돌리다 보면 컴퓨터가 금세 여러 대로 늘어난다. 매번 SSH로 접속하고, 터미널 세션을 만들고, 로그를 확인하는 일은 번거롭다. Slack 하나를 "공용 터미널"처럼 쓰면, 어디서든 스마트폰으로도 랩 서버를 제어할 수 있다.
이 튜토리얼이 끝나면 다음과 같이 일할 수 있게 된다.
04-25 07:56:30 28KB v2/translated/hagita.md ← 방금 04-25 07:51:26 125KB v2/translated/salisbury.md 04-25 07:30:05 41KB v2/translated/arbib.md 04-25 07:23:39 45KB v2/translated/arkin.md 04-25 07:16:03 65KB v2/translated/dario.md패턴: v2/translated/ 밑에 번역 md가 6–10분 간격으로 쌓이는 중.
02동작 원리
전체 구조는 의외로 단순하다. 네가 Slack 채널에 메시지를 던지면, 각 컴퓨터에서 돌고 있는 Claude Code가 그 채널을 주기적으로 읽고(폴링), 자기 이름이 불리면 일을 실행한 뒤 결과를 다시 채널에 쓴다.
핵심 3요소
- 공용 Slack 채널 — 모든 컴퓨터가 같은 채널을 읽고 쓴다. 메시지 버스 역할.
- 각 머신의 Claude Code 세션 — Slack MCP(또는 connector)가 붙어 있어서 채널을 읽고 쓸 수 있다.
- 주기적 폴링 루프(
/loop) — 각 에이전트가 1분 간격으로 채널을 확인하고 새 지시가 있으면 실행한다.
03사전 준비
본격적인 설정 전에 다음 네 가지가 준비되어 있어야 한다.
| 항목 | 설명 |
|---|---|
| Claude Code | 각 컴퓨터에 설치되어 있고 로그인된 상태. claude --version으로 확인. |
| Slack 워크스페이스 | 랩 공용 워크스페이스 또는 개인 워크스페이스. 채널을 만들 권한이 있어야 한다. |
| Slack MCP 연결 | Claude Code에서 Slack connector가 연결되어 있어야 한다. claude.ai 설정 → Connectors에서 Slack을 추가한다. |
| 전용 채널 | 예: #lab-agents, #progress-ping. 다른 사람 대화에 간섭 안 되게 전용으로 분리하는 걸 권장. |
04설정 절차
-
Slack에 전용 채널을 만든다
Slack에서 + 버튼으로 새 채널#lab-agents를 만든다. 공개/비공개는 상황에 따라. 민감한 경로(SSH 키, API 토큰 등)를 주고받을 거면 비공개 채널을 추천한다. -
첫 번째 컴퓨터(예: 랩 GPU 서버)에서 Claude Code를 연다
해당 머신에 SSH나 VNC로 접속해서 터미널을 띄우고, 프로젝트 작업 디렉토리로 이동한 뒤claude를 실행한다.
Slack connector가 제대로 붙었는지 먼저 테스트. "#lab-agents 채널에 '포도 깨어남' 이라고 메시지 보내줘" 라고 시켜본다. Slack에 메시지가 뜨면 성공.# 예: 랩 GPU 서버에 접속 후 $ ssh aprl@gpu-server.dgist.ac.kr $ cd ~/work/ $ claude -
에이전트 이름을 알려준다
Claude Code 세션 안에서 "앞으로 이 채널에서 '포도'라는 이름으로 불릴 거야. 다른 이름이 호출되면 무시해" 라고 지시한다. Claude Code의 메모리에 저장된다.> 너는 이 컴퓨터(랩 GPU 서버)에서 돌고 있어.
이름은 "포도". #lab-agents 채널에서
"포도야 ~" 로 시작하는 메시지만 너에게 온 지시야.
다른 이름(머루, 키위 등)이 호출되면 건너뛰어.
응답할 땐 "포도다 🍇 ~" 로 시작해. -
주기적 폴링 루프를 건다
/loop명령으로 채널을 1분마다 확인하게 만든다.
이렇게 걸면 세션이 켜져 있는 동안 계속 채널을 확인한다. 터미널을 닫으면 루프도 같이 종료되는 점에 유의./loop 1m #lab-agents 채널에서 "포도야"로 시작하는 새 메시지가 있으면 그 지시를 수행해 -
나머지 컴퓨터들도 같은 방식으로 설정한다
집의 워크스테이션은 "머루 🫐", 미니 PC는 "키위 🥝" 같은 식으로 이름만 다르게 해서 2~5번을 반복한다. 이름·이모지를 다르게 주는 이유는 채널 로그에서 어느 머신이 말하는지 한눈에 구분하기 위함이다. -
Slack에서 테스트해본다
스마트폰이든 노트북이든, Slack#lab-agents채널에 직접 메시지를 써본다.1분 이내에 해당 에이전트에서 답이 오면 성공.나Giseop포도야 현재 시간과 호스트명 알려줘
05에이전트 이름 붙이는 법
이름을 잘 정해두면 쓰기 훨씬 편해진다. 좋은 이름의 조건:
- 짧을 것 — 두 글자 한글이 멘션하기 제일 편하다.
- 다른 이름의 부분문자열이 아닐 것 — "포도"와 "포도알" 같은 건 피하자. 매칭이 꼬인다.
- 이모지와 짝지을 것 — 답변 앞에 항상 같은 이모지를 붙이게 하면 로그에서 식별이 빠르다.
추천 네이밍 패턴
| 컨셉 | 예시 | 장점 |
|---|---|---|
| 과일 시리즈 | 포도 🍇 / 머루 🫐 / 키위 🥝 / 감 🍊 | 귀엽고 기억하기 쉬움 |
| 머신 역할 | 집사 / 서기 / 전령 / 파수꾼 | 역할을 이름에 담아 의도가 드러남 |
| 모델명 기반 | 오푸스 / 소넷 / 하이쿠 | 어느 모델이 돌고 있는지 한눈에 보임 |
| 장소 기반 | 랩돌이 / 집순이 / 서버형 | 물리적 위치가 직관적 |
06실전 사용 예시
여기서는 실제 터미널에서 이렇게 로그가 찍힌다는 것을 그대로 보여준다. 학생들이 처음 돌려보면 "정말 이게 돌고 있나?" 싶을 때가 많은데, 아래 로그 패턴이 보이면 정상 동작이다.
A. 에이전트가 "대기 중"일 때의 로그
루프가 걸린 뒤, 아무도 메시지를 보내지 않으면 터미널에는 이런 로그가 반복된다.
1분마다 slack read channel을 호출해서 채널을 확인하고, 새 지시가 없으면 건너뜀을 기록한다.
지루해 보여도 이게 정상이다.
slack read channel 사용함— 에이전트가 채널을 한 번 읽었다는 뜻.포도 앞 새 지시 없음 — 건너뜀— 자기 이름이 포함된 새 메시지를 못 찾아서 아무것도 안 한 것.- 1분 간격이 일정하지 않을 수 있다. cron 최소 단위가 1분이라 58초~62초 사이에서 흔들리는 게 정상.
B. 지시가 들어왔을 때의 로그 (파일 현황 요청)
슬랙에서 "포도야 OneDrive의 roboticists interview 폴더에 어떤 파일이 최근 생성되고 있는지 표로 정리해서 알려줘" 라고 보냈을 때의 실제 세션 흐름:
Slack 채널에서는 같은 시점에 이런 대화가 오간다.
시각 (KST) 크기 경로 ──────────────────────────────────────────── 04-25 07:59:29 6KB .DS_Store 04-25 07:56:30 28KB v2/translated/hagita.md ← 방금 04-25 07:51:26 125KB v2/translated/salisbury.md 04-25 07:30:05 41KB v2/translated/arbib.md 04-25 07:23:39 45KB v2/translated/arkin.md 04-25 07:16:03 65KB v2/translated/dario.md 04-25 07:04:43 43KB v2/translated/dillmann.md 04-25 06:57:33 48KB v2/translated/khatib.md 04-25 06:49:33 59KB v2/translated/asada.md 04-25 06:38:25 40KB v2/translated/bajcsy.md 04-25 06:32:31 68KB v2/translated/dickmanns.md 04-25 06:22:01 60KB v2/translated/siegwart.md 04-25 06:11:16 49KB v2/translated/mataric.md 04-25 06:04:00 61KB v2/translated/ishiguro.md 04-25 05:55:14 73KB v2/translated/chatila.md패턴: v2/translated/ 밑에 번역 md가 평균 6–10분 간격으로 하나씩 생성 중. 최근 2시간 동안 15개 생성. 가장 최근은 hagita.md (약 3분 전).
C. 후속 지시 (파일 내용 요약)
위 결과를 보고 "그럼 그 md들 내용도 요약해봐"라고 이어서 지시할 수 있다. 같은 세션이 이어서 처리한다.
공통 포맷: IEEE 로봇공학 선구자들의 구술 역사 인터뷰(oral history) 한국어 번역본. 각 파일이 1명씩 커버.
구조: [이름 소개] → [인터뷰 소개] → 유년기/교육 → 초기 연구 → 주요 프로젝트 → IEEE·학회 활동 → 로봇공학 미래 전망 → 젊은 후학 조언
인물별 핵심 주제:
bekey — USC 이동 로봇, 로봇 보조기구, IEEE RAS 창립 멤버 chatila — SLAM 개발 참여, CNRS, Eden·COMET·Cogniron 프로젝트 ishiguro — 안드로이드 로봇 (Robovie, Geminoid, Telenoid) mataric — 사회적 보조 로보틱스(HRI), USC siegwart — 자율 마이크로 항공기, 행성 탐사 로봇 (ETH/EPFL) dickmanns — 동적 컴퓨터 비전, 자율주행차 (1970s~) bajcsy — GRASP 연구소 창립(UPenn), NSF CISE 리드 dillmann — 휴머노이드, PbD(Programming by Demonstration), KIT khatib — 로봇 제어·동작계획, Stanford, Romeo/Juliet asada — RoboCup 연맹 회장, 오사카대 적응기계시스템 arkin — 행동기반 로봇, 로봇 윤리, Georgia Tech arbib — 이론 신경과학 × 컴퓨터과학, USC dario — 생의학/마이크로 로봇, Scuola Sant'Anna salisbury — 햅틱 인터페이스, Stanford-JPL 손, 수술 로봇 hagita — 인간-로봇 상호작용, 네트워크 로봇, ATR howard — 치료용 로봇(Zyrobotics), NASA JPL, Georgia Tech결론: 이건 IEEE RAS가 기록한 로봇공학 원로들의 구술사 전집을 번역하는 작업. 전부 비슷한 서술 구조 + "이 분야가 어디서 와서 어디로 가는가"에 대한 1인칭 증언. 107명 중 16명 완료, 다음은 Robin Murphy.
D. 전체 흐름 타임라인
위 대화가 세션 안에서 시간순으로 어떻게 흘렀는지 정리하면:
bash 툴로 파일 목록 수집 → 표로 정리 → Slack에 전송.- 지시를 연달아 빠르게 보내도 괜찮지만, 이전 지시 처리가 끝난 후에 다음 지시가 잡힌다. 폴링 주기 내에 여러 메시지가 쌓이면 한 번에 묶어서 처리하는 경우도 있다.
- 답변이 길면 Slack에서 자동으로 끊어 여러 메시지로 올라갈 수 있다. 스레드로 답하게 지시해두면 채널이 깔끔해진다.
- 에이전트가 잠깐 "생각하는" 동안(툴 호출 중) Slack에는 아무것도 안 뜬다. 터미널 로그에서
●또는✓마크가 보이는지 확인.
E. 여러 에이전트를 병렬로 굴리기
에이전트를 여러 개 띄우는 건 두 가지 경로가 있다. 같은 원리로 돌아간다.
| 구성 | 언제 쓰나 | 예시 |
|---|---|---|
| 여러 머신 × 1세션씩 | 물리적으로 분산된 자원 활용 (랩 GPU + 집 PC + 서버) | 포도(랩) · 머루(집) · 키위(미니PC) |
| 한 머신 × 여러 세션 | 노트북 1대만 있어도 역할·프로젝트별로 분리 | 포도(DRIM 담당) · 머루(SLAM 담당) · 키위(문서정리 담당) |
중요한 건 에이전트가 돌아가는 물리적 위치가 아니라 독립된 Claude Code 프로세스가 몇 개인가다. 한 노트북 안에서 tmux 세션 3개를 띄워도 각 세션은 서로 모르는 독립된 일꾼이다. 각자 자기 이름으로만 반응한다.
# 한 노트북에서 세션 3개 띄우는 예
$ tmux new -s 포도 -d
$ tmux new -s 머루 -d
$ tmux new -s 키위 -d
# 각 세션 들어가서 claude 실행, 이름 알려주고 /loop 걸기
$ tmux attach -t 포도
# ... claude 실행, "너는 포도다" 지시, /loop 1m 걸기, Ctrl+B D로 빠져나옴
# 머루, 키위도 동일하게 세팅
머루야 SLAM 레포 git status 알려줘
키위야 오늘 다운로드 폴더에 뭐 쌓였는지 정리해
logs/drim_train.log 마지막 20줄:
epoch 42 loss=0.0234 val=0.0512 epoch 43 loss=0.0221 val=0.0508 epoch 44 loss=0.0215 val=0.0501 ← best ...
scalemaster/ git 상태: 스테이지 되지 않은 수정 3개 (configs/default.yaml, src/model.py, README.md). 커밋 필요.
~/Downloads에 쌓인 파일 8개 — PDF 5, 이미지 2, zip 1. PDF 중 4개는 arXiv 논문으로 추정. 폴더 정리해줄까?
세 에이전트가 각자 자기 이름만 받아서 병렬로 1분 안에 답한다. 여러 머신이든, 한 머신의 여러 tmux 세션이든 동작은 완전히 같다. 이게 이 구조의 진짜 강점 — SSH로 세 창 띄워서 따로 작업하던 걸, Slack 한 채널에서 동시에 시킬 수 있다.
~/research/drim/만 건드려라. 다른 폴더 요청이 와도 거부해."
07세션 영속성 — 오래 돌리기
/loop은 터미널 창을 닫으면 꺼진다. 장시간 돌리려면 추가 조치가 필요하다.
방법 1. tmux / screen 사용 (권장)
가장 간단하고 확실한 방법. SSH 세션이 끊어져도 백그라운드에서 계속 돈다.
# 랩 서버 접속 후
$ tmux new -s agent
$ claude
# ... /loop 명령 걸기 ...
# 세션에서 빠져나오기 (프로세스는 계속 돌아감)
$ Ctrl+B, 그 다음 D
# 나중에 다시 들어가기
$ tmux attach -t agent
방법 2. 클라우드 크론 (/schedule)
세션과 무관하게 클라우드 상에서 돌게 하려면 /schedule 명령을 사용한다.
다만 이건 작업의 성격(클라우드에서 실행되어도 되는 일인가?)에 맞을 때만 쓴다.
로컬 파일을 건드리는 일은 /loop + tmux가 맞다.
방법 3. systemd / launchd 서비스화 (고급)
재부팅 후에도 자동 복구하려면 OS 레벨 서비스로 등록해야 한다. 처음부터 이 단계까지 할 필요는 없고, 구조가 안정화되고 "이 세팅을 정말 오래 쓸 것"임이 확실해진 다음에 시도하자.
08보안과 권한 — 꼭 읽어볼 것
필수 체크리스트
--dangerously-skip-permissions절대 금지. Claude Code의 권한 확인 기능을 끄면 위험 명령도 그냥 실행된다.- 채널은 비공개(private)로. 경로·파일명·중간 결과가 다 로그에 남는다.
- API 키·비밀번호를 채널에 쓰지 않는다. 에이전트에게 필요하면 로컬
.env파일로 읽게 하자. - 위험 디렉토리는 접근 제한.
~/.ssh,~/.aws등은 에이전트가 건드릴 이유가 없다. Claude Code 설정의 allowlist/denylist를 활용한다. - "삭제" 계열 명령은 확인을 거치게 한다. 시스템 프롬프트에 "rm, git reset --hard, DROP TABLE 등 파괴적 명령은 실행 전 반드시 사용자 확인을 받아라" 박아두자.
09자주 겪는 문제
Q1. 에이전트가 반응을 안 해요
- 터미널 세션이 살아있는지 확인 (tmux에서 attach).
/loop이 켜져 있는지 확인. 중단됐으면 다시 걸기.- 채널에 직접 "지금 #lab-agents 채널 읽어줘" 라고 시켜서 Slack connector 자체가 동작하는지 점검.
Q2. 여러 에이전트가 동시에 반응해요
이름 매칭 규칙이 약해서 생기는 문제. 시스템 프롬프트를 더 명확히 쓴다.
메시지가 "포도야 "(띄어쓰기 포함)로 정확히 시작할 때만 처리.
그 외엔 전부 무시.
Q3. 1분 지연이 답답해요
급할 땐 터미널에서 직접 지시하자. Slack은 "원격에서 굳이 접속 안 하고 일 시키고 싶을 때"를 위한 채널이지, 실시간 REPL이 아니다. 폴링 주기를 30초로 줄일 순 있지만 그러면 API 비용이 2배가 된다.
Q4. 로그가 너무 쌓여요
에이전트마다 Slack 스레드를 사용하게 하면 채널 메인 화면이 덜 지저분해진다. "길게 답할 땐 스레드로 답해" 를 시스템 프롬프트에 추가한다.
103초 컷 부트스트랩 — agent-start 스킬
여기까지 따라왔다면 새 머신마다 또는 새 세션마다
(1) tmux 만들기 → (2) claude 실행 → (3) 이름·이모지 정해주기 → (4) 시스템 프롬프트 넣기 → (5) Slack 기상 알림 → (6) /loop 걸기 → (7) alive cron 예약
을 매번 손으로 해야 한다는 게 보였을 거야. 한 세션 만드는 데 30초~1분이 걸린다.
이걸 한 줄로 줄이는 부트스트랩 스킬을 별도로 패키징했다.
설치
스킬 패키지를 받아서 한 번만 설치 스크립트를 돌리면 끝. 새 터미널 또는 source ~/.zshrc 후부터 agent-start가 어디서든 동작.
# 1. 패키지를 받는다 (예: GitHub Pages에서 다운로드 또는 git clone)
$ git clone https://github.com/gisbi-kim/slack-claude-commander-tutorial.git
$ cd slack-claude-commander-tutorial/skill
# 2. 쉘에 alias 등록
$ bash install-alias.sh
$ source ~/.zshrc # 또는 ~/.bashrc
# 3. 끝. 어디서든 사용 가능
$ agent-start 포도
$ agent-list
$ agent-stop 포도
패키지 구성
스킬 폴더 안 5개 파일이 전부야. 각 파일을 클릭하면 GitHub Pages에서 바로 읽을 수 있다.
스킬이 강제하는 안전장치
- 이름 강제.
agent-start인자 없이 호출하면 즉시 에러 메시지 출력 후 종료. 아무 작업도 시작하지 않음. - 이모지 일관성. 한 번 확정한 이모지는 세션 종료까지 절대 변경되지 않음 (메모리에 고정).
- 이름 부분문자열 충돌 회피. "포"·"포도"처럼 접두사 충돌 가능한 이름 거부.
- tmux 세션 중복 방지. 같은 이름의 세션이 이미 있으면 거부.
- 채널 동명 에이전트 감지. Slack 채널 최근 로그를 확인해 같은 이름이 이미 살아있으면 거부.
- cron 재등록 버그 방지.
/loop안에/schedule을 넣지 않고 분리해서 한 번만 예약.
속도 비교
| 방식 | 소요시간 | 단계 수 | 실수 가능성 |
|---|---|---|---|
| 수동 (이 튜토리얼 04 ~ 05장) | 30초 ~ 1분 | 7단계 (각 손으로) | 높음 (이름·이모지·loop·cron 각각 깜빡) |
agent-start <이름> |
~3초 | 1단계 | 거의 없음 (스킬이 검증) |
agent-start를 쓰게 하는 게 좋다.
매번 손으로 하면 어딘가 빠뜨려서 "왜 안 돼요"라는 질문이 끊이지 않는다.
11"그럼 공식 Dispatch 쓰면 되지 않나요?"
Anthropic이 공식적으로 제공하는 Dispatch 라는 기능이 있다. 폰의 Claude 앱에서 메시지를 보내면 내 데스크톱이 받아서 일을 처리해주는, 말 그대로 "원격 조종" 기능이다. 네가 혹시 이미 Dispatch를 써봤다면 이런 의문이 들 수 있다 — "그냥 Dispatch 쓰면 되지, 왜 Slack으로 이 수고를 하나?"
정답부터 말하면 둘은 커버하는 범위가 다르다. 핵심 차이는 하나:
| 축 | 공식 Dispatch | 이 튜토리얼 (Slack 방식) |
|---|---|---|
| 연결 구조 | 폰 1대 ↔ 데스크톱 1대 (1:1 페어링) | Slack 채널 ↔ 머신 N대 (1:N) |
| 설정 난이도 | QR 코드 스캔 2번 (2분) | MCP 연결 + /loop 세팅 (30분) |
| 지연시간 | 즉시 | 최대 1분 (폴링 주기) |
| 잘 맞는 상황 | "폰에서 내 노트북에 일 시키기" | "랩 서버 + 집 PC + 미니 PC 동시 관리" |
- 폰에서 내 노트북 한 대에만 원격으로 일 시키는 거라면 → 공식 Dispatch가 훨씬 편하다. 이 튜토리얼은 덮어두자.
- 여러 대의 컴퓨터(랩·집·서버)를 한 채널로 묶어 관리하고 싶다면 → Dispatch로는 불가능. 이 Slack 방식이 답이다.
12마무리
작게 시작하자. 컴퓨터 한 대에 에이전트 하나부터 띄워서 1~2주 써보고, 편하면 두 번째 머신을 추가하는 식이 안전하다. 처음부터 랩 전체를 네트워크로 묶으려 하지 말 것.
질문이나 제안은 #lab-tutorials 채널로. 이 튜토리얼 자체도 Pull Request 환영이다.
- Claude Code 공식 문서 —
docs.claude.com/claude-code - MCP (Model Context Protocol) 이해하기 — 연결 구조의 근간
- tmux 치트시트 — 세션 관리 기본기