Post

사내 업무 자동화 체계 구축 — devex에서 toolkit까지

devex로 이슈 플로우를 자동화한 뒤, 사내 특수 설정이 계속 늘어났습니다. OMC(oh-my-claudecode)의 구조를 참고하여 독립적인 사내 업무 자동화 플러그인을 만든 과정을 정리합니다.

사내 업무 자동화 체계 구축 — devex에서 toolkit까지

TL;DR devex로 이슈 플로우를 자동화한 뒤, 사내 특수 설정이 계속 늘어났습니다. OMC(oh-my-claudecode)의 구조를 참고하여 독립적인 사내 업무 자동화 플러그인을 만든 과정을 정리합니다.

1. 배경 — devex 이후에 남은 문제

devex는 Claude Code 플러그인으로, 이슈 생성부터 PR 머지까지의 개발 워크플로우를 /flow 한 번으로 자동화하는 오케스트레이터입니다.

하지만 사내에서 실제로 일하려면 이슈 플로우만으로는 부족했습니다.

  • 데일리로그: 매일 작성해야 하는 일일 업무 보고. 이슈 상태, 캘린더 일정, 근무시간 기록 시스템을 수집하여 조합해야 합니다.
  • Dooray API: 이슈 조회, 위키 발행, 메신저 알림 등 모든 사내 업무의 기반입니다.
  • 콘텐츠 파이프라인: 위키 작성 → 블로그 발행 → 스케줄 관리. 기술 블로그를 꾸준히 운영하려면 자동화가 필요합니다.
  • 성과 정리: 이슈 수집 → 프로젝트별 분류 → 연말 성과 평가 작성.

이런 설정들이 devex의 SKILL.md나 CLAUDE.md에 계속 쌓이면서 두 가지 문제가 발생했습니다.

첫째, 토큰 비용입니다. Claude Code는 세션 시작 시 CLAUDE.md를 매번 로드합니다. 사내 특수 설정이 여기에 쌓이면 Dooray와 무관한 세션에서도 토큰을 소비합니다. 공식 문서에서도 스킬/에이전트로 분리하여 온디맨드 로딩하는 것을 권장합니다.

둘째, 관심사 혼재입니다. devex는 이슈 플로우 오케스트레이터입니다. 데일리로그 규칙이나 위키 발행 절차까지 들어가면 책임이 모호해집니다. devex를 쓰지 않는 사람도 데일리로그는 필요할 수 있습니다.

2. OMC에서 영감을 얻다

oh-my-claudecode(OMC)는 Claude Code 위에서 동작하는 서드파티 멀티 에이전트 오케스트레이션 레이어입니다. 유저 스코프로 설치하여 빈 디렉토리에서도 글로벌하게 동작하는 방식이 필요했는데, OMC가 그 구조를 잘 구현하고 있었습니다. 직접 사용하면서 구조를 분석하고, 사내 플러그인 설계에 적용했습니다.

2-1. 스킬/에이전트 분리와 온디맨드 로딩

OMC는 수십 개의 에이전트(architect, executor, verifier 등)를 정의하지만, 세션 시작 시 모두 로드하지 않습니다. 스킬은 호출 시에만, 에이전트는 위임 시에만 로드됩니다.

이 패턴을 적용하여 사내 설정을 12개 스킬로 분리했습니다. 데일리로그 작업 시에는 dooray-dailylog 스킬만 로드되고, 위키 작성 시에는 content-write 스킬만 로드됩니다.

2-2. 읽기/쓰기 위임 분리

OMC는 읽기 작업을 경량 에이전트(haiku)에게 위임하고, 쓰기 작업은 메인 에이전트가 직접 처리합니다. 이 패턴을 toolkit에도 적용했습니다.

작업 유형처리 주체이유
Dooray 조회 (이슈, 위키, 캘린더)서브 에이전트독립적, 메인 컨텍스트 절약
Dooray 수정 (이슈 생성, 위키 발행)메인 에이전트 직접커스텀 프로토콜 보존 필요

서브 에이전트의 응답이 메인 에이전트로 전달될 때 URL 정규화가 일어납니다. 커스텀 프로토콜이 https://로 변환되어 사내 연동이 깨졌습니다. 쓰기 작업을 메인 에이전트로 제한하여 해결했습니다.

2-3. 키체인 기반 보안

OMC 생태계의 여러 플러그인이 환경변수 대신 macOS Keychain을 사용하는 패턴을 참고했습니다. 환경변수는 셸 히스토리에 노출되고 세션 종료 시 사라지지만, Keychain은 하드웨어 암호화와 영속성을 동시에 제공합니다.

