---
title: "케이스 스터디: ClaudeOps"
description: "한 줄 정의 여러 Claude 에이전트가 자율적으로 일하고, 서로의 작업을 같은 데이터베이스 위에서 추적·보고하는 개인 내부 협업 플랫폼이다. 왜 만들었나 이나 cron + 헤드리스로 자동화를 늘리다 보면 어딘가에서 막힌다. 자동화 하나하나는 잘…"
date: 2026-05-03
updated: 2026-05-03T14:02:11.861Z
tags: [사이드 프로젝트, claude, 클로드]
canonical: https://blog.wooncloud.com/posts/8
---

## 한 줄 정의

여러 Claude 에이전트가 자율적으로 일하고, 서로의 작업을 같은 데이터베이스 위에서 추적·보고하는 개인 내부 협업 플랫폼이다.

## 왜 만들었나

`/loop`이나 cron + 헤드리스로 자동화를 늘리다 보면 어딘가에서 막힌다. 자동화 하나하나는 잘 도는데, 그것들의 **상태가 어디에도 없다**. 어떤 잡이 마지막에 뭘 했는지, 다른 에이전트가 같은 파일을 손대고 있는지, 보고는 어디 쌓이는지 — 다 흩어져 있다.

자동화 개수가 셋을 넘기면 공유 상태 저장소가 필요해진다. ClaudeOps는 그 자리를 채우려고 만든 것이다.

## 핵심 설계 결정: 스케줄러 없는 스케줄러 플랫폼

가장 결정적인 선택은 **ClaudeOps 안에 스케줄러를 넣지 않은 것**이다.

처음엔 NestJS의 스케줄 모듈로 직접 cron을 돌리고, 시간이 되면 Anthropic API를 호출해서 에이전트를 깨우는 구조를 잡으려 했다. 그런데 그걸 다 만들면 ClaudeOps가 두 가지 일을 하게 된다 — *데이터 허브* + *AI 워커*. 한 시스템 안에 너무 다른 책임이 섞인다.

대신 깨우는 일은 외부에 맡겼다. **Claude Cowork의 스케줄러**가 정해진 시각에 에이전트를 깨우고, 깨어난 에이전트가 ClaudeOps API에 접속해서 스스로 할 일을 가져간다. ClaudeOps는 그냥 CRUD 서버다.

```
[Cowork 스케줄러]
   ↓ 에이전트 깨움
[Claude 에이전트 (Skills 문서 읽고 시작)]
   ↓ GET /api/agent/tasks/pending
[ClaudeOps]
   ↓ 할 일 반환
[에이전트 작업 수행]
   ↓ POST /api/agent/tasks/:id/report
[ClaudeOps에 보고 누적]
```

이 분리 덕에 얻은 것 세 가지.

- ClaudeOps에서 AI 호출 비용이 0이다. 비용은 Cowork 쪽 사용량 한도에서 처리된다.
- 에이전트가 10개로 늘어도 ClaudeOps는 여전히 가벼운 CRUD 서버다.
- ClaudeOps 자체는 내려가도 에이전트들이 일을 안 받아갈 뿐 깨는 동작은 멈추지 않는다. 책임 경계가 깔끔하다.

## 데이터 모델

테이블 네 개로 끝난다.

- **Agent.** 고유 `agent_id` + `api_key`. 누가 뭘 했는지 추적 가능.
- **Project.** 작업 단위 묶음. 새 사업이 생기면 프로젝트 하나 추가하고 에이전트 배정.
- **Task.** 등록된 할 일 + 상태(pending / in_progress / done / failed).
- **Report.** 에이전트가 작업 끝나고 남기는 결과.

권한은 Bearer 토큰. 한 에이전트의 토큰이 새도 그 에이전트 권한 범위 안에서만 위험하다.

## Skills 디렉토리: 프롬프트의 진짜 위치

에이전트의 프롬프트는 짧게 유지한다. "이런 일을 해라"는 길게 적지 않는다. 대신 **Skills 문서**라는 외부 마크다운을 두고, 깨어난 에이전트가 그걸 먼저 읽게 한다.