# 키체인 헬퍼 — 모든 스킬이 공유
source ~/.claude/toolkits/dooray/config/keychain.sh
API_TOKEN=$(keychain_get "api-token")

3. 플러그인 구조 — 12개 스킬

toolkit의 디렉토리 구조는 다음과 같습니다.

dooray-toolkit/
├── config/
│   ├── keychain.sh      # 키체인 헬퍼 (전 스킬 공유)
│   └── user.json        # 사용자 정보
├── agents/
│   └── dooray-api.md    # 조회 전용 서브 에이전트
└── skills/              # 12개 스킬
    ├── dooray-api/      # API 인증 가이드 + 레퍼런스
    ├── dooray-dailylog/ # 데일리로그 자동화 (핵심)
    ├── dooray-notify/   # 메신저 알림 (webhook)
    ├── dooray-wiki-write/ # 위키 발행 오케스트레이터
    ├── content-write/   # 개인 위키 포스팅
    ├── publish/         # 블로그 발행 (대외비 제거)
    ├── collect/         # 이슈 수집
    ├── sync-issue-wiki/ # 이슈 → 위키 동기화
    ├── review/          # 성과 리뷰
    ├── work-review/     # 연말 성과 평가
    ├── peer-review/     # 동료 리뷰
    └── db-client/       # MySQL 다중 환경 접속

스킬을 기능별로 분류하면:

영역스킬사용 빈도
일일 업무dooray-dailylog, dooray-notify매일
콘텐츠content-write, publish, dooray-wiki-write주 2회
이슈/성과collect, sync-issue-wiki, review, work-review, peer-review분기~연
인프라dooray-api, db-client필요 시

db-client는 사내 업무 자동화와 성격이 다릅니다. 다만 Keychain 기반 인증과 다중 환경 관리라는 공통 인프라를 공유하므로 같은 플러그인에 포함했습니다. 다만 이 영역의 위험도는 다음 편에서 별도로 다룹니다.

4. 데일리로그 자동화 — 가장 깊은 스킬

12개 스킬 중 가장 복잡하고, 자주 쓰이며, 많은 교훈을 준 스킬입니다.

4-1. 왜 자동화했는가

데일리로그는 단순 메모가 아닙니다. 다음 정보를 매일 수집하여 정해진 구조로 조합해야 합니다.

  • 어제 완료한 이슈와 오늘 진행할 이슈 (Dooray 이슈 상태 기반)
  • 오늘 캘린더 일정 (회의 포함 여부 판단)
  • 근무시간 기록 (프로젝트별 시간 배분)
  • 장기 계획에서 일일 계획으로 이동한 항목

수동으로 하면 매일 15~20분, 자동화 후 확인만 하면 2~3분입니다.

4-2. 3단계 파이프라인

데일리로그는 3단계 파이프라인으로 생성됩니다.

Phase 1: 데이터 수집 (스크립트, 병렬)
  ├── preflight.sh   → 사용자, 날짜, 중복 확인, 전일 본문
  ├── check-issues.sh → 미체크 이슈 워크플로우 상태 (병렬)
  └── get-calendar.sh → 오늘 캘린더 필터링 (병렬)
          ↓
Phase 2: 본문 생성 (Python, 11개 처리 단계 적용)
  └── compose-body.py → dailylog-body.md + dailylog-meta.json
          ↓
Phase 3: API 작성 (메인 에이전트)
  └── POST → 워크플로우 변경 → 캐시 갱신 → 근무시간 입력 요청

Phase 1은 셸 스크립트로 데이터를 수집합니다. preflight.sh가 먼저 실행되어 중복 생성을 차단하고, 이후 이슈 확인과 캘린더 조회가 병렬로 실행됩니다.

Phase 2는 Python 스크립트(compose-body.py)가 수집된 3개의 JSON 파일을 읽어 11개 처리 단계를 적용하여 본문을 생성합니다. 전체 규칙은 rules.md에 상세히 기술되어 있습니다.

Phase 3은 메인 에이전트가 직접 API를 호출합니다. 2-2절에서 설명한 커스텀 프로토콜 보존 문제 때문입니다.

4-3. 11개 처리 단계가 쌓이기까지

이 단계들은 처음부터 설계한 것이 아닙니다. 운영하면서 하나씩 발견하고 추가했습니다.

#처리 단계발견 계기
1날짜를 항상 명시적으로 조회AI가 시스템 시간을 추론하여 날짜를 틀림
2개인별 관리 (현재 사용자만)다른 사람의 데일리로그를 수정하는 사고
3담당자/수정일 필터과거 이슈가 오늘 데일리로그에 혼입
4PUT 전 유효성 검증오래된 캐시로 덮어쓰기
5중복 생성 방지같은 날 데일리로그 2개 생성
6완료 이슈 정리비영업일 완료 이슈가 누적
7하이브리드 완료 처리API 상태와 체크박스 불일치
8캘린더 확인내일 일정을 일일 계획에 반영
9목요일 리셋근무시간 테이블 초기화 누락
10근무시간 정합성 검증날짜 범위 불일치
11마크업 보존HTML 엔티티가 API 통과 시 깨짐

특히 2번(다른 사람의 데일리로그 수정)은 AI가 사용자를 구분하지 못하고 팀원의 데일리로그를 덮어쓸 뻔한 사고였습니다. 이후 모든 쓰기 작업 전에 userId 필터를 강제하는 방식으로 방지했습니다.

이 단계들이 rules.md에 축적되어 있고, compose-body.py가 자동 적용합니다. AI가 규칙을 읽고 적용하는 것보다, 스크립트가 강제하는 것이 확실합니다.

4-4. devex:flow와의 연결

데일리로그는 devex의 이슈 플로우와 양방향으로 연결됩니다.

/issue create → 장기 계획에 이슈 추가
/issue start  → 장기 계획에서 일일 계획으로 이동
/issue complete → 일일 계획에서 체크 표시
데일리로그 생성 → 완료된 이슈를 주간 보고로 이관

이 연결은 devex의 프로바이더 시스템을 통해 이루어집니다. 프로바이더는 특정 이슈 트래커(GitHub, Dooray, Jira 등)와 통신하기 위한 어댑터 파일입니다. 로컬 프로바이더에 Dooray 전용 설정(API 인증, 워크플로우 ID, 데일리로그 연동 규칙)이 정의되어 있습니다. devex:flow가 이 프로바이더를 읽어 toolkit의 스킬을 호출합니다.

devex:flow → internal.md (프로바이더) → toolkit:dooray-dailylog

devex와 toolkit의 연결점은 이 프로바이더 파일 하나뿐이므로 결합도가 낮습니다. 사내 플랫폼이 바뀌어도 프로바이더만 교체하면 되고, devex의 이슈 플로우 로직은 변경할 필요가 없습니다.

5. 노트북 교체 대비 — 데스크탑 독립 환경

실제 운영하다 보니 플러그인이 3개, 스킬이 수십 개로 늘어나면서 환경 이식성도 중요해졌습니다. 3년 주기 노트북 교체를 대비하여 모든 플러그인을 사내 레포에 올렸습니다.

레포내용환경 의존성
claude-devex이슈 플로우 오케스트레이터없음 (범용)
claude-toolkit사내 업무 자동화API 토큰 (Keychain)
claude-ssh-tools서버/인프라 접근SSH 키, Kerberos 비밀번호 (Keychain)

새 노트북에서의 복원 절차:

  1. claude plugin install 3개 플러그인 설치
  2. Keychain에 토큰/비밀번호 등록 (1회)
  3. 로컬 프로바이더 파일 복사 (git 제외 파일)

비밀정보는 Keychain에만 존재하고, 프로바이더의 개인 설정만 수동 복사하면 됩니다.

6. 교훈

  1. 관심사를 플러그인 단위로 분리합니다. devex(이슈 플로우), toolkit(사내 업무), ssh-tools(인프라)는 각각 독립 설치/삭제가 가능합니다. 역할별로 나누면 불필요한 토큰 소비를 줄일 수 있습니다. 다른 사람에게 일부만 공유하는 것도 가능합니다. OMC의 구조를 참고했지만, 기능 의존성은 처음부터 없습니다. 독립적으로 설계했기 때문에 OMC 없이도 동작합니다.

  2. 반복되는 규칙은 코드로 강제합니다. 데일리로그의 11개 처리 단계는 compose-body.py가 자동 적용합니다. AI가 매번 rules.md를 읽고 적용하는 것보다, 스크립트가 강제하는 것이 빠뜨림 없이 확실합니다.

  3. 프로바이더 패턴으로 결합도를 낮춥니다. devex와 toolkit의 연결점은 프로바이더 파일 하나뿐입니다. 사내 플랫폼이 바뀌어도 프로바이더만 교체하면 됩니다.

이 글은 Claude와 함께 작업했습니다.

This post is licensed under CC BY 4.0 by the author.