```
curl -s https://claudeops.wooncloud.com/api/skills/claudeops_usage
curl -s https://claudeops.wooncloud.com/api/skills/report_format
curl -s https://claudeops.wooncloud.com/api/skills/agent_roles
```

이게 좋은 이유:

- **운영 중에 행동을 바꿀 수 있다.** Skills 문서만 수정하면 모든 에이전트의 다음 실행부터 행동이 바뀐다. 프롬프트 자체를 안 건드린다.
- **프롬프트가 공통화된다.** 에이전트마다 다른 건 식별 정보(agent_id, api_key, 프로젝트명)뿐이고, 일하는 방식은 Skills에서 공유된다.
- **버전 관리된다.** Skills를 git에 두면 에이전트의 행동 변경이 커밋 히스토리로 남는다.

## 자율 동작 원칙: 할 일 없을 때도 일하기

이 부분이 단순 잡 큐와 가장 큰 차이다.

```
1. 깨어남
2. Skills 문서 읽음
3. 할 일 있나? 
   - 있으면 → 수행 → 보고 → 끝
   - 없으면 → 자체 리팩토링 모드로 전환
4. 단, 직전 5커밋에 refactor: 가 있으면 건너뜀 (과한 리팩토링 방지)
5. 어느 경우든 commit / push까지 끝낸다
6. 실패해도 실패 보고는 반드시 제출
```

"할 일이 없으면 쉬어"가 아니라 "할 일이 없으면 코드를 점검해" — 에이전트의 유휴 시간을 자기 개선에 쓰는 구조다. 다만 무한 리팩토링 루프를 막기 위한 가드(직전 5커밋 체크)가 들어가 있다.

## 자동화 카테고리에서의 위치

이 시리즈에서 다룬 방법들의 **조합**이다.

| 시리즈 항목 | ClaudeOps에서의 역할 |
|---|---|
| 외부 스케줄러 + 헤드리스 (3번) | Cowork이 정확히 이 패턴으로 동작 |
| Webhook + 헤드리스 (6번) | 향후 PR 이벤트로 깨우기로 확장 가능 |
| Hooks (5번) | 위험 명령 차단·자동 commit 메시지 검증에 적용 |

즉 ClaudeOps는 새로운 방법이 아니라, 기존 방법들이 **공유 상태** 위에서 협업하기 시작했을 때 필연적으로 나오는 형태다. 자동화가 일정 규모를 넘으면 누구나 비슷한 걸 만들게 된다.

## 한계와 다음 과제

만들고 운영해보면서 보이는 약점.

- **스케줄러 의존.** Cowork이 안 깨우면 ClaudeOps는 빈 서버다. Cowork 쪽 장애가 곧 자동화 정지로 이어진다.
- **동시 작업 충돌.** 두 에이전트가 같은 파일을 만지면 git 충돌이 난다. 현재는 git worktree로 분리하지만, 더 늘면 파일 단위 락이 필요해진다.
- **신뢰 경계.** 에이전트가 commit·push 권한을 갖는다는 건 자동화의 끝이자 가장 위험한 지점이다. hooks로 PreToolUse 단에서 위험 명령을 막는 건 거의 필수다.
- **관측.** 어떤 에이전트가 토큰을 가장 많이 쓰는지, 어떤 태스크가 자주 실패하는지 — 대시보드 단이 약하다. 다음 단계.

## 정리

처음엔 "에이전트들이 자율적으로 일하는 걸 보고 싶다"가 시작이었지만, 결국 만들고 보니 핵심은 모델 자체가 아니라 **스케줄러 + 공유 상태 + Skills 문서**의 조합이었다.

작은 플랫폼이지만, 이 시리즈에서 다룬 자동화 방법들의 종착지가 어떤 모양인지 보여주는 사례라고 생각한다. /loop이 임시 알람이고, 루틴이 등록된 잡이고, cron + 헤드리스가 전통적 스케줄러라면 — ClaudeOps는 그것들 위에 올라가는 *얇은 협업 레이어*다.